Compaq Multimedia Services
for OpenVMS Alpha
Programmer's Guide


Previous Contents Index


Chapter 3
Waveform Audio Services

This chapter presents the waveform audio services available to applications. An application uses waveform audio services to manage recording and playback of waveform audio data.

3.1 Waveform Audio Services Overview

Waveform audio services provide a device-independent interface to audio hardware in the OpenVMS system. For example, a playfile application uses waveform audio functions to play back audio data from a file.

Figure 3-1 shows how an application works with the elements of Multimedia Services for OpenVMS that support audio.

Figure 3-1 Audio Architecture


3.2 Using Waveform Audio Services

Waveform audio services control different types of waveform audio devices. This section presents general information about using the waveform audio services.

3.2.1 Querying Waveform Audio Devices

Before playing or recording audio, determine the capabilities of the audio hardware present in the system. Audio capability varies from one multimedia computer to another. Do not assume that the audio hardware is present in any given system. An application needs to determine the number of audio devices and then query each device for its capabilities. The following sections describe these tasks.

3.2.1.1 Getting the Number of Waveform Audio Devices

Use the waveInGetNumDevs and waveOutGetNumDevs functions to determine the number of waveform audio input and output devices present in the system.

Audio devices are identified by a device identifier (ID). The device ID is determined implicitly from the number of devices present in a given system. Device IDs range from 0 to the number of devices present minus 1. For example, if there are three waveform audio output devices in a system, valid device IDs are 0, 1, and 2.

See the descriptions of the waveInGetNumDevs and waveOutGetNumDevs functions in Section 3.8 for more information about determining the number of waveform audio devices.

3.2.1.2 Getting the Capabilities of a Waveform Audio Device

Use the following functions to determine the capabilities of audio input and output devices present in the system:

waveInGetDevCaps
waveInGetDevCapsEx
waveOutGetDevCaps
waveOutGetDevCapsEx

In addition to the device capabilities, these functions will return information about the standard formats (see Section 3.6 for a list of standard formats) supported by the device.

The waveInGetDevCaps and waveOutGetDevCaps functions only return a format that is currently available on the device. A format may become unavailable if the device is in use, and it cannot handle simultaneous processing of different sample rates; therefore, in some cases, formats with different sample rates are temporarily unavailable.

The waveInGetDevCapsEx and waveOutGetDevCapsEx functions will always return all standard formats supported by the device.

The waveInGetDevCaps , waveOutGetDevCaps , waveInGetDevCapsEx , and waveOutGetDevCapsEx functions have an input argument that is a pointer to a data structure, which the functions fill with information about the capabilities of a specified device. The data structures are WAVEINCAPS and WAVEOUTCAPS, and are described in Section 3.6.

See the function descriptions in Section 3.8 for more information about determining the capabilities of a device.

3.2.1.3 Getting the Formats of a Waveform Audio Device

Use the following functions to determine the formats of audio input and output devices present in the system:

waveInFormatDetails
waveInGetFormatInfo
waveOutFormatDetails
waveOutGetFormatInfo

The waveInGetFormatInfo and waveOutGetFormatInfo functions return information relating to all formats supported by the device.

The waveInFormatDetails and waveOutFormatDetails functions return detailed information relating to a specific supported format.

The waveInGetFormatInfo and waveOutGetFormatInfo functions take a pointer to a WAVEFORMATINFO data structure and return high-level information common to all formats supported by the device. The WAVEFORMATINFO data structure is described in Section 3.6.

The waveInFormatDetails and waveOutFormatDetails functions take a pointer to an ACMFORMATDETAILS data structure. The ACMFORMATDETAILS data structure is described in Section 3.6.

See the function descriptions in Section 3.8 for more information about determining the capabilities of a device.

3.2.2 Opening and Closing a Waveform Audio Device

After getting the capabilities of an audio device, you must open the device before using it. Audio devices are not guaranteed to be shareable, so a particular device might not be available when you request it.

Use the waveInOpen and waveInClose functions to open and close an audio input device. Use the waveOutOpen and waveOutClose functions to open and close an audio output device.

Note

Be sure to close audio devices when playback and recording operations are completed.

Each function that opens an audio device takes a device ID, a pointer to a memory location, and other arguments unique to the type of device. The memory location is filled with a device handle. Use this handle to identify the open audio device when calling other audio functions.

The distinction between audio device IDs and audio device handles is subtle. It is important that you do not confuse the two in your application. The differences between device IDs and device handles are as follows:

