VC: Playback of large WAV files (10/25/1999) Regular sound files in the design of multimedia software, using the API function SnDplaySound provided by Windows to play the playback of small WAV files. However, when the WAV file is greater than the available memory, the SndPlaySound function cannot play, so how do you use MCI to play large audio files? This article will introduce a method. Windows supports two Riff (Resource Interchange File Format, "Resource Interaction File Format") audio file: MIDI's RMID file and waveform audio file format WAV file, this article will show you how to play large WAV files with the MCI command. Playing an audio file with the SNDPlaySound requires only one line of code. For example, the way asynchronous play is SnDplaySound ("C: /Windows/ding.wav", SND_ASYNC); thus it can be seen that the use of SndPlaySound is very simple. But there is a limit to play an audio file with the SNDPlaySound, that is, the entire audio file must all be transferred to the available physical memory. Therefore, the audio file played by SnDPlaySound is relatively small, up to 100K. To play large audio files (in multimedia design, it is often encountered) requires the use of MCI's features. This article creates a CWVE class that can handle the MCI commands that play an audio, as this class can perform a lot of MCI commands and establish a data structure, so you only need a simple member function (such as OpenDevice, CloseDevice, Play, and STOP). Abstract MCI commands and data structures in the CWAVE class, only a few simple member functions OpenDevice, ClosedEvice, Play, and STOP. The waveform audio device is a composite device. If the waveform device is turned on, then turn off and close each waveform element, the waveform device is finally closed, which makes the playback performance better. Call CWAVE :: OpenDevice You can open the waveform device. OpenDevice passes the MCI_open command to the MCISendCommand function. If the call is successful, use the data structure MCI_Open_PARMS to return the identifier of the waveform device, the identifier Saves the privately used Data members. Once the CWACE object is opened, the WAV file name and one window pointer are passed to the Play method to send the MCI notification message to the formulated window. The play of the WAV file is divided into two steps. First, by assigning an MCI_Open_PARMS structure and set the LPSTRELEMENTNAME member to open the WAV file by setting the WAV file to be played. The structure and MCI_open are passed to MCISendCommand, open the WAV file and return the element identifier with the WDEVICEID member of the MCI_Open_Parms structure. The second step is to command the waveform audio device to play the WAV file. The MCI_Play_Parms structure is assigned and set the DWCallback member to the window handle. If you want to play an audio waveform file synchronously, add the MCI_wait flag and skip the window handle. This will make the application wait for the WAV file to play before the MCISENDCOMMAND function returns. The most likely case is asynchronous to play large WAV files, you can specify the MCI_notify flag as follows, and set the dwcallback member to do this.
MCI_PLAY_PARMS mciPlayParms; MciPlayParms.dwCallback = (DWORD) pWnd-> m_hWnd; DwResult = mciSendCommand (m_nDevice, MCI_PLAY, MCI_NOTIFY, (DWORD) (LPVOID) & mciPlayParms); thus begins playback of WAV files and, after finished playing, MM_MCINOTIFY The message will be sent to the specified window, Figure 1 (图 略) The event sequence that occurs in a WAV file playback: (1) Command play the WAV file and return immediately; (2) Play the WAV file; (3) Send a notification after completion news. Close the WAV file element after the playback is the programmer's responsibility, and the STOP member function of the CWAVE class is available. The STOP member function passes the WAV file identifier and the MCI_close command to the MCISendCommand function, and does not have to assign an MCI structure for this command. The following code closes WAV file MCISendCommand (M) NELEMENT, MCI_Close, Null, Null; play all WAV After the file must turn off the waveform audio device, the CWAVE sector is called CWAVE :: CloseDevice Automatically complete. To add the CWVE class described in this article to your own program, you can easily apply it to play the audio file. // Establish a CWAVE class, place Class CWAVE: Public Cobject {// Construction Public: CWAVE (); DWORD CLOSEDEVICE (); DWORD CLOSEDEVICE () Play (CWnd * pParentWnd, LPCSTR pFileName); DWORD Stop (); // Implementation protected: void DisplayErrorMsg (DWORD dwError); // Members protected: MCIDEVICEID m_nDeviceID; MCIDEVICEID m_nElementID;}; // Cwave class implementation code, Cwave. CPP # include # include "cwave.h"
CWAVE :: CWAVE ()
{
m_ndeviceID = 0;
m_nelementid = 0;
}
CWAVE :: ~ cwave ()
{
IF (m_nelementid)
STOP ();
IF (M_NDeviceID)
CloseDevice ();
}
DWORD CWAVE :: OpenDevice ()
{
DWORD dWResult = 0;
IF (M_NDeviceID)
MCI_open_parms mciopenparms;
Mciopenparms.lpstrDeviceType = (LPSTR) MCI_DEVTYPE_WAVEFORM_AUDIO
// Open the Wave Device
DWRESULT = MCISENDCOMMAND (NULL, MCI_Open,
MCI_open_type | mci_open_type_id | mci_wait,
(DWORD) & mciopenparms;
// Save Device Identifier, Will Use EITHER MCI Commands
m_ndeviceid = mciopenparms.wdevice;
// Display Error Message IF Failed
IF (dWResult)
DisplayerrorMsg (dwresult);
}
// Return Result of MCI OperationReturn DWRESULT;
}
DWORD CWAVE :: CloseDevice ()
{
DWORD dWResult = 0;
// Close if currently Open
IF (M_NDeviceID)
{
// Close the MCI Device
DWRESULT = MCISENDCOMMAND (M_NDeviceID, MCI_Close, NULL, NULL);
// Display Error Message IF Failed
IF (dWResult)
DisplayerrorMsg (dwresult);
// set identifier to close State
Else
m_ndeviceID = 0;
}
// Return Result of MCI Operation
Return dwresult;
}
DWORD CWAVE :: Play (CWND * PWND, LPCSTR PFILENAME)
{
MCI_open_parms mciopenparms;
// Initialize Structure
Memset (& MciopenParms, 0, SizeOf (MCI_Open_PARMS);
// set the wav file name to be played
Mciopenparms.lpstreamentname = pfilename;
// first open the Device
DWORD DWRESULT = MCISENDCOMMAND (M_NDeviceID, MCI_open,
MCI_Open_Element, (DWORD) & mciopenParms;
// Display Error Message IF Failed
IF (dWResult)
DisplayerrorMsg (dwresult);
// if successful, instruct the device to play the wav file
Else
{
// Save Element Indentifier
m_nelementid = mciopenparms.wdeviceId;
MCI_Play_Parms McIPlayParms;
// set the window this will receive notification message
McIPlayParms.dwcallback = (dword) PWND-> M_HWND;
// Instruct Device to Play File
DWRESULT = MCISENDCOMMAND (M_NelementID, MCI_Play,
MCI_Notify, (DWORD) & MCIPARMS);
// Display Error and Close Element IF Failed
IF (dWResult)
{
DisplayerrorMsg (dwresult);
STOP ();
}
}
// Return Result of MCI Operation
Return dwresult;
}
DWORD CWAVE :: STOP ()
{
DWORD dWResult = 0;
// Close if Element is currently Open
IF (m_nelementid)
{
DWRESULT = MCISENDCOMMAND (m_nelementid, mci_close, null, null);
// Display Error Message IF Failed
IF (dWResult)
DisplayerrorMsg (dwresult);
// set identifier to closed state
Else
m_nelementid = 0;}
Return dwresult;
}
Void CWAVE :: DisplayError (DWORD DWERROR)
{
// check if there is an error
IF (dwerror)
{
// Character String That Contains Error Message
Char szerrormsg [maxErrorlength];
// Retrieve String Associated Error Message
IF (! MciGeterrorString (dwerror, szerrormsg, sizeof (szerrormsg)))
STRCPY (SzerrorMSG, "Unknown Error");
// Display Error String in Message Box
AfxMessageBox (SzerrorMSG);
}
}