**
**
FXLMS主动降噪的Simulink建模与仿真
**
**
最近在研究关于主动降噪的课题,在摸索学习的过程中,分享一些初步学到的知识。
**FXLMS算法是基于LMS算法在次级通道补偿方向上做出的改进算法,我在simulink中对其进行了建模与仿真,希望对一起学习的小伙伴有所帮助。
**
以下是我的仿真图:
其中用2个频率分别为80HZ和110HZ的正弦信号叠加模拟噪音信号,初级通道传递函数为假定值,用滤波器函数来代替。
次级通道传递函数也是用滤波器来假定的值。
而次级通道传递函数估计是对次级通道的估计,实际情况下可以由在线辨识或离线辨识得到,在这里我假定理想状态次级通道估计和次级通道相同。
FXLMS fliter 是用S函数块编写的自适应滤波器,其中有三个输入,两个输出。
输入1:初始噪音信号
输入2:经过次级通道传递函数估计补偿的噪音信号
输入3:噪音抵消后的误差信号,理想状态为0
输出1:经过LMS算法计算权重后的自适应滤波器输出,用来抵消噪音
输出2:LMS算法计算的权重
function test(block)
setup(block);
%endfunction
function setup(block)
%% Register dialog parameter: LMS step size
block.NumDialogPrms = 1;
block.DialogPrmsTunable = {'Tunable'};
% block.DialogPrm(1).Name = 'StepSize';
% block.DialogPrm(1).DataTypeId = 0;
%% Regieste number of input and output ports
block.NumInputPorts = 3;
block.NumOutputPorts = 2;
%% Setup functional port properties to dynamically
%% inherited.
block.SetPreCompInpPortInfoToDynamic;
block.SetPreCompOutPortInfoToDynamic;
block.InputPort(1).Complexity = 'Real';
block.InputPort(1).DataTypeId = 0;
block.InputPort(1).SamplingMode = 'Sample';
block.InputPort(1).Dimensions = 1;
block.InputPort(2).Complexity = 'Real';
block.InputPort(2).DataTypeId = 0;
block.InputPort(2).SamplingMode = 'Sample';
block.InputPort(2).Dimensions = 1;
block.InputPort(3).Complexity = 'Real';
block.InputPort(3).DataTypeId = 0;
block.InputPort(3).SamplingMode = 'Sample';
block.InputPort(3).Dimensions = 1;
block.OutputPort(1).Complexity = 'Real';
block.OutputPort(1).DataTypeId = 0;
block.OutputPort(1).SamplingMode = 'Sample';
block.OutputPort(1).Dimensions = 1;
block.OutputPort(2).Complexity = 'Real';
block.OutputPort(2).DataTypeId = 0;
block.OutputPort(2).SamplingMode = 'Sample';
block.OutputPort(2).Dimensions = 1;
%% Set the block simStateCompliance to default (i.e., same as a built-in block)
block.SimStateCompliance = 'DefaultSimState';
%% Register methods
block.RegBlockMethod('CheckParameters', @CheckPrms);
block.RegBlockMethod('ProcessParameters', @ProcessPrms);
block.RegBlockMethod('PostPropagationSetup', @DoPostPropSetup);
block.RegBlockMethod('Start', @Start);
block.RegBlockMethod('WriteRTW', @WriteRTW);
block.RegBlockMethod('Outputs', @Outputs);
%% Block runs on TLC in accelerator mode.
block.SetAccelRunOnTLC(true);
%endfunction
function CheckPrms(block)
mu = block.DialogPrm(1).Data;
if mu <= 0 || mu > 1
error(message('simdemos:adapt_lms:stepSize'));
end
%endfunction
function DoPostPropSetup(block)
%% Setup Dwork
N = 32; %% Filter length
block.NumDworks = 3;
block.Dwork(1).Name = 'X'; %% u[n],...,u[n-31]
block.Dwork(1).Dimensions = N;
block.Dwork(1).DatatypeID = 0;
block.Dwork(1).Complexity = 'Real';
block.Dwork(1).UsedAsDiscState = true;
block.Dwork(2).Name = 'H'; %% Filter coefficients
block.Dwork(2).Dimensions = N;
block.Dwork(2).DatatypeID = 0;
block.Dwork(2).Complexity = 'Real';
block.Dwork(2).UsedAsDiscState = true;
block.Dwork(3).Name = 'l'; %% Filter coefficients
block.Dwork(3).Dimensions = N;
block.Dwork(3).DatatypeID = 0;
block.Dwork(3).Complexity = 'Real';
block.Dwork(3).UsedAsDiscState = true;
%% Register all tunable parameters as runtime parameters.
block.AutoRegRuntimePrms;
%endfunction
function ProcessPrms(block)
block.AutoUpdateRuntimePrms;
%endfunction
function Start(block)
%% Initialize Dwork
block.Dwork(1).Data = zeros(1, 32);
block.Dwork(2).Data = zeros(1, 32);
block.Dwork(3).Data = zeros(1, 32);
%endfunction
function Outputs(block)
mu = block.RuntimePrm(1).Data;
N = 32;
u = block.InputPort(1).Data;
e = block.InputPort(3).Data;
r = block.InputPort(2).Data;
X = block.Dwork(1).Data;
H = block.Dwork(2).Data;
l = block.Dwork(3).Data;
%%
%% H^(n+1)[i] = H^(n)[i]+mu*(d(n)-y(n))*u(n-i)
%%
X(2:N) = X(1:N-1);
X(1) = u;
l(2:N) = l(1:N-1);
l(1) = r;
y = X'*H;
H = H+mu*e*l;
block.Dwork(1).Data = X;
block.Dwork(2).Data = H;
block.Dwork(3).Data = l;
block.OutputPort(1).Data = y;
block.OutputPort(2).Data = norm(H);
运行结果:
蓝色为噪音信号,黄色为降噪后信号,可以看到明显的降噪效果。
图为LMS算法计算的权重
同时面临这一个问题,在负反馈时,ERRO误差信号在初始阶段为0,所以在降噪的初始阶段,会呈现不稳定状态,加入延迟模块最初是为了消除代数环,可对初始的误差状态并未起改善作用,希望有人能提出中肯的指点与建议,第一次发文,不妥之处请见谅,谢谢。