See the descriptions of these functions in Section 3.8 for more information about device handles.

3.2.3 Sharing a Waveform Audio Device

Compaq has extended the API specification to enable a waveform audio device to be opened as a shared device. Multiple applications can open a device as a shared device. When a device is shared, the audio streams are mixed before playing out through the physical device. The maximum number of applications that can connect to a device is limited by the audio driver type.

To open a waveform audio device as shareable, an application must specify the WAVE_OPEN_SHAREABLE flag in the dwFlags argument of the waveOutOpen function. If an application does not provide this flag, the device is opened for exclusive access.

If the device is already open for shareable access, it cannot be opened for exclusive access. Conversely, if a device is already open for exclusive access, it cannot be opened for shareable access.

Note

Compaq recommends opening a waveform audio device for shareable access so that other applications (such as the Audio Control utility program) may also access the device.

See the description of the waveOutOpen function in Section 3.8 for more information about opening a waveform audio device as a shared device.

3.2.4 Controlling Playback and Record Volume

Compaq has extended the API specification to provide record volume control. Use the waveInGetVolume and waveInSetVolume functions to obtain and set the current record volume.

See Section 3.3.5, Section 3.4.7, and the descriptions of the volume control functions in Section 3.8 for more information about controlling waveform audio playback and record volume.

3.2.5 Allocating and Preparing Waveform Audio Data Blocks

Some waveform audio functions require applications to allocate data blocks to be passed to the device drivers for playback or recording operations. Each function uses a data structure or header to describe its data block. These functions are waveInAddBuffer and waveOutWrite .

Both functions use the WAVEHDR data structure to describe their data blocks. Before calling one of the functions to pass a data block to a device driver, allocate memory for both the WAVEHDR data structure and the data block.

To allocate memory for the WAVEHDR data structure, use the mmeAllocMem function. To allocate memory for the audio data block, use the mmeAllocBuffer function. The mmeAllocBuffer function returns a pointer to the data block. Use the mmeFreeMem and mmeFreeBuffer functions to free the memory allocated for the data structure and the data block, respectively, after you finish your recording or playback session.

See the descriptions of the waveInAddBuffer and waveOutWrite functions in Section 3.8 for more information about allocating and preparing waveform audio data blocks.

3.2.6 Managing Waveform Audio Data Blocks

Unless the audio 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, applications must determine when a device driver is finished with the data block before the application can free the memory associated with the data block.

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, as described in Section 3.2.7. If an application does not get a data block to the device driver when needed, there can be an audible gap in playback or loss of incoming recorded information. To prevent this from happening, use at least a double-buffering scheme --- staying a minimum of one data block ahead of the device driver.

Note

Wait until the audio driver returns a callback message indicating the data block is done before using the mmeFreeBuffer function to free data blocks in your application.

3.2.7 Using Callback Functions to Process Driver Messages

To specify a callback function to process messages sent by the device, set the CALLBACK_FUNCTION flag in the dwFlags argument and specify the address of the callback function in the dwCallback argument of the waveInOpen or waveOutOpen function.

Note

Multimedia Services for OpenVMS does not support the use of a callback window (CALLBACK_WINDOW flag). Only callback functions are supported.

Use callback functions to notify you when the device is finished opening or closing and when it is processing a data block.

Note

Applications must not execute any Multimedia Services for OpenVMS API function calls from a callback function.

It is important to write callback functions carefully to adhere to the Multimedia Services for OpenVMS callback scheme. See the descriptions of the waveInOpen and waveOutOpen functions in Section 3.8 for more information about using callbacks.

3.2.8 Handling Errors

The waveform audio functions return nonzero error codes. Multimedia Services for OpenVMS provides a set of functions that convert error codes into textual descriptions of the errors. An application must first examine an error code to determine how to proceed, then prompt the textual description of the error code to describe it to users.

Use the waveInGetErrorText and waveOutGetErrorText functions to retrieve textual descriptions of specified waveform audio input and output errors.

The only waveform audio functions that do not return error codes are the waveInGetNumDevs and waveOutGetNumDevs functions. These functions return a value of 0 if no devices are present in a system or if any errors are encountered by the function.

See the descriptions of the waveInGetErrorText and waveOutGetErrorText functions in Section 3.8 for more information about handling waveform audio errors.

3.3 Playing Waveform Audio Data

This section contains information about the waveform audio output functions that do the following:

An application uses waveform audio output functions to play back audio data.

