The primary purpose of an audio device driver is to transfer audio data (waveform or MIDI) between an application and an audio device. The model for data transfer is a little different for waveform devices than it is for MIDI devices because of the nature of the data. Auxiliary audio devices do not require the transfer of audio data, just control information.
The following sequence of operations occurs when transferring audio data between a client application and a waveform output device driver:
1 The client allocates the memory for the data block.
2 The client requests that the driver prepare the data block.
3 The client sends the data block to the driver.
4 The driver puts the data block in its output queue.
5 The client can send additional data blocks, which the driver also puts in its output queue.
6 When the driver has sent a data block from its output queue to its output device, it returns the data block to the client by sending the client a message.
7 The client requests that the driver clean up the preparation previously done on the data block.
8 The client then frees the memory for the data block.
In addition, the driver must transfer the data it receives from the client to the waveform hardware. This transfer takes place in the background, as an interrupt-driven process. The driver may transfer data directly, or it may use the computer's DMA controller to transfer the data. Whether you choose to transfer data directly or use DMA depends on the capabilities of your target hardware. For input devices, the model is similar, except the client sends the driver an empty buffer. The buffer is filled with audio data directly by the driver or with DMA. The driver notifies the client when the buffer is filled.
With MIDI system-exclusive events, data transfer between a client application and a MIDI device driver is identical to the sequence described previously for waveform drivers. However, for all other MIDI events, the driver uses a different transfer mechanism. Because all other MIDI events are three bytes or less in size, they are packed into a DWORD and sent directly to the driver for output. The driver parses the event to determine its size and sends the individual bytes to the MIDI output hardware. If the driver is for an internal synthesizer, it parses the event and responds accordingly. MIDI input device drivers wait until receiving a complete MIDI event before packing the event into a DWORD and sending it to the client application through its callback.