Multimedia Audio SDK

WEBINAR:On-Demand

Introduction

Any game that deprives the user of music remains incomplete. The moment the element of sound is introduced in a game, the feel of the game changes, giving the game a more realistic effect. In this article, you will built two music applications. The first application is a simple dialog-based application that can be used to play MPEG, WMA, and WAV files. In the second program, you have proceeded a step further to play more than one audio file simultaneously. This feature of the second application finds its application in the development of multiplayer games.

Before you start your first music application, take a look at the features implemeted in the MM Audio API. The MM Audio API provides support for the following:

Loading and playing sound from supported audio files regardless of audio compression type. It supports automatic conversion of audio data whenever it is required.

Playback of multiple sources simultaneously.

Locating sound in a 3D environment.

Applying pitch, reverb, and other effects to sound.

Facilities to stream or statically load the sound file into memory.

Control the EAX parameters on source and listener on systems with EAX support.

A 11-band frequency equilizer (software-based) to have finer control over sound quality.

Audio buffers or streams are represented by a unique ID instead of pointers. Now, the client application can focus more on programming than searching for NULL audio interfaces or stream pointers.

Header and Libraries

al.h must be included in the project to enable the MM Audio API routines in the application. The import library is al.lib, which must be linked to the application.

A MM Audio Application

In this program, you will create a dialog-based application that uses MM Audio API to play MPEG, WMA, and WAV files.

To create this, run Visual C++/Borland C++. You will use VC++ 6.0. For Borland users, refer to the note at the end. Run VC++ and select "File > New." Select the project type as "MFC AppWizard (Exe)". Supply the name as "music1" and click OK. Select a "Dialog based" application from the new dialog that appears. Click on "Finish."

Build the dialog

Add the following child control to the dialog in the resource editor as shown in Figure 1.

Figure 1

Give the following IDs to the controls, as shown in the following table.

S Number

Contol's ID

1

Edit Box IDC_FILENAME

2

Button IDC_BROWSE

3

Button IDC_PLAY

4

Button IDC_STOP

Initializing the API

Before any call is made into Audio API, it must be initialized for use. Call ALInit() and check the return value for TRUE, which indicates successful initialization.

Creating the Audio Context

An audio context must be created before any file or device operation is performed. Use ALCreate( HDC ) and pass the parent window's graphics device context to it. If the function returns a NON-NULL value, this value is the device ID of the audio device that is being used. Pass this value to ALSetCurrent( HAL ) and the device is set as the current useful audio device.

In the above code, you see that the audio API is initialized with ALInit(). Then, dc—that is, a device context—is created for the parent window and this GDI context is passed to the ALCreate function. This function returns the audio device context id, which is set as current by using ALSetCurrent( HAL ).

Opening the Audio File

The CFileDialog is used to create an open dialog box with file types required. When user selects a file and clicks OK, the path name is retrieved by using CFileDialog::GetPathName(). This is typecasted respectively and passed to the ALOpenWave(ALdword, ALchar*, ALbool, ALbool, ALbool, or ALbool) function to be opened.

The first parameter represents the stream ID that is unique. This means that the ID must not represent another stream (valid or invalid).

The second parameter is the wave filename with the full path of the file to open. The file name must be passed with an extension.

The third parameter represents the support of 3D interfaces on an opened stream. If set to TRUE, the stream will support a 3D parameter set.

The fourth parameter represents a streaming property flag. If this flag is set to TRUE, the opened buffer will be streaming data from a file. Setting it to FALSE requires that all the wave data will be loaded at once to the audio buffer.

The fifth parameter represents a Global audible flag; setting it to TRUE enables the hearing of the stream, on playing, even if the parent window loses focus. If set to FALSE, the audio will be muted if the window loses focus.

The sixth parameter represents thw EAX setting. If set to TRUE, it will set the Creative EAX (2.0) property set on an opened stream. This will again automatically set the 3D HW flag set on the audio stream. If EAX effect cannot be set or is not available on the selected device, the function ignores the requested action.

