sunlight

DirectSound 7

Introduction

In this part of the tutorial, we will cover:

  • DirectSound
  • Loading sounds from resources

DirectSound

Note: This section deals with DirectSound 7. New applications should use DirectX Audio.

We now have a large and extensive program to which we want to add sound. However, it's best to start simple with a new idea, and because DirectSound has a few new ideas, we're going to go back to basics and make a console program.

To use DirectSound, you will need to add MMSYSTEM.H and DSOUND.H to your header file includes:

#include <mmsystem.h>
#include <dsound.h>

and add DSOUND.LIB to your project.

We will need a new function to initialise DirectSound. This function will first need to call DirectSoundCreate to create an IDirectSound object.
BOOL InitDirectSound()
{
	DirectSoundCreate(NULL, &pDS, NULL);

Now, as before, we must set the co-operative level of the application. The co-operative level defines how much access we need to the sound hardware. We want non-exclusive access to the sound card (so that other applications can play sound), but we want priority access to allow us to change the sound buffer format.

Since we have no window handle for SetCooperativeLevel, we'll make one up:

	HWND hWnd = GetForegroundWindow();
	if (hWnd == NULL)
		hWnd = GetDesktopWindow();
	pDS->SetCooperativeLevel(hWnd, DSSCL_PRIORITY); 

Now we have access to the sound hardware. We could set the hardware to any format we like - the default is 22kHz, 8-bit. This doesn't affect what sound formats you can play through it - if they are not 22kHz 8-bit sounds, they will be converted to be so before playing. The default is fine for our purposes, so all we will do is create the primary buffer without specifying a format.

	IDirectSoundBuffer	*lpDsb;
	DSBUFFERDESC		dsbdesc;

	memset(&dsbdesc, 0, sizeof(DSBUFFERDESC));
	dsbdesc.dwSize = sizeof(DSBUFFERDESC);
	dsbdesc.dwFlags = DSBCAPS_PRIMARYBUFFER;
	pDS->CreateSoundBuffer(&dsbdesc, &lpDsb, NULL);

The primary buffer, to which we have just received a pointer, is the output buffer (rather like the primary surface in DirectDraw). In order to get the sound hardware going, we have to play this buffer:

	lpDsb->Play(0, 0, DSBPLAY_LOOPING);

Primary buffers must always specify 'looping' to avoid clicks (as the primary buffer starts up in the middle of a sound).

We need a cleanup function:

void ExitDirectSound()
{
	pDS->Release();
	pDS = NULL;
}

Loading a Sound

Unlike DirectDraw, in which we could call a GDI function to load an image file, in DirectSound there are no functions to load .WAV files. This is not quite as troublesome as it seems, because there are sample functions to load WAV files, but for now, we will use a slightly easier method.

Open your resources (or create a new resource script) and add a "WAVE" resource. In Visual C++, this is done by choosing Insert - Resource, clicking 'Import' and finding a .WAV file. This will add the WAVE file to your resources. Give it an ID of IDR_SOUND Those of you who are using text editors can add the line

IDR_SOUND WAVE DISCARDABLE "Splat.wav" 

to your .RC file, and put a #define in your .h file to give IDR_SOUND a value.

Now, as before, we will require some helper functions. I will provide them here, since they have been left out of the new DirectSound samples: dsutil.cpp and dsutil.h. Add the .cpp file to your project (as before), and put the include file in:

#include "dsutil.h"

Now we will write our main function. First we will need to initialise DirectSound:

int _tmain()
{
	InitDirectSound();

Now we will create a secondary buffer, which contains the sound we want to play:

	IDirectSoundBuffer *pSound;
	
	pSound = DSLoadSoundBuffer(pDS, MAKEINTRESOURCE(IDR_SOUND));

Now we will play it:

	pSound->Play(0, 0, 0);

And finally, we must wait for the sound to finish (this is only a simple application, so we will just sleep until it stops).

	DWORD dwStatus;

	do
	{
		Sleep(0);

		pSound->GetStatus(&dwStatus);
	}
	while (dwStatus & DSBSTATUS_PLAYING);

	return 0;
}

That's it - we've created a sound-playing program. You can get the code here: DirectSoundBones.cpp. Note that in this code, I've put a lot of error-handling that I haven't put on this page, incorporating the concepts of the previous page.

 

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!