使用LMS算法對進行信号分離
clear
close all
clc
a1=-1.6;
a2=0.8;
[x,fs1]=audioread('handel.wav');
[dn,fs2]=audioread('handel_echo.wav');
figure;
subplot(2,1,1);
plot(x);
title('spk參考信号');
subplot(2,1,2);
plot(dn);
title('MICin-期望信号');
n=max(size(x)); % 信号中的時間點個數
P=5; % LMS算法重複運算5次,用于評估五次運算産生的誤差的平均水準
e=zeros(1,n); % 用于存放誤差
ep=zeros(1,n); % 用于存放五次運算累積的誤差
ee=zeros(1,n); % 用于存放平方差
%算法
h=waitbar(0,'計算進度');
steps = P;
for p=1:P
L=100; % 濾波器階數,考慮到兩個信号之間沒有延時,且這裡隻是用來分離出輸入的x信号,而且誤差不做要求,是以不需要設定太高的階數
u=0.0022; % 增益常數
wL=zeros(L,n); % 産生一個權向量矩陣
% 計算的時候需要注意兩個音頻序列的長度是否比對,否則會出現index越界,矩陣大小不比對等問題。
for i=(L+1):n % 計算權向量矩陣中第三組權向量到最後一組權向量相關的變量,根據x和e=x-y求下一個y,沒有d(n)
X=x(i-L:1:(i-1)); % 更新濾波器的參考矢量X(n)
y(i)=X'*wL(:,i); % 根據x計算i時刻輸出信号
e(i)=dn(i)-y(i); % 計算i時刻誤差信号
wL(:,(i+1))=wL(:,i)+2*u*e(i)*X; % 更新i時刻濾波器的權向量
ee(i)=e(i)^2; % 更新平方差
end
ep=ep+ee; % 平方差累積
waitbar(p/steps);
end
close(h);
eq=ep/P; % 五十次重複計算平方差求均值
a1L=-wL(2,1:n); % a1在LMS算法下值的變化,wL矩陣中第一行的1到n個數,權向量矩陣第一行
a2L=-wL(1,1:n); % a2在LMS算法下值的變化 ,wL矩陣中第二行的1到n個數,權向量矩陣第二行
%畫圖
figure;
subplot(3,2,1);
plot(x);
title('需要采集的聲音Voice'); % 根據w産生的随機信号x
subplot(3,2,2);
plot(dn);
title('被回聲污染的了Voice,就是MICin'); % 五十次運算誤差求均值
subplot(3,2,3);
plot(y);
title('合成回聲信号'); % 根據w産生的随機信号x
subplot(3,2,4);
plot(e);
title('誤差'); % 五十次運算誤差求均值
subplot(3,2,5);
plot(a1L,'r-'); % 權向量矩陣第一行
hold on;
plot(a2L,'k-'); % 權向量矩陣第二行
title('權向量參數的學習過程');
legend('a1L','a2L');
運作後效果