声音使应用程序在Android上滞后 - 任何解决方案?



所以我的游戏在PC上运行流畅(win 10(,但在Android手机上滞后(Mi 9T pro,SD 855,6GB ram(。我并不是说只有声音滞后,还有图形。当我禁用声音时,它运行得非常流畅(应该如此(。

是的,我知道这个问题被问了很多次和回答。我尝试了所有提供的"解决方案",但没有任何帮助。尝试使用22KHz样本,44.1Khz,48Khz。尝试在每个样本结束时添加 1 秒的静音。没帮助。

我正在使用此方法加载示例:

private void loadSounds(String path)
{
FileHandle dirHandle;
dirHandle = Gdx.files.internal(path);
for (FileHandle entry: dirHandle.list()) {
Sound sound = new Sound(entry.nameWithoutExtension(), path+"/"+entry.name());
sounds.add(sound);
}
}

其中声音类如下所示:

public class Sound {
public String name;
private com.badlogic.gdx.audio.Sound soundObject;
public Sound(String name, String filePath) {
this.name = name;
soundObject = Gdx.audio.newSound(Gdx.files.internal(filePath));
}
public void play()
{
soundObject.play();
}

public void play (float pitch)
{
soundObject.play(1,pitch,0);
}

public void stop()
{
soundObject.stop();
}
public void dispose()
{
soundObject.dispose();
}
}

只是一种普通的方式,没什么特别的。因此,我在应用程序启动时预加载所有声音样本,并在游戏过程中播放它们。玩是导致滞后的原因,要清楚。 任何关于如何摆脱Android滞后的建议都是值得赞赏的。

不确定延迟,但您不应该同时播放很多声音,因为大多数设备只能输出一个视图通道。我通常做的是有一个声音管理器,当一个声音已经在播放时,我会停止该声音并在一帧中播放新声音。我个人没有注意到突然停止的声音,我相信很多游戏都是这样做的。

因此,只需有一个类似 SoundManager 类的东西,其中包含所有声音的数组、列表、集或映射,以及当您想要播放所有声音循环时,如果它们当前正在播放,请停止它们。

playSound(String soundName){
for (Sound sound : soundMap) {
sound.stop();
}
soundMap.get(soundName).play();
}

您可以将其扩展到具有多个声音列表,如果您出于任何原因确实需要同时播放一些声音。您还可以保留正在播放的声音列表或单个声音对象,以直接访问和停止声音。但是,只要映射了几十个声音,您应该不会有任何性能问题。

使用更严格的声音管理器类解决了这个问题。

首先,在加载声音样本时,我正在计算每个声音样本持续多长时间(大约(。原因是 LibGDX Sound 类不提供该功能。由于我的所有样本都是相同的格式,计算就足够了:

final long WAV_HEADER_SIZE = 2415;
final long WAV_BPS = 41137;
FileHandle file = Gdx.files.internal(filePath);
duration = (long)(1000f * (file.length() - WAV_HEADER_SIZE) / WAV_BPS);

所以我以毫秒为单位获得这种采样持续时间。样本为22Khz,352Kbps。

然后,当我播放一些声音时,我会记得播放开始的时间,因此在任何时候都可以使用此持续时间变量计算出声音是否仍在播放。

有了这个,我可以检查我同时播放了多少声音。我当时达到的最大数字是 8。这种情况很少发生,也不会持续很长时间。常见的样本数是 0 到 4 或 5。

然后,我为每个播放调用添加了"优先级"字段(值 1 - 10(,在播放声音之前,我正在计算当前播放样本的数量,以及哪个声音具有最低优先级。

final int MAX_PRIORITY = 10;
final int MAX_NUMBER_OF_SOUNDS_PLAYED_SIMULTANEITY = 2;
if (muted > 0 || soundName.isEmpty()) return;
Array<Sound> matchedSounds = new Array<Sound>(10);
int playingCount = 0;
int lowestPriority = MAX_PRIORITY + 1;
int lowestPriorityIndex = -1;
for (int i = 0; i<sounds.size; i++){
Sound sound = sounds.get(i);
if (sound.isPlaying()){
if (sound.priority < lowestPriority){
lowestPriority = sound.priority;
lowestPriorityIndex = i;
}
playingCount++;
}
if (sound.name.startsWith(soundName)) {
matchedSounds.add(sounds.get(i));
}
}
if (playingCount > MAX_NUMBER_OF_SOUNDS_PLAYED_SIMULTANEITY){
if (priority <= lowestPriority){
return;
}else{
sounds.get(lowestPriorityIndex).stop();
}
}

所以我首先检查允许的声音数量是否大于当前播放的声音数量。如果不是,我会定期播放新声音。

如果是,并且新声音的优先级低于当前播放的所有声音,我只是忽略了新声音。

如果是并且新声音不是优先级最低的,我会停止最低的声音并播放新声音。

这样,我将当前播放的声音数量保持在固定数量。

最令人惊讶的是,当时没有滞后的最大样本数为 2 ?!?! 播放 3 个或更多声音时,系统会滞后什么样的声音?!?这里真的有些不对劲。

无论如何,即使当时最多有 2 个样本,声音听起来也不错......缺失的声音并不明显。

相关内容

最新更新