0
\$\begingroup\$

I'm working on a (Windows-only) game in XNA, and I have multiple music tracks. I don't want to load them all into memory, but play them on demand. To properly dispose them, I have a separate ContentManager just for music and a method that looks like this:

    public void PlayMusic(MusicTracks trackToPlay)
    {
        if (trackToPlay == _currentlyPlayingTrack)
            return;

        MediaPlayer.Stop();
        _musicContentManager.Unload();

        Song song = null;
        switch (trackToPlay)
        {
            case MusicTracks.TitleMusic:
                song = _musicContentManager.Load<Song>("TitleMusic");
                break;
            case MusicTracks.CreditsMusic:
                song = _musicContentManager.Load<Song>("CreditsMusic");
                break;
        }

        if(song != null)
        {
            MediaPlayer.Play(song);
            MediaPlayer.IsRepeating = true;
        }
        _currentlyPlayingTrack = trackToPlay;
    }

(MusicTracks is an enum).

Is this the correct way to make sure I'm not using more RAM/Resources than required? Or should I be looking into XACT? To be clear, I don't need to play multiple Songs at the same time (I do need to play 1 Song and a few SoundEffects though) and I don't need any crazy effects apart from setting the Volume of the music independently from the soundeffects, which should be straight forward with MediaPlayer.Volume.

\$\endgroup\$
  • 1
    \$\begingroup\$ How about if you try it in the way you're proposing, and if you have problems, you fix them? It is very difficult to know in advance if you're going to have memory or performance problems unless you actually implement your code, and then test, measure and profile it to know where a bottleneck is. In most cases, pieces of code that you think you may require optimization don't; so focus on clarity and on writing code that makes sense to you, so you can focus more on making a fun game instead of optimizing where it may not be needed. \$\endgroup\$ – Panda Pajama Mar 7 '14 at 6:27
  • \$\begingroup\$ @Panda The point is to reach out to people that might have already dealt with this for their own games and point out if there's better ways. Not all issues are always obvious. \$\endgroup\$ – Michael Stum Mar 7 '14 at 21:23
  • 1
    \$\begingroup\$ I stand by my point. As Andrew said, for a Windows game, it will make a very small, almost unnoticeable difference. Even if you're completely decoding the entire songs, one 3 minute song will take some 30MiB. 10 songs will take 300 MiB, and any moden computer has 300 MiB to spare. XNA's Song streams the files anyways, so this is completely a non-issue. The time you use while "optimizing" this non-issue is most likely better spent on making the game more fun, so you should really not care about this, unless it actually becomes a problem. \$\endgroup\$ – Panda Pajama Mar 8 '14 at 14:37
2
\$\begingroup\$

The code you have there appears to be just fine.

The alternative would be to use a custom ContentManager that allowed you to Dispose of the Song objects directly, rather than having to go through Unload. See this blog post for details.

A minor nit-pick: You set IsRepeating after you call Play. Theoretically this is a race condition: the song could end before IsRepeating becomes true. So set it before you call Play.


In XNA, MediaPlayer is optimised for playing background music, whereas XACT and SoundEffect are for... well... sound effects. On PC it's not going to make much difference. But on mobile (for example) it can make a big difference, as it can use the dedicated audio decoder hardware.

\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.