Tricks of the Windows Game Programming Gurus:Sounding Off with DirectSound and DirectMusic

All ITKnowledge Source Code Search Tips Advanced Search |

| Tricks of the Windows Game Programming Gurus by Andre LaMothe Sams, Macmillan Computer Publishing ISBN: 0672313618 Pub Date: 09/27/99

Search this book:

Previous | Table of Contents | Next

#### The Types

First is the DirectSound object. There are only two types for the sound engine: one to hold a digital sample, and the other to hold a MIDI segment:

    // this holds a single sound

    typedef struct pcm_sound_typ

       {

       LPDIRECTSOUNDBUFFER dsbuffer;  // the directsound buffer

                    // containing the sound

       int state;   // state of the sound

       int rate;    // playback rate

       int size;    // size of sound

       int id;      // id number of the sound

       } pcm_sound, *pcm_sound_ptr;

And now the DirectMusic segment type:

    // directmusic MIDI segment

    typedef struct DMUSIC_MIDI_TYP

    {

    IDirectMusicSegment        *dm_segment;  // the directmusic segment

    IDirectMusicSegmentState   *dm_segstate; // the state of the segment

    int                        id;           // the id of this segment

    int                        state;        // state of midi song

    } DMUSIC_MIDI, *DMUSIC_MIDI_PTR;

Both sounds and MIDI segments, respectively, will be stored by the engine in the preceding two structures. Now let’s take a look at the globals.

#### Global Domination

T3DLIB3 contains a number of globals. Let’s take a look. First are the globals for the DirectSound system:

    LPDIRECTSOUND       lpds;    // directsound interface pointer

    DSBUFFERDESC    dsbd;    // directsound description

    DSCAPS        dscaps;  // directsound caps

    HRESULT        dsresult // general directsound result

    DSBCAPS        dsbcaps; // directsound buffer caps

    pcm_sound    sound_fx[MAX_SOUNDS]; // array of sound buffers

    WAVEFORMATEX    pcmwf;  // generic waveformat structure

And here are the globals for DirectMusic:

    // direct music globals

    // the directmusic performance manager

    IDirectMusicPerformance    *dm_perf ;

    IDirectMusicLoader *dm_loader;  // the directmusic loader

    // this hold all the directmusic midi objects

    DMUSIC_MIDI dm_midi[DM_NUM_SEGMENTS];

    int dm_active_id;   // currently active midi segment

> Note: The highlighted lines show the arrays that hold sounds and MIDI segments.

You shouldn’t have to mess with any of these globals, except to access the interfaces directly if you want to do so. In general, the API will handle everything for you, but the globals are there if you want to tear them up.

There are two parts to the library: DirectSound and DirectMusic. Let’s take a look at DirectSound first, and then DirectMusic.

#### The DirectSound API Wrapper

DirectSound can be simple or complicated, depending on how you use it. If you want a “do it all” API, you’re going to end up using most of the DirectSound functions themselves. But if you want a simpler API that allows you to initialize DirectSound and load and play sounds of a specific format, that’s a lot easier to wrap up into a few functions.

So what I’ve done is take much of your work in the DirectSound part of this chapter and formalize it into functions for you. In addition, I’ve created an abstraction around the sound system, so you refer to a sound with an ID (same for the DirectMusic part) that is given to you during the loading process. Thus, you can use this ID to play the sound, check its status, or terminate it. This way there aren’t any ugly interface pointers that you have to mess with. The new API supports the following functionality:

  • Initializing and shutting down DirectSound with single calls.
  • Loading `.WAV` files with 11 KHz 8-bit mono format.
  • Playing a loaded sound file.
  • Stopping a sound.
  • Testing the play status of a sound.
  • Changing the volume, playback rate, or stereo panning of a sound.
  • Deleting sounds from memory.

Let’s take a look at each function one by one.

> Note: Unless otherwise stated, all functions return `TRUE (1)` if successful and `FALSE (0)` if not.

Function Prototype:

    int DSound_Init(void);

Purpose:

`DSound_Init()` initializes the entire DirectSound system. It creates the DirectSound COM object, sets the priority level, and so forth. Just call the function at the beginning of your application if you want to use sound. Here’s an example:

    if (!DSound_Init(void))

       { /* error */ }

Function Prototype:

    int DSound_Shutdown(void);

Purpose:

`DSound_Shutdown()` shuts down and releases all the COM interfaces created during `DSound_Init()`. However, `DSound_Shutdown()` will not release all the memory allocated to all the sounds. You must do this yourself with another function. Anyway, here’s how you would shut down DirectSound:

    if (!DSound_Shutdown())

       { /* error */ }

Function Prototype:

    int DSound_Load_WAV(char *filename);

Purpose:

`DSound_Load_WAV()` creates a DirectSound buffer, loads the sound data file into memory, and prepares the sound to be played. The function takes the complete path and filename of the sound file to be loaded (including the extension `.WAV`) and loads the file from the disk. If successful, the function returns a non-negative ID number. You must save this number because it is used as a handle to reference the sound. If the function can’t find the file, or too many sounds are loaded, it will return -1. Here’s an example of loading a `.WAV` file named `FIRE.WAV`:

    int fire_id = DSound_Load_WAV(“FIRE.WAV”);

    // test for error

    if (fire_id==-1)

       { /* error */}

Previous | Table of Contents | Next

Copyright © Macmillan Computer Publishing, Inc.

Products | Contact Us | About Us | Privacy | Ad Info | Home
Use of this site is subject to certain Terms & Conditions, Copyright © 1996-2000 EarthWeb Inc. All rights reserved. Reproduction in whole or in part in any form or medium without express written permission of EarthWeb is prohibited. Read EarthWeb's privacy statement.