ARTICLE DETAIL

资讯详情

深耕网站建设与运营推广的一线实战洞察。

音频处理核心算法:傅里叶变换、语音增强、回声消除与主动降噪

音频处理核心算法:傅里叶变换、语音增强、回声消除与主动降噪 1. 先搞清楚音频信号处理到底在解决什么问题1.1 一个真实场景里的音频链路你开着一场线上会议对方在嘈杂的咖啡馆里说话你听到的不仅是他的声音还有咖啡机轰鸣、杯碟碰撞、旁边顾客的交谈声。与此同时你自己的说话声通过扬声器传出去被对方的麦克风拾取后又传回来形成一层层重复的回声。更麻烦的是如果你戴着主动降噪耳机耳机内部还在拼命产生反向声波来抵消外界噪声。这三个问题——噪声、回声、环境干扰——恰恰是音频信号处理最核心的四个算法要解决的傅里叶变换负责把声音“解剖”开语音增强负责把噪声“挑”出来扔掉回声消除负责把不该回来的声音“掐断”主动降噪则是在声波层面直接“硬碰硬”。这篇文章写给谁主要是刚入门音频算法、语音通信、耳机声学开发的工程师也包括那些需要理解音频处理原理的产品经理和嵌入式开发者。我会围绕这四块核心算法讲原理、讲数学直觉、讲工程落地时真正踩过的坑。读完你应该能理解一条完整的音频处理pipeline是怎么串起来的以及每个环节的参数选择和调试思路为什么要这么定。1.2 四大算法的分工边界很多人容易把语音增强和主动降噪混为一谈其实两者解决的是完全不同的场景。语音增强处理的是“已经把声音变成电信号之后”的事它是在数字域里对信号做处理目标是把信噪比提上去主动降噪处理的是“声波还没有进入麦克风之前”的事它需要额外的扬声器发出反向声波在物理空间里进行声波抵消。回声消除则更特殊它处理的是“自己人说话”的问题——对方的声音经过你的扬声器播放出来又被你的麦克风拾取形成一个闭合环路。如果不做回声消除对方会听到自己的回声沟通体验极差。傅里叶变换在这里扮演的角色是“翻译官”。它把时间域上的波形信号翻译成频率域上的频谱分布让后续所有算法都能在频域里工作。可以这么说没有傅里叶变换语音增强和回声消除的效率会低好几个数量级甚至根本无法在实时系统里跑起来。下面我先从傅里叶变换讲起因为它是整个音频算法体系的基石也是理解后面所有内容的钥匙。2. 傅里叶变换整个音频处理的地基2.1 从时域到频域为什么非变不可先做一个简单的思考实验。你在一个录音棚里录下来一段语音用波形图去看它是一条非常复杂的、不规则的振幅起伏曲线。波形图告诉你“在某个时刻声音有多大”但它不告诉你“这段声音里包含了哪些频率成分”。而人耳对声音的感知恰恰是频率相关的——一颗子弹飞过的声音和一段低音鼓的声音可能音量差不多但频谱结构完全不同。傅里叶变换的核心思想就是把任意一个周期性信号分解成一系列不同频率正弦波的叠加。用数学语言说任何一个满足狄利克雷条件的周期信号都可以表示成傅里叶级数的形式对于非周期信号则用傅里叶积分来推广。实际工程里我们用得最多的是离散傅里叶变换DFT而它的快速实现就是FFT快速傅里叶变换。FFT把原本需要O(N²)次复数乘法的DFT压缩到O(NlogN)这使得实时处理成为可能。在嵌入式处理器上跑音频算法几乎全部依赖FFT的高效实现。为什么要做这种变换两个核心原因。第一很多在时域里看起来极其复杂的操作到了频域就变得非常简单比如滤波——时域里一个高阶滤波器的卷积运算在频域里只需要做逐点相乘。第二语音增强、回声消除这类算法的核心逻辑本身就是基于频域特征的噪声大多集中在特定频段语音也有其特定的频谱分布规律在频域里处理才能精准地下手。2.2 相位到底重不重要关于傅里叶变换有一个网上讨论非常多的话题相位到底有什么用很多人做音频处理时只关注幅值谱把相位信息丢掉或者简单处理结果出来的声音往往“嗡嗡”的或者有严重的听感畸变。我在这里明确说相位极其重要尤其是在语音场景。你想象一下一段语音的频谱由两部分构成——幅值谱决定“哪些频率分量有多响”相位谱决定“这些频率分量在时间上如何对齐”。如果只保留幅值谱、丢掉相位谱相当于你把一支交响乐队每个乐手都保留了下来但他们彼此之间的节拍全乱了演奏出来的东西根本没法听。在语音增强里很多经典算法比如谱减法只对幅值谱做处理相位直接用带噪信号的相位这在理论上是对的——因为人耳对相位的敏感度低于幅值短时帧内这样做误差可接受。但这不代表相位不重要只是短期内的近似处理。我记得最早做语音增强的时候我尝试在频域里直接对相位做平滑结果语音的清晰度反而下降了。后来才理解相位谱中包含了语音的精细时域结构乱改相位会破坏语音的起音和辅音信息。所以在做基础语音增强时老老实实保持带噪相位不变只在幅值谱上做文章是更稳妥的做法。2.3 三角脉冲的傅里叶变换记忆方法网上的热搜词里有个“三角脉冲的傅里叶变换记忆方法”我顺带讲一下这个知识点因为它在做信号处理基本功时经常会碰到。三角脉冲函数是指信号从0开始线性上升到峰值再线性下降回0形成一个三角形波形的时域信号。它的傅里叶变换结果是sinc函数的平方X(f) A·T·sinc²(πfT)。为什么是这个结果这里有一个非常优雅的记忆方法——利用卷积定理。矩形脉冲的傅里叶变换是sinc函数即sin(πx)/(πx)。而三角脉冲恰好等于两个相同矩形脉冲的卷积你把一个矩形脉冲和它自身做卷积得到的重叠区域面积随位移变化形成一个三角形。那么根据卷积定理时域卷积对应频域乘积三角脉冲的傅里叶变换就等于sinc函数乘以sinc函数——也就是sinc的平方。这个思路比硬记公式靠谱得多而且能帮助你举一反三任何能拆成简单函数卷积的信号其变换结果都可以用卷积定理推导。顺带说一句这个知识在音频处理里也有实际用处比如在做线性插值上采样的时候插值核的频域响应就和sinc函数密切相关理解三角脉冲的频谱特性有助于你分析插值对高频成分的影响。3. 语音增强把噪声从语音里“摘”出来3.1 谱减法最经典的入门算法语音增强要做的事情通俗讲就是“去噪”。它假设麦克风拾取到的信号y(t) 语音s(t) 噪声n(t)目标是找到一个估计值ŝ(t)尽可能接近原始语音。最早也最直观的方法是谱减法。谱减法的思路很简单在频域里带噪语音的功率谱减去噪声的功率谱就得到干净的语音功率谱估计。具体操作分几步对带噪信号做分帧和加窗每帧做FFT得到频谱在语音间歇段没有语音的帧估计噪声功率谱再把当前帧的带噪功率谱减去估计的噪声功率谱得到增强后的幅值最后用带噪相位重构时域信号。实现上谱减法的公式是|Ŝ(f)|² |Y(f)|² - α·|N̂(f)|²其中α是减法因子也叫过减因子。谱减法有个臭名昭著的副作用叫“音乐噪声”。因为噪声估计存在误差频谱上会出现一些随机出现的孤立尖峰听感上就像背景里有若隐若现的“叮叮”声。解决这个问题的方法包括使用过减因子α 1来更激进地扣除噪声引入平滑机制对相邻帧的增益做平滑以及使用频谱下限约束把增强后的频谱限制在一个最小阈值以上避免出现负值和过大动态波动。我在实际项目里用谱减法得出来的经验是谱减法适合信噪比在10dB以上的场景如果信噪比低于5dB谱减法出来的效果就很勉强了。另外谱减法对稳态噪声如风扇声、空调声效果不错但对非稳态噪声如键盘敲击声、突然的关门声基本无能为力因为后面这类噪声的功率谱快速变化你前面估计的噪声谱早就过时了。为了解决非稳态噪声问题业界后来发展出了更复杂的基于最小统计量噪声跟踪、基于IMCRA的噪声估计算法以及基于神经网络的语音增强方案这些后面有机会再展开。3.2 维纳滤波更“优雅”的频域去噪方法维纳滤波是另一个里程碑式的算法它的出发点不太一样它不追求噪声删得干净而是追求“增强后的信号与原始干净语音之间的均方误差最小”。从数学上讲维纳滤波器的最优传输函数是H(f) P_s(f) / (P_s(f) P_n(f))其中P_s是语音功率谱P_n是噪声功率谱。这个公式的直觉很清晰在语音能量很强的频率点H趋近于1几乎不做衰减在噪声主导的频率点H趋近于0把信号压下来在两者相当的地方H约等于0.5做折中。维纳滤波比谱减法“温和”音乐噪声更少听感更自然。但它有个前提问题——你需要知道语音功率谱P_s而真实语音的功率谱恰恰是未知的。实际工程里常见的做法是用带噪语音的瞬时功率谱替代H(f) ξ(f) / (1 ξ(f))这里ξ(f)是后验信噪比的估计。再配合“决策导向”方法Decision-Directed approach——将当前帧增益计算时的权重一部分来自前一帧的估计结果——可以大幅平滑增益波动进一步降低音乐噪声。决策导向方法是我个人非常推荐的一个技巧几乎所有商用降噪方案里都有它的影子。3.3 实操中的语音增强经验这里分享一些在DSP和嵌入式平台上做语音增强时的真实经验和参数选择思路。分帧参数语音信号是非平稳的但短时内可以视为平稳所以需要分帧处理。帧长一般取20ms到30ms对应16kHz采样率下就是320到480个采样点。帧移一般取帧长的50%也就是典型的10ms。窗函数建议用汉宁窗旁瓣衰减快频谱泄漏小。注意FFT点数要覆盖帧长如果不满足2的幂次可以直接取下一个2的幂次做补零但要注意补零处理对频域分辨率的影响。噪声估计不是一次性完成的而是持续更新。最简单的思路是拿语音活动检测器VAD判断当前帧是语音还是噪声如果是噪声就持续更新噪声功率谱估计。但VAD本身就会出错误判的后果是噪声估计过高导致语音被过度压制。更稳健的方法是使用最小统计量方法不依赖VAD在连续若干帧内跟踪每个频点的功率最小值认为最小值接近该频段的噪声底。这个方法的实现细节更多但对低信噪比场景提升非常明显。还有一点容易被忽略处理完频域增强之后时域合成时要保证帧间平滑连接。直接的重叠相加OLA或重叠存储OLS方法都会带来帧边界不连续的问题实际工程里常用加权重叠相加WOLA在合成时再做一次窗函数处理。这个细节如果不注意你降噪后的信号会有一阵一阵的“呼吸感”给人的感觉就是音量在抖动。这也是很多新手做出来的demo一听就有瑕疵的重要原因。4. 回声消除通话里最隐蔽的“鬼”4.1 声学回声是怎么产生的回声消除Acoustic Echo CancellationAEC是通信领域一个老话题也是我见过非常多工程师栽跟头的地方。问题的根源在于你打电话时自己的声音从扬声器播放出来在房间墙壁、桌面等物体上反射一部分声波最终被麦克风拾取。如果这个被拾取的回声信号不回传给你而回传给了对方对方就会在通话里听到自己的声音而且带有延迟非常难受。关键点在于麦克风拾取到的信号是“远端语音”经过一个复杂的声学路径扬声器到麦克风的传播路径之后的结果。这个路径包括直达声、反射声、混响甚至还包括扬声器和麦克风的频响特性。它不是一个简单的线性滤波器而是会随时间变化——你移动一下脑袋或者有人走过麦克风旁边路径就变了。所以要消除回声必须用自适应滤波器去“在线追踪”这个时变的声学路径实时估计出回声的形态然后从麦克风信号里减掉。4.2 自适应滤波器的核心思想自适应滤波器的核心逻辑是用一个可调系数的滤波器来模拟声学路径并通过误差信号不断调整滤波器的系数使其输出逼近真实回声。最常用的基础自适应算法是LMS最小均方算法而实际工程中使用最多的是它的变体NLMS归一化最小均方算法。NLMS的系数更新公式是w(n1) w(n) μ·e(n)·x(n) / (||x(n)||² δ)其中x(n)是远端参考信号e(n)是误差信号麦克风拾取信号减去估计回声后的残差μ是步长因子δ是防止除零的常数。步长μ怎么选是个大学问μ太大会导致滤波器发散输出刺耳的啸叫μ太小则收敛太慢跟不上声路径变化。常用的经验值是μ取0.05到0.2之间具体取决于参考信号的能量和滤波器的长度。在AEC里还有个极其重要的模块叫双讲检测Double-Talk DetectionDTD。当只有远端说话时自适应滤波器可以放心地收敛当本地用户也开始说话时麦克风信号里同时包含近端语音和回声这时候如果还继续用误差信号去更新滤波器系数滤波器会被带偏。所以必须在双讲期间冻结滤波器更新只在单讲期间只有远端回声时更新系数。经典的DTD方法是比较近端信号能量和远端参考信号能量做判决现代方案也有用相关系数来做的但基本原理不变。4.3 AEC工程落地中的坑回声消除在实际工程里远比教科书复杂。第一个常见坑是参考信号采集延迟。芯片上的AEC算法需要拿到“送给扬声器的原始参考信号”但如果代码架构里这个参考信号经过了其他模块比如音量控制、音效处理才到达扬声器而算法拿到的参考信号是处理前的就会存在时延。时延直接破坏NLMS滤波器的延迟对齐假设导致回声消除效果急剧下降。处理方案是做一个延迟估计模块在参考信号和麦克风信号之间对齐时延或者在架构设计时就从DAC后端取参考信号。第二个坑是非线性失真。扬声器在音量较大时会出现非线性失真产生了原始参考信号里根本不存在的谐波成分自适应线性滤波器是线性系统无法消除这些非线性分量。所以完整的AEC链路里除了线性自适应滤波通常还会有一个非线性处理器NLP把残余的小幅回声再做一次压制或抑制。NLP如果做得激进会误伤近端语音如果太保守回声又压不干净。这里没有银弹工程调试时需要在通话效果和回声抑制深度之间反复权衡。第三个坑是滤波器长度与采样率的关系。滤波器长度决定了可以模拟的最大回声路径时长。在16kHz采样率下一个100ms的混响路径就需要1600个抽头的滤波器这对应1600次乘加运算——单纯从计算量看不吓人但要用实时FFT做频域自适应滤波如分块频域自适应滤波FDAF才够经济。这是为什么商用的AEC算法实现大多走频域路线很少有时域NLMS方案。5. 主动降噪在声波层面“正面硬刚”5.1 主动降噪的物理原理主动降噪Active Noise CancellationANC与前面讲的所有算法都不一样它是在物理声场层面进行的操作。核心原理是声波干涉两个频率相同、相位相反的声波叠加时振幅会相消听起来就像声音消失了。ANC耳机通过麦克风拾取环境噪声再由DSP生成与噪声相位相反、幅值相等的声波通过扬声器发出来与环境噪声在耳朵里完成相消干涉。这里有一个非常重要的参数叫“降噪带宽”它直接决定你硬件方案的选择。声学理论告诉我们主动降噪对低频噪声20Hz到1kHz效果显著对中高频噪声2kHz以上效果急剧下降。原因有两点一是高频噪声的波长更短空间噪声场变化剧烈麦克风采样的“点”无法代表整个耳道区域的声场二是数字信号处理存在固有延迟波长越短对相位误差越敏感一点点相位偏差就会让“抵消”变成“叠加”反而放大噪声。所以绝大多数主动降噪耳机的标称降噪量都是在100Hz到500Hz这个频段测的那些标称“降噪深度-40dB”的宣传数据通常也是指低频段的峰值降噪量中高频其实是达不到的。5.2 三种架构对比前馈、反馈与混合主动降噪的系统架构通常有三种前馈式、反馈式和混合式。前馈式Feedforward的麦克风朝外放在耳罩外侧采集环境噪声经过DSP处理后生成反向声波。它的优点在于可以在噪声进入耳道之前就做预判式的抵消留给DSP的处理时间窗口更大缺点是麦克风采集到的噪声不等于耳朵处听到的噪声两者之间隔着一个耳罩或耳塞的声学隔离层声学路径复杂误差较大。反馈式Feedback的麦克风朝内放在耳机内侧直接采集耳道附近的实际噪声和音乐混合声。这个信号的时延更短能够更好地应对非稳态噪声但它的缺点也很明显——如果不做精细的稳定性约束反馈环路容易发生自激振荡表现为高频啸叫。所以反馈式ANC对环路调节的稳定性要求非常高工程调适难度大。混合式就是前馈加反馈两者结合外侧麦克风负责拾取环境噪声做预判内侧麦克风负责监测残余误差做补偿校准综合了两种架构的优点。这也是目前高端降噪耳机的普遍方案。我在开发ANC耳机时左右耳各用一颗前馈麦克风和一颗反馈麦克风配合一颗低延迟的DSP芯片整个系统的延迟需要控制在几十微秒到几百微秒量级这对算法和硬件选型都提出了极高的要求。5.3 调参实战心得主动降噪的DSP实现里最核心的模块是滤波器和延时管理。前馈控制滤波器的传递函数可以粗略设计成待抵消噪声路径响应与次级路径扬声器到耳道响应的比值必要时再叠加一个频响均衡器把不想降的频段比如人声频段特意留出来。很多降噪耳机有“透明模式”或“人声增强模式”本质就是在频域上精确控制降噪增益曲线。反馈式ANC里还有一个关键动作环路增益调校。反馈控制环路存在“多余延时”会破坏相位裕度导致在某些频率点出现正反馈让系统发散。我调试时会在特定频点逐步加大控制增益观察耳机是否开始低频振荡或高频啸叫一旦出现立即回退增益并调整环路滤波器的相位修正。这个调试过程有点像给音响调反馈抑制器——你永远在“增益尽量大”和“不发生自激”之间找平衡。另外ANC的降噪效果非常依赖佩戴的密封性。同一套ANC算法戴紧和戴松的降噪效果差距可以超过10dB。所以在耳机结构设计和算法调试阶段都要考虑到不同用户的佩戴差异。商用的高端方案通常会增加一个在线自适应模块根据反馈麦克风的残余噪声信号自动微调滤波器系数以此应对佩戴不一致的问题。这一步对实际体验的提升非常明显做产品时强烈建议加上。6. 这四块算法是怎么协同工作的6.1 一条完整的音频处理pipeline在实际产品里这四块算法很少是孤立工作的。以一台支持通话降噪的TWS耳机为例物理上外向麦克风采集环境噪声内向麦克风采集耳道内混合信号数字层面主控芯片里并行跑着多路算法。麦克风信号先经过自适应波束成形这可能不在本文范围但值得知道它存在定向增强目标语音方向然后送入语音增强模块做噪声谱估计和频域滤波同时AEC模块接收从扬声器播放的远端参考信号对近端信号做回声消除处理再叠加ANC模块生成的抗噪声波由扬声器播放出来与人耳处的环境噪声完成物理干涉。这里很关键的一点是模块间的先后顺序和资源共享。AEC和语音增强都工作在频域可以共用一组FFT结果大幅降低计算量。但两个模块不能同时占用同一处理器核太久否则实时性就崩了。我在一个低功耗MCU上做方案时把FFT运算做了时分复用的调度优化AEC跑48kHz、语音增强跑16kHz降采样率两个人的处理时间差开最终总算力才勉强控制在了处理器预算之内。这个领域里算法设计和工程实现的耦合度极高纯做算法仿真和真正在嵌入式平台跑通完全是两回事。6.2 工程落地时要提前想好的事关于平台选型音频算法的实时性要求非常苛刻通常要求算法延迟低于20ms才不会被人感知到。在处理器的算力评估上一定要把“实际最恶劣情况”考虑进去而不是只测试实验室里的平均负载。FFT运算是最占资源的如果采样率是48kHz、帧长512点每帧要做一次FFT和一次IFFT再加上各种逐点运算单通道的处理时间在低端MCU上可能就逼近帧周期了。这个预算不做充足就提前设计系统后面就等着删特性和降低采样率吧。另外一个很容易被忽视的是测试环境。AEC的调优必须用真实的扬声器-麦克风声学环境测试不能只依赖仿真ANC的降噪效果必须用人工头Head and Torso SimulatorHATS来测量不能只靠主观试听。我见过太多团队在软件仿真阶段把指标调得很漂亮一上真实硬件就翻车原因就是没有提前把声学路径的时变性和非线性因素考虑进去。尽早建立“仿真-硬件在环-真机测试”的闭环是项目节奏上最重要的建议。6.3 我个人对这些算法的最终体会做音频算法这些年最大的感受是这四个算法没有一个是“调好参数就能一劳永逸”的它们都需要持续跟踪和自适应。噪声环境在变声学路径在变用户的佩戴习惯也在变——算法的价值很大程度上取决于它的自适应能力而不是静态最优解。另一个体会是调试顺序不能乱每次只调一个变量。比如AEC和语音增强同时开启的时候如果效果很差你先分别关闭其中一个判断问题出在哪一环不然根本找不到根源。音频问题的定位周期一般很漫长耐心和方法论比一时的灵感更重要。最后再分享一个调试小技巧在开发阶段把各个模块的中间信号比如噪声谱估计、滤波器系数变化、误差信号全程监控导出离线分析定位问题——很多时候一个问题单靠听是听不出来的但看着信号波形和频谱图三分钟就能锁定问题所在。音频处理是一个“耳朵眼睛”结合的功夫保持对信号的敏感和好奇比掌握某一两个具体算法套路重要得多。
返回列表