Как правильно использовать SoundPool в игре? - PullRequest
2 голосов
/ 16 сентября 2011

У меня проблемы с производительностью при использовании SoundPool. Каждый раз, когда я играю звук, частота кадров падает. Я добавил несколько логов и вижу на logcat, что функция «play» иногда занимает 8 мс.

Я использую * .ogg файлы, и инициализация SoundPool выполняется при запуске приложения:

mAudioManager = (AudioManager) context.getSystemService(Context.AUDIO_SERVICE);
mSoundPool = new SoundPool(size, AudioManager.STREAM_MUSIC, 0);
mSoundPoolMap = new HashMap<Integer, Integer>();
mSoundPoolMap.put(index, mSoundPool.load(context, R.raw.shot, 1));

Для воспроизведения звука я использую следующий код (внутри игрового цикла):

mSoundPool.play(id, streamVolume, streamVolume, 1, loop, 1f);

Мои вопросы:

  • Должен ли я вызывать "играть" в другом потоке, вне игрового цикла?
  • Должен ли я позвонить "играть" через службу?
  • Я что-то не так делаю?

Спасибо!


UPDATE:

Я только что протестировал воспроизведение звука в другом потоке и воспроизведение звука через службу, но задержка все еще присутствует.

Тогда я сделал следующие тесты: * воспроизводить звук с интервалами 1000 мс -> задержка всегда происходит * воспроизводить звук с интервалами 200 мс -> задержка НИКОГДА не происходит

Как это возможно?!?!? После этих тестов кажется, что когда ничего не воспроизводится, SoundPool сбрасывается, а когда он снова начинает играть, инициализация занимает больше времени ... очень странно!

Ответы [ 6 ]

6 голосов
/ 19 сентября 2011

Я решил проблему, проиграв приглушенный звук:

mSoundPool.play(id, 0, 0, 1, -1, 1f);

Лаг полностью исчез!

Это кажется неправильным, поэтому, если кто-нибудь знает, как это объяснить, пожалуйста, сообщите нам!

Подробнее: http://www.thiagorosa.com.br/en/how-to/improve-soundpool-performance

1 голос
/ 07 марта 2012

У меня есть отдельный цикл рисования и игры, и когда я вызываю пул звуков, моя петля рисования испытывает некоторое отставание.Не всегда, но это заставляет мое приложение казаться медленным.

Я пробовал и wav, и ogg, но, похоже, нет большой разницы.Wav немного лучше, но это вызывает другую проблему: soundpool иногда воспроизводит wav-файлы дважды, когда они вызывают только один раз, поэтому я переключился на ogg.

Мое текущее решение состоит в том, чтобы вызывать игру из нового runnable как:

public class MyRunnable implements Runnable {
        private int s_id; 
        public MyRunnable(int sound_id) {
            s_id = sound_id;
        }
        public void run() {
            SoundManager.playSound(s_id, 1);
        }
}

, а затем из моего игрового цикла я звоню

Runnable r = new MyRunnable(sound_id);
handler.postDelayed(r, 0);

Я испытываю гораздо меньшее отставаниетаким образом, но я уверен, что это не правильное / лучшее решение.

1 голос
/ 10 января 2012

Вы можете попытаться загрузить MP3 вместо OGG, я обнаружил, что на некоторых телефонах OGG просто не играют хорошо.

0 голосов
/ 08 октября 2013

MP3 - ваш лучший выбор, поскольку, хотя OGG предоставляется для всех платформ, эти платформы могут не поддерживать его.

0 голосов
/ 06 июня 2012

Я только что реализовал нечто похожее на технику тиаголрового зацикливания молчания на заднем плане.Я согласен, что это не похоже на правильный способ «исправить» проблему - но это работает.Я использовал MediaPlayer для зацикливания фонового «звука», потому что если я использовал поток из SoundPool, он иногда использовался для воспроизведения реального звукового эффекта, и проблема возвращалась.

Еще одна вещь, которую я думаюпомогла конвертировать весь мой звук в 16-битный 22-килограммовый ogg.

Полагаю, что самым большим недостатком зацикливания тишины на заднем плане является небольшой удар по батарее, но, похоже, стоит проигрывать звуковые эффекты, когдадолжен.Я делаю это только на устройствах, использующих Gingerbread или ниже.Он прекрасно работает на Kindle Fire, и я думаю, что он неплохо работает на Nook Tablet.Мое приложение уже немного медленное на Nook Color, но я не думаю, что это ухудшило ситуацию.На днях мне нужно полностью преобразовать код для рисования в OpenGL.

0 голосов
/ 16 сентября 2011

Должен ли я вызвать "play" в другом потоке, вне игрового цикла?

Должен ли я позвонить "играть" через услугу?

Я пробовал оба, и они оба, казалось, предлагали идентичное повышение производительности. Оба исправили видимое отставание, которое я заметил в моем приложении. Поэтому я бы сказал, что да, выберите один из них, и это должно помочь вашей работе.

...