Poor performance when playing songs starts in WP7

I have an XNA arcade game that is working on a Silverlight framework. The game has several sound clips that play randomly as background music.

As stated at http://msdn.microsoft.com/en-us/library/microsoft.xna.framework.media.songcollection.aspx , the developer cannot have full control over the Media Player. In particular, developers cannot create their own collection of songs or add songs to the play queue. There is a recommendation to play songs one at a time by calling MediaPlayer.Play ().

This is exactly what I do, but every time another song starts playing I am lacking in performance. The game freezes for a moment when I call MediaPlayer.Play (), even though all sound clips are loaded during game initialization and not at runtime. This only happens on some devices (eg HTC Mozart). In contrast, if I mute the game sounds and play the same clips in the phones music player while playing the game, there are no performance issues during song change. I also have no performance issues if we play clips using the SoundEffect class. However, I really want to use MediaPlayer for background audio for two reasons: - SoundEffect does not give a notification when playback ends - SoundEffect does not seem to work with .mp3 files.and using .wav files is very expensive

I also run profiling tests that confirm that the bad runtime starts a few milliseconds after MediaPlayer.Play () and lasts for about 0.4 seconds. During this time, my game does not perform any heavy operations, just a regular game update function ().

Here are my code snippets:

public void PlayBackgroundMusic(Song song)
{
    if ((!(App.Current as App).AppModel.SoundDisabled) && (song != null))
    {
        if (MediaPlayer.State != MediaState.Stopped)
        {
            StopBackgroundMusic();
        }
        MediaPlayer.Play(song);
    }
}

public void StopBackgroundMusic()
{
    MediaPlayer.Stop();
}

      

and the handler:

private void OnMediaStateChanged(object sender, EventArgs e)
{
    if (MediaPlayer.State != MediaState.Playing)
    {
        if (!AppModel.SoundDisabled)
        {
            int index = soundRandomizer.Next(0, sounds.Length - 1);
            PlayBackgroundMusic(sounds[index]);
        }
    }
}

      

Are there any suggestions?

+3


source to share


1 answer


In the end, I found a solution that I am happy with. It completely eliminates bias. Its idea is to use each MediaPlayer API on a separate thread obtained from the thread pool. I don't know how it fixes the problem, but this actually works for me:



public void PlayBackgroundMusic(Song song)
{
    if ((!(App.Current as App).AppModel.SoundDisabled) && (song != null))
    {
        if (MediaPlayer.State != MediaState.Stopped)
        {
            StopBackgroundMusic();
        }

        ThreadPool.QueueUserWorkItem((o) =>
        {
            MediaPlayer.Play(song);
        }
    }
}

public void StopBackgroundMusic()
{
    ThreadPool.QueueUserWorkItem((o) =>
    {
        MediaPlayer.Stop();
    }
}

      

+1


source







All Articles