Low level audio input and output

To record waveform audio, you have to determine which recording device to use first. You can get the number of recording device by calling waveInGetNumDevs(). Then, call waveInOpen() to acquire the recording device. You can pass 0 to (waveInGetNumDevs() - 1) to choose which device to use. You can also use WAVE_MAPPER as device ID and use Windows default settings. You also pass a WAVEFORMATEX to the function to specify the recording format. After you open the recording device, you have to prepare a buffer for the recording data. First, allocate a buffer by calling GlobalAlloc(). Then, allocate a WAVEHDR structure and it got a field and the field should be pointing to the buffer. Then, you have to call waveInPrepareHeader() to prepare the header. Then, tell Windows which buffer can be used in recording by calling waveInAddBuffer(). At the end, you call waveInStart() to actually start the recording process. If you know the maximum length of your recording, you can allocate one buffer which is equal to the maximum size of the recording. Otherwise, you have to allocate, prepare and add at least two buffers. Therefore, if one buffer is filled up, you will be notified (if you specified you want to be notified in waveInOpen()) and you can add more buffer for recording without interrupting the recording. (Since the first one is filled up, the second one is automatically used. If you get one buffer only, Windows has no way to write the data even it notified you right away.) I wrote a simple wave editor before for the company I am working for. I implement harddisk recording by preparing two buffer. When one of them filled up, I got notified and I wrote the buffer to file and then readd the buffer for recording. However, the write operation must be flush everytimes. Otherwise, Windows may lazily write it and the actual write operation may get too big and screw up the recording. After everything is finished, call waveInReset() to stop recording. waveInUnprepareHeader() to unprepare the buffer and waveInClose() to release the recording device.

Playing back waveform is very similar to recording. Call waveOutGetDevs() to get number of audio output device available. Then, call waveOutOpen() to acquire the output device. Then, allocate the output buffer and prepare it by calling waveOutPrepareHeader(). Then, actually play back the audio data by calling waveOutWrite(). After play back is finished, call waveOutReset() to stop recording. waveOutUnprepareHeader() to release the buffer and waveOutClose() to release the output device.

Check out a MFC sample sample4.zip for actual implementation.


Professional Games/Multimedia Programming
Copyright John Wong, 1998
Last revised on July 29, 1998

Please send any comments on this web site to [email protected]