误差信号为,由此得到自适应横向滤波器按最小平方准则设计的代价函数:
NNJ(n)??e(i)???d(i)?y(i)? ②
22i?1i?1将①代入式②中,展开得:
?N?J(n)??d(i)?2?wk(n)??d(i)x(i?k?1)?n?1m?1?i?1?2NM??k?1M?w(n)wkm?1Mm(n)?x(i?k?1)x(i?m?1)i?1N
式中,M≤N。
简短的表示滤波器的代价函数,将上式有关项定义为以下参数:
(1)确定性相关函数表示输入信号在抽头k与抽头m之间两信号的相关性,
?(N,k,m)??x(i?k)x(i?m);i?1Nk,m?0,1,?,M?1.
(2)确定性互相关函数表示期望响应与在抽头k输入型号之间的互相关性:
?(N,k)??d(i)x(i?k);i?1Nk?0,1,?,M?1.
(3)期望响应序列的能量为:
将上述定义的三个参数代入式③中,得:
J(n)?Ed(n)?2?wk(n)?(N;k?1)???wk(n)wm(n)?(N;k?1,m?1) ④
k?1k?1m?1MMM为了估算滤波器的最佳滤波系数,把式④对滤波系数(权系数)微分一次,并令其导数等于0:
M?J(n)??2?(N;k?1)?2?wm(n)?(N;k?1,m?1)?0;?wk(n)m?1k?1,2,?,M. ⑤
得:
?wm?1Mm(n)?(N;k?1,m?1)??(N;k?1);k?1,2,?,M. ⑥
这是最小二乘法自适应滤波的正则方程。 RLS递推计算公式为:
?(n)?w?(n?1)?K(n)[d(n)?xT(n)w?(n?1)]?w?(n?1)?K(n)?(n) w
式中为增益矢量,它等于相关矩阵的逆矩阵与延迟线抽头输入阵的乘积。是真正的估计误差,它等于:
自适应递归最小二乘算法的信号流程图如图3:
图3-2 RLS算法信号流程图
RLS算法的计算步序如图4:
图3-3 RLS算法步序
3.2 RLS算法程序程序设计
在理解RLS算法的基本原理后,我决定自行编写RLS算法程序块,RLS算法可以理解为将输出反馈给滤波器来调整相关参数,达到校正误差的目的。算法实现模块代码如下所示:
Worder=32; %滤波器阶数 lambda=1 ; % 设置遗忘因子 Delta=0.001 ;
p=(1Delta) * eye ( Worder,Worder ) ;
w=zeros(Worder,1);
output=primary; %主语音输出 loopsize=max(size(primary));
for i=1+Worder:loopsize %写RLS算法公式 z=primary(i)-w'*(fref(i-Worder+1:i))'; n2=fref(i-Worder+1:i)'; k=(1lambda)*p*n2; K=k(1+n2'*k); w = w + K*z; p0=K*n2'; p= (p-p0*p)lambda; output(i-Worder)=z; disp(i); end;
4 RLS算法滤波方案实现
4.1信号的获取
本次课程设计对我们自行处理和灵活运用的能力提出了很高的要求。首先,设计中未要求所需要用到的语音信号;其次,录制噪声和被噪声污染的语音信号也是一个的问题。
经过考虑,原始音频信号选择从网上下载的一段WAV格式的5秒铃声,然后用randn(length(source),1)函数输出作为噪声,记做RLSrefns.wav。将这两段语音信号叠加并保存下来记做RLSprimsp.wav。
4.2读取语音文件
主麦克风录制的语音信号是RLSprimsp.wav,参考麦克风录制的参考噪声是RLSrefns.wav,都是.wav格式,用waveread指令读取音频信号;
指令写为如下:
primary = wavread('RLSprimsp.wav');
primary = primary';
ref = wavread('RLSrefns.wav'); fref = fref';
4.3RLS算法实现
RLS算法的收敛特性较LMS算法优越,但相应的复杂度也要高许多,考虑到收敛时间的影响,从起始时间到收敛时间经滤波器处理得到到输出误差依然很大,故直接将前32项去掉,先通过两输入作差得到预期值,再将所有预期值与对应时刻的实际输出值作差求平方,将这些平方值相加可以得到一个变量为W的函数,取W是函数的值最小。另外,显然距离n最近的量与Y(n)最接近,引入遗忘因子使得从n-1到0,相关程度逐渐减小。最后求得相关偏差,反馈给滤波器以矫正输出,达到减小误差的目的。
% 初始化
Worder=32; %滤波器阶数 Delta=0.001 ; p=(1Delta) * eye ( Worder,Worder ) ; w=zeros(Worder,1);
output=primary; %主语音输出 loopsize=max(size(primary));
for i=1+Worder:loopsize %写RLS算法公式 z=primary(i)-w'*(fref(i-Worder+1:i))'; n2=fref(i-Worder+1:i)'; k=p*n2; K=k(1+n2'*k); w = w + K*z; p0=K*n2'; p = (p-p0*p); output(i-Worder)=z; end;
4.4提取语音信号
用MATLAB中的wavread指令分别读取被噪声污染后的语音文件RLSprimsp.wav和噪声文件RLSrefns.wav后,进行RLS算法处理,滤除噪声后,得到语音文件,先由plot指令绘出语音文件波形,再用Y=fft()函数求出频谱,
由plot指令绘出语音文件频谱图,然后通过MATLAB中的sound命令播放语音文件。代码如下所示:
%************************************************************************
figure; %作图
%************************************************************************ subplot(2,4,1);
plot(source); %画出原始语音波形 title('原始语音波形');
[y1,Fs1,bits1]=wavread('hen.wav'); Y1=fft(y1,4096); subplot(2,4,5);
plot(abs(Y1)); %画出原始语音频谱 title('原始语音频谱');
%************************************************************************ subplot(2,4,2);
plot(primary); %画出麦克风主语音波形 title('麦克风主语音波形');
[y2,Fs2,bits2]=wavread('RLSprimsp.wav'); Y2=fft(y2,4096); subplot(2,4,6);
plot(abs(Y2)); %画出麦克风主语音频谱 title('麦克风主语音输入频谱');
%************************************************************************ subplot(2,4,3);
plot(fref); %画出噪声语音波形 title('噪声语音波形');
[y3,Fs3,bits3]=wavread('RLSrefns.wav'); Y3=fft(y3,4096); subplot(2,4,7);
plot(abs(Y3)); %画出噪声语音频谱 title('噪声输入频谱');