Reputation: 7027
I'm having performance issues while using SoundPool. Everytime I play a sound, the frame rate drops. I added some logs and I can see on logcat that the "play" function sometimes takes 8ms.
I'm using *.ogg files and the SoundPool initialization is done on the app startup:
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));
To play the sound, I use the following code (inside the game loop):
mSoundPool.play(id, streamVolume, streamVolume, 1, loop, 1f);
My questions are:
Thanks!
UPDATE:
I just tested playing the sound on another thread and playing the sound through a service, but the lag is still present.
Then I did the following tests: * play the sound on 1000ms intervals -> the lag always happens * play the sound on 200ms intervals -> the lag NEVER happens
How is that possible?!?!? After these tests, it seems that when there is nothing playing, SoundPool is resetting and when it is going to play again, it takes longer to initialize... very weird!
Upvotes: 2
Views: 7558
Reputation: 3721
MP3 is pretty much your best bet since while OGG is provided for all platforms, those platforms may not support it.
Upvotes: 0
Reputation: 367
I just implemented something similar to thiagolr's technique of looping silence in the background. I agree that it doesn't seem like the right way to "fix" the problem--but it works. I used a MediaPlayer to loop the background "sound," because if I used a stream from the SoundPool, it sometimes got reused to play an actual sound effect, and the problem was back.
Another thing that I think helped was converting all of my audio to 16-bit 22K ogg.
I suppose the biggest downside to looping silence in the background is a small battery hit, but it seems worth it to have sound effects play when they're supposed to. I only do this on devices using Gingerbread or below. It works wonderfully well on the Kindle Fire, and I think adequately well on the Nook Tablet. My app is already a little on the slow side on the Nook Color, but I don't think this made it any worse. One of these days I need to do a complete conversion of my drawing code to use OpenGL.
Upvotes: 0
Reputation: 353
I have a seperate drawing and game loop, and when I call the sound pool play, my drawing loop experience some lag. Not always, but it makes my app seems laggy.
I've tried both wav and ogg, but doesnt seem to have much difference. Wav is a bit better, but it causes another problem, soundpool sometimes plays wav files twice when they called only once, so I switched to ogg.
My current solution is to call play from new runnable as:
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);
}
}
and then from my game loop, I call
Runnable r = new MyRunnable(sound_id);
handler.postDelayed(r, 0);
I experience much less lag in this way, but I'm sure it's not the correct/best solution.
Upvotes: 2
Reputation: 13
You could try to load MP3s instead of OGGs, I found that on some phones OGGs just don't play well.
Upvotes: 1
Reputation: 7027
I solved the issue by playing a muted sound in loop:
mSoundPool.play(id, 0, 0, 1, -1, 1f);
The lag disappeared completely!
This doesn't seem the right thing to do, so if anyone knows how to explain this, please let us know!
More Info: http://www.thiagorosa.com.br/en/how-to/improve-soundpool-performance
Upvotes: 6
Reputation: 46856
Should I call "play" on another thread, outside the game loop?
Should I call "play" through a service?
I've tried both and they both seemed to offer an identical performance boost. Both did fix the visible lag that I noticed within my application though. So I would say yes pick one of those to do and it should help out your performance.
Upvotes: 0