Once you open a waveform input device, you can begin recording waveform data. Waveform data is recorded into application-supplied buffers specified by a WAVEHDR data structure. This is the same data structure used for waveform playback described in “Writing Waveform Data,” earlier in this chapter. Memory for the WAVEHDR structure and its accompanying data buffer must be allocated and prepared, as shown in “Allocating and Preparing Audio Data Blocks,” earlier in this chapter.
The Multimedia extensions provide the following functions to manage waveform recording:
waveInAddBuffer
Sends a buffer to the device driver so it can be filled with recorded waveform data.
waveInReset
Stops waveform recording and marks all pending buffers as done.
waveInStart
Starts waveform recording.
waveInStop
Stops waveform recording.
Use the waveInAddBuffer function to send data buffers to the device driver. As the buffers are filled with recorded waveform data, the application is notified with either a window message or with a callback message, depending on the flag specified when the device was opened.
Use the waveInStart function to begin recording. Before beginning recording, you should send at least one buffer to the driver, or incoming data might be lost. To stop waveform recording, use waveInStop.
Before closing the device using waveOutClose, call waveOutReset to mark any pending data blocks as being done.
The following messages can be sent to a window procedure function for managing waveform recording:
Message | Description |
MM_WIM_CLOSE | Sent when the device is closed using waveInClose. |
MM_WIM_DATA | Sent when the device driver is finished with a data buffer sent using waveInAddBuffer. |
MM_WIM_OPEN | Sent when the device is opened using waveInOpen. |
There is a wParam and lParam parameter associated with each of these messages. The wParam parameter always specifies a handle to the open waveform device. The lParam parameter is unused for the MM_WIM_CLOSE and MM_WIM_OPEN messages.
For the MM_WIM_DATA message, lParam specifies a far pointer to a WAVEHDR structure that identifies the data buffer. This data buffer might not be completely filled with waveform data—recording can stop before the buffer is filled. Use the dwBytesRecorded field of the WAVEHDR structure to determine the amount of valid data present in the buffer.
The most useful message is MM_WIM_DATA. Unless you need to allocate memory or initialize variables, you probably don't need to use the MM_WIM_OPEN and MM_WIM_CLOSE messages. When the device driver is finished with a data block, you can clean up and free the data block as described in “Allocating and Preparing Audio Data Blocks,” earlier in this chapter.
This syntax of the low-level callback function for waveform input devices is as follows:
void FAR PASCAL waveInCallback(hWaveIn, wMsg, dwInstance, dwParam1, dwParam2)
The following messages can be sent to the wMsg parameter of waveform input callback functions:
Message | Description |
WIM_CLOSE | Sent when the device is closed using waveInClose. |
WIM_OPEN | Sent when the device is opened using waveInOpen. |
WIM_DONE | Sent when the device driver is finished with a data block sent using waveInAddBuffer. |
These messages resemble messages sent to window-procedure functions, but their parameters are different. A handle to an open waveform device is passed as a parameter to the callback function, along with the DWORD of instance data that was passed using waveInOpen.
Summary: Message-Dependent Parameters
The callback has two message-dependent parameters: dwParam1 and dwParam2. For the WIM_CLOSE and WIM_OPEN messages, these parameters are not used. For the WIM_DONE message, dwParam1 specifies a far pointer to a WAVEHDR structure identifying the completed data block and dwParam2 is not used.
After the driver is finished with a data block, you can clean up and free the data block. Because of the restrictions of low-level audio callback functions, you can't do this within the callback. You must set some semaphores and do this outside of the callback. See “Using a Callback Function to Process Driver Messages,” earlier in this chapter, for details on the restrictions on using callback functions.