3.3.1 Querying a Waveform Audio Output Device

Before playing a waveform, call the waveOutFormatDetails , waveOutGetDevCaps , waveOutGetDevCapsEx , or waveOutGetFormatInfo functions to determine the waveform output capabilities of the playback device, as described in Section 3.2.1.2. The waveOutGetDevCaps and waveOutGetDevCapsEx functions take a pointer to a WAVEOUTCAPS data structure and fill it with information about the capabilities of a given device, which includes the manufacturer and product IDs, the product name for the device, and the version number of the device driver.

The WAVEOUTCAPS data structure also provides information about the standard waveform formats and features supported by the device driver. The dwFormats field specifies the waveform audio formats supported by a device. The dwSupport field specifies the features supported by a device, such as volume control.

The waveOutGetFormatInfo function takes a pointer to a WAVEFORMATINFO data structure and returns high-level information common to all formats supported by the device.

The waveOutFormatDetails function takes a pointer to a ACMFORMATDETAILS data structure.

Example 3-1 shows how to determine if a device supports a waveform audio format of 16-bit stereo at 44.1 kHz.

Example 3-1 Determining Waveform Audio Device Format Support

if(waveOutCaps.dwFormats & WAVE_FORMAT_4S16) 
    /* Format is supported */ 
else 
    /*Format is not supported */ 

Note

This information on standard format support also applies to the WAVEINCAPS data structure used with waveform audio input devices.

Example 3-2 shows how to determine if a device supports volume control.

Example 3-2 Determining Waveform Audio Device Volume Control Support

if(waveOutCaps.dwFormats & WAVECAPS_VOLUME) 
    /* Volume control is supported */ 
else 
    /*Volume control is not supported */ 

See Section 3.3.5 and Section 3.4.7 for information about modifying playback and record volume levels.

To determine if a specific format is supported by a device, use the waveOutOpen function with the WAVE_FORMAT_QUERY flag. The WAVE_FORMAT_QUERY flag tells the waveOutOpen function to check if the requested format is supported. The waveform audio device is not actually opened. The requested format is specified in the WAVEOUTCAPS data structure pointed to by the lpFormat argument passed to the waveOutOpen function. For information about setting up this data structure, see Section 3.3.3.

Example 3-3 shows how to determine if a given waveform audio device supports a specific format.

Example 3-3 Determining Device Support of a Specific Waveform Audio Format

#include <mme/mme_api.h> 
 
/* Determines if the given waveform audio output device supports a  */ 
/* specific waveform format.  Returns 0 if the format is supported. */ 
/* Returns the WAVERR_BADFORMAT error code if the format is not     */ 
/* supported.  Returns one of the MMSYSERR_ERROR codes if there are */ 
/* other errors encountered in the given waveform audio device.     */ 
 
MMRESULT IsFormatSupported(LPPCMWAVEFORMAT lpPCMWaveFormat, 
                           UINT uDeviceID) 
{ 
    return (waveOutOpen( 
            NULL,                           /* ptr NULL for query */ 
            uDeviceID,                      /* device ID          */ 
            (LPWAVEFORMAT)lpPCMWaveFormat,  /* defines format     */ 
            NULL,                           /* no callback        */ 
            (DWORD)0,                       /* no instance data   */ 
            WAVE_FORMAT_QUERY));            /* query only         */ 
} 

Note

The technique shown in Example 3-3 also applies to waveform audio input devices, except that the waveInOpen function is used instead of the waveOutOpen function to query the device.

To determine if a particular waveform audio data format is supported by any of the waveform audio devices in a system, use the technique in the previous example, but specify the WAVE_MAPPER constant as the value of the uDeviceID argument. See Section 3.3.2 for more information about using the WAVE_MAPPER constant.

3.3.2 Opening a Waveform Audio Output Device

Use the waveOutOpen function to open a waveform audio output device for playback. The waveOutOpen function opens the device associated with the specified device ID and returns a handle to the open device by writing the handle to a specified memory location.

Some multimedia computers have multiple waveform audio output devices. Use the WAVE_MAPPER constant as the device ID when it is not important which audio device gets opened by a waveOutOpen function call. The waveOutOpen function selects the audio device in the system that is best capable of playing back audio data in the specified format.

The waveOutOpen function supports a callback function that can be used to process messages sent by the device driver.

See the description of the waveOutOpen function in Section 3.8 for more information about opening a waveform audio output device.


Previous Next Contents Index