如何在游戏中正确使用SoundPool?
我在使用 SoundPool 时遇到性能问题。每次我播放声音时,帧速率就会下降。我添加了一些日志,我可以在 logcat 上看到“播放”功能有时需要 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);
我的问题是:
- 我应该在另一个线程上调用“play”吗?在游戏循环之外?
- 我应该通过服务调用“play”吗?
- 我做错了什么吗?
谢谢!
更新:
我刚刚测试了在另一个线程上播放声音并通过服务播放声音,但延迟仍然存在。
然后我做了以下测试: * 以1000ms的间隔播放声音->滞后总是会发生 * 以200ms的间隔播放声音->从来没有发生过滞后
这怎么可能?!?!? 经过这些测试,似乎没有播放任何内容时,SoundPool 正在重置,而当再次播放时,初始化时间会更长......非常奇怪!
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:
- Should I call "play" on another thread, outside the game loop?
- Should I call "play" through a service?
- Am I doing anything wrong?
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!
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(6)
我通过循环播放静音解决了这个问题:
延迟完全消失了!
这似乎不正确,所以如果有人知道如何解释这一点,请告诉我们!
更多信息:
http://www.thiagorosa.com.br/en/how-to/improve-声音池性能
I solved the issue by playing a muted sound in loop:
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
我有一个单独的绘图和游戏循环,当我调用声音池播放时,我的绘图循环遇到一些滞后。并非总是如此,但这让我的应用程序看起来很滞后。
我已经尝试过wav和ogg,但似乎没有太大区别。 wav 好一点,但它会导致另一个问题,soundpool 有时只调用一次 wav 文件就会播放两次,所以我改用 ogg。
我当前的解决方案是从新的可运行对象中调用 play 为:
然后从我的游戏循环中,我称
以这种方式体验到的延迟要少得多,但我确信这不是正确/最佳的解决方案。
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:
and then from my game loop, I call
I experience much less lag in this way, but I'm sure it's not the correct/best solution.
您可以尝试加载 MP3 而不是 OGG,我发现 OGG 在某些手机上播放效果不佳。
You could try to load MP3s instead of OGGs, I found that on some phones OGGs just don't play well.
我都尝试过,它们似乎都提供了相同的性能提升。不过,两者都确实修复了我在应用程序中注意到的明显延迟。所以我想说的是,选择其中一项去做,它应该有助于提高你的表现。
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.
我刚刚实现了类似于 thiagolr 在后台循环静音的技术。我同意这似乎不是“解决”问题的正确方法,但它确实有效。我使用 MediaPlayer 循环背景“声音”,因为如果我使用 SoundPool 中的流,它有时会被重用来播放实际的声音效果,问题又回来了。
我认为有帮助的另一件事是将我的所有音频转换为 16 位 22K ogg。
我认为背景循环静音的最大缺点是电池电量消耗较小,但在应该播放的时候播放音效似乎是值得的。我只在使用 Gingerbread 或更低版本的设备上执行此操作。它在 Kindle Fire 上运行得非常好,我认为在 Nook 平板电脑上也运行得很好。我的应用程序在 Nook Color 上已经有点慢了,但我不认为这会让情况变得更糟。有一天,我需要对我的绘图代码进行完全转换以使用 OpenGL。
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.
MP3 几乎是您最好的选择,因为虽然 OGG 为所有平台提供,但这些平台可能不支持它。
MP3 is pretty much your best bet since while OGG is provided for all platforms, those platforms may not support it.