我最近在学习自适应滤波器,lms算法matlab有自带的adaptfilt.lms,我现在准备进一步学习lms算法的频域实现办法,自己查看了一些资料,综合后自己编写了程序如下:
function [h,y,e]=flms(x,d,u,N)
%FLMS算法
% 输入参数:
% x 输入的信号序列 (行向量)
% d 所期望的响应序列 (行向量)
% N 滤波器的阶数 (标量)
% u 收敛因子(步长) (标量) 要求大于0,小于xn的相关矩阵最大特征值的倒数
% 输出参数:
% h为估计的FIR滤波器
% e 误差序列(itr x 1) (行向量)
% y 实际输出序列 (行向量)
% 初始化参数
M=length(x);
y=zeros(1,M);
h=zeros(1,N);
e=zeros(1,M);
% 迭代计算
for i= 1:fix(M/N)-1 % 第k次迭代
X = fft(x((i-1)*N+1:(i+1)*N)); % 滤波器M个抽头的输入
H=fft([h,zeros(1,N)]);
o1=real(ifft(X.*H));
y(i*N+1:(i+1)*N)=o1(N+1:(2*N));
e(i*N+1:(i+1)*N)=d(i*N+1:(i+1)*N)-y(i*N+1:(i+1)*N);
E=fft([zeros(1,N),e(i*N+1:(i+1)*N)]);
o2=real(ifft(E.*conj(X)));
v=o2(1:N);
h=h+2*u*v;
end
以上是定义的flms.m
然后
close all;
clear all;
%读入信号
[xin,fs,bits]=wavread('e:\12.wav');%这里根据你自己的音频而定
xs=xin(:,1); %因为采集进来时是双声道的列向量
%sound(xs,fs,bits);
%产生噪音信号
[A,B] = size(xs);
randn('state',sum(A*clock));
xno=0.005*randn(A,1); %系数可以在0.01左右调整
xno = xs+xno;
%sound(xno,fs,bits); %播放加噪声后语音
wavwrite(xno,fs,'e:\befor_lms.wav');
wav_l=length(xno);
yo=zeros(A,1);
frame_l=512; %根据fs选择帧长,??????????
step_l=floor(0.5*frame_l); %设置帧移
num_frame=floor((wav_l-frame_l)/step_l)+1; %确定帧数
for i=1:num_frame
n1=(i-1)*step_l+1;
n2=(i-1)*step_l+frame_l;
zy(i,:)=xno(n1:n2,1).'; %存储每一帧噪音(行向量) %win_ham、yt是列向量,需转置
yy(i,:)=xs(n1:n2,1).'; %存储每一帧纯净语音
x = zy(i,:); % 输入信号序列
d = yy(i,:); % 预期结果序列
[h,y,e]=flms1(x,d,0.0006,128);
yo(n1:n2,1)=y.';
end
wavwrite(yo,fs,'e:\after_lms.wav');
结果输出是这样的
2014-3-27 14:18 上传