Unity FMOD 音效失真变形

时间:2024-05-22 07:11:34

【1】SampleRate差异导致的失真

环境:Unity 2017.4.14f1 (64-bit), FMOD Studio 1.10.02
原因:SampleRate初始化设置与实际音效存在差异导致音效失真
解决方法:配置合适的Default Settings的SampleRate以及代码默认值,比如44100
注:SampleRate Platform Default:Editor:48000, Mobile:24000
注意FMOD Setting配置,以及代码默认值,如下
Unity FMOD 音效失真变形

		// 默认值(48000)可依据实际修改
		// --------   Sample Rate ----------------------
        public int GetSampleRate(FMODPlatform platform)
        {
            return GetSetting(SampleRateSettings, platform, 48000);
        }

【2】OpenSL的支持导致的音效抖动和延迟问题

问题转自 Unity FMOD音效抖动和延迟问题解决方案 , 记录下,并未遇到及验证

问题描述

声音延迟问题可以分为两种:一种是抖动问题,例如一个音效本来是如下的序列: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左右。上面的方案目前位置没有发现其他问题。暂时把不好的解决方案也贴在下面。

之前 问题解决方案

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