Deallocating Memory Blocks Associated with Audio Data
A version of this page is also available for
4/8/2010
An application must be able to determine when a device driver is finished with the data block, so that the application can unprepare and free the memory that is associated with the data block and header structure. The following list describes several ways to determine when a device driver is finished with a data block:
- By specifying a callback function to receive a message that is sent by the driver when it is finished with a data block
- By using an event callback
- By specifying a window or a thread to receive a message that is sent by the driver when the driver is finished with a data block
- By polling the WHDR_DONE flag in the dwFlags member of the WAVEHDR structure that is sent with each data block
To use a callback function for driver messages
Specify the CALLBACK_FUNCTION flag in the fdwOpen parameter of the waveInOpen function or the waveOutOpen function.
Specify the address of the callback in the dwCallback parameter of waveInOpen or waveOutOpen.
Messages that are sent to a callback function are similar to messages that are sent to a window, except that messages sent to a callback function have two DWORD parameters instead of one UINT and one DWORD parameter.
The following list describes the techniques for passing instance data from an application to a callback function:
Pass the instance data by using the dwInstance parameter of the function that opens the device driver.
Pass the instance data by using the dwUser member of the WAVEHDR structure that identifies an audio data block that was sent to a device driver.
Note
If you need more than 32 bits of instance data, pass a pointer to a structure that contains the additional data.
To use an event callback
Retrieve the handle of an event from the CreateEvent function.
Specify the CALLBACK_EVENT flag for the fdwOpen parameter in your call to waveOutOpen.
Use the waveOutPrepareHeader function or the waveInPrepareHeader function to prepare the data block.
Call the ResetEvent function with the event handle that is retrieved by the CreateEvent function.
This action creates a nonsignaled event.
Send the waveform audio data block to the driver.
Call the WaitForSingleObject function, specifying as parameters the event handle and a time-out value of INFINITE.
This call should be inside a loop that checks whether the WHDR_DONE flag is set in the dwFlags member of the WAVEHDR structure.
Because event callbacks do not receive specific close, done, or open notifications, an application might have to check the status of the process that is waiting for notification after the event occurs. It is possible for a number of tasks to be completed by the time that WaitForSingleObject returns.
To use a window callback function
- Call waveInOpen or waveOutOpen with the fdwOpen parameter set to CALLBACK_WINDOW and a window handle that is passed in the dwCallback parameter.
To use a callback thread
Call waveInOpen or waveOutOpen with the fdwOpen parameter set to CALLBACK_THREAD and a thread handle that is passed in the dwCallback parameter.
Note
Messages that are sent to the window callback or the thread callback are specific to the audio I/O device type that is used.
In addition to using a callback function, you can poll the dwFlags member of a WAVEHDR structure to determine when an audio I/O device is finished with a data block. You should sometimes poll dwFlags rather than wait for another mechanism to receive messages from the drivers. For example, after calling the waveOutReset function or waveInReset function to release pending data blocks, you immediately can poll dwFlags for the WHDR_DONE flag to be sure that the data blocks have been released.
After you determine that the function has released the data block, call the waveInUnprepareHeader function or the waveOutUnprepareHeader function to unprepare the header file. After you have unprepared the header file, you can deallocate the memory normally.