1 简介
基于维纳滤波、卡尔曼滤波、谱减法实现语音去噪处理。
2 部分代码
function [wiener_enspeech] = wienerfilter(testsignal)
%维纳滤波器函数
testsignal=testsignal';
frame_len=256; %帧长
step_len=0.5*frame_len; %分帧时的步长,相当于重叠50%
wav_length=length(testsignal);
R = step_len;
L = frame_len;
f = (wav_length-mod(wav_length,frame_len))/frame_len;
k = 2*f-1; % 帧数
h = sqrt(1/101.3434)*hamming(256)'; % 汉宁窗乘以系数的原因是使其复合条件要求;
% testsignal = testsignal(1:f*L); % 带噪语音与纯净语音长度对齐
% signal= signal(1:f*L);
win = zeros(1,f*L); % 设定初始值;
wiener_enspeech = zeros(1,f*L);
%-------------------------------分帧-------------------------------------
for r = 1:k
y = testsignal(1+(r-1)*R:L+(r-1)*R); % 对带噪语音帧间重叠一半取值;
y = y.*h; % 对取得的每一帧都加窗处理;
w = fft(y); % 对每一帧都作傅里叶变换;
Y(1+(r-1)*L:r*L) = w(1:L); % 把傅里叶变换值放在Y中;
end
%-------------------------------估计噪声-----------------------------------
NOISE= stationary_noise_evaluate(Y,L,k); %噪声最小值跟踪算法
% 每帧中的傅里叶变换和噪声估计均如上所示
%-------------------------------winner-------------------------------------
for t = 1:k
X = abs(Y).^2;
S=max((X(1+(t-1)*L:t*L)-NOISE(1+(t-1)*L:t*L)),0);
G_k=(X(1+(t-1)*L:t*L)-NOISE(1+(t-1)*L:t*L))./X(1+(t-1)*L:t*L);
S = sqrt(S);
A1=G_k.*S;
A = Y(1+(t-1)*L:t*L)./abs(Y(1+(t-1)*L:t*L)); % 带噪于语音的相位;
S = A1.*A; % 因为人耳对相位的感觉不明显,所以恢复时用的是带噪语音的相位信息;
s = ifft(S);
s = real(s); % 取实部;
wiener_enspeech(1+(t-1)*L/2:L+(t-1)*L/2) = wiener_enspeech(1+(t-1)*L/2:L+(t-1)*L/2)+s; % 在实域叠接相加;
win(1+(t-1)*L/2:L+(t-1)*L/2) = win(1+(t-1)*L/2:L+(t-1)*L/2)+h; % 窗的叠接相加;
end
wiener_enspeech = wiener_enspeech./win; % 去除加窗引起的增益得到增强的语音;
wiener_enspeech=wiener_enspeech';
end
- 1.
- 2.
- 3.
- 4.
- 5.
- 6.
- 7.
- 8.
- 9.
- 10.
- 11.
- 12.
- 13.
- 14.
- 15.
- 16.
- 17.
- 18.
- 19.
- 20.
- 21.
- 22.
- 23.
- 24.
- 25.
- 26.
- 27.
- 28.
- 29.
- 30.
- 31.
- 32.
- 33.
- 34.
- 35.
- 36.
- 37.
- 38.
- 39.
- 40.
- 41.
- 42.
3 仿真结果
4 参考文献
[1]郑永敏, 鲍鸿, & 张晶. (2017). 基于维纳–小波分析的语音去噪新方法. 广东工业大学学报, 34(5), 4.
[2]何志勇, 朱忠奎. 脉冲噪声环境下基于卡尔曼滤波的语音增强[J]. 计算机应用, 2011, 31(12):5.