本文簡要探討了語音信號的基本特性砰粹,并介紹了譜減法的基本原理孵稽,同時基于Matlab實現(xiàn)了原始譜減法及其一種改進版政模。最后給出音頻波形呐粘、頻譜满俗,從主觀的人耳和客觀的評判標(biāo)準(zhǔn)來量化所達到的效果。
1 語音信號
1.1 宏觀的非平穩(wěn)性與微觀的平穩(wěn)性
在現(xiàn)實世界中作岖,我們獲得的所有信號波形都是其對應(yīng)分布的一組觀測值唆垃。平穩(wěn)信號指的是其分布及分布的參數(shù)不會發(fā)生變化,非平穩(wěn)信號則是其分布或分布的參數(shù)發(fā)生變化痘儡。對于語音信號來說辕万,由于信號直接由說話者控制,其分布和分布的參數(shù)都是不確定的沉删。以一個宏觀的角度來看渐尿,語音信號具有非平穩(wěn)性。而在-這個尺度矾瑰,受人的發(fā)聲器官所限定砖茸,語音信號是平穩(wěn)的,即在微觀下殴穴,語音信號具有平穩(wěn)性凉夯。正是這種特性,導(dǎo)致了在語音信號處理過程中采幌,短時分析成為一個重要的手段劲够。
2 基本譜減法的原理
對噪聲的基本假設(shè)
- 噪聲是局部穩(wěn)定的,即與語音信號一致休傍,在微觀尺度下具有平穩(wěn)性征绎。
- 噪聲是加性噪聲
- 噪聲與純凈的語音信號是不相關(guān)的
基于以上的假設(shè),我們?nèi)缦露x
- 為純凈的語音信號
- 為噪聲信號
- 為加噪后的語音信號
則有
對加噪后的語音信號做傅里葉變換可得
可得加噪后的能量譜如下
又因為噪聲與純凈的語音信號不相關(guān)尊残,則
即
亦由于語音信號的質(zhì)量與其頻率幅度譜密切相關(guān)炒瘸,而與頻率相位圖并無太大關(guān)聯(lián)。則寝衫,我們可以保留加噪后的語音信號的頻率相位譜顷扩,并且估計出噪聲的能量譜,就通過以上式子進行語音增強
3 論文復(fù)現(xiàn)
我們復(fù)現(xiàn)了M.Berouti等人的Enhancement of speech corrupted by acoustic noise中提出的一種改進版本的譜減法慰毅,并使用了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