Skip to content
Gabor Szauer edited this page Aug 19, 2015 · 4 revisions

#Sound Manager You will notice that the SoundManager is very similar to the TextureManager. The sound manager has 3 important roles: to load, play and unload sounds.

  • Load a sound: Returns a reference counted handle to a sound. If you load the same sound two times, it will ony be in memory once. You will have to unload a sound as many times as it's been loaded.
  • Playing a sound: This is as straight forward as it gets, it plays a sound. If a sound is playing and you call play on it again, it will not play twice on top of each other. The sound will stop, and start playing from the start.
  • Unload a sound: Removes one from the sounds reference count. Once the reference count reaches 0 the sound is eligable to be released.

Remember, if you load a sound 3 times you have to unload it 3 times. The load and unload counts must match.

The sound manager is capable of loading MP3 and WAV files. Adding support for OGG files should be pretty easy if we want to try.

In general there are two ways to play a sound. You can either uncompress the entire sound into memory and play it, OR you can stream a portion of the sound.

Streaming takes a LOT less memory as it uncompresses a little bit of the sound at a time to be played, but because of runtime decompression it's more processing heavy.

Decompressing the entire sound into memory and playing it from there obviously takes more memory, but it makes for better performance. It takes up a LOT more memory, a 3 MB MP3 file might uncompress into 16 MB in memory.

The sound manager does not include support for streaming. When you load an MP3, the full file is decompressed into memory. This is done to keep the framework as performant as possible.

Lets explore how to actually use the sound manager. We are going to be starting from the skeleton created on the repositorys front page.

#Initialize and shutdown The Sound Manager's Initialize and shutdown functions have the same signature as the Texture and Graphics managers. Lets initialize and shut down the sound manager in Program.cs

public static void Initialize(object sender, EventArgs e) {
    SoundManager.Instance.Initialize(Window);
}

public static void Update(object sender, FrameEventArgs e) {
    // UPDATE GAME
}

public static void Render(object sender, FrameEventArgs e) {
    // RENDER GAME
}

public static void Shutdown(object sender, EventArgs e) {
    SoundManager.Instance.Shutdown();
}

#Load and Unload Download this sound pack. Unzip into a folder names Assets next ot the visual studio solution (.sln) file. Make sure the working directory for your project is set properly.

We can load a sound using the LoadMp3 and LoadWav functions of the SoundManager. The signatures of these functions look like this:

public int LoadMp3(string path)
public int LoadWav(string path)

The functions return a handle to the sound that you just loaded. You need to hand on to this integer in order to play and unload the sound. Let's add some globals to Program.cs

static int sound1 = -1;
static int sound2 = -1;

Now that we have some variables to hold the sounds, lets actually load sounds into them:

public static void Initialize(object sender, EventArgs e) {
    SoundManager.Instance.Initialize(Window);

    sound1 = SoundManager.Instance.LoadMp3("Assets/BGMusic.mp3");
    sound2 = SoundManager.Instance.LoadWav("Assets/SampleSound.wav");
}

And of course, when we call load we also call unload

public static void Shutdown(object sender, EventArgs e) {
    SoundManager.Instance.UnloadSound(sound1);
    SoundManager.Instance.UnloadSound(sound2);

    SoundManager.Instance.Shutdown();
}

#Playing a sound The SoundManager has a super simple PlaySound function that will play a sound. It's signature looks like this:

public void PlaySound(int soundId)

We're going to call PlaySound right in the initialize function:

public static void Initialize(object sender, EventArgs e) {
    SoundManager.Instance.Initialize(Window);

    sound1 = SoundManager.Instance.LoadMp3("Assets/BGMusic.mp3");
    sound2 = SoundManager.Instance.LoadWav("Assets/SampleSound.wav");

    SoundManager.Instance.PlaySound(sound2);
}

Run the game and you should hear a sound as soon as the window opens.

#Check sound status The SoundManager has a nifty IsPlaying function you can call to check if a sound is playing or not. The signature for this function looks like this:

public bool IsPlaying(int soundId)

This function is needed to loop a sound. If you want to loop some background music for example, you would check if the sound is playing in each update of the game. If it is not playing you'd call play again. Let's do just that:

public static void Update(object sender, FrameEventArgs e) {
    if (!SoundManager.Instance.IsPlaying(sound1) && !SoundManager.Instance.IsPlaying(sound2)) {
        Console.WriteLine("LOOP");
        SoundManager.Instance.PlaySound(sound1);
    }
}

This block is simple, if neither sound 1 or sound 2 is playing we call play on sound 1. Because this is in the Update function the check will happen every frame, and the sound will start playing as soon as it's stopped. Whenver the sound starts playing we print "LOOP" to the console to make it obvious what happened. If i recall correctly, the provided sound is a 24 second loop.

#Volume The sound manager provides two functions to deal with volume, they are: GetVolume and SetVolume the signatures for these functions look like this:

public float GetVolume(int soundId)
public void SetVolume(int soundId, float volume) 

The volume of a sound is normalized, meaning it's between 0.0f and 1.0f

Let's do something fun in update, we're going to get the volume of the sound1, and if it's greater than 0 subtract 0.25 from it. Meaning, every time the sound plays it should get quieter.

public static void Update(object sender, FrameEventArgs e) {
    if (!SoundManager.Instance.IsPlaying(sound1) && !SoundManager.Instance.IsPlaying(sound2)) {
        Console.WriteLine("LOOP");
        SoundManager.Instance.PlaySound(sound1);

        float volume = SoundManager.Instance.GetVolume(sound1);
        if (volume > 0.0f) {
            volume -= 0.25f;
            SoundManager.Instance.SetVolume(sound1, volume);
        }
    }
}

And that's all there is to the sound manager.

Clone this wiki locally