音频对讲调试指导

Version 2.0


1. MI AudIo 内部流程介绍

1.1. MI Audio 内部框图介绍

下图为MI Audio的基本数据流向:

(以下描述为不包含声源定位、声音检测、beamforming、重采样、编解码等算法的基本情况)

1.2. AI数据流向分析

上图中绿色箭头方向为AI数据的流向,数据由麦克风采集,经过芯片内部的增益,到达MI层(A点),此处(A点)的数据为原始的PCM数,接着和AO端的数据(B点)一起送入AEC算法进行处理,AEC算法处理后的数据(C点)会继续送到后面的APC算法(APC为ANR、EQ、AGC算法的集合)进行处理,处理后的数据即为最终的数据(D点)。

SW loop back与HW loop back的区别:

SW loop back和HW loop back的主要区别在于送回AEC算法的AO数据差异。SW loop back用于处理AEC算法的AO数据是只经过了芯片内部增益的数据,好处在于不需要外部电路进行特定分压设计,且只需占用一个音频输入通道,与HW loop back相比,对于外部电路的功放芯片引起的失真,SW loop back 没法较好地进行处理。而HW loop back用于处理AEC算法的AO数据为外部电路功放芯片处理后的数据,可以较好地应对上述情况,但需要对外部电路进行特定的分压设计,多占用一个音频输入通道,以及需要确保loop back回来的峰值不能超过芯片内部量程(3.3V)。HW loop back必须要有两个音频输入通道才能使用。

(HW loop back 只有两通道的Amic才能使用)

1.3. AO数据流向分析

