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

Of course, it’s up to you how you want to save the IDs. You might want to use an array or something else.

Finally, you might wonder where the sound data is and how to mess with it. If you really must, you can access the data within the `pcm_sound` array `sound_fx[]`, using the ID you get back from either load function as the index. For example, here’s how you would access the DirectSound buffer for the sound with ID `sound_id`:

    sound_fx[sound_id].dsbuffer

Function Prototype:

    int DSound_Replicate_Sound(int source_id); // id of sound to copy

Purpose:

`DSound_Replicate_Sound()` is used to copy a sound without copying the memory used to hold the sound. For example, let’s say you have a gunshot sound and you want to fire three gunshots, one right after another. The only way to do this right now would be to load three copies of the gunshot sound into three different DirectSound memory buffers, which would be a waste of memory.

Alas, there is a solution—it’s possible to create a duplicate (or replicant, if you’re a Blade Runner fan) of the sound buffer, excluding for the actual sound data. Instead of copying it, you just point a pointer to it, and DirectSound is smart enough to be used as a “source” for multiple sounds using the same data. If you wanted to play a gunshot up to eight times, for example, you would load the gunshot once, make seven copies of it, and acquire a total of eight unique IDs. Replicated sounds work exactly the same as normal sounds, except that instead of using `DSound_Load_WAV()` to load and create them, you copy them with `DSound_Replicate_Sound()`. Get it? Good! I’m starting to get dizzy! Here’s an example of creating eight gunshots:

    int gunshot_ids[8]; // this holds all the id’s

    // load in the master sound

    gunshot_ids[0] = Load_WAV(“GUNSHOT.WAV”);

    // now make copies

    for (int index=1; index<8; index++)

        gunshot_ids[index] = DSound_Replicate_Sound(gunshot_ids[0]);

    // use gunshot_ids[0..7] anyway you wish, they all go bang!

Function Prototype:

    int DSound_Play_Sound(int id,       // id of sound to play

                         int flags=0,  // 0 or DSBPLAY_LOOPING

                         int volume=0, // unused

                         int rate=0,   // unused

                         int pan=0);   // unused

Purpose:

`DSound_Play_Sound()` plays a previously loaded sound. You simply send the ID of the sound along with the play flags—0 for a single sound, or `DSBPLAY_LOOPING` to loop—and the sound will start playing. And if the sound is already playing, it will restart at the beginning. Here’s an example of loading and playing a sound:

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

    DSound_Play_Sound(fire_id,0);

Or, you can leave out the 0 for flags entirely because its default parameter is 0:

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

    DSound_Play_Sound(fire_id);

Either way the `FIRE.WAV` sound will play once and then stop. To make it loop, send `DSBPLAY_LOOPING` for the flags parameter.

Function Prototype:

    int DSound_Stop_Sound(int id);

    int DSound_Stop_All_Sounds(void);

Purpose:

`DSound_Stop_Sound()` is used to stop a single sound from playing (if it’s playing already). You simply send the ID of the sound and that’s it. `DSound_Stop_All_Sounds()` will stop all the sounds currently playing. Here’s an example of stopping the `fire_id` sound:

    DSound_Stop_Sound(fire_id);

And at the end of your program, it’s a good idea to stop all the sounds from playing before exiting. You could do this with separate calls to `DSound_Stop_Sound()` for each sound, or a single call to `DSound_Stop_All_Sounds()`, like this:

    //...system shutdown code

    DSound_Stop_All_Sounds();

Function Prototype:

    int DSound_Delete_Sound(int id); // id of sound to delete

    int DSound_Delete_All_Sounds(void);

Purpose:

`DSound_Delete_Sound()` deletes a sound from memory and releases the DirectSound buffer associated with it. If the sound is playing, the function will stop it first. `DSound_Delete_All_Sounds()` deletes all previously loaded sounds. Here’s an example of deleting the `fire_id` sound:

    DSound_Delete_Sound(fire_id);

Function Prototype:

    int DSound_Status_Sound(int id);

Purpose:

`DSound_Status_Sound()` tests the status of a loaded sound based on its ID. All you do is pass the ID number of the sound to the function, and the function will return one of these values:

  • `DSBSTATUS_LOOPING`—The sound is currently playing and is in loop mode.
  • `DSBSTATUS_PLAYING`—The sound is currently playing and is in single-play mode.

If the value returned from `DSound_Status_Sound()` is neither of the these constants, the sound is not playing. Here’s a complete example that waits until a sound has finished playing and then deletes it:

    // initialize DirectSound

    DSound_DSound_Init();

    // load a sound

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

    // play the sound in single mode

    DSound_Play_Sound(fire_id);

    // wait until the sound is done

    while(DSound_Sound_Status(fire_id) &

                  (DSBSTATUS_LOOPING | DSBSTATUS_PLAYING));

    // delete the sound

    DSound_Delete_Sound(fire_id);

    // shutdown DirectSound

    DSound_DSound_Shutdown();

Pretty cool, huh? A lot better than the couple hundred or so lines of code required to do it manually with DirectSound!

Function Prototype:

    int DSound_Set_Sound_Volume(int id,   // id of sound

                         int vol); // volume from 0-100

Purpose:

`DSound_Set_Sound_Volume()` changes the volume of a sound in real-time. Send the ID of the sound, along with a value from 0-100, and the sound will change instantly. Here’s an example of reducing the volume of a sound to 50 percent of what it was loaded as:

    DSound_Set_Sound_Volume(fire_id, 50);

You can always change the volume back to 100 percent, like this:

    DSound_Set_Sound_Volume(fire_id, 100);

Function Prototype:

    int DSound_Set_Sound_Freq(

                   int id,    // sound id

                   int freq); // new playback rate from 0-100000

Purpose:

`DSound_Set_Sound_Freq()` changes the playback frequency of the sound. Because all sounds must be loaded at 11 KHz mono, here’s how you would double the perceived playback rate:

    DSound_Set_Sound_Freq(fire_id, 22050);

And to make you sound like Darth Vader, do this:

    DSound_Set_Sound_Freq(fire_id, 6000);

Function Prototype:

    int DSound_Set_Sound_Pan(

        int id,   // sound id

        int pan); // panning value from -10000 to 10000

Purpose:

`DSound_Set_Sound_Pan()` sets the relative intensity of the sound on the right and left speakers. A value of -10,000 is hard left, and 10,000 is hard right. If you want equal power, set the pan to 0. Here’s how you would set the pan all the way to the right side:

    DSound_Set_Sound_Pan(fire_id, 10000);

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.