android gdx声音性能问题

android gdx声音性能问题,android,performance,audio,libgdx,Android,Performance,Audio,Libgdx,我正在用libgdx构建一个滚动射击程序。在windows中,一切运行正常,但在android上,我得到了明显的抖动,帧速率从没有声音的平均61 fps下降到有声音的平均48-56 fps。它同时播放许多小音效,因为有很多子弹要发射,敌人要同时击中。我的声音程序: import com.badlogic.gdx.Gdx; import com.badlogic.gdx.audio.Sound; public class SoundFX { static final int BGDIE

我正在用libgdx构建一个滚动射击程序。在windows中,一切运行正常,但在android上,我得到了明显的抖动,帧速率从没有声音的平均61 fps下降到有声音的平均48-56 fps。它同时播放许多小音效,因为有很多子弹要发射,敌人要同时击中。我的声音程序:

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


这里发生了什么,我该怎么解决?它使游戏看起来非常不专业,而且在硬级别上几乎无法玩。

了解一下为什么在播放多个声音时会出现如此大的性能下降。这是因为在封面下,libgdx需要将声音混合在一起,然后再向用户播放。当您同时运行一定数量的声音时,对系统进行混音的要求会明显提高。由于您可能在渲染线程上尝试播放声音,因此需求的增加会导致帧速率下降

根据我在游戏中使用任何音效的经验,当你遇到一个同时播放大量小声音的情况时,几乎没有解决方案。我将把这些作为libGDX更一般的解决方案,而不是具体的解决方案:

1) 在单个线程上播放所有声音

这就是您目前正在做的,但一旦播放大量声音,它就无法正常工作。它很容易实现,并且在大多数情况下都能正常工作。然而,一旦你们在一起播放足够多的声音,你们就会注意到延迟和质量差

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

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

3) 播放高达上限的声音

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

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


这有点难以实现,但它工作得非常好,因为您基本上是在设置性能上限。您要做的是确定要播放的声音的优先级。离你很近吗?声音大吗?重要吗?然后,您只播放重要到可以播放到某个上限的声音(可以是4、6、8等)。您还需要跟踪当前播放的声音数量,以确定在给定时间点可以播放多少新声音。

了解一下为什么在播放多个声音时会出现性能大幅下降的问题。这是因为在封面下,libgdx需要将声音混合在一起,然后再向用户播放。当您同时运行一定数量的声音时,对系统进行混音的要求会明显提高。由于您可能在渲染线程上尝试播放声音,因此需求的增加会导致帧速率下降

根据我在游戏中使用任何音效的经验,当你遇到一个同时播放大量小声音的情况时,几乎没有解决方案。我将把这些作为libGDX更一般的解决方案,而不是具体的解决方案:

1) 在单个线程上播放所有声音

这就是您目前正在做的,但一旦播放大量声音,它就无法正常工作。它很容易实现,并且在大多数情况下都能正常工作。然而,一旦你们在一起播放足够多的声音,你们就会注意到延迟和质量差

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

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

3) 播放高达上限的声音

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

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

这有点难以实现,但它工作得非常好,因为您基本上是在设置性能上限。您要做的是确定要播放的声音的优先级。离你很近吗?声音大吗?重要吗?然后,您只播放重要到可以播放到某个上限的声音(可以是4、6、8等)。你还需要了解马英九是如何做到的
if (Gdx.graphics.getFramesPerSecond() > 56) playSound();