If the stream can be opened successfully, the function returns TRUE. This indicates that the Audio Stream ID now represents a valid audio stream that can be selected as the current audio stream by using the ALSetWave(b&) function.

Open the resource editor and open the dialog in Figure 1. Double-click on the OPEN button and a window appears. There, type the function name as OnBrowse() and click Okay. Now, modify the code of OnBrowse() as follows:

Playing the Audio File

The audio file had been loaded by your function ALBrowse and been set as current. And, because there is only one current stream, you assume that if any stream is set as current, it should be your stream. So, you call ALPlayWave( ALbool ) to the play the wave and ALStopWave() to stop it.

The ALPlayWave( ALbool ) takes one parameter, which represents that nature of the playback. If this value is TRUE, the stream is played an infinite number of times; that is, it is looped forever. For the value FALSE, it is played once.

The ALStopWave() function will stop the playing audio imediately when called.

To check the statues of playback, you may call ALIsWavePlaying(). This function returns TRUE if the wave is playing. Otherwise, it returns FALSE.

Open the resourse editor to the dialog in Figure 1. There, double-click the Play button; a window opens where you type OnPlay() and select "OK". Again, re-open the dialog in Figure 1 and double-click the Stop button; a window opens where you type OnStop and select "OK". Now, modify the code of OnPlay() and OnStop() as follows:

Closing the Wave File

One call to the ALCloseWave() or ALDeleteWave() function will close the current wave stream.

Closing the Audio Device

Once all the opened streams are closed, it's time to end the application. Call ALDelete() to release the current audio device.

Deinitializing the MM Audio API

When your application is done with the API, it's time to shut it down. So, call ALUninit() to deinitialize it. But remember, once this function is called none of the Audio API functions should be called. This should be the last API call made.

To achieve the Deinitialization action in your application, you modify the OnDestroy() function as follows:

Multimedia Audio SDK

WEBINAR:On-Demand

Multistream Playback

Multistream playback is useful for games. As objects simulating those in real life emits sound waves of different pitch and frequency, when used in games requires multiple audio streams to supply audio data.

In the first program, you designed a program that uses only one audio stream, so you called ALSetWave( ... ) once, set the file ID, and forgot about throughout. But, this should not be the case for multiple audio stream playback. The audio ID of the file stream must be set each time its property changes. Therefore, the stream ID is an important matter here.

A MMAudio MultiStream Web playback application

In this program, you will create a dialog-based application that uses the MM Audio API to play four simultaneous audio files from the Web.

To create this, run Visual C++/Borland C++. You will use VC++ 6.0. For Borland users, refer to the note at the end. Run VC++ and select "File > New." Select the project type as "MFC AppWizard (Exe)." Supply the name as "music2" and click OK. Select a "Dialog based" application from the new dialog that appears. Click on "Finish."

Build the dialog

Add the following child control to the dialog in the resource editor, as shown in Figure 2.

[MM2.jpg]

Figure 2

Give the following IDS to the controls, as shown in the table below.

S Number

Contol's ID

1

Button IDC_STREAM1

2

Button IDC_STREAM2

3

Button IDC_STREAM3

4

Button IDC_STREAM4

Initializing the APIand Opening the Web Stream

Before any call is made into Audio API, it must be initialized for use. Call ALInit() and check the return value for TRUE, which indicates successful initialization.

Creating the Audio Context

An audio context must be created before any file or device operation is performed. Use ALCreate( HDC ) and pass the parent window's graphics device context to it. If the function returns a NON-NULL value, this value is the device ID of the audio device that is being used. Pass this value to ALSetCurrent( HAL ) and the device is set as current useful audio device.

In the above code, you see that the audio API is initialized with ALInit(). Then dc—that is, a device context—is created for the parent window and this GDI context is passed to ALCreate function. This function returns the audio device context id, which is set as current using ALSetCurrent( HAL ).

