Providing ACM Support in Device Drivers

Some waveform devices can play and record data that is in a compressed format. For these devices, clients do not have to call ACM functions to convert data streams. However, ACM functions provide one of the means by which clients determine which formats are supported on a system. So even if a particular format is supported by device hardware, the client still might call ACM functions to determine if the format is supported. (The other means by which clients determine if a device supports a compressed format is by specifying the WAVE_FORMAT_DIRECT flag with the WODM_OPEN and WIDM_OPEN audio driver messages.)

If you are designing a user-mode audio driver for a waveform device that supports a format in hardware, your driver’s DriverProc function must support, at a minimum, the following ACM driver messages:

A user-mode audio driver that supports ACM messages is, in reality, both a device driver and an ACM driver. As such, it must be installed twice ¾ once as an audio device driver and once as an ACM driver. (See Installing Multimedia Drivers and Installing ACM Drivers.)

A driver of this type must be capable of determining when it is being opened as an audio driver and when it is being opened as an ACM driver. An easy way to make this determination is to examine the lParam2 argument to DriverProc when a DRV_OPEN message is received. When the driver is being opened by the ACM, this argument is a pointer to an ACMDRVOPENDESC structure. When the driver is being opened by any other client, such as winmm.dll or a Control Panel applet, the lParam2 argument is NULL.

Following is a possible scenario in which the driver is used as both an ACM driver and an audio driver:

  1. A client calls acmDriverDetails (in the ACM) to send an ACMDM_DRIVER_DETAILS message. The driver sets the specified ACMDRIVERDETAILS structure’s ACMDRIVERDETAILS_SUPPORTF_HARDWARE flag.

  2. The client detects this flag and calls acmMetrics (in the ACM), specifying the ACM_METRIC_HARDWARE_WAVE_OUTPUT flag to obtain a device identifier.

  3. The client uses the obtained device identifier as input to waveOutOpen (in winmm.dll), to open an output stream to a waveform device, and then sends data to the device using waveOutWrite.