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)'; % 汉宁窗乘以系数的原因是使其复合条件要求; 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
时间: 2023-08-25 09:14:42 浏览: 51
这个函数实现的是维纳滤波的语音降噪。输入是一个测试信号,输出是一个降噪后的语音信号。函数中也使用了一些参数定义,如帧长、步长、汉宁窗等。函数首先对输入信号进行分帧处理,然后估计噪声功率谱。接下来,对每一帧进行维纳滤波处理,得到降噪后的语音信号。最后,函数对每一帧处理得到的降噪语音信号进行叠接相加,得到最终的降噪语音信号。与谱减法不同的是,维纳滤波使用带噪语音的功率谱和噪声功率谱的比值作为滤波器的增益函数,从而对每一帧进行滤波处理。
相关问题
% 读入语音 [Input, Fs] = audioread('sp01.wav'); Time = (0:1/Fs:(length(Input)-1)/Fs)'; Input = Input(:,1); SNR=10; [NoisyInput,Noise] = add_noise(Input,SNR);%加噪 %% 算法 [spectruesub_enspeech] = spectruesub(NoisyInput); [wiener_enspeech] = wienerfilter(NoisyInput); [Klaman_Output] = kalman(NoisyInput,Fs,Noise); %将长度对齐 sig_len=length(spectruesub_enspeech); NoisyInput=NoisyInput(1:sig_len); Input=Input(1:sig_len); wiener_enspeech=wiener_enspeech(1:sig_len); Klaman_Output=Klaman_Output(1:sig_len); Time = (0:1/Fs:(sig_len-1)/Fs)';
这段代码中,你读入了一个名为"sp01.wav"的语音文件,并将其存储在Input中。接着,你使用add_noise函数为其添加了一定的噪声,并将处理后的语音信号存储在NoisyInput中。
然后,你使用了三种语音增强算法:spectruesub、wienerfilter和kalman。这些算法通过对NoisyInput进行处理,试图去除噪声并还原原始语音信号。处理后的信号分别存储在spectruesub_enspeech、wiener_enspeech和Klaman_Output中。
最后,你将处理后的信号长度对齐,并存储在相应的变量中。Time变量是一个时间轴,用于可视化和分析处理后的语音信号。
错误使用 plot 矢量长度必须相同。 出错 audio_gui>pushbutton2_Callback (line 164) plot(Time, wiener_enspeech);
这个错误通常是由于矢量长度不同导致的。在你的代码中,可能存在一些变量的长度与预期不符,导致在调用 `plot` 函数时出现了这个错误。建议你检查一下代码中与 `Time` 或 `wiener_enspeech` 相关的变量,看看它们的长度是否正确。另外,你也可以在调用 `plot` 函数之前,先打印一下 `Time` 和 `wiener_enspeech` 变量的长度,以便更好地定位问题。