You also have defined four IDs, IDW_STREAM1 through IDW_STREAM4, as 1000 to 1300. These represent the audio IDS of the wave stream. You have also defined a function named Open( ALdword, ALchar* ) that takes the Audio ID as the first parameter and the URL name of the audio file as the second parameter, and opens the file stream.

Playing the Audio File

The audio file had been loaded during the initialization of the dialog. And, due to the presence of multiple streams, you have to set the respective stream as current before you change its property or state. After you set a current stream using ALSetWave( stream id ), you call ALPlayWave( ALbool ) to the play the wave and ALStopWave() to stop it.

The ALPlayWave( ALbool ) takes one parameter, which represents that nature of the playback. If this value is TRUE, the stream is played an infinite number of times; that is, it is looped forever. For the value FALSE, it is played once.

The ALStopWave() function will stop the playing audio imediately when called.

To check the statues of playback, you may call ALIsWavePlaying(). This function returns TRUE if the wave is playing. Otherwise, it returns FALSE.

Open the resourse editor to the dialog in Figure 2. There double-click the Stream1 button; a window opens where you type OnStream1() and select "OK." Similarly, OnStream2(), OnStream3, and OnStream4() are defined for button named IDC_STREAM2, IDC_STREAM3, and IDC_STREAM4, respectively:

The function Play( id ) is defined to take care of playing the respective audio stream. It is defined as the following:

void CMusic2Dlg::Play(ALdword id)
{
//Play the respective stream from the start
ALSetWave(id); // Set the stream as current
ALSeekWave(0); // Set to beginning of stream
ALPlayWave(FALSE); // Play the file once
}

Closing the Wave File

One call to the ALCloseWave() or ALDeleteWave() function will close the current wave stream.

Closing the Audio Device

Once all the opened streams are closed, it's time to end the application. Call ALDelete() to release the current audio device.

Deinitializing the MM Audio API

When your application is done with the API, it's time to shut it down. So, call ALUninit() to deinitialize it. But remember, once this function is called, none of the Audio API functions should be called. This should be the last API call made. But, it should be remembered that this function may cause an access violation error if the stream is web-based. So better, never call this function or call this function at the destructor to the class.

To achieve the Deinitialization action in your application, you modify the OnDestroy() function as follows:

Here, you have defined a function named Close( id ). It takes the source stream id as its input parameter and closes the stream. It is defined as:

void CMusic2Dlg::Close(ALdword id) // Close the stream with the
// ID given
{
ALSetWave(id); // Set the respective stream as current
ALCloseWave(); // Close the current stream
}

Compile the program and run. You have successfully completed your second music program using the MMAudio API.

MM Audio SDK for Borland C++

Borland C/C++ users cannot use the audio.lib file provided with the SDK. But, the al.h file remains unchanged. To get a Borland Import library, use the IMPLIB.EXE utility provided by the Borland C++ package. Run it at command line with the following parameter:

implib al.lib al.dll

The generated library module must be used with the BC/C++ compiler to compile the projects that use the MMAudio SDK.

Download Links

Note: This article was written for CG (www.codeguru.com). The related applications, documentations, and SDK with rutime are present at http://streetx.freespaces.com/. All files were scanned thoroughly for virus using Avast! 4.7 Home. but you should thoroughly scan any files you download for viruses. Neither the author nor CodeGuru cannot be held responsible for damages arising out of the product or related files. Use them at your own risk.

About the Author

Arnav Guddu

A hobby programmer. Do much of programming in graphics, animation, sound and multimedia. But a lot crazy about C++ related development. I may be reached at http://pendorasoft.byethost15.com/

Advertiser Disclosure:
Some of the products that appear on this site are from companies from which QuinStreet receives compensation. This compensation may impact how and where products appear on this site including, for example, the order in which they appear. QuinStreet does not include all companies or all types of products available in the marketplace.

Thanks for your registration, follow us on our social networks to keep up-to-date