sunlight

DirectX Audio

Introduction

In this part of the tutorial, we will cover:

  • DirectX Audio
  • Loading sounds and music from files

DirectX Audio is a functional extension of DirectMusic, from DirectX 6.1, so we'll refer to it as DirectMusic from now on.

Previous View Code Download Code Next

Sound Support

To use DirectMusic, you will need to add DMUSICC.H and DMUSICI.H to your header file includes:

#include <dmusicc.h>
#include <dmusici.h>

DirectMusic initialisation works slightly differently from that of DirectDraw. It uses the standard COM call CoCreateInstance to create the IDirectMusicPerformance object. Therefore, we don't need a library for DirectMusic. You will have to add OLE32.LIB for CoCreateInstance, though.

BOOL InitDirectMusic()
{
	::CoInitialize(NULL);
	::CoCreateInstance(CLSID_DirectMusicPerformance, NULL, 
                     CLSCTX_INPROC, IID_IDirectMusicPerformance8,
                     (void **)&g_pPerformance);

We now initialise the audio. We want the defaults for almost everything. We will specify a standard music (stereo and reverb) setup:

	g_pPerformance->InitAudio(NULL, NULL, NULL, 
		DMUS_APATH_SHARED_STEREOPLUSREVERB, 
		64, DMUS_AUDIOF_ALL, NULL);

We must now create an IDirectMusicLoader object, which will load our audio files for us.

	::CoCreateInstance(CLSID_DirectMusicLoader, NULL, 
                     CLSCTX_INPROC, IID_IDirectMusicLoader8,
                     (void **)&g_pLoader);

We need a cleanup function:

void ExitDirectMusic()
{
	if (g_pPerformance)
	{
		g_pPerformance->CloseDown();
		g_pPerformance->Release();
		g_pPerformance = NULL;
	}
	if (g_pLoader)
	{
		g_pLoader->Release();
		g_pLoader = NULL;
	}
}

Loading a Sound

Unlike DirectDraw, in which we had to call a GDI function to load an image file, in DirectMusic we use an IDirectMusicLoader object. This gives us back an IDirectMusicSegment object, which represents the loaded music data, which we can then play through the performance.

Unusually (and in contrast to DirectInput), DirectMusic interfaces all operate in Unicode. We can call LoadObjectFromFile to load a music file:

	IDirectMusicSegment8 *pSegment = NULL;

	g_pLoader->LoadObjectFromFile(CLSID_DirectMusicSegment, 
		IID_IDirectMusicSegment8, L"passport.mid", (void **) &pSegment);

This file is a standard MIDI file, containing all the patch and tempo changes for the piece. We must tell DirectMusic this:

    // Standard MIDI file
    g_pBackgroundMusic->SetParam(GUID_StandardMIDIFile, 
        0xFFFFFFFF, DMUS_SEG_ALLTRACKS, 0, NULL);

We want the file to repeat over and over:

    // Repeat forever
    g_pBackgroundMusic->SetRepeats(DMUS_SEG_REPEAT_INFINITE);

We must now download this segment to the audio system, to make sure all the instruments are loaded.

	pSegment->Download(g_pPerformance);

Now we will play it. The segment will loop, as we specified.

	g_pPerformance->PlaySegment(pSegment, DMUS_SEGF_AFTERPREPARETIME, 0, NULL);

And finally, we must stop the sound when we finish.

	g_pPerformance->Stop(NULL, NULL, 0, 0);

That's it - we've added background music, a welcome relief after the large amounts of code required for DirectInput. It doesn't just play MIDI-format files, either: try playing a WAV file with it, too. This means that you can play sound effects using this; with DirectMusic, you can add reverb and other effects to them, too. Try it!

We've come to the end of our brief rundown of the features of DirectDraw, DirectInput and DirectX Audio. All that remains is to clean up: add error-checking, support for lost surfaces and clipping, which we'll do in the next section.

The old DirectX 7 DirectSound tutorial is also available.

 

Copyright © David McCabe, 1998 - 2001. All rights reserved.

You will need to download and install the m-math control to display any equations on this Web site. Without this control, you will not see most of the equations. Please do not e-mail me asking why the equations do not display!