4 min read

Background Music

Introduction

In the previous tutorial, we looked at how to play sound effects using a simple and direct approach. In this tutorial, we will follow a similar approach and add background music to our game.

Adding Audio Content to Your Project

As usual, our first step is to add the content that we need to our project. I’ll let you find the audio files that you want on your own. If you want some suggestions about what you can do for audio for your game, feel free to look at my suggestions.

We will be able to use .mp3, .wma, and .wav files for this, so make sure you’ve got the right format. Add your music to the project like we usually do, by right-clicking on the Content element in the Solution Explorer and choosing Add > Existing Item. Then browse until you find your audio files, and add them to the project.

When you compile your project, you can look through your built content and see that XNA is converting your audio files to .wma.

Using the Song and MediaPlayer Classes to Play Audio

In its simplest form, we only need about two lines of code to play our audio files. We could simply add the lines below to the LoadContent() method, and we would start playing music.

Song song = Content.Load<Song>("song_title");  // Put the name of your song here instead of "song_title"
MediaPlayer.Play(song);

While this is really all we need, I’m going to go a step further in this tutorial. We’ll do our audio a little bit differently, and display some information about the song. I’m going to use SpriteFonts to do this, so if you haven’t done the SpriteFont tutorial, now might be a good time to do that. Or you could just continue on and ignore the SpriteFont and text drawing stuff that comes up.

So let’s start by creating a variable to store our song and the font that we want. Let’s add the following two lines of code as member variables to our game:

protected Song song;
protected SpriteFont font;

Also, at this time, create a new SpriteFont file in your program as we did in the SpriteFont tutorial.

Now let’s load our content. Go to the LoadContent() method and add the following two lines of code:

song = Content.Load<Song>("song_name"); // use the name of your song instead of "song_name"
font = Content.Load<SpriteFont>("font_name");  // use the name of your font here as well.

MediaPlayer.Play(song); // this will start the song playing

Now at this point, we wanted to draw some information on the screen. We are ready to do that. Let’s draw the song title and some information about how long the song is, and how long it has been playing for. For the timing information, we can get the song’s length and how long it has been playing for, but it comes to us as an instance of the TimeSpan class. We want to get the time into a human-readable form, so to do this, let’s add a method to our class that looks like the one below:

public string GetHumanReadableTime(TimeSpan timeSpan)
{
    int minutes = timeSpan.Minutes;
    int seconds = timeSpan.Seconds;

    if (seconds < 10)
        return minutes + ":0" + seconds;
    else
        return minutes + ":" + seconds;
}

This method will return the time in the format: mm:ss (like “4:03”).

Now we just need to actually draw the text we want. In the Draw() method, add the following code:

TimeSpan time = MediaPlayer.PlayPosition;
TimeSpan songTime = song.Duration;

spriteBatch.Begin();

spriteBatch.DrawString(font,
    song.Name, new Vector2(100, 100), Color.Black);

spriteBatch.DrawString(font,
    GetHumanReadableTime(time) + " / " + GetHumanReadableTime(songTime),
    new Vector2(100, 150), Color.Black);            

spriteBatch.End();

We can now run our program, which should run, and give us accurate information about how far into the song the player is. The program will look something like the screenshot below:

Screenshot

Other Useful Song and MediaPlayer Things

There are a number of other things that might be useful when working with the Song and MediaPlayer classes. For starters, the MediaPlayer class also has methods called Pause() and Resume() that allow you to temporarily pause your song, and then pick up where you left off. It also has a Stop() method which will stop the song entirely.

In the MediaPlayer class, there is also a Volume property, which can be set to values between 0 and 1, and control the volume of the audio playback. 0 is basically so quiet you can’t hear it, and 1 means that it is playing at full volume.

Also, the PlayPosition property in the MediaPlayer class, which we used to display the current time earlier in the tutorial can be used to set the position of playback as well.

Yet another interesting feature of the MediaPlayer class is that it has a property called IsRepeating that indicates whether or not the song will repeat when it is finished. You can set this to true by using the code below to have the song repeat forever.

MediaPlayer.IsRepeating = true;

Also, note that in addition to the song’s name and length, which we looked at earlier, the Song class has properties that can get the genre (song.Genre), the album (song.Album), the artist, (song.Artist), whether or not the song has been rated (song.IsRated), the play count (song.PlayCount), the rating (song.Rating) and the track number (song.TrackNumber). Not all of these will really make sense for a game, and in fact, not all of this information may even really be available (or valid) when you are playing music in your game. These are all bits of data that come from the development of XNA on the Zune with XNA 3.0.