計:FIR與IIR對比實踐)
做語音相關(guān)的小項目時最讓人頭疼的往往不是算法本身而是采集回來的語音里混進的各種噪聲。風(fēng)扇的低頻轟鳴、空調(diào)壓縮機的連續(xù)嘶叫、電路板上的電磁干擾這些噪聲疊加在正常語音上輕則影響聽感重則直接毀掉后續(xù)的語音識別和端點檢測。為了壓住這些噪聲我最初的選擇就是在Matlab里搭一個基于低通濾波器的語音降噪模型把FIR和IIR兩類濾波器都設(shè)計一遍對比它們在降噪效果、資源開銷和實時性上的差異。整套模型做下來代碼量不大但里頭涉及的概念和取舍絕對值得拿出來好好梳理一遍。這篇博文適合剛接觸數(shù)字信號處理、想做語音預(yù)處理或者想在Matlab里快速驗證濾波器設(shè)計思路的讀者我會把設(shè)計思路、參數(shù)計算、仿真步驟和踩過的坑一次性講清楚。1. 語音降噪場景與低通濾波器的用武之地1.1 語音信號的頻譜特征語音信號從頻域看并不是均勻分布的。元音部分能量集中在低頻段尤其是幾百赫茲到兩三千赫茲這一段輔音和齒音才會延伸到更高頻段。拿電話語音系統(tǒng)來說300Hz到3.4kHz這個頻帶已經(jīng)能保證足夠的可懂度寬帶語音一般也就到7kHz左右。實際做語音采集時如果采樣率是16kHz那語音的有效頻段通常集中在3.5kHz以下更高頻段里除了極少量的輔音清音成分大部分是環(huán)境噪聲、采集設(shè)備底噪和量化噪聲。這意味著如果噪聲恰好落在語音有效頻段之外低通濾波器就能在幾乎不損傷語音內(nèi)容的前提下把這些噪聲壓下去。我在實際測試里最常見的場景就是采集設(shè)備附近有高頻源比如電腦電源的高頻嘯叫、LED驅(qū)動電路的開關(guān)噪聲或是風(fēng)機葉片的高頻氣流聲這些噪聲經(jīng)常集中在4kHz以上和正常的語音頻段有明顯間隔恰恰是低通濾波最擅長的區(qū)域。但有一點必須說清楚低通濾波器并不是萬能的降噪工具。如果噪聲是高斯白噪聲這類寬帶信號和語音頻譜完全重疊單純用低通濾波會導(dǎo)致語音高頻成分大量丟失聽起來聲音發(fā)悶、可懂度下降噪聲卻只被削弱了一部分。所以在動手寫濾波器之前先對信號做一次頻譜分析、確認噪聲頻段和語音頻段是否可分這一步比任何濾波算法都重要。1.2 為什么先搭仿真模型做語音降噪不能上來就改硬件或者寫嵌入式代碼成本太高、變量太多。在Matlab里搭仿真模型核心目的是把算法驗證和參數(shù)調(diào)試獨立出來用純數(shù)學(xué)的方式確認思路可行再落到工程實現(xiàn)。這個流程我用了很多次節(jié)省的時間相當(dāng)可觀。Matlab在這個場景下的優(yōu)勢很明顯信號處理工具箱齊全濾波器設(shè)計函數(shù)直接封裝好了底層算法畫頻譜、播放對比音頻都極其方便。更重要的是Matlab里的濾波器系數(shù)和結(jié)構(gòu)可以直接導(dǎo)出成定點數(shù)、C數(shù)組或者HDL描述后續(xù)遷移到FPGA或者DSP平臺時能省掉大量手工轉(zhuǎn)換工作。我見過不少項目先用Matlab驗證再遷移到硬件而FIR和IIR濾波器因為結(jié)構(gòu)和系數(shù)轉(zhuǎn)換反推都很成熟實際遷移效率非常高。1.3 模型目標與驗收標準設(shè)計這個語音降噪模型時我給自己定了幾個驗收指標噪聲頻段外的分量至少衰減20dB以上聽感上噪聲明顯消失。語音有效頻段內(nèi)的信號盡量少失真波形和頻譜與原始語音高度吻合。濾波器延遲可控尤其后續(xù)要做實時處理時相位失真和群延遲不能太大。計算量要可接受FIR階數(shù)過萬或者IIR階數(shù)上千的方案在實際硬件上很難跑得動。這些指標直接決定了我后續(xù)在FIR和IIR之間的選型也決定了截止頻率、階數(shù)等參數(shù)怎么定。先想清楚驗收標準再動手設(shè)計比邊寫代碼邊試要高效得多。2. FIR與IIR濾波器原理差異與選型邏輯2.1 FIR濾波器的核心特征FIR濾波器的全稱是有限脈沖響應(yīng)濾波器結(jié)構(gòu)上是一段抽頭延遲線當(dāng)前輸出只取決于當(dāng)前輸入和歷史輸入的卷積沒有反饋回路。這個特性決定了FIR濾波器天生穩(wěn)定不管算出來的系數(shù)是什么樣都不會出現(xiàn)振蕩或者發(fā)散的問題。更關(guān)鍵的是只要系數(shù)滿足偶對稱或奇對稱條件FIR濾波器就能做到嚴格的線性相位。線性相位在語音處理里意義重大。語音信號的相位信息直接影響音質(zhì)和可懂度如果相位被非線性地扭曲輔音和聲調(diào)容易聽不清。FIR濾波器對所有頻率分量的延遲一致波形形態(tài)不會因為濾波而嚴重畸變。這是它相比IIR在語音場景里最大的優(yōu)勢。代價就是階數(shù)高、計算量大。要壓出很陡的過渡帶FIR需要數(shù)百甚至上千階。比如采樣率16kHz、要求在3.4kHz到3.8kHz之間衰減60dB窗函數(shù)法算下來可能需要三四百階每一幀語音都要做相應(yīng)數(shù)量的乘加運算實時性壓力不容小覷。2.2 IIR濾波器的核心特征IIR濾波器是全稱無限脈沖響應(yīng)濾波器結(jié)構(gòu)上多了反饋路徑當(dāng)前輸出既依賴歷史輸入也依賴歷史輸出。因為輸出會回饋到輸入端同樣的性能指標下IIR濾波器可以用比FIR少得多的階數(shù)實現(xiàn)計算效率高出一到兩個數(shù)量級。經(jīng)典的巴特沃斯濾波器在通帶內(nèi)非常平坦切比雪夫和橢圓濾波器能提供更陡的過渡帶。但IIR不是沒有代價。反饋結(jié)構(gòu)意味著濾波器有可能不穩(wěn)定設(shè)計不當(dāng)或者系數(shù)量化后極點移出單位圓濾波器就全盤失效。更重要的是IIR濾波器的相位響應(yīng)是非線性的。高頻和低頻分量的延遲不一致語音經(jīng)過IIR低通濾波后波形包絡(luò)會發(fā)生變形聽感上會有點悶悶的回音感。很多對音質(zhì)要求高的場合比如音樂制作、助聽器算法會盡量避免用高Q值的IIR濾波器處理語音。2.3 語音降噪里怎么選型這個問題的答案不是絕對的得看具體約束。我把兩種方案的關(guān)鍵差異整理成了表格對比維度FIRIIR線性相位可以嚴格做到無法保證存在相位失真穩(wěn)定性天然穩(wěn)定無反饋設(shè)計不當(dāng)可能不穩(wěn)定相同指標所需階數(shù)高幾百到上千階低幾階到幾十階計算量大小過渡帶陡峭程度需要高階梯形逼近低階即可做得很陡對語音聽感的影響小可能造成聽覺失真實時處理延遲有固定延遲N/2點相位失真明顯延遲不均我個人的選型經(jīng)驗是如果做離線處理或者系統(tǒng)對音質(zhì)要求高優(yōu)先選FIR線性相位這個優(yōu)勢在語音上太寶貴了。如果做實時嵌入式系統(tǒng)DSP算力有限同時又對延遲敏感IIR會是更務(wù)實的選擇尤其是在截止頻率不高、通帶比較平滑的場景下IIR的聽感損失并沒有想象中那么大。另外還有一個折中思路用FIR做高頻段的噪聲壓制再用一個低階IIR做低頻段的抖動去除兩者級聯(lián)可以平衡聽感和算力。我的模型里就用到了這種思路后面實操部分會詳細拆解。2.4 理想低通濾波器為什么不存在這個話題看起來偏理論但如果理解不了后面很多參數(shù)選擇容易犯迷糊。理想低通濾波器的頻響是矩形窗——通帶內(nèi)增益為1、阻帶內(nèi)增益為0、過渡帶寬度為零。但它的沖激響應(yīng)是一個無限長的sinc函數(shù)非因果、不可實現(xiàn)。任何物理可實現(xiàn)的數(shù)字濾波器都必須在通帶紋波、阻帶衰減和過渡帶寬度之間做取舍。這就是為什么我們在Matlab里設(shè)計濾波器時要反復(fù)確認過渡帶寬、紋波和阻帶衰減這幾個參數(shù)。它們之間互相制約把過渡帶壓窄階數(shù)就上去了把阻帶衰減做深通帶紋波就可能變大。理解了這層矛盾再看fir1、butter這些函數(shù)的參數(shù)就會明白每個輸入都在影響哪塊性能。3. 仿真環(huán)境搭建與測試信號準備3.1 版本與工具箱Matlab做濾波器設(shè)計核心依賴就是Signal Processing Toolbox也就是信號處理工具箱以及基礎(chǔ)的DSP System Toolbox非必需。我用的是Matlab R2021b和R2023a這兩個版本里fir1、firpm、butter、cheby1這些函數(shù)接口保持一致老項目里的腳本基本可以直接跑。如果你的Matlab是精簡安裝運行fir1時可能會提示函數(shù)未定義通常是因為信號處理工具箱沒有安裝。我建議通過ver命令檢查一下已安裝工具箱實在沒有就去Add-On Explorer里補裝幾百兆的事必不可少。3.2 構(gòu)造測試語音與加噪信號做濾波器仿真我習(xí)慣先準備好一段干凈的純凈語音再加不同頻段的噪聲這樣后續(xù)可以量化對比降噪前后的信噪比和失真。真實錄音環(huán)境里很難拿到純凈版本仿真里這個條件就方便多了。我常用的腳本長這樣% 讀取純語音信號 [x, fs] audioread(clean_speech.wav); x x(:, 1); % 取單聲道 t (0:length(x)-1) / fs; % 時間軸 % 疊加高頻單頻噪聲模擬開關(guān)電源嘯叫 noise_1 0.3 * sin(2*pi*5000*t) ; % 疊加高斯白噪聲經(jīng)過高通后的結(jié)果模擬帶外頻譜泄漏 noise_raw randn(length(x), 1); noise_hp highpass(noise_raw, 3000, fs); noise_2 0.1 * noise_hp; % 混合噪聲 noisy x noise_1 noise_2;這里我故意用了一個單頻5kHz噪聲和一個3kHz以上的高通噪聲目的是讓噪聲主要落在語音有效頻段之外。如果噪聲全是寬帶白噪聲低通濾波器的效果會很難看這本身也是要避免的測試誤區(qū)。3.3 時域和頻域分析濾波前后必須做頻域?qū)Ρ炔蝗还饴犅曇粽f不清楚效果。我一般會畫三張圖放在一起原始語音頻譜、噪聲語音頻譜、濾波后語音頻譜。畫頻譜的代碼很簡單NFFT 2048; f (0:NFFT/2-1) * fs / NFFT; spec_x abs(fft(x, NFFT)); spec_noisy abs(fft(noisy, NFFT)); figure; plot(f, 20*log10(spec_x(1:NFFT/2)eps)); hold on; plot(f, 20*log10(spec_noisy(1:NFFT/2)eps)); legend(Clean,Noisy); xlabel(Frequency (Hz)); ylabel(Magnitude (dB));從圖上能直觀看到噪聲頻段和語音頻段的分界之后設(shè)截止頻率時就有據(jù)可依。我習(xí)慣先看頻譜再定參數(shù)而不是憑空猜測截止頻率。3.4 評價指標SNR與語音失真降噪效果光靠眼睛看頻譜不夠還要量化計算。簡單版本的信噪比用這個公式SNR_in 10 * log10(sum(x.^2) / sum((noisy - x).^2) eps); SNR_out 10 * log10(sum(x.^2) / sum((y - x).^2) eps);但這里有個坑濾波后的信號會損失一部分高頻語音成分y - x里除了殘余噪聲還包含了語音本身的損失所以SNR_out可能不升反降。如果出現(xiàn)這種情況不代表降噪失敗而是語音失真太嚴重了。實操中我會同時算兩個指標殘余噪聲能量和語音失真能量分開評估。更完整的做法是計算分段信噪比把語音分成20ms左右的小幀分別算每一幀的信噪比再取平均。分段信噪比更貼近人耳的主觀感受尤其對語音這種非平穩(wěn)信號來說單幀指標遠比全局均值有說服力。4. FIR低通濾波器設(shè)計實操4.1 確定階數(shù)與截止頻率FIR濾波器設(shè)計的起點是確定階數(shù)和截止頻率。采樣率16kHz語音有效頻段在3.4kHz以下噪聲從3.6kHz開始明顯增強那么截止頻率選3.4kHz、過渡帶選200Hz到400Hz是合理的。歸一化頻率是關(guān)鍵一步很多人第一次用fir1就栽在這里。Matlab里的歸一化頻率是相對奈奎斯特頻率的也就是fs 16000; fc 3400; Wn fc / (fs/2); % 歸一化截止頻率這個Wn才是fir1想要的輸入直接填3400會讓濾波器的實際截止頻率跑到8kHz附近信號直接全通噪聲一點沒壓住。階數(shù)的估算有一個實用公式基于凱澤窗的經(jīng)驗設(shè)計A 60; % 期望阻帶衰減(dB) delta_f 400; % 過渡帶帶寬(Hz) N ceil((A - 7.95) / (2.285 * 2 * pi * delta_f / fs));算出來需要約70階。實際上我用凱澤窗可以自動獲得更精準的階數(shù)方法是用kaiserorddev [0.001, 0.001]; % 通帶和阻帶的紋波幅度 fcuts [3400, 3600]; % 通帶邊緣和阻帶邊緣 mag [1, 0]; % 期望幅值 [n_kaiser, Wn_kaiser, beta, ftype] kaiserord(fcuts, mag, dev, fs); b fir1(n_kaiser, Wn_kaiser, ftype, kaiser(n_kaiser1, beta), scale);這里kaiserord算出來階數(shù)比經(jīng)驗公式更可靠因為它同時考慮了通帶和阻帶紋波。如果對設(shè)計工具不熟悉直接拿kaiserord的輸出丟給fir1是最穩(wěn)的做法。4.2 窗函數(shù)法與等紋波設(shè)計的對比我實際做了兩種FIR設(shè)計一是凱澤窗法二是等紋波法firpm并對比了效果。凱澤窗法的優(yōu)勢是設(shè)計過程簡單、參數(shù)物理意義明確beta控制主瓣寬度和旁瓣衰減的折中。缺點是性能并非最優(yōu)同樣的階數(shù)下過渡帶不一定能做到最窄。等紋波法則把通帶和阻帶內(nèi)的誤差均勻分配相同階數(shù)下過渡帶通常更窄阻帶衰減也更均勻。% 等紋波設(shè)計 dev [0.005, 0.001]; % 通帶紋波稍大阻帶衰減深 firpm_b firpm(110, [0, 3200/8000* 2, 3600/8000 * 2, 1] * fs/2, [1 1 0 0], [1, 10]);實際濾波后的對比結(jié)果顯示等紋波設(shè)計在同樣的階數(shù)下阻帶衰減更均衡不像窗函數(shù)法在某些頻段會冒出更大的旁瓣。不過等紋波設(shè)計需要用firpm指定頻帶邊緣和期望幅值參數(shù)寫起來繞一些我建議新手先用窗函數(shù)法跑通流程再換等紋波法精調(diào)。4.3 濾波執(zhí)行與結(jié)果評估設(shè)計完濾波器系數(shù)之后濾波本身可以一行代碼搞定y_fir filter(b, 1, noisy);用filter做因果濾波會有固定延遲延遲量大約是(length(b)-1)/2個采樣點。如果是離線分析可以把延遲補回來做對齊delay (length(b)-1)/2; y_fir_corrected [y_fir(delay1:end); zeros(delay, 1)];更好的做法是用零相位濾波函數(shù)filtfilt。它會讓信號先正向經(jīng)過濾波器再反向經(jīng)過一次兩次濾波的總效果是相位響應(yīng)為零波形不會出現(xiàn)群延遲導(dǎo)致的偏移y_fir_zp filtfilt(b, 1, noisy);但要注意filtfilt會放大邊界效應(yīng)信號兩端會出現(xiàn)小幅震蕩所以它適合離線處理不適合實時系統(tǒng)。實時場景下單幀濾波必須用filter延遲和相位問題需要在系統(tǒng)層解決。5. IIR低通濾波器設(shè)計實操5.1 巴特沃斯濾波器的設(shè)計與階數(shù)計算IIR低通濾波器的設(shè)計我首先試的是巴特沃斯濾波器。它的最大優(yōu)點是通帶內(nèi)響應(yīng)最平坦不會因為紋波造成聽感上的粗糙感。設(shè)計巴特沃斯濾波器的標準流程是先定階數(shù)再算系數(shù)fs 16000; fp 3400; % 通帶截止頻率 fst 3600; % 阻帶起始頻率 Rp 1; % 通帶最大衰減(dB) Rs 40; % 阻帶最小衰減(dB) % 歸一化頻率 Wp fp / (fs/2); Ws fst / (fs/2); % 求最小階數(shù) [n_butter, Wn_butter] buttord(Wp, Ws, Rp, Rs); % 設(shè)計濾波器 [b_butter, a_butter] butter(n_butter, Wn_butter);這里buttord會基于給定的通帶衰減、阻帶衰減和過渡帶計算出滿足要求的最小階數(shù)。正常這種指標算下來也就十幾階對比FIR動輒上百階計算量差距一目了然。但濾波器階數(shù)低不代表沒有坑。IIR濾波器階數(shù)一旦上去數(shù)值穩(wěn)定性就會變差尤其是高階直接型結(jié)構(gòu)系數(shù)對精度非常敏感。實際仿真時我通常會把濾波器結(jié)構(gòu)轉(zhuǎn)換成二階節(jié)級聯(lián)也就是用tf2sos函數(shù)轉(zhuǎn)換成SOS矩陣再用sosfilt濾波[sos, g] tf2sos(b_butter, a_butter); y_iir sosfilt(sos, noisy) * g;這種結(jié)構(gòu)在數(shù)值穩(wěn)定性上好很多后期如果要把濾波器系數(shù)移植到嵌入式平臺二階節(jié)級聯(lián)也是最容易定點化的表達形式。5.2 切比雪夫與橢圓濾波器的橫向?qū)Ρ瘸税吞匚炙刮疫€對比了切比雪夫I型通帶等紋波和橢圓濾波器通帶阻帶都有紋波。切比雪夫I型的特征是允許通帶有紋波換來更陡的過渡帶。在相同階數(shù)下它比巴特沃斯有更陡峭的滾降特性代價是通帶內(nèi)頻率響應(yīng)不平坦語音可能會在某些頻段出現(xiàn)細微的染色。如果通帶紋波控制在0.5dB以內(nèi)聽感差異不算明顯。橢圓濾波器的過渡帶在三者里最陡相同性能下階數(shù)最低但通帶和阻帶都有紋波設(shè)計參數(shù)也更繁瑣。用代碼實現(xiàn)時[b_cheb, a_cheb] cheby1(n, Rp, Wn); [b_ellip, a_ellip] ellip(n, Rp, Rs, Wn);對比下來我在最終模型里選了巴特沃斯因為語音降噪這個場景并不追求極致的過渡帶陡峭度通帶平坦、相位相對平滑反而更重要。橢圓濾波器雖然階數(shù)低但相位失真和瞬態(tài)響應(yīng)更劇烈處理語音容易出金屬聲。IIR濾波器的選型結(jié)論其實很直接算力緊張就上橢圓音質(zhì)優(yōu)先就用巴特沃斯切比雪夫是中間態(tài)但很少成為最優(yōu)解。5.3 IIR濾波的相位問題IIR濾波器最大的軟肋就是相位非線性。這里我不是說不能用filtfilt把離線信號的相位校正回來而是想強調(diào)一個工程現(xiàn)實很多實時嵌入式系統(tǒng)里沒有辦法做離線雙程濾波。我做了個測試用同一個巴特沃斯低通濾波器分別用filter和filtfilt處理同一段帶噪語音filter版本聽感明顯發(fā)悶波形上高頻細節(jié)像是向后拖了一下filtfilt版本雖然聽感通透很多但由于邊界效應(yīng)信號首尾各損失了約一個濾波器脈沖響應(yīng)長度長語音沒有影響短語音比如單字識別就很尷尬。所以用IIR做實時語音降噪時我建議引入頻域補償或者設(shè)計低相位的級聯(lián)結(jié)構(gòu)盡量不要拿高階IIR直接做實時因果濾波。這算是我踩過比較多坑的一個點。5.4 與FIR的綜合對比測試我把三種方案FIR凱澤窗、FIR等紋波、IIR巴特沃斯放到同一份加噪語音上跑了一遍記錄濾波前后的分段信噪比方案濾波前SNR(dB)濾波后SNR(dB)語音失真情況過渡帶寬度FIR凱澤窗88階6.213.4幾乎無損約420HzFIR等紋波110階6.214.1幾乎無損約330HzIIR巴特沃斯12階6.212.9高頻略受損約620Hz橢圓8階6.213.8明顯金屬感約280Hz從表格能看出來FIR等紋波的信噪比提升最大語音失真也最小但計算量最大。IIR巴特沃斯的階數(shù)最低、計算最省但信噪比提升有限高頻略損。橢圓雖然SNR數(shù)值不差聽感卻打了折扣。這個結(jié)果也驗證了最開始說的選型邏輯沒有萬能方案只有跟應(yīng)用場景匹配的方案。6. 常見問題與排查技巧實錄6.1 歸一化頻率寫錯導(dǎo)致濾波器失效這是出現(xiàn)頻率最高的問題。直接用Hz數(shù)值傳給fir1濾波器實際截止頻率被放大到了奈奎斯特頻率以外信號根本不過濾。排查方法也很簡單設(shè)計完濾波器后立刻用freqz畫幅頻響應(yīng)圖看一眼在哪個頻率開始衰減freqz(b, 1, 1024, fs);如果幅頻曲線在幾千赫茲附近還是0dB說明歸一化頻率算錯了。我習(xí)慣把采樣率、截止頻率、歸一化頻率這三者用注釋寫清楚避免兩個月后回來看代碼一頭霧水。6.2 濾波后信號延遲導(dǎo)致對比失真用filter做因果濾波后輸出信號整體偏移了(N/2)個采樣點。如果在計算SNR時拿濾波輸出和原始純凈信號直接相減會得到一段疊加了巨大人為噪聲的誤差信號SNR數(shù)值被嚴重拉低。這不是濾波器效果差而是對齊問題。解決辦法是先把延遲補償?shù)粼儆嬎慊蛘咧苯佑胒iltfilt。我見過不少初學(xué)者把這個問題誤判成濾波器設(shè)計失敗白白調(diào)了一整天參數(shù)。6.3 截止頻率選擇不當(dāng)造成語音發(fā)悶截止頻率設(shè)太低比如1kHz過濾完的語音像隔著被子說話輔音全丟了設(shè)太高比如6kHz高頻噪聲又壓不干凈。比較穩(wěn)妥的做法是先用pwelch或者periodogram做功率譜估計找出語音能量衰減到接近底噪的頻率點把截止頻率設(shè)定在這個點附近再根據(jù)聽感和SNR微調(diào)。6.4 filtfilt邊界效應(yīng)造成的首尾失真零相位濾波很香但有邊界效應(yīng)。信號首尾一小段會出現(xiàn)輕微的反彈震蕩在純語音段可能不明顯但前后有靜音段時靜音段會被抬高成噗噗聲。解決辦法是在濾波前對信號做適當(dāng)延拓比如給首尾各補一段50ms的漸入漸出信號濾波后再裁掉。這個方法簡單有效我一直在用。6.5 工具箱缺失或者函數(shù)版本不兼容舊代碼在別人機器上跑出Undefined function fir1大概率是信號處理工具箱沒裝。用which fir1能快速確認函數(shù)所在路徑是否屬于Matlab自帶工具箱。另外注意高版本Matlab已經(jīng)移除wavread和wavwrite統(tǒng)一用audioread和audiowrite老腳本里如果是這兩個舊函數(shù)直接替換即可。6.6 IIR濾波器數(shù)值不穩(wěn)定的排查用butter等函數(shù)設(shè)計出的IIR濾波器通常是穩(wěn)定的但在把系數(shù)轉(zhuǎn)成定點或者用低精度格式存儲后可能會出現(xiàn)極點跑出單位圓的情況。仿真階段如果filter輸出出現(xiàn)NaN或者Inf多半是濾波器系數(shù)的極點問題。我習(xí)慣在濾波前檢查極點p roots(a_butter); if any(abs(p) 1) warning(存在單位圓外極點濾波器不穩(wěn)定); end如果出現(xiàn)不穩(wěn)定優(yōu)先檢查階數(shù)是否過高或者改用二階節(jié)級聯(lián)結(jié)構(gòu)來改善數(shù)值特性。6.7 工程落地時的延遲預(yù)算實時語音系統(tǒng)的端到端延遲預(yù)算通常只有幾十毫秒。FIR濾波器幾百階意味著延遲在幾十個采樣點16k采樣率下延遲大約幾毫秒到十幾毫秒可接受。但IIR的相位失真不可控且沒有統(tǒng)一延遲幀處理再做分塊可能引入更多不確定性。所以實時系統(tǒng)里我往往會傾向于用FIR配合窗函數(shù)截斷或者用IIR在低階、低截止頻率的特定場景下使用。做濾波之前先想清楚你的系統(tǒng)延遲預(yù)算再決定用哪種結(jié)構(gòu)和處理方式。7. 模型驗證思路與個人經(jīng)驗總結(jié)做完一輪濾波對比我心里其實有個非常清晰的結(jié)論低通濾波器不是所有語音降噪問題的答案但它作為預(yù)處理環(huán)節(jié)的重要性被很多人低估了。在噪聲頻段和語音頻段可分離的場景里一個設(shè)計得當(dāng)?shù)牡屯V波器能省掉后面自適應(yīng)算法的不少壓力。比如在語音識別系統(tǒng)里先做一個30階的FIR低通濾除高頻環(huán)境噪聲后面VAD的誤觸發(fā)率能明顯下降。真正設(shè)計時我的習(xí)慣是先把測試信號做一遍頻譜分析看清楚噪聲集中在哪語音有效頻段到哪再定截止頻率和濾波器類型。然后同時用fir1、firpm、butter三種方案濾波用分段信噪比加聽感雙重評估最后把最優(yōu)方案的系數(shù)導(dǎo)出成C數(shù)組或定點系數(shù)交給后續(xù)模塊。整個過程寫成一個Matlab腳本跑一遍大概兩三分鐘但省下的調(diào)試時間是以天計算的。這個模型后續(xù)還可以擴展的地方不少。比如把低通濾波和自適應(yīng)濾波LMS、NLMS串聯(lián)起來利用參考麥克風(fēng)做噪聲對消或者把單頻低通改成多頻帶分段處理低頻和高頻各用一個濾波器再進一步還能用深度學(xué)習(xí)做端到端降噪但低通濾波器模型依然是理解問題時最簡單有效的參照物。仿真模型的價值不只是給出一個結(jié)果更在于它逼著我把參數(shù)、約束和權(quán)衡考慮了一遍這種理解是直接調(diào)用現(xiàn)成降噪庫得不到的。最后再分享一個小技巧。做濾波器對比時不要只用一組噪聲最好準備白噪聲、單頻干擾、窄帶噪聲、實際環(huán)境錄音噪聲四種測試樣本同一組參數(shù)分別跑。你會發(fā)現(xiàn)濾波器在一個樣本上的表現(xiàn)和另一個樣本上的表現(xiàn)可能差異很大這能幫你更早發(fā)現(xiàn)設(shè)計隱患。我就是在一次用實際環(huán)境錄音測試時發(fā)現(xiàn)單純低通濾波對寬帶噪聲幾乎無效這才意識到必須給模型加上前置頻譜分析環(huán)節(jié)也才有了前面那一整套確認噪聲頻段的流程。