譜減法(Spectral Subtraction)

本文簡要探討了語音信號的基本特性,并介紹了譜減法的基本原理,同時基于Matlab實(shí)現(xiàn)了原始譜減法及其一種改進(jìn)版。最后給出音頻波形、頻譜,從主觀的人耳和客觀的評判標(biāo)準(zhǔn)來量化所達(dá)到的效果。

1 語音信號

1.1 宏觀的非平穩(wěn)性與微觀的平穩(wěn)性

在現(xiàn)實(shí)世界中,我們獲得的所有信號波形都是其對應(yīng)分布的一組觀測值。平穩(wěn)信號指的是其分布及分布的參數(shù)不會發(fā)生變化,非平穩(wěn)信號則是其分布或分布的參數(shù)發(fā)生變化。對于語音信號來說,由于信號直接由說話者控制,其分布和分布的參數(shù)都是不確定的。以一個宏觀的角度來看,語音信號具有非平穩(wěn)性。而在10-30ms這個尺度,受人的發(fā)聲器官所限定,語音信號是平穩(wěn)的,即在微觀下,語音信號具有平穩(wěn)性。正是這種特性,導(dǎo)致了在語音信號處理過程中,短時分析成為一個重要的手段。

2 基本譜減法的原理

對噪聲的基本假設(shè)

  • 噪聲是局部穩(wěn)定的,即與語音信號一致,在微觀尺度下具有平穩(wěn)性。
  • 噪聲是加性噪聲
  • 噪聲與純凈的語音信號是不相關(guān)的

基于以上的假設(shè),我們?nèi)缦露x

  • x(t)為純凈的語音信號
  • n(t)為噪聲信號
  • y(t)為加噪后的語音信號

則有

y(t) = x(t) + n(t)

對加噪后的語音信號做傅里葉變換可得

Y(\omega) = X(\omega) + N(\omega)

可得加噪后的能量譜如下

|Y(\omega)|^2 = |X(\omega)|^2 + |N(\omega)|^2 +X^*(\omega)N(\omega) + N^*(\omega)X(\omega)

又因?yàn)樵肼暸c純凈的語音信號不相關(guān),則

|Y(\omega)|^2 = |X(\omega)|^2 + |N(\omega)|^2

|X(\omega)|^2 = |Y(\omega)|^2 - |N(\omega)|^2

亦由于語音信號的質(zhì)量與其頻率幅度譜密切相關(guān),而與頻率相位圖并無太大關(guān)聯(lián)。則,我們可以保留加噪后的語音信號的頻率相位譜,并且估計(jì)出噪聲的能量譜,就通過以上式子進(jìn)行語音增強(qiáng)

3 論文復(fù)現(xiàn)

我們復(fù)現(xiàn)了M.Berouti等人的Enhancement of speech corrupted by acoustic noise中提出的一種改進(jìn)版本的譜減法,并使用了Dong Wang等人發(fā)布的開源語言數(shù)據(jù)集THCHS-30

3.1 音頻波形展示

時域信號幅度圖
語譜圖

3.2 代碼

3.2.1 譜減法

function output = spectral_subtraction(input, wlen, inc, nlen, a, b)
%------------------------------------
%  input : input signal
%  wlen  : the size of each frame
%  inc   : the size of frame shift
%  nlen  : the size of noisy without speech
%  output: output signal
%------------------------------------
window_function = hamming(wlen);                       % set window function

y = enframe(input, window_function, inc)';             % subframe: y is a matrix with wlen×frame_n
frames_n = size(y, 2);                                 % the number of frames

y_fft = fft(y);                                        % fft
y_fft_amplitude = abs(y_fft);                          % amplitude
y_fft_energy = y_fft_amplitude.^2;                     % energy
y_fft_phase = angle(y_fft);                            % phase

noisy_energy = mean(y_fft_energy(:,1:nlen), 2);        % noisy energy is a vector with wlen×1

output_energy = ones(wlen, frames_n);
for ii = 1:frames_n
    for jj = 1:wlen
        if y_fft_energy(jj, ii) > a*noisy_energy(jj)
            output_energy(jj, ii) = y_fft_energy(jj, ii) - a*noisy_energy(jj);
        else
            output_energy(jj, ii) = b*y_fft_energy(jj, ii);
        end        
    end
end
output_amplitude = sqrt(output_energy);                % output amplitude

output = OverlapAdd2(output_amplitude, y_fft_phase, wlen, inc);

end
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容