Плохое исполнение при запуске воспроизведения песни в WP7 - PullRequest
3 голосов
/ 03 апреля 2012

У меня есть аркадная игра XNA, которая работает в среде Silverlight.В игре есть несколько звуковых клипов, которые воспроизводятся в случайном порядке в качестве фоновой музыки.

Как указано в http://msdn.microsoft.com/en-us/library/microsoft.xna.framework.media.songcollection.aspx,, разработчик не может иметь полный контроль над Media Player.В частности, разработчики не могут создавать свои коллекции песен или добавлять песни в очередь воспроизведения.Рекомендуется воспроизводить песни по одной, вызывая MediaPlayer.Play ().

Это именно то, что я делаю, но я испытываю недостаток производительности каждый раз, когда начинает играть другая песня.Игра зависает на мгновение, когда я вызываю MediaPlayer.Play (), несмотря на то, что все звуковые клипы загружаются во время инициализации игры, а не во время выполнения.Это происходит только на некоторых устройствах (например, HTC Mozart).Напротив, если я отключаю звуки игры и играю те же клипы в музыкальном проигрывателе телефона во время запуска игры, при смене песни проблем с производительностью не возникает.У меня также не возникает проблем с производительностью, если мы воспроизводим клипы с помощью класса SoundEffect.Тем не менее, я настоятельно хочу использовать MediaPlayer для целей фонового звука по двум причинам: - SoundEffect не выдает уведомление, когда воспроизведение завершено - SoundEffect, похоже, не работает с файлами .mp3, и использование файлов .wav оченьдорогой

Я также провел тесты профилирования, которые подтвердили, что временные рамки с низкой производительностью начинаются через несколько миллисекунд после MediaPlayer.Play () и продолжаются в течение примерно 0,4 секунды.В это время моя игра не выполняет каких-либо тяжелых операций, только функция Update () обычного игрового таймера.

Вот мои фрагменты кода:

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();
}

и обработчик:

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]);
        }
    }
}

Есть ли предложения?

1 Ответ

1 голос
/ 06 апреля 2012

В конце концов, я нашел решение, которым я доволен.Это устраняет покачивание почти полностью.Его идея состоит в том, чтобы использовать каждый MediaPlayer API в отдельном потоке, полученном из пула потоков.Я не знаю, как это решает проблему, но это действительно работает для меня:

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();
    }
}
...