android gdx声音表现问题

时间:2013-04-01 11:42:54

标签: android performance audio libgdx

我正在使用libgdx构建一个滚动射击游戏。在Windows中,一切运行得很好,但在Android上我得到明显的抖动,帧率从61 fps avg无声音下降到48-56 fps avg with sound。它会同时发挥很多小的声音效果,因为有很多子弹可以射击,敌人可以同时击中。我的声音例程:

import com.badlogic.gdx.Gdx;
import com.badlogic.gdx.audio.Sound;

public class SoundFX {

    static final int BGDIE = 1, BGHIT = 2, BGLASER = 3, BGSPAWN = 4, PDIE = 5, PHIT = 6, PLASER = 7, PSPAWN = 8, PAUSE = 9;
    Sound S_BGDIE, S_BGHIT, S_BGLASER, S_BGSPAWN, S_PDIE, S_PHIT, S_PLASER, S_PSPAWN, S_PAUSE;

    public void load()
    {
        S_BGDIE = Gdx.audio.newSound(Gdx.files.internal("data/sfx/badguydie.mp3"));
        S_BGHIT = Gdx.audio.newSound(Gdx.files.internal("data/sfx/badguygothit.mp3"));
        S_BGLASER = Gdx.audio.newSound(Gdx.files.internal("data/sfx/badguylaser.mp3"));
        S_BGSPAWN = Gdx.audio.newSound(Gdx.files.internal("data/sfx/badguyspawn.mp3"));
        S_PDIE = Gdx.audio.newSound(Gdx.files.internal("data/sfx/playerdie.mp3"));
        S_PHIT = Gdx.audio.newSound(Gdx.files.internal("data/sfx/playergothit.mp3"));
        S_PLASER = Gdx.audio.newSound(Gdx.files.internal("data/sfx/playerlaser.mp3"));
        S_PSPAWN = Gdx.audio.newSound(Gdx.files.internal("data/sfx/playerspawn.mp3"));
        S_PAUSE = Gdx.audio.newSound(Gdx.files.internal("data/sfx/pause.mp3"));
    }

    public void unload()
    {
        S_BGDIE.dispose();
        S_BGHIT.dispose();
        S_BGLASER.dispose();
        S_BGSPAWN.dispose();
        S_PDIE.dispose();
        S_PHIT.dispose();
        S_PLASER.dispose();
        S_PSPAWN.dispose();
        S_PAUSE.dispose();
    }

    public void play(int id)
    {
        switch(id)
        {
        case BGDIE:
            S_BGDIE.play();
            break;
        case BGHIT:
            S_BGHIT.play();
            break;
        case BGLASER:
            S_BGLASER.play();
            break;
        case BGSPAWN:
            S_BGSPAWN.play();
            break;
        case PDIE:
            S_PDIE.play();
            break;
        case PHIT:
            S_PHIT.play();
            break;
        case PLASER:
            S_PLASER.play();
            break;
        case PSPAWN:
            S_PSPAWN.play();
            break;
        case PAUSE:
            S_PAUSE.play();
            break;
        default:
            System.out.println("invalid sfx call");
            break;
        }
    }
}
根据游戏中发生的情况,游戏每秒大约被调用4-10次,声音效果持续时间不到一秒,平均每次8kb。

这里发生了什么,我该如何解决这个问题?它使游戏看起来非常不专业,并且几乎无法播放。

2 个答案:

答案 0 :(得分:5)

关于在播放多个声音时你注意到性能大幅下降的问题的一个小背景。这是因为在封面下方,libgdx需要将声音混合在一起,然后再播放给用户。当您同时运行一定数量的声音时,系统对混音的要求会变得非常高。由于您可能在渲染线程上尝试播放声音,因此需求的增加会导致帧速率下降。

根据我对游戏中任何声音效果的体验,当你遇到同时播放大量小声音的情况时,很少有解决方案。我将把它们写成比libGDX的具体更通用的解决方案:

1)在一个帖子上播放所有声音

这是你目前正在做的事情,虽然一旦播放它的大量声音很容易实现,并且在大多数情况下它可以正常工作。但是,一旦你得到足够的声音,你会发现滞后和质量差。

2)在渲染线程的单独线程上播放声音

这是一种可能的方法(并且取决于框架是否允许),它不是很好,因为它不能很好地扩展。但是,如果你只是遭受轻微的性能损失并且不期望同时播放大量(~20 +)的声音,这是一个相对较小的变化,通常可以解决问题。

3)播放声音达到上限

此解决方案需要更多工作,如果您有必须播放的声音,则可能无法接受。您只需跟踪播放的声音数量,并允许播放其他声音,直到您达到某个点。上限之上的任何东西都不会被播放。这使您可以保证一定的性能水平。这种方法的最大缺点是,当你的角色受到重伤并且没有被播放时播放声音,那么这可能会让用户感到不安,因为他们可能会听到声音,知道他们是否会很快死去,但发现自己死了。

4)有选择地播放重要声音

这有点难以实现,但它的效果非常好,因为您实际上是在设置性能上限。你想要做的是确定播放声音的优先级。它离你很近吗?它响亮吗?那很重要么?然后,你只播放重要到足以播放某个上限的声音(可能是4,6,8等)。您还需要跟踪当前播放的声音数量,以确定您可以在给定点播放的新声音数量。

答案 1 :(得分:0)

解决方法:对播放器播放不太重要的声音,只有当前FPS高于某个值时才能播放它们。例如:

if (Gdx.graphics.getFramesPerSecond() > 56) playSound();

无论FPS值如何,都应该播放重要的声音。