Each ACM driver, whether a codec, converter, or filter, treats data as a stream. A client passes the input stream to the driver in one or more source buffers. The driver performs a conversion operation on the data and returns the converted stream to the client in one or more destination buffers.
ACM drivers can be designed to handle data conversion operations either synchronously or asynchronously. Generally, asynchronous operation only makes sense when a driver can perform hardware-assisted conversions. Drivers providing software-implemented conversions, such as the sample ACM drivers, usually operate synchronously.
A driver opens a stream when a client sends it an ACMDM_STREAM_OPEN message. With this message, the client includes pointers to structures that describe the format and other characteristics of both the source (input) and destination (output) streams. The driver uses this information to determine the types of transformations to perform on the source data.
If the client sends the driver an ACMDM_STREAM_SIZE message, specifying a source (or destination) buffer size, the driver returns the required size of a destination (or source) buffer. The driver uses the source and destination format characteristics, received with the previous ACMDM_STREAM_OPEN message, to determine the necessary source or destination buffer size.
Before the client can pass data buffers to the driver, it must prepare the buffers for use by passing them to the driver with an ACMDM_STREAM_PREPARE message. Each ACMDM_STREAM_PREPARE message includes the address of a stream header structure, defined by ACMDRVSTREAMHEADER, containing pointers to a source buffer and a destination buffer.
When the driver receives an ACMDM_STREAM_CONVERT message from the client, it begins the data transformation. Each ACMDM_STREAM_CONVERT message includes the address of a prepared stream header structure. The algorithm for what happens next depends on whether the driver is designed to operate synchronously or asynchronously.
When the client has finished the conversion, it sends an ACMDM_STREAM_UNPREPARE message for each stream header structure, and then sends an ACMDM_STREAM_CLOSE message.
Note: If your driver supports asynchronous conversions and a client requests a synchronous conversion (by not specifying the ACM_STREAMOPENF_ASYNC flag with the acmStreamOpen function, which is described in the Win32 SDK), the ACM manager sets the ACM_STREAMOPENF_ASYNC flag and specifies a local event handle as a callback target. In other words, the driver always receives ACM_STREAMOPENF_ASYNC with ACMDM_STREAM_OPEN if it is an asynchronous driver. The ACM receives the callback notification messages sent by the driver, and the conversion appears to operate synchronously from the client’s point of view. For more information about callbacks, see Notifying Clients from ACM Drivers.
Generally, ACM drivers should perform conversions in real time. This means the driver should be able to perform conversion operations fast enough that there are no delays in a recording or playback operation, if a client is requesting the conversion to take place simultaneously with the recording or playback operation. (An example of such a client is the wave mapper.) Consequently, if a driver’s conversion algorithm requires relatively large amounts of calculations, it might not be able to run in real time.
When a client sends an ACMDM_STREAM_OPEN message, it can set a flag to indicate that it does not require the conversion to take place in real time. Drivers that cannot provide real time conversions can only operate if the client sets this flag.
Some waveform devices support hardware-assisted conversions. These devices accept data in one format, convert it to another format, and return the converted data without playing it. Hardware-assisted conversions are typically faster than conversions that must be entirely implemented in software. Drivers that make use of hardware assistance should probably be written to operate asynchronously.
To access a hardware conversion operation, an ACM driver must call the device’s kernel-mode driver, typically by means of the DeviceIOControl function described in the Win32 SDK. (For more information about kernel-mode drivers, see Kernel-Mode Multimedia Drivers.)