Unity中FMOD音效抖动和延迟问题解决方案

发表于2015-11-24
评论3 1.62w浏览

我们的项目之前使用FMOD移植到Android平台上时,有非常严重的延迟问题,之后通过更新新插件版本以及针对个别手机进行特殊设置解决了音效的延迟问题。下面来讲述声音延迟问题的来源和相应设置。

问题描述

声音延迟问题可以分为两种:一种是抖动问题,例如一个音效本来是如下的序列:1234567,抖动的效果就是1-2-3-4-5-6-7,其中'-'表示声音的停顿,就像游戏界面的卡帧现象一箱。另一种现象就是延迟现象,还是上面你的例子,延迟后的效果就是--1234567,表现就是点击一个按钮播放声音时要等一会音效才会出来。

问题出现的原因

这个可以参考 http://km.oa.com/articles/show/192778?kmref=search 的介绍,因为android系统默认使用OpenSL进行音频输出,而各个厂商对OpenSL的支持不是完美的,因此默写机型会出现这些问题。

在我们项目的开发过程中,遇到有问题的机型包括:魅族MX3, samsung GT-S7898, 

samsung GT-S7562i, 华为G7, 荣耀4X 和 红米2A。

问题解决方案和代码设置

问题的解决方案和上面的帖子介绍的方法类似,但是在Unity中有点特殊。还是要在FMOD初始化之前设置好FMOD的输出方式。
问题是Unity本身自带的音频系统也是使用FMOD的,该FMOD模块使用了FMOD_OUTPUTTYPE_AUDIOTRACK这种输出方式,因此当我们将我们使用的FMOD设置成这种输出方式后,所有的音效都会听不见。
因此我们使用的输出方式是sys.setOutput(FMOD.OUTPUTTYPE.AUTODETECT,添加的部分代码如下:

#if UNITY_ANDROID && !UNITY_EDITOR 
  FMOD.System sys = null
  ERRCHECK(system.getLowLevelSystem(out sys)); 
if (null != sys) { 
if (FMOD.RESULT.OK != sys.setOutput(FMOD.OUTPUTTYPE.AUDIOTRACK)) 
 
  sys.setOutput(FMOD.OUTPUTTYPE.AUTODETECT); 
  }
 
 } 
#endif

 注意这点代码需要在FMOD.Studio.System.initialize函数之前执行,否则不生效。

PS: 下面的方案是之前的方案,该方案针对出问题的机型设置DSP Buffer的大小,可以解决卡顿的问题,但是会带来延迟的问题,延迟会在0.5s左右。上面的方案目前位置没有发现其他问题。暂时把不好的解决方案也贴在下面。

之前 问题解决方案

FMOD中的音效都要经过DSP(Digital Signal Process,数字信号处理),音频文件需要读取并解压到内存中,然后添加一些特效如过滤等来进行播放的。FMOD DSP BUFFER就是用来进行解压和处理的这部分内存,主要的压力来自于解压这块。如果这个缓存过小让解压的速度跟不上播放速度,就会导致抖动问题;而如果这个缓存过大就会让一次解压的内容过大,从而导致延迟现象。FMOD中默认的DSP BUFFER SIZE是512字节。
在iOS中,音频解码都是使用硬件来进行的,因此缓存一般都够用;但是Android设备厂商千奇百怪,硬件和软件都有被剪裁的可能,导致一些设备播放出现问题。因此视乎各种设备出现的问题可以进行分别的设置来保证游戏所需要打到的效果。

之前 具体设置代码

DSP BUFFER SIZE的设置需要在FMOD.Studio.System::initialize函数之前执行,我的习惯是在FMOD_StudioSystem.cs中FMOD_StudioSystem::Init函数中进行设置,设置代码如下:

#if UNITY_ANDROID
FMOD.System lowLevelSystem;
result = system.getLowLevelSystem(out lowLevelSystem);
if (result != FMOD.RESULT.OK)
  FMOD.Studio.UnityUtil.LogError("Unable to get lowlevel system");
}
if (lowLevelSystem != null)
  FMOD.OUTPUTTYPE outputType; 
  lowLevelSystem.getOutput(out outputType); 
  result = lowLevelSystem.setDSPBufferSize(2048, 4); 
  if (result != FMOD.RESULT.OK) 
 
  Debug.LogError("ERROR: Set DSP Buffer size error:" + result); 
 
 }
#endif

如社区发表内容存在侵权行为,您可以点击这里查看侵权投诉指引

标签: