Проблемы с Android Soundpool - PullRequest
       7

Проблемы с Android Soundpool

6 голосов
/ 03 октября 2010

У меня есть приложение на Android Market, и я использую классы SoundPool для звуковых эффектов. Я заметил, что из всех частей API Android это, кажется, вызвало у меня больше всего проблем. Например:

  • HTC Desire имеет проблемы с воспроизведением файлов WAV (это приводит к случайной блокировке). Использование .ogg файлов исправляет это

  • На Droid, если вы превысили количество каналов в вызове установки init:

mSoundPool = new SoundPool(4, AudioManager.STREAM_MUSIC, 0);

трубка заблокируется. Если вы можете вообразить трудности в отладке этого! На телефоне я не владею. Это потребовало много самоотверженной помощи от моих клиентов. Изменение «4» на «16» устранило проблему. Я не сомневаюсь, что, если 16 звуков воспроизводятся одновременно, он все равно рухнет. К счастью, шансы на это невелики.

  • Также получаю случайные сбои на разных устройствах. У меня есть один из моих клиентов, у которого есть ошибки «Переполнение кучи», относящиеся к воспроизведению звуков.

Я изменил свой диспетчер звука, чтобы использовать MediaPlayer. Это, кажется, работает хорошо сейчас. Мне просто интересно, сталкиваются ли другие разработчики с такими проблемами?

1 Ответ

4 голосов
/ 22 апреля 2011

Это кажется AudioFlinger может иметь до 1 Мбайт звука, происходящего в любой момент времени.Ошибки кучи возникают, если этот предел превышен.Это предположение основано на некотором коде, который я нашел в исходном коде AudioFlinger:

AudioFlinger::Client::Client(const sp<AudioFlinger>& audioFlinger, pid_t pid) 
     :   RefBase(), 
         mAudioFlinger(audioFlinger), 
         mMemoryDealer(new MemoryDealer(1024*1024)), 
         mPid(pid) 
{ 
     // 1 MB of address space is good for 32 tracks, 8 buffers each, 4 KB/buffer 
} 

И это:

size_t size = sizeof(audio_track_cblk_t); 
size_t bufferSize = frameCount*channelCount*sizeof(int16_t); 
if (sharedBuffer == 0) { 
    size += bufferSize; 
} 
mCblkMemory = client->heap()->allocate(size); 
if (mCblkMemory != 0) {
    ...
} else {
    LOGE("not enough memory for AudioTrack size=%u", size); 
    client->heap()->dump("AudioTrack"); 
}

Кто-нибудь еще лучше информирован?

...