Playback of large WAV files
The sound file is often handled in the design of multimedia software, and the API function SnDplaySound provided by Windows can realize 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, and Figure 1 shows the event sequence that occurred in a WAV file playback: (1) Command play the WAV file and return immediately; (2) Play the WAV file; (3) Send a notification message after completion. Figure 1 Turning a WAV file After the playback is turned off, the WAV file element is the programmer's responsibility, and the STOP member function of the CWAVE class can be invoked. 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 (); // OperationSpublic: DWord OpenDeevice (); DWord CloseDevice (); DWORD 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
} // 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.lpstrElementName = pFileName; // first open the device DWORD dwResult = mciSendCommand (m_nDeviceID, MCI_OPEN, MCI_OPEN_ELEMENT, (DWORD) (LPVOID) & 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 that will receive notification message mciPlayParms.dwCallback = (DWORD) pWnd -> m_hwnd; // instruct device to play file dwresult = mciSendcommand (m_nelementid, mci_play, mci_notify, (dword) (lpvoid) & mciplayparms); // Display Error and CLO SE 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;