上图中黄色箭头方向为AO数据的流向,待播放PCM数据(E点)由应用通过MI接口送入后,经过APC算法(ANR、EQ、AGC处理后(F点),经过芯片内部的增益、外部电路的功放芯片,再由喇叭输出。

1.4. 确认原始数据和算法处理正常

上图中所有蓝色点的数据都可以通过SDK提供的debug手段dump出来(因为此功能仅仅是为了debug用,若有出现文件名有误,SDK暂时不做修正)。SDK提供的dump手段,需要在应用起来之前,通过export一系列的环境变量来指定文件的保存路径以及需要dump的数据位置。

指定文件保存的路径:

export MI_AI_DUMP_PATH=xxx,指定AI的dump路径为xxx

export MI_AO_DUMP_PATH=xxx,指定AO的dump路径为xxx

指定dump的数据位置:

AI:

export MI_AI_DUMP_PCM_ENABLE=1,指定dump AI的原始pcm(即A点处的数据),文件名为MI_AI_Dev*Chn*_*K_Src.pcm。

export MI_AI_DUMP_AEC_ENABLE=1,指定dump AI AEC前后的数据(即A、B、C点处的数据),文件名为MI_AI_Dev*Chn*_*K_AiIn.pcm、MI_AI_Dev*Chn*_*K_AoIn.pcm和MI_AI_Dev*Chn*_*K_AecOut.pcm。(当AEC开启时,MI_AI_Dev*Chn*_*K_AiIn.pcm和MI_AI_Dev*Chn*_*K_Src.pcm的内容是一致的。)

export MI_AI_DUMP_VQE_ENABLE=1,指定dump AI APC前后的数据(C、D点处的数据),文件名为MI_AI_Dev*Chn*_*K_VqeIn.pcm和MI_AI_Dev*Chn*_*K_VqeOut.pcm(当AEC开启时,MI_AI_Dev*Chn*_*K_VqeIn.pcm和MI_AI_Dev*Chn*_*K_AecOut.pcm的内容是一致的。当没有开启AEC时,MI_AI_Dev*Chn*_*K_Src.pcm和MI_AI_Dev*Chn*_*K_VqeIn.pcm的内容是一致的。)

AO:

export MI_AO_DUMP_PCM_ENABLE=1,指定dump 最终送给驱动的数据(即F点处的数据),文件名为MI_AO_Dev*_*K_Dst.pcm。

export MI_AO_DUMP_VQE_ENABLE=1,指定dump AO APC前后的数据(即E、F点处的数据),文件名为MI_AO_Dev*_*K_VqeIn.pcm和MI_AO_Dev*_*K_VqeOut.pcm。(当AO端只有APC算法开启时,MI_AO_Dev*_*K_VqeOut.pcm和MI_AO_Dev*_*K_Dst.pcm的内容一致。)

(*为应用具体使用的device id、channel id、采样率)

建议值要dump自己想要的节点处的音档,不要所有都同时dump,不然可能会引起一直在写文件导致SDK丢帧。


2. MI AudIo 相关算法介绍

2.1. AEC(Acoustic Echo Cancellation)

2.1.1. AEC算法的简单介绍

AEC即回声消除,通过算法来消除由扬声器设备发出的直接或间接耦合回麦克风的声音。

2.1.2. AEC算法的参数说明

下面为MI API开给应用设定AEC参数的数据结构:

typedef struct MI_AI_AecConfig_s

{

    MI_BOOL bComfortNoiseEnable;

    MI_S16 s16DelaySample;

    MI_U32 u32AecSupfreq[6];

    MI_U32 u32AecSupIntensity[7];

    MI_S32 s32Reserved;

} MI_AI_AecConfig_t;
参数 作用 限制/注意事项/详细说明
bComfortNoiseEnable AEC加入背景噪声使能 默认情况设置FALSE。 说明:当使能该参数时,AEC算法的处理结果会加入一些背景噪声,使处理后声音不会过于空洞。此项主要是为了解决AEC消得太干净,导致ANR收敛需要太长时间。 注意:若非上述情况,此项不建议打开。
s16DelaySample 左右声道间的回声延迟样本 默认情况设置0。 说明:由于麦克风和喇叭的放置位置、麦克风间的距离等会造成左右声道接收到回声的时间点不一致,两个声道之间回声延迟有差异。此值表示左声道比右声道提早多少个采样点收到回声。 注意:此参数只适用于双声道做AEC的情况,且不建议使用
u32AecSupfreq AEC处理的频段 推荐参数:{4, 6, 36, 49, 50, 51} 说明:该数组将当前采样率的最高频率分成8个频段来处理。以下数组元素和频率范围的转换公式:

假设当前采样率16K,以上述推荐参数为例,当前采样率为16K,最大的采样频率为8K,第一个频段F1 = (0~4) * 8000 / 128 = 0~250Hz,第二个频段F2 = (4~6) * 8000 / 128 = 250~375Hz,第三个频段F3 = (6~36) * 8000 / 128 = 375~2250Hz,第四个频段F4 = (36~49) * 8000 / 128 = 2250~3062Hz,第五个频段F5 = (49~50) * 8000 / 128 = 3062~3125Hz,第六个频段F6 = (50~51) * 8000 / 128 = 3125~3187Hz,第七个频段F7 = (51~128) * 8000 / 128 = 3187~8000Hz。注意:数组要求每一个元素都必须比前一个元素大。参数范围是[1,127]。
u32AecSupIntensity AEC处理的强度 推荐参数:{5, 4, 4, 5, 10, 10, 10} 说明:此数组代表频段的回声消除强度,各元素和u32AecSupfreq划分出来的频率范围一一对应。 注意:参数的范围是[0,15],强度越大,消除的细节越多,声音越不自然。反之,强度越小,细节保留越多,但会回声消除不够干净。(若用户对消除效果不满意,只能让用户来权衡,再做微调)

2.2. ANR(Acoustic Noise Reduction)

2.2.1. ANR算法的简单介绍

ANR即声音降噪,通过算法来消除环境中持续存在的噪声(比如白噪声,粉红噪声等),没法很好地处理突然出现的噪声。

2.2.2. ANR算法的参数说明

下面为MI API开给应用设定ANR参数的数据结构:

typedef struct MI_AUDIO_AnrConfig_s

{

    MI_AUDIO_AlgorithmMode_e eMode;

    MI_U32 u32NrIntensity;

    MI_U32 u32NrSmoothLevel;

    MI_AUDIO_NrSpeed_e eNrSpeed;

}MI_AUDIO_AnrConfig_t;
参数 作用 限制/注意事项/详细说明
eMode ANR算法的模式 说明:此参数表示ANR算法的模式,不同的模式对应不同的应用场景。 E_MI_AUDIO_ALGORITHM_MODE_DEFAULT:此模式为语音模式,会使用算法中为语音数据调教的默认降噪参数。 E_MI_AUDIO_ALGORITHM_MODE_USER:此模式全部使用应用下的降噪参数。(目前的lib user mode处理上有点问题,暂不建议使用) E_MI_AUDIO_ALGORITHM_MODE_MUSIC:此模式为音乐模式,会使用算法中为音乐数据调教的降噪参数。(推荐使用此模式)
u32NrIntensity ANR算法的强度 推荐值:20 说明:该参数表示ANR算法的降噪强度,该值越大,降噪效果越好,但细节损失越多。反之,降噪强度越小,细节保留越多,但噪声也没法去除干净。(此值也需要权衡和微调。) 注意:参数范围为[0,30]。
u32NrSmoothLevel ANR算法的平滑程度 推荐值:10 说明:该参数表示ANR算法处理的平滑程度,值越大降噪效果越平滑。平滑程度越小在频域上损失的细节越多。 注意:参数范围为[0,10]。
eNrSpeed ANR算法的收敛速度 推荐值:E_MI_AUDIO_NR_SPEED_MID 说明:此值表示ANR算法的收敛速度,收敛速度越快损失的细节越多。反之,收敛速度越慢,参考的时间越长,细节保留越多,但也会延长降噪起作用的时间。

2.3. EQ(Equalizer)

2.3.1. EQ算法的简单介绍

EQ即均衡器,该算法用于提高或降低某些频段的能量。

2.3.2. EQ算法的参数说明

下面为MI API开给应用设定EQ参数的数据结构:

typedef struct MI_AUDIO_EqConfig_s

{

    MI_AUDIO_AlgorithmMode_e eMode;

    MI_S16 s16EqGainDb[129];

}MI_AUDIO_EqConfig_t;
参数 作用 限制/注意事项/详细说明
eMode EQ算法的模式 说明:该值表示EQ算法的模式 E_MI_AUDIO_ALGORITHM_MODE_DEFAULT:默认模式,完全不吃应用下的参数。 E_MI_AUDIO_ALGORITHM_MODE_USER:此模式全部使用应用下的降噪参数。(当用户需要自己调教时使用此模式)
s16EqGainDb EQ算法的均衡器数组 说明:该数组表示各个频段的增益设置。该参数把当前采样率对应的最大采样频率分成129份,可单独对某个频段进行能量的调节。假设当前的采样率为16K,则最大的采样频率为8K,每一份对应的频段大小为F = 8000 / 129 ≈ 62Hz。此数组元素对应的频段为062Hz,62124Hz,124192Hz,……,79388000Hz。
注意:该参数的为范围是[-50,20]dB。
当需要调整的增益变化很大时,往往没法在一个频段内完成增益的变化,此时需要将附近相邻的频段也设置为同样的参数,来达到调整该频段的目的。

2.4. AGC(Automatic Gain Control)

2.4.1. AGC算法的简单介绍

AGC即自动增益控制,此算法可以对输入的数据进行增益控制,当信号过小时,会对信号进行增益,当信号过大时,会对信号进行衰减。

2.4.2. AGC算法的参数说明

下面为MI API开给应用设定AGC参数的数据结构:

typedef struct AgcGainInfo_s{

MI_S32 s32GainMax;

MI_S32 s32GainMin;

MI_S32 s32GainInit;

}AgcGainInfo_t;

typedef struct MI_AUDIO_AgcConfig_s

{

    MI_AUDIO_AlgorithmMode_e eMode;

    AgcGainInfo_t stAgcGainInfo;

    MI_U32 u32DropGainMax;

    MI_U32 u32AttackTime;

    MI_U32 u32ReleaseTime;

    MI_S16 s16Compression_ratio_input[5];

    MI_S16 s16Compression_ratio_output[5];

    MI_S32 s32TargetLevelDb;

    MI_S32 s32NoiseGateDb;

    MI_U32 u32NoiseGateAttenuationDb;

}MI_AUDIO_AgcConfig_t;
参数 作用 限制/注意事项/详细说明
eMode AGC算法的模式 说明:此参数表示AGC算法的模式,不同的模式对应不同的应用场景。 E_MI_AUDIO_ALGORITHM_MODE_DEFAULT:此模式为语音模式,会使用算法中为语音数据调教的AGC参数。 E_MI_AUDIO_ALGORITHM_MODE_USER:此模式全部使用应用下的AGC参数。(当用户需要自己调教时使用此模式) E_MI_AUDIO_ALGORITHM_MODE_MUSIC:此模式为音乐模式,会使用算法中为音乐数据调教的AGC参数。
s32GainMax AGC算法调节增益的最大值(dB) 说明:此值为AGC算法增益可调节的最大值。
注意:该参数的范围为[0,60]dB。(只有比较新的lib(2019.07后)能调整到60dB,较旧的只能调整到30dB)
s32GainMin AGC算法调节增益的最小值(dB) 说明:此值为AGC算法增益可调节的最小值。
注意:该参数的范围为[-20,30]dB。
s32GainInit AGC算法调节增益的初始值(dB) 说明:此值为AGC算法增益的初始值。
注意:该参数的范围为[-20,60]dB。(只有比较新的lib(2019.07后)能调整到60dB,较旧的只能调整到30dB)
u32DropGainMax AGC算法增益下降的最大值(dB) 推荐值:12dB
说明:此值为AGC算法增益调节超过目标值(s32TargetLevelDb)时,可下降的最大值,防止输出饱和。(当出现此情况时,AGC算法会在0dB~u32DropGainMax dB的范围内衰减,并不是只要一超过就会衰减u32DropGainMax dB) 注意:该参数的范围为[0,60]dB。该值不宜设置太小,否则当输入信号远高于目标值时,增益没法快速的降下来,导致出现削顶。同时,该值也不宜设置过大,在输入信号远高于目标值s32TargetLevelDb时,信号的增益会瞬间下降太大,导致帧与帧之间没法接起来,可能导致出现明显的噗噗声。 (比较新的lib(2019.07后)当输入信号大于目标值s32TargetLevelDb时会瞬间降下来,较旧的则会慢慢的往下降)
u32AttackTime AGC算法增益下降的时间 推荐值:1
说明:此值为AGC算法增益下降的时间(多少个时间单位下降0.5dB),一个时间单位为16ms。此值越小,增益下降越快。此值尽量设小,否则当输入信号高于目标值s32TargetLevelDb,没法快速地降下来。
注意:该值的范围为[1,20]
u32ReleaseTime AGC算法增益上升的时间 推荐值:10
说明:此值为AGC算法增益上升的时间(多少个时间单位上升0.5dB),一个时间单位为16ms。此值越小,增益上升越快。此值尽量避免设置太小,否则当经过长时间的增益积累,突然出现一个较大的输入信号,则会导致声音爆掉。
注意:该值的范围为[1,20]
s16Compression_ratio_input AGC算法的增益设置曲线 说明:由s16Compression_ratio_input和s16Compression_ratio_output组成一条具有4段斜率的增益调节曲线。
注意:两个数组的元素的参数范围为[-80,0]dBFS。建议将compression ratio output的最大值设定为-3dBFS及以下,以防削顶。 (比较新的lib(2019.07后)曲线的优先级大于目标值s32TargetLevelDb,较旧的则反过来)
s16Compression_ratio_output
s32TargetLevelDb AGC算法的增益目标值 说明:AGC算法允许输出的增益最大值,大于此值算法将会对信号进行衰减,以防爆音。
注意:此值的参数范围为[-80,0]dB。 (比较新的lib(2019.07后)曲线的优先级大于目标值s32TargetLevelDb,较旧的则反过来)
s32NoiseGateDb AGC算法处理的噪声门限值 推荐值:-60
说明:AGC算法处理的噪声门限值,但输入信号的增益低于此值时,AGC会认为是噪声,会配合u32NoiseGateAttenuationDb的设置,对噪声进行衰减。若想保留噪声的话,需要将此值设定到-80,且同时将-80dBFS到实测噪声门限值之间的这段曲线的斜率设置为1。建议尽量使用曲线来处理噪声。 注意:此参数范围为[-80,0]dBFS
u32NoiseGateAttenuationDb AGC算法处理的噪声衰减值 推荐值:0
说明:AGC算法处理的噪声衰减的增益,此值会配合s32NoiseGateDb来处理低于门限值的噪声。不推荐使用此值来对噪声进行衰减,防止输出信号听起来像被中断,当使用此值时,会导致说话的开头和结尾被消掉,使声音听起来不够自然。 注意:此参数范围为[0,100]dB

注:以上说的版本并非SDK的版本,而是APC lib的版本。

s16Compression_ratio_input和s16Compression_ratio_output是需要根据用户所需要的增益曲线来设定的,没有默认推荐值。

下面按以s16Compression_ratio_input = {-80,-60,-40,-20,0}; s16Compression_ratio_output = {-80,-60,-30,-15,-10};这组参数进行讲解。如下面的折线图所示,在输入增益为-80~0dB划分为四段斜率,-80dB~-60dB范围内保持原来的增益,斜率为1,-60dB~-40dB范围内需要稍微提高增益,斜率为1.5,-40dB~-20dB范围内斜率为1.25,-20dB~0dB范围内斜率为0.25。即输入增益在-80~-60dB范围内的信号,输出增益为-80~-60dB; 输入增益在-60~-40dB范围内的信号,输出增益为-60~-30dB; 输入增益在-40~-20dB范围内的信号,输出增益为-30~-15dB; 输入增益在-20~0dB范围内的信号,输出增益为-15~-10dB;

根据所需的曲线转折点对s16Compression_ratio_input和s16Compression_ratio_output设置,若不需要那么多段曲线,则将数组不需要的部分填0。

注:(此图仅为了说明曲线的参数及其意义,并无实际参考价值)


3. 如何确认设备的结构好坏

当拿到设备时,如何确认设备结构设计的好坏?主要由以下两点来确认:内部隔离和回声损耗(EchoReturn Loss (ERL))。(若这两项没法达到要求,则说明结构设计不太合理,要么建议可以修改结构,要么只能降低对效果的要求,尽量接近)

注:首先必须先确认使用的是HW loop back还是SW loop back,若是使用HW loopback必须先对chn1做衰减处理(-6,-3,0dB),保证chn0不会因为chn1,而导致失真。以下所有步骤均在不开启任何音频算法的前提下操作。

3.1. 测试音档介绍

TestFile1为一段粉红噪声,用于辅助确认microphone和speaker的增益。

TestFile2为一段对话语音,主要是外国友人的声音,频段比较全,消除难度相对比TestFile4高,用于调整AEC参数。

TestFile3为一段频率逐渐增加的声音,用于扫频,用于检查mic和speaker的频率响应特性。

TestFile4为一段对话语音,主要是国人的声音,用于调整AEC参数。

3.2. 确定speaker和microphone的增益

需要测量内部隔离和回声损耗,首先第一步是根据用户的需求(mic的收音距离和speaker的音量),通过测量定好microphone和speaker的增益。此步骤为后续调音的最为重要的一步,若用户需要更改这两个增益,所有的调音参数都需要重新调整,相当于之前的工作全部白费(为了减少工作量切记切记先跟用户定好增益)。

3.2.1. 确认speaker的增益

  1. 寻找一个比较安静的环境,保证环境噪音低于40dbA。

  2. 用待测设备播放TestFile1,调整speaker的增益,在保证没有爆音的前提下,使之达到用户的需求。

3.2.2. 确认microphone的增益

  1. 寻找一个比较安静的环境,保证环境噪音低于40dbA。

  2. 将分贝仪和待测设备放置在同一位置,在距离待测设备一米处,放置一台播放设备,用播放设备播放TestFile1,并调节播放设备的增益,使分贝仪达到70dbA。

  3. 使用待测试设备进行收音,dump A点处的数据(或demo在不打开任何算法的情况下录制的最终数据),用音频分析软件(这里使用的工具为Adobe audition,下面篇章使用audition进行讲解)查看RMS,调整microphone增益,使RMS达到-25 DBRMS或以上。

  4. 确定speaker和microphone的增益后,待测设备使用speaker得到的增益播放TestFile2,同时使用调整好的microphone增益录制音档,确认microphone录制的音档,没有失真。若有失真请继续调整speaker或microphone的增益(减小speaker的增益或减小microphone的增益)。但有时候会因为结构、speaker、功放等因素,无论你怎么调整录回来的音档都会有某些频段存在失真,此时只能从音档上分析是什么原因造成的,尽量去调整,找到原因,并反馈给用户,要么对此作出修改,要么只能接受较差的音质。

  5. 若结构设计不合理或者microphone选型灵敏度太低没法达到-25DBRMS,则以开启AEC后microphone录回来的回音没有爆音的情况下,将microphone的增益调整到足够大。

如何查看音档是否达到-25DBRMS?

3.3. 内部隔离

内部隔离越大越好,至少需要确保大于6dB。以下为测量内部隔离的步骤:

  1. 寻找一个比较安静的环境,保证环境噪音低于40dbA。

  2. 用待测设备自录自播测试音档TesFile1(dumpA点处的数据,或者使用demo在关闭所有算法的情况下录制的数据),查看平均RMS振幅,记为AVGRMS1。

  3. 用黏土堵住机壳上的microphone孔,待测设备自录自播测试音档TesFile1(dumpA点处的数据,或者使用demo在关闭所有算法的情况下录制的数据),查看平均RMS振幅,记为AVGRMS2。

  4. 内部隔离为AVGRMS1 - AVGRMS2。

3.4. 回音损耗

回音的损耗同样也是越大越好,至少需要确保这个值为一个正值。以下为测量回音损耗的步骤:

  1. 寻找一个比较安静的环境,保证环境噪音低于40dbA。

  2. 用工具查看测试音档TestFile1的平均RMS振幅,记为AVGRMS1。

  3. 用待测设备自录自播测试音档TesFile1(dumpA点处的数据,或者使用demo在关闭所有算法的情况下录制的数据),查看平均RMS振幅,记为AVGRMS2。

  4. ERL = AVGRMS1 - AVGRMS2。

  5. 将microphone和speaker的增益设置为0dB,用测试音档TestFile3代替TestFile1,自播自录,dump下音档(dumpA点处的数据,或者使用demo在关闭所有算法的情况下录制的数据)。

  6. 确认该音档在任何频段都不能有失真。

3.5. 频响特性

如何查看音档或特定区域的频响特性?(若结构设计合理没有引起共振,且microphone和speaker选型没有明显缺陷,此处得到的频响特性曲线应该趋向于一条曲线)

如何初步确定设备的频响特性的好坏?如何分析导致频响特性差的原因?

  1. 寻找一个比较安静的环境,保证环境噪音低于40dbA。

  2. 将mic和speaker的增益都设置为0dB,自播自录扫频音档TestFile3,查看收音的音档。

若发现收音音档的频响特性比较差时,可以按以下步骤来确认问题点:

  1. 先把机壳拆开,确认mic和speaker是否有固定牢固,重复扫频操作,若频响特性变好,则确定为mic和speaker没有固定牢的原因。

  2. 使用高保真音响播放测试音档TestFile3,用标准麦克风和设备的mic同时拾音,对比两者的频响特性,确认是否为microphone的频响特性问题(因mic的集成度较高,一般频响特性没有太大的问题)。

  3. 把speaker拿到机壳外,重复扫频操作,若频响特性变好,则确定为机构问题。

  4. 当把speaker拿到机壳外,使用标准麦克风(或上面测量频响特性没有太大问题的mic),重复扫频动作,若只有小部分频段失真,则可以在确定增益后使用AO端的EQ来对失真的频段进行修复。如下图所示,我们可以对400~1.2K内频段和5K以上的频段稍作调整即可。

  5. 当把speaker拿到机壳外,使用*标准麦克风*(或上面测量频响特性没有太大问题的mic),重复扫频动作,若基本上是全频段失真如下图。首先尝试下降speaker的增益,若发现已经降到很低了,还是会有全频段的失真,这时需要请硬件同事帮忙确认功放电路设计是否存在问题,可以修改电路最好。若没法通过修改电路来改善,则一直降speaker的增益,自录自播扫频音档,找到一个最大且不失真的增益(这一步也可通过用示波器来量功放的输出端波形来确定,此方法更加精确,但需要拆卸设备的外壳以及硬件同事的协助),以此增益来作为最大的输出增益。若在此增益上觉得speaker出来的声音大小不满足需求,可以使用AO端的AGC将输出信号拉高,并限制在-3~-1dB以下,来提高声音的大小。


4. 音效参数调整

当基础的microphone和speaker增益确认后,且频响特性没有太大的问题,就可以进行音效的调整。

4.1. 确定mic和speaker的增益

如果在步骤3.2.2. 确认microphone的增益因为结构设计不合理或者microphone的选型灵敏度太低等原因没法达到-25DBRMS的情况下,请按以下步骤来确定增益,若能达到-25DBRMS,则请沿用前面选定的microphone和speaker增益。

  1. 寻找一个比较安静的环境,保证环境噪音低于40dbA。

  2. 将microphone和speaker的增益都设定为0dB。

  3. 播放测试音档TestFile3,自录自播,查看录制下来的音档(dumpA点处的数据,或者使用demo在关闭所有算法的情况下录制的数据),确认录到的幅值比较小。(此时某些频段有失真不用太过关心,下文有讲解处理的方式)。

  4. 播放测试音档TestFile2,自录自播,将microphone增益在保证不失真的情况下调整到最大(dumpA点处的数据,或者使用demo在关闭所有算法的情况下录制的数据)。

  5. 调整speaker到符合用户要求的增益,在调整speaker增益后,microphone增益也要跟随一起调整,大体遵循加一减一,speaker加1dB,microphone相应要降1dB。

在第(4)步时,可能会因为结构设计不合理,造成mic用很小的增益都会失真,或者说在保证不失真的前提下mic输出的声音振幅很小,请按以下步骤进行尝试调整:

当microphone增益很小就出现了失真,可以根据步骤3.3.内部隔离,确认机构是否合理,建议用户修改机构。若用户不想修改机构,则需要跟用户协商调小speaker的增益,根据新的speaker增益进行步骤4.1.1确定mic和speaker的增益来确定新的microphone增益。或者通过调整speaker端来尝试消除此失真,步骤如下:

  1. 寻找一个比较安静的环境,保证环境噪音低于40dbA。

  2. 将microphone和speaker的增益都设定为当前增益。

  3. 播放测试音档TestFile3,自录自播(dumpA点处的数据,或者使用demo在关闭所有算法的情况下录制的数据)。通过录制的音档查看,寻找到有失真的地方,应用工具的频率分析,找出增益比其他频段要高的频段,通过设置AO的EQ将这些频段做衰减(4.1.2. 调整AO的EQ参数,修正speaker的频响特性,此方法不适用于因谐振产生的失真),重复步骤(1)和(2),若对这些频段调整EQ后还有失真的情况,则只能加大到衰减值继续尝试。

当speaker端使用EQ修正speaker的频率响应,效果仍然没有较大改善时,可以考虑降低microphone的增益,以及打开microphone端的ANR和AGC来对数据进行调整,在AEC处理后的数据中找到消不掉的回声,用ANR和AGC对回声进行衰减。

当进行以上操作得到的microphone数据仍然很小声的时候,只能尝试在拉大microphone增益,让回声爆掉的同时,加大AEC的消回声处理强度。(或建议用户改做单向对讲)(若使用HW loopback,则转为SW loopback)

4.2. 调整AO的EQ参数,修正speaker的频响特性

只有当speaker的频响特性非常差,或者说有部分固定频率的回声消不掉时,才要使用AO的EQ。

如何得到AO EQ的调整table呢?当只有少部分特定频段会失真时,可以直接通过dump到的音档来确认是哪些频段,然后在AO EQ的table上直接填写适当的衰减来修正这些失真。但是当录制的音档频响特性较差时(大部分频段都有失真,有谐振等情况),可以考虑以下方法来调整AO EQ的table。(此调整是基于当前AI/AO的增益)

  1. 在audition中新建一个临时的双声道文件。

  2. 将录进来的数据放置在左声道,播放的原始音档放置在右声道,时间上对齐。

  3. 打开上述音档的频率分析,得到频响特性曲线数据。

  4. 打开Excel,粘贴上面的曲线数据,并删除D栏(平均)。

  5. 统计录进来的音档和播放音档在各个频段相差的增益值,以及相差增益值的平均值。

    此时得到相差增益值的平均值为-37.0908dB

  6. 用各个相差增益值减去平均值。

  7. 排除掉太大的值后,转换为整数,填入到AO EQ的table中。

    如图的F列即为填入AO EQ的数据。

4.3. AEC频段和强度调整

当我们确定好speaker和microphone的增益后,就需要对AEC的频段和强度进行调整。

  1. 将AEC的频段划分和强度设置成以下参数,并进行单向对讲(可用自录自播TestFile2进行模拟)。

    MI_U32 u32AecSupfreq[6] = {20,40,60,80,100,120};
    
    MI_U32 u32AecSupIntensity[7] = {4,4,4,4,4,4,4};
    
  2. dump得到AEC处理后的音档,查看音档是否有消不干净的回声,有则找到回声对应的频段,对上面的频段划分进行调整,将回声的频率范围调整成一个频段,设置到u32AecSupfreq数组中,同时调整u32AecSupIntensity数组,增强对此频段的消回声强度。

注:当有某些固定的频段的回声一直消不掉时,可以使用mic端的EQ对这些频段来做衰减,来消掉这些回声。

4.4. ANR参数调整

当我们录进来的声音因为环境或硬件问题存在持续的噪声时,则可以使用ANR来进行降噪,但是ANR没法处理那些突然出现的噪声。测试ANR最近先不要说话,让ANR收一段音作为参考。

  1. 将ANR的默认参数按以下设置,在Vqe设置中只使能AEC和ANR,抓取APC算法前后的音档。

    eMode = E_MI_AUDIO_ALGORITHM_MODE_MUSIC;
    
    u32NrIntensity = 20;
    
    u32NrSmoothLevel = 10;
    
    eNrSpeed = E_MI_AUDIO_NR_SPEED_MID;
    
  2. 查看APC算法处理后的音档

  3. 若觉得ANR算法收敛的时间过长(即音档中噪声从开始到稳定下来的时间),则增大eNrSpeed。

  4. 若ANR算法收敛后,仍觉得噪声没法接受,则增大u32NrIntensity。

4.5. AGC参数调整

AGC的参数设置完全依赖AEC,ANR,EQ等算法的处理效果来进行调整,使用音频分析工具来看录制下来的音档,根据用户的需求对各个增益范围进行处理。

注:当使用AGC后,当开启AGC后0.5输出信号没有任何变化时,请检查 Gain info、release time、attack time、曲线斜率、noise gate是否设置正确。若开启AGC后,。

  1. 使用一下参数作为AGC起始参数:

    compression_ratio_input[AGC_CR_NUM] = {-80,-60,-40,-20,0};
    
    compression_ratio_output[AGC_CR_NUM] = {-80,-40,-20,-10,-5};
    
    user_mode = 1;
    
    gain_max = 30;
    
    gain_min = 0;
    
    gain_init = 0;
    
    drop_gain_max = 36;
    
    attack_time = 1;
    
    release_time = 3;
    
    noise_gate_db = -80;
    
    noise_gate_attenuation_db = 0;
    
    target_level_db = -5;
    
  2. 将Vqe的AEC,ANR,(EQ,若有使用EQ)使能,dump出APC算法处理后的数据查看,分析出要增强的声音和要抑制的声音分别在哪个dB范围内,根据应用需求调整曲线的斜率,即想要增强的部分,增加曲线的斜率,想要抑制的部分,减小曲线的斜率,来初步调整曲线。

  3. 将Vqe的AEC,ANR,(EQ,若有使用EQ),AGC使能,dump出APC算法处理后的数据查看,是否符合预期。

  4. 若数据存在大量削顶时,可加大drop_gain_max、减小对应曲线的斜率、减小target_level_db、以及增加release_time等方式来缓解。

  5. 若数据的增益没有达到要求,可增加对应曲线的斜率、减小release_time、增大gain_max等方式解决。

  6. 若数据没有任何变化,请检查参数是否设置正确。

参数如何调整可参考6. 基本调试流程,但读者拿到的机子遇到的情况不一定与此相同,该过程仅供参考。


5. 音效调整结构设计建议以及硬件选型

5.1. Speaker和microphone的选型建议

  1. microphone最好选择灵敏度在-35dB以下的,但不建议太小,以免达不到收音距离的要求。

  2. 必须选择带有外壳的speaker。

5.2. 结构设计建议

  1. Microphone和speaker之间的距离最好在4~10cm,距离越远效果越好。

  2. 禁止在结构中使用裸露的speaker,speaker外壳前后之间的紧密连接有助于降低声音从后腔到扬声器前部的传播。

  3. Speaker的外壳必须牢牢地固定在 空腔内,可以避免扬声器产生咔哒咔哒的杂音。

  4. 当将speaker安装到结构内时,可使用高密度泡沫橡胶(防震,隔音)来使speaker更加紧密牢固。

  5. 结构上speaker位置的开孔至少要达到speaker面积的20%以上,且开孔应距离speaker 1~2mm。

  6. 可在microphone后面加上泡沫橡胶,来减少speaker和microphone的直接耦合。更进一步可以将麦克风和泡沫橡胶装到一个独立的外壳内。

  7. Microphone必须对准机壳上的开孔。


6. 基本调试流程

以下记录一次简单的调试过程,好让读者了解大概调整的流程,以下参数仅适用用某款机型,不具有参考意义。

第一步,确定AO的增益。

根据3.2.1. 确认speaker的增益,在设备上使用demo播放TestFile1TestFile2,根据用户的要求选择一个足够大声的增益。(因此机型用户没有给出具体要求speaker要多响,这里自行先选择一个合适的增益)。此处选择0dB作为AO的增益。

第二步,确定AI的增益。

用上述选定的初始增益,跟据3.2.2.确认microphone的增益,将设备放置和分贝仪一同放置在桌上,在距离设备一米处,放置一个可播放音频的设备,使用播放设备播放TestFile1,调整播放设备的音量,使分贝仪能达到70dBA。此时逐步调节microphone的增益,使收进来的声音足够大声,最好收进来的声音能到-25DBRMS。由于手上的机型mic的灵敏度比较低,故mic增益设定到54dB才能勉强达到接近-25DBMS。

第三步,测试结构的内部隔音效果。

用上述选定的初始增益,按照3.3.内部隔离的步骤测量,内部的隔音效果如何。自录自播TestFile1,得到平均RMS振幅,记为AVGRMS1,堵住mic孔,重复上面的操作,记为AVGRMS2,内部隔音= AVGRMS1 - AVGRMS2。下图分别为自录自播TestFile1的平均RMS振幅和堵住mic孔自录自播TestFile1的平均RMS振幅。

由此可见内部的隔音效果满足要求。

第四步,测试结构的回声损耗。

按照*3.4.回音损耗*的步骤测量,回声损耗的效果如何。TestFile1音档本身的平均RMS振幅记为AVGRMS1,自录自播TestFile1,得到平均RMS振幅,记为AVGRMS2。下图分别为AVGRMS1和AVGRMS2。由此可见该机构对回声几乎没有损耗,设计较差。

第五步,调整AI和AO的增益。

微调AI和AO的增益,使自录自播TestFile2,尽量不会出现失真。若有出现失真,这可以通过减小microphone和speaker的增益来调整到不失真(speaker播出来就失真这种情况除外)。

由上图看出部分波形已经削顶了,我们需要对microphone和speaker的增益进行调整。用分贝计在距离一米处进行测试,发现speaker播放TestFile2时,已经达到约75dBA,这个值已经是比较大的了,对speaker增益进行调整,调整到分贝计显示65dBA左右。经过调整后确定microphone和speaker增益为48dB和-9dB。

第六步,对speaker进行扫频,修正speaker的EQ。

首先我们在上面确定的增益基础上,自录自播扫频音档TestFile3。创建一个双声道的文件,将录制的放在左声道,原始扫频音档放置到右声道,将左右声道对齐。

点击频率分析,设置相应的参数得到该音档的频响特性。

得到曲线的信息,复制到Excel中,计算出AO的EQ table。

填入到AO的EQ table中。

开启AO的EQ,同样自录自播TestFile3。发现以下频段的增益太大了,对相应的频段继续做衰减。

第七步,调整AEC参数。

首先我们填入AEC的初始化参数,设置环境变量,先进行single talk测试,自录自播TestFile2,录出AEC的相关音档。由AecOut的音档可以看出消不掉基本只有红色标记的两个频段,蓝色标记处为AEC算法还没收敛,不用管,接着调整AEC的参数,对这两个频段的AEC强度。

调整参数后,录制的AecOut音档如下:

接下来可以进行double talk的测试。由下图可见回声主要集中在2K以上的频段。

继续调整参数,将以上频段加强。后面发现即使我们怎么调AEC的强度此处的回声都没法消掉,即使将AEC的强度开到了最大,仍然没法消掉这个部分的回声。只能将参数调整至microphone收音仍然比较大,且回声较小的情况,后面利用EQ来尝试消掉。

下图是将回声频段的AEC强度调回正常水平,我们可以看出,这些回声的部分几乎没有太大变化。

第七步,调整AI NR参数。

此处基本上我们将默认参数填入即可,当发现因电路和测试环境等因素,发现降噪效果不理想时,再做微调。

eModeE_MI_AUDIO_ALGORITHM_MODE_MUSIC

u32NrIntensity20

u32NrSmoothLevel10

eNrSpeedE_MI_AUDIO_NR_SPEED_MID

第八步,调整AI EQ参数。

除了在某些频段的噪声消不掉,其他情况不建议直接使用AI 的EQ来进行调整增益的处理。

第九步,调整AI AGC参数。

跟AEC一样,我们先填入起始参数再来进行微调。起始参数如下:

compression_ratio_input[AGC_CR_NUM] = {-80,-60,-40,-20,0};

compression_ratio_output[AGC_CR_NUM] = {-80,-40,-20,-10,-5};

user_mode = 1;

gain_max = 30;

gain_min = 0;

gain_init = 0;

drop_gain_max = 36;

attack_time = 1;

release_time = 3;

noise_gate_db = -60;

noise_gate_attenuation_db = 0;

target_level_db = -5;

接着我们来分析AEC处理后的音档

我们选取几段想要调整的范围,查看他们的平均DBRMS。

再更改默认参数曲线中的output参数,调整到想到的dB值。调整如下:

以上突然飙高的地方均为喇叭失真导致的突然出现且没法消除的回声被AGC拉高了,这个除了改喇叭改结构没有其他的办法。

总结:调音的过程都是慢慢调整参数,录制音档,看效果,循环反复,没有什么一步到位的技巧。以上短短的调试过程,也是前前后后录制了80多次音档调试出来的。


7. 常见案例

  1. 功放电路失真

    功放电路失真的案例,主要在于如何来确定问题点在功放电路上,以及确认问题后相应的解决方法。当我们拿到用户的机器,来进行初步的扫频分析时(将mic和speaker的增益设定为0dB,自播自录扫频音档),若此时看到的频响特性非常差,几乎所有频段都有谐振,且能量也比较高。这时就需要怀疑功放电路在当前的状态下已经出现了非常严重的失真,在确定mic频响特性没有太大问题的前提下,可通过更换喇叭来进行测试。若更换了几个喇叭后,对比音档频响特性均没有较大的改善。这时则需要请硬件同事测量功放电路的输入和输出信号,来进行确定。若speaker增益已经衰减得比较大,功放的输入信号正常幅值较小,但功放的输出信号仍然出现失真,就要请硬件同事确认是否为功放放大倍数太大,或者是功放的供电电压太小没法满足放大的需要,出现削顶。这时若能修改功放电路解决最好。但在不可抗力因素下,比如用户已量产、硬件修改对用户影响太大或修改难度大等原因,我们只能在不失真的前提下,尽量提高对讲时的信号幅值来弥补声音小的缺陷。首先请硬件同事帮忙测量在播放扫频音档时,speaker增益最大下到多少可以保证功放电路的输出信号不失真,以此增益作为软件可调整的最大增益值,同时为了使speaker输出的声音足够大,使用AO端的AGC尽量对输出数据拉大,并限制在-3~-1dB以下(留有余量,避免功放失真)。

  2. Speaker端源数据爆音处理

    在对讲时发现即将播放的数据(即far end传过来的原始数据)会经常爆掉的情况下,可以对传过来的数据进行相应的处理来减缓这种情况,可以对数据进行多点平均的做法来将一些爆掉的点拉下来,多点平均(将当前采样点的数值与前面多个点进行平均,至于多少个点做一次平均请按具体情况来调整,爆得越严重要求的点数越多,计算公式:y = x(n)/n + x(n-1)/n + x(n-2)/n + … + x(0)/n)的方法相当于做了一次低通滤波,可以有效地消除锯齿,带来的副作用就是周期短的高频信号会被滤掉。多点平均的做法会把音质变糊,其他情况不建议使用。


8. 注意事项

在speaker增益固定后,按当前的增益播放1KHz0dB的正弦波音档或扫频音档TestFile3,请硬件同事帮忙测量送到speaker端信号的峰峰值,根据speaker的阻抗,请硬件同事计算此增益下,功率是否超过了speaker本身的额定功率,以防烧坏喇叭。