Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/android/232.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
LibGDX/Android:播放音效会让游戏变得口吃-声音。play()在高端设备上需要4毫秒_Android_Performance_Audio_Libgdx - Fatal编程技术网

LibGDX/Android:播放音效会让游戏变得口吃-声音。play()在高端设备上需要4毫秒

LibGDX/Android:播放音效会让游戏变得口吃-声音。play()在高端设备上需要4毫秒,android,performance,audio,libgdx,Android,Performance,Audio,Libgdx,每当我在Android设备上玩LibGDX游戏时,游戏就会结巴。我已经在三台三星设备上试用过该游戏: 在Galaxy S7 Edge(2016,安卓8)和Galaxy Tab S 10.5(2014,安卓6.0.1)上,游戏仍然可以玩,但在播放多个音效时运行不平稳(循环播放音效不是问题) 但是,在Galaxy S20 Ultra(2020,Android 10)上,游戏无法播放:每次调用Sound.play()需要2…4毫秒,并导致“音频输出\u FLAG\u被服务器快速拒绝;帧数0->542

每当我在Android设备上玩LibGDX游戏时,游戏就会结巴。我已经在三台三星设备上试用过该游戏:

  • 在Galaxy S7 Edge(2016,安卓8)和Galaxy Tab S 10.5(2014,安卓6.0.1)上,游戏仍然可以玩,但在播放多个音效时运行不平稳(循环播放音效不是问题)
  • 但是,在Galaxy S20 Ultra(2020,Android 10)上,游戏无法播放:每次调用Sound.play()需要2…4毫秒,并导致“音频输出\u FLAG\u被服务器快速拒绝;帧数0->54276”错误。此错误不会出现在其他设备上,但会出现Sound.play()仍然需要1…2毫秒,这当然是16毫秒帧中相当大的一部分
因此,我认为非常清楚的是,问题出在Sound.play()方法中,而不是例如并发播放声音的数量(我限制为8个,但也尝试了4个),或者Android设备处理声音的速度太慢(在这种情况下,6岁的GT不应超过今年的高端S20),或者音效文件太大(我用于测试的文件最初是3.8 kB WAV)。是的,我正在使用AssetManager提前加载声音

我现在花了两天时间做研究,在不同论坛上找到了大约15-20个关于我认为是相同或相关问题的主题,并尝试了所有建议的修复方法,但没有成功:

  • 将音频格式从WAV更改为OGG
  • 不同的采样率:两种格式的采样率分别为44.1k、48k、96k(使用96k时,不会出现口吃和错误,但也不会发出声音)
  • 使用上述格式和采样率的所有组合,在音效结束时添加1或2秒的静音(其本身长度为41毫秒)
  • 有人说在“背景”中循环播放一段无声的声音片段已经解决了这个问题,但无论如何,我在游戏中不断播放另一段声音(汽车引擎),这似乎没有任何效果
我也看到过使用音乐类而不是声音的建议,但它不适合使用Box2D的碰撞声音效果,因为音高无法调整

我发现但还没有尝试过的唯一解决方法是在不同的线程上播放声音。我没有尝试过,因为我不熟悉多线程,也没有找到足够全面的指南来指导如何(正确地)执行多线程在LibGDX中。我还假设这种方法对于任何声音都是有问题的,这些声音可能必须在某个参与者从主线程播放的过程中暂停、停止或调整。此外,根据“您不应该对任何与图形或音频相关的东西执行多线程操作”


因此,在我开始熟悉这个主题(多线程)之前,我只想再问一次:真的没有其他解决方案吗?今年的高端安卓设备无法以4毫秒的速度播放一个小的WAV声音,这让人感觉不太对劲。Play store中有很多游戏都具有良好的音效和流畅的游戏体验,它们真的都在使用多线程吗?

I我没有一个完整的答案,但我会在这里分享一些想法

我自己的轶事经验是,对于Android上的典型渲染线程来说,启动声音播放等声音操作往往过于耗时。我尝试了几种不同的方法(
AudioTrack
SoundPool
,等等),我记得在每种情况下都得到了类似的结果

将音频放在不同的线程上似乎是最实际的解决方案。如果您不熟悉多线程,我理解您的犹豫,我认为您应该谨慎,尤其是在使用第三方库时。但是,对于简单的任务,Android提供了一些相当简单的工具,如
HandlerThread
处理程序
,这可能是可以利用的

至于LibGDX文档中说不要对任何与音频相关的线程执行多线程操作,我不清楚这是否意味着不要在渲染线程以外的线程上执行任何与音频相关的操作,或者只是意味着将所有音频保留在单个线程上,但该线程不一定是渲染线程后者,然后将音频放在单独的线程上可能是一种选择

我快速浏览了一下LibGDX源代码。我必须花更多的时间来更好地理解正在发生的事情,但是我看到了
AudioTrack
SoundPool
的使用,我很确定我在这两个方面都遇到了这个问题

但是,我也看到了一些异步声音功能的迹象。有一些名称中带有“asynchronous”的类使用了专用的处理程序线程。我不知道这个功能是否有文档记录(我无法立即找到文档)或者以其他方式得到支持,但它似乎确实存在于源代码中。评论说有一些限制,但我还不清楚它们是什么

至于渲染线程和音频线程之间的通信,这会增加一些复杂性,但您应该能够使用处理程序或其他类似工具相当直接地进行通信。事实上,我所看到的LibGDX代码就是这样做的——它创建了一个
HandlerThread
,并使用
处理程序
(自然)发布。这仍然很困难,尤其是在使用第三方库时,您无法控制所有音频操作的发生位置。例如,LibGDX可能总是在特定线程(例如渲染线程)上设置音频对象,这意味着如果您使用另一个线程,那么您将在一个线程上使用对象,而不是在该线程上创建对象