FXLMS主动降噪的simulink建模与仿真

**
**

FXLMS主动降噪的Simulink建模与仿真

**
**

最近在研究关于主动降噪的课题,在摸索学习的过程中,分享一些初步学到的知识。

**FXLMS算法是基于LMS算法在次级通道补偿方向上做出的改进算法,我在simulink中对其进行了建模与仿真,希望对一起学习的小伙伴有所帮助。
**
以下是我的仿真图:
FXLMS算法仿真图
其中用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,所以在降噪的初始阶段,会呈现不稳定状态,加入延迟模块最初是为了消除代数环,可对初始的误差状态并未起改善作用,希望有人能提出中肯的指点与建议,第一次发文,不妥之处请见谅,谢谢。

猜你喜欢

转载自blog.csdn.net/qq_33618544/article/details/100566328