Before playing a waveform, you should call the waveOutGetDevCaps function to determine the waveform output capabilities of the playback device, as described earlier in this chapter. This function takes a pointer to a WAVEOUTCAPS structure, which it fills with information about the capabilities of a given device. This information includes the manufacturer and product IDs, a product name for the device, and the version number of the device driver.
In addition, the WAVEOUTCAPS structure provides information on the standard waveform formats and features supported by the device driver. The MMSYSTEM.H header file defines WAVEOUTCAPS as follows:
typedef struct waveoutcaps_tag {
UINT wMid; /* manufacturer ID */
UINT wPid; /* product ID */
VERSION vDriverVersion; /* driver version */
char szPname[MAXPNAMELEN]; /* product name */
DWORD dwFormats; /* supported standard formats */
UINT wChannels; /* number of channels */
DWORD dwSupport; /* supported features */
} WAVEOUTCAPS;
The dwFormats field of the WAVEOUTCAPS structure specifies the standard waveform formats supported by a device. The MMSYSTEM.H header file defines the following standard waveform format identifiers for the dwFormats field:
Format Identifier | Waveform Format |
WAVE_FORMAT_1M08 | 8-bit mono at 11.025 kHz |
WAVE_FORMAT_1S08 | 8-bit stereo at 11.025 kHz |
WAVE_FORMAT_1M16 | 16-bit mono at 11.025 kHz |
WAVE_FORMAT_1S16 | 16-bit stereo at 11.025 kHz |
WAVE_FORMAT_2M08 | 8-bit mono at 22.05 kHz |
WAVE_FORMAT_2S08 | 8-bit stereo at 22.05 kHz |
WAVE_FORMAT_2M16 | 16-bit mono at 22.05 kHz |
WAVE_FORMAT_2S16 | 16-bit stereo at 22.05 kHz |
WAVE_FORMAT_4M08 | 8-bit mono at 44.1 kHz |
WAVE_FORMAT_4S08 | 8-bit stereo at 44.1 kHz |
WAVE_FORMAT_4M16 | 16-bit mono at 44.1 kHz |
WAVE_FORMAT_4S16 | 16-bit stereo at 44.1 kHz |
The dwFormats field is a logical OR of the flags listed above. For example, to determine if a device supports a waveform format of 16-bit stereo at 44.1 kHz, use this technique:
if(waveOutCaps.dwFormats & WAVE_FORMAT_4S16)
/* Format is supported */
else
/* Format is not supported */
This information on standard-format support also applies to the WAVEINCAPS structure used with waveform input devices. For information on the WAVEINCAPS structure, see “Querying Waveform Input Devices,” later in this chapter.
To determine if a specific format is supported by a device (as opposed to all standard formats supported by a device), use the waveOutOpen function with the WAVE_FORMAT_QUERY flag as shown in the next section.
Waveform devices can support non-standard formats not listed in the preceding table. To see if a particular format (standard or non-standard) is supported by a device, you can call waveOutOpen with the WAVE_FORMAT_QUERY flag. The WAVE_FORMAT_QUERY flag tells waveOutOpen to check if the requested format is supported. The wave device is not actually opened. The requested format is specified by the structure pointed to by the lpFormat parameter passed to waveOutOpen. For information about setting up this structure, see “Specifying Waveform Data Formats,” later in this chapter. The following code fragment uses this technique to determine if a given waveform device supports a given format:
/* Determines if the given waveform output device supports a given wave-
* form format. Returns 0 if the format is supported, WAVEERR_BADFORMAT
* if the format is not supported, and one of the MMSYSERR_ error codes if
* there are other errors encountered in opening the given waveform device.
*/
UINT IsFormatSupported(LPPCMWAVEFORMAT lpPCMWaveFormat, UINT wDeviceID)
{
return (waveOutOpen(
NULL, // ptr can be NULL for query
wDeviceID, // the device ID
(LPWAVEFORMAT)lpPCMWaveFormat, // defines requested format
NULL, // no callback
NULL, // no instance data
WAVE_FORMAT_QUERY)); // query only, don't open device
}
This technique to determine non-standard format support also applies to waveform input devices. The only difference is that the waveInOpen function is used in place of waveOutOpen to query for format support.
Note:
To determine if a particular waveform-data format is supported by any of the waveform devices in a system, use the technique illustrated in the previous example, but specify the WAVE_MAPPER constant for the wDeviceID parameter. See “Selecting a Waveform Output Device,” later in this chapter, for more information on using the WAVE_MAPPER constant.
Waveform output devices vary in the capabilities they support. The dwSupport field of the WAVEOUTCAPS structure indicates whether a given device supports capabilities such as volume and pitch changes. MMSYSTEM.H defines the following flags for the dwSupport field:
Flag | Description |
WAVECAPS_PITCH | Pitch-change support |
WAVECAPS_PLAYBACKRATE | Playback-rate-change support |
WAVECAPS_VOLUME | Volume-control support |
WAVECAPS_LRVOLUME | Individual volume-control support for both left and right channels |
The dwSupport field is a logical OR of the flags listed in the preceding table. For example, to determine if a device supports volume changes, use this technique:
if(waveOutCaps.dwSupport & WAVECAPS_VOLUME)
/* Volume changes are supported */
else
/* Volume changes are not supported */
For more information on playback volume levels, see “Changing Waveform Playback Volume,” later in this chapter. For more information on pitch and playback rates, see “Changing Pitch and Playback Rate,” also later in this chapter.