Audio Data Blocks

[The feature associated with this page, Waveform Audio, is a legacy feature. It has been superseded by WASAPI and Audio Graphs. WASAPI and Audio Graphs have been optimized for Windows 10 and Windows 11. Microsoft strongly recommends that new code use WASAPI and Audio Graphs instead of Waveform Audio, when possible. Microsoft suggests that existing code that uses the legacy APIs be rewritten to use the new APIs if possible.]

The waveInAddBuffer and waveOutWrite functions require applications to allocate data blocks to pass to the device drivers for recording or playback purposes. Both of these functions use the WAVEHDR structure to describe its data block.

Before using one of these functions to pass a data block to a device driver, you must allocate memory for the data block and the header structure that describes the data block. The headers can be prepared and unprepared by using the following functions.

Function Description
waveInPrepareHeader Prepares a waveform-audio input data block.
waveInUnprepareHeader Cleans up the preparation on a waveform-audio input data block.
waveOutPrepareHeader Prepares a waveform-audio output data block.
waveOutUnprepareHeader Cleans up the preparation on a waveform-audio output data block.

 

Before you pass an audio data block to a device driver, you must prepare the data block by passing it to either waveInPrepareHeader or waveOutPrepareHeader. When the device driver is finished with the data block and returns it, you must clean up this preparation by passing the data block to either waveInUnprepareHeader or waveOutUnprepareHeader before any allocated memory can be freed.

Unless the waveform-audio input and output data is small enough to be contained in a single data block, applications must continually supply the device driver with data blocks until playback or recording is complete.

Even if a single data block is used, an application must be able to determine when a device driver is finished with the data block so the application can free the memory associated with the data block and header structure. There are several ways to determine when a device driver is finished with a data block:

  • By specifying a callback function to receive a message sent by the driver when it is finished with a data block
  • By using an event callback
  • By specifying a window or thread to receive a message sent by the driver when it is finished with a data block
  • By polling the WHDR_DONE bit in the dwFlags member of the WAVEHDR structure sent with each data block

If an application does not get a data block to the device driver when needed, there can be an audible gap in playback or a loss of incoming recorded information. This requires at least a double-buffering scheme — staying at least one data block ahead of the device driver.

The following topics describe ways to determine when a device driver is finished with a data block:

Using a Callback Function to Process Driver Messages