主要内容

过滤音频信号使用马铃薯代码

学习目标

在本教程中,您将学习如何:

  • 使用MATLAB函数块添加matlab®函数来模拟万博1manbetx®用于建模、模拟和部署到嵌入式处理器的模型。

    这种能力对于用MATLAB的文本语言编写算法比用Simulink的图形语言编写算法更有用。万博1manbetx

  • 使用coder.extrinsic调用MATLAB代码MATLAB函数堵塞。

    此功能允许您从Simulink调用现有的Matlab代码,而无需使该代码适用于代码生成,允许快速原型化。万博1manbetx

  • 检查现有的MATLAB代码是否适合代码生成。

  • 将MATLAB算法从批处理转换为流传输。

  • 使用适合代码生成的代码中的持久变量。

    您需要使筛选权重保持不变,以便筛选算法不会在每次运行时重置它们的值。

教程的先决条件

你需要知道的

要完成本教程,您应该基本熟悉MATLAB软件。您还应该了解如何创建基本的Simulink模型以及如何模拟该模型。万博1manbetx有关更多信息,请参见创建一个简单的模型

所需的产品s manbetx 845

要完成本教程,您必须安装以下产品:s manbetx 845

  • 马铃薯

  • Matlab Coder™

  • 万博1manbetx

  • 万博1manbetxSimulink编码器

  • DSP System Toolbox™

  • C编译器

    有关受支持的编译器列表,请参万博1manbetx见万博1manbetx支持编译器

有关安装MathWorks的说明®s manbetx 845产品,请参阅安装文档。如果已安装MATLAB并希望检查安装了哪些其他MATHWORKS产品,请输入s manbetx 845版本在matlab命令窗口中。有关安装和设置C编译器的说明,请参阅设置C或c++编译器(MATLAB编码器)

示例:LMS滤波器

描述

最小均方滤波器是一种根据优化算法调整传递函数的自适应滤波器。您可以向滤波器提供所需信号的示例和输入信号。然后,滤波器计算滤波器权重,或系数,产生输出信号和期望信号之间误差的最小均方。

此示例使用LMS滤波器删除乐谱中的噪声。有两个输入。第一个输入是扭曲的信号:音乐录制加上过滤噪声。第二输入是所需的信号:未过滤的噪声。过滤器可用于消除输出信号和所需信号之间的差异,并输出差异,在这种情况下,该差异是清洁音乐录制。当您开始模拟时,您可以听到噪音和音乐。随着时间的推移,自适应过滤器消除了噪音,以便您只听音乐。

算法

本例使用最小均方(LMS)算法去除输入信号中的噪声。LMS算法计算滤波输出、滤波误差和给定的失真和期望信号的滤波权值。

在教程开始时,LMS算法使用批处理来过滤音频输入。该算法适用于MATLAB,您可能会在整个信号中加载并一次处理它。但是,批处理不适合实时处理信号。在完成教程时,您可以优化滤波器的设计,以将算法转换为基于流的流的流。

算法的基线函数签名是:

Function [signal_out, err, weights] =…lms_01 (signal_in所需)

过滤在以下循环中执行:

使用卷积计算输出样本:signal_out(n,ch) = weights' * signal_in(n:n+FilterLength-1,ch);%更新滤波系数:err(n,ch) = desired(n,ch) - signal_out(n,ch);weights = weights + mu*err(n,ch)*signal_in(n:n+FilterLength-1,ch);结尾
在哪里SignalLength为输入信号的长度,FilterLength是过滤器的长度,和μ是适应步骤尺寸。

什么是适应步骤尺寸?

过滤过程

过滤过程有三个阶段:

  • 卷积

    滤波器的卷积执行如下:

    n:n+FilterLength-1,ch);

    卷积是什么?

  • 计算的错误

    误差是所需信号和输出信号之间的差异:

    err(n,ch)=期望(n,ch) -  signal_out(n,ch);

  • 适应

    滤波器权值的新值是滤波器权值的旧值加上一个基于误差信号、畸变信号和自适应步长的校正因子:

    权重=权重+ mu * err(n,ch)* signal_in(n:n + filterlength-1,ch);

参考

Haykin,Simon。自适应滤波器理论.上部马鞍河,NJ:Prentice-Hall,Inc。,1996年。

本教程的文件

关于教程文件

本教程使用以下文件:

  • 万博1manbetxSimulink模型文件为教程的每个步骤。

  • MATLAB代码文件为每个步骤的示例。

    在本教程中,您将使用Simulink模型,这些模型调用包含简单最小均方(LMS)万博1manbetx滤波算法的MATLAB文件。

文件的位置

以下文件夹中提供了教程文件:docroot \工具箱\仿真软万博1manbetx件\ \ lms例子.要运行本教程,必须将这些文件复制到本地文件夹。说明,请参阅在本地复制文件

文件的姓名和描述

类型 名称 描述
MATLAB文件 lms_01 基线MATLAB批量过滤器的实施。不适合代码生成。
lms_02 从批处理修改到流式筛选。
lms_03 基于帧的流过滤器与重置和适应控制。
lms_04 基于帧的流过滤器与重置和适应控制。适合代码生成。
lms_05 禁用代码生成的内联。
lms_06 证明使用编码器.NULLCOPY.
万博1manbetxSimulink模型文件 acoustic_environment 万博1manbetx提供了声学环境概述的Simulink模型。
kide_cancel_00. 万博1manbetxSimulink模型没有aMATLAB函数堵塞。
koteg_cancel_01. 完整的kide_cancel_00.模型包括MATLAB函数堵塞。
kide_cancel_02 万博1manbetx用于使用的Simulink模型lms_02.m
kide_cancel_03. 万博1manbetx用于使用的Simulink模型LMS_03.M.
kide_cancel_04. 万博1manbetx用于使用的Simulink模型LMS_04.M.
kide_cancel_05. 万博1manbetx用于使用的Simulink模型lms_05.m
koteg_cancel_06. 万博1manbetx用于使用的Simulink模型lms_06.m
design_templates. 万博1manbetxSimulink模型包含自适应和复位控制。

教程步骤

在本地复制文件

复制教程文件到本地文件夹:

  1. 创建一个本地万博 尤文图斯例如,文件夹,C:\ Test \ L万博 尤文图斯MS \ Solutions

  2. 改变docroot \工具箱\仿真软万博1manbetx件\例子文件夹中。在MATLAB命令行,输入:

    CD(FullFile(Docroot,'工具箱','simuli万博1manbetxnk','示例'))

  3. 复制的内容LMS.子文件夹给你万博 尤文图斯文件夹的完整路径名万博 尤文图斯文件夹:

    COPYFILE('LMS','万博 尤文图斯')
    您的万博 尤文图斯文件夹中现在包含了本教程的完整解决方案集。万博 尤文图斯如果不想为每个任务执行步骤,可以查看提供的解决方案,以了解代码的外观。

  4. 创建一个本地工作例如,文件夹,c: \ \ lms \测试工作

  5. 从您的文件中复制以下文件万博 尤文图斯文件夹给你工作文件夹中。

    • lms_01

    • lms_02

    • kide_cancel_00.

    • acoustic_environment

    • design_templates.

    您的工作文件夹现在包含了开始时需要的所有文件。

    现在可以设置C编译器了。

设置C编译器

建立你的MATLAB函数块需要一个受支持的编译器。万博1manbetxMATLAB自动选择一个作为默认编译器。如果您的系统上安装了多个支持matlab的编译器,您可以万博1manbetx使用墨西哥人设置命令。看到改变默认的编译器以及万博1manbetx支持编译器

运行Acoustic_Environment模型

跑过acoustic_environment模型,以理解您试图使用LMS过滤器解决的问题。该模型将限带白噪声添加到音频信号中,并将结果信号输出到扬声器。

为了模拟该模型:

  1. 打开acoustic_environmentSimulink模万博1manbetx型:

    1. 将MATLAB当前文件夹设置为包含本教程的工作文件的文件夹。在MATLAB命令行,输入:

      光盘工作
      在哪里工作包含文件的文件夹的完整路径名。看到查找文件和文件夹了解更多信息。

    2. 在MATLAB命令行,输入:

      acoustic_environment

  2. 确保您的发言者正在开启。

  3. 要模拟模型,在Simulink模型窗口中单击万博1manbetx跑步

    随着S万博1manbetximulink运行模型,您可以听到噪声失真的音频信号。

  4. 在模拟运行时,双击手动开关选择音频源。

    现在你听到了想要的音频输入没有任何噪音。

本教程的目标是使用MATLAB LMS滤波算法从嘈杂的音频信号中去除噪声。通过加aMATLAB函数块调用模型,并从该块调用MATLAB代码。

添加一个MATLAB函数块到您的模型

要自己修改模型和代码,请完成本节中的练习。否则,打开提供的模型koteg_cancel_01.在你的万博 尤文图斯子文件夹以查看修改后的模型。

出于本教程的目的,您添加了MATLAB函数块的kide_cancel_00.模型提供了教程。在实践中,您必须以空Simulink模型开始开发自己的测试台。万博1manbetx

添加A.MATLAB函数块的kide_cancel_00.模型:

  1. 打开kide_cancel_00.在Si万博1manbetxmulink中。

    kide_cancel_00.

  2. 添加A.MATLAB函数块到模型:

    1. 在MATLAB命令行中,输入SllaryBrowser.打开Simulink库浏万博1manbetx览器。

    2. 从Simulink库列表中,选择万博1manbetx用户定义函数图书馆。

    3. 单击MATLAB函数阻止并将其拖到kide_cancel_00.模型。将块放在红色文本注释的上方将Matlab功能块放在此处

    4. 从模型中删除红色文本注释。

    5. 将模型保存在当前文件夹中koteg_cancel_01.

      最佳实践 - 保存增量代码更新

打电话给你的马铃薯代码作为快速原型设计的外在功能

在本部分教程中,您将使用coder.extrinsic从中调用matlab代码的功能MATLAB函数快速原型块。

为什么叫马铃薯代码作为外部函数?调用MATLAB代码作为一个外部函数提供了以下好处:

  • 对于快速原型设计,您不必制作适合代码生成的MATLAB代码。

  • 使用coder.extrinsic使您能够在MATLAB中调试MATLAB代码。控件中可以添加一个或多个断点LMS_01.M.文件,然后在Simulink中开始模拟。万博1manbetx当Matlab执行引擎遇到断点时,它会暂时停止执行,以便您可以检查MATLAB工作区并查看内存中所有变量的当前值。有关调试MATLAB代码的更多信息,请参阅调试MATLAB程序

如何打电话马铃薯作为外部函数的代码。从。调用MATLAB代码MATLAB函数堵塞:

  1. 双击MATLAB函数块打开MATLAB功能块编辑器。

  2. 删除MATLAB函数块编辑器中显示的默认代码。

  3. 将以下代码复制到MATLAB函数堵塞。

    function [Signal_Out, Weights] = LMS(Noise_In, Signal_In) %#codegen % outside: coder.extrinsic('lms_01');%计算LMS: [~, Signal_Out, Weights] = lms_01(Noise_In, Signal_In);结尾

    为什么使用波浪号(~)运算符?

  4. 保存模型。

    lms_01函数的输入kotex_in.Signal_In现在显示为块的输入端口和功能输出signal_out.重量显示为输出端口。

连接MATLAB函数块输入和输出

  1. 连接MATLAB函数阻止输入和输出,以便您的模型如下所示。

  2. MATLAB函数块代码,通过在外部呼叫后添加以下代码来预先采用输出:

    %输出:Signal_Out = 0 (size(Signal_In));重量= 0(32岁,1);
    的大小重量设置为匹配声环境子系统中数字滤波器的数字滤波器的数量系数。

    为什么要预先分配输出?

    修改后的MATLAB功能块代码

  3. 保存模型。

    现在可以检查模型中的错误了。

模拟噪声_cancel_01模型

为了模拟该模型:

  1. 确保您可以看到时域情节。

    查看图,在koteg_cancel_01.模型中,打开分析和可视化块然后打开时域堵塞。

  2. 在Simuli万博1manbetxnk模型窗口中,单击跑步

    在Si万博1manbetxmulink运行模型时,您可以看到和听到输出。最初,你听到的音频信号被噪声扭曲了。然后过滤器逐渐减轻噪音,直到您只听到剩余噪音非常小的噪音。两秒钟后,您再次听到扭曲的嘈杂信号,过滤器再次衰减噪声。这个循环连续重复。

    MATLAB显示了下面这个循环的图。

  3. 停止仿真。

为什么滤镜每2秒重置一次?

修改过滤器以使用流式传输

什么是流媒体?重复调用流过滤器以处理输入数据的固定大小块,或框架,直到它处理了整个输入信号。帧尺寸可以像单个样本一样小,在这种情况下,滤波器将以基于样本的模式运行,或者最多几千个样本,用于基于帧的处理。

为什么使用流?。滤波器算法的设计lms_01有以下缺点:

  • 算法不有效地使用内存。

    在程序的生命周期内为每个输入信号预先分配固定数量的内存意味着分配的内存比使用的内存更多。

  • 在调用函数时,必须知道输入信号的大小。

    如果输入信号是实时到达的,或者是以样本流的形式到达的,那么在将其作为批处理传递给滤波器之前,您必须等待将整个信号积累起来。

  • 信号尺寸限于最大尺寸。

在嵌入式应用程序中,滤波器可能正在处理连续输入流。结果,输入信号可以基本上长于以批量模式工作的滤波器可以处理的最大长度。要使过滤器工作为任何信号长度,它必须实时运行。一种解决方案是将滤波器从基于批处理的处理转换为基于流的处理。

查看修改后马铃薯代码。转换为流媒体涉及:

  • 介绍一个先进的,首先(FIFO)队列

    FIFO队列充当临时存储缓冲区,其包含来自输​​入数据流的少量样本。由FIFO队列保持的样本数量必须与过滤器脉冲响应中的样本数量完全相同,因此该功能可以在滤波器系数和输入信号之间执行卷积操作。

  • 使FIFO队列和滤芯持久

    过滤器被反复调用,直到它处理完整个输入信号。因此,FIFO队列和过滤器权重需要保持不变,以便在每次后续调用该函数后,适应过程不必重新开始。

打开提供的文件lms_02.m在你的工作子文件夹以查看修改后的算法。

lms_02.m内容

过滤算法的变化摘要。注意滤波器算法的以下一个重要更改:

  • 过滤器权重和FIFO队列声明为持久的:

    持续的权重;坚持先进先出;

  • 初始化FIFO队列:

    fifo = 0 (FilterLength ChannelCount);

  • FIFO队列在过滤器更新循环中使用:

    每个通道的百分比:对于每个采样时间的Ch = 1:ChannelCount%fifo (FilterLength ch) = signal_in (n, ch);%使用卷积计算输出样本:signal_out(n,ch) = weights' * fifo(:,ch);%更新滤波系数:err(n,ch) = desired(n,ch) - signal_out(n,ch);重量=权重+ mu * err(n,ch)* fifo(:,ch);结束

  • 不能输出持久变量。因此,一个新变量,权力_out.,用于输出滤波器权重:

    函数[signal_out,err,weights_out] = ... lms_02(扭曲,需要)
    权力_out =权重;

修改模型以调用更新后的算法。要自己修改模型,请完成本节中的练习。否则,打开提供的模型kide_cancel_02在你的万博 尤文图斯子文件夹以查看修改后的模型。

  1. koteg_cancel_01.模型中,双击MATLAB函数块打开MATLAB功能块编辑器。

  2. 修改MATLAB函数拨打电话代码lms_02

    1. 修改外部呼叫。

      %外在:coder.extrinsic(“lms_02”);

    2. 修改对滤波器算法的调用。

      %计算LMS: [~, Signal_Out, Weights] = lms_02(Noise_In, Signal_In);

      修改后的MATLAB功能块代码

  3. 更改帧大小1638464.,表示更现实的值。

    1. 右键单击模型窗口中,然后选择模型属性

    2. 选择回调标签。

    3. 模型的回调列表,选择InitFcn

    4. 改变价值FrameSize64.

    5. 点击申请并关闭对话框。

  4. 将模型保存为kide_cancel_02

模拟流算法。为了模拟该模型:

  1. 确保您可以看到时域情节。

  2. 开始模拟。

    在Si万博1manbetxmulink运行模型时,您可以看到和听到输出。最初,你听到的音频信号被噪声扭曲了。然后,在最初的几秒钟里,过滤器逐渐减弱噪音,直到你只听到播放的音乐,剩下的噪音非常少。MATLAB显示了下面的图,显示了滤波器在几秒钟后收敛。

  3. 停止仿真。

滤波器算法现在适用于Simulink。万博1manbetx您已准备好详细说明您的模型适应重置控制。

添加调整和重置控件

为什么要添加适应和重置控制?在本教程的这一部分中,您可以在筛选器中添加调整和重置控件。使用这些控件,您可以打开和关闭过滤。什么时候适应启用时,过滤器不断更新过滤器权重。什么时候适应被禁用,滤波器权重留在其当前值处。如果重置已设置,过滤器重置滤波器权重。

修改你的马铃薯代码。要自己修改代码,请通过本节中的练习。否则,打开提供的文件LMS_03.M.在你的万博 尤文图斯子文件夹以查看修改后的算法。

修改过滤代码:

  1. 打开lms_02.m

  2. 设置部分,替换

    If (isempty(weights))
    If (reset || isempty(weights))

  3. 在滤波器循环中,仅在滤波器系数时更新滤波器系数适应

    If adapt weights = weights + mu*err(n,ch)*fifo(:,ch);结尾

  4. 将函数签名更改为使用适应重置输入并将函数名更改为lms_03

    函数[signal_out, err, weights_out] =…Lms_03 (signal_in, desired, reset, adapt)

  5. 将文件保存在当前文件夹为LMS_03.M.

lms_03.m内容

滤波算法的变化摘要

修改模型以使用重置和调整控件。要自己修改模型,请完成本节中的练习。否则,打开提供的模型kide_cancel_03.在你的万博 尤文图斯子文件夹以查看修改后的模型。

  1. 打开kide_cancel_02模型。

  2. 双击MATLAB函数块打开MATLAB功能块编辑器。

  3. 修改MATLAB函数块代码:

    1. 更新函数声明。

      功能[signal_out,权重] = ... lms(适应,重置,keck_in,signal_in)
    2. 更新外部呼叫。

      coder.extrinsic(“lms_03”);

    3. 更新对LMS算法的调用。

      %compute lms:[〜,signal_out,权重] = ... lms_03(kets_in,signal_in,重置,调整);

    4. 关闭MATLAB功能块编辑器。

      lms_03函数的输入重置适应现在显示为输入端口MATLAB函数堵塞。

  4. 打开design_templates.模型。

  5. 将设置块从此模型复制到您的kide_cancel_02模型:

    1. 来自design_templates.模型菜单中,选择编辑>全选

    2. 选择编辑>复制

    3. 来自kide_cancel_02模型菜单中,选择编辑>粘贴

  6. 将设置子系统的Adapt和Reset输出连接到相应的输入MATLAB函数堵塞。您的模型现在应该如下看起来。

  7. 将模型保存为kide_cancel_03.

用自适应和复位控制对模型进行仿真。要模拟模型,请参阅调整和重置控件的效果:

  1. kide_cancel_03.模型,查看收敛范围:

    1. 双击分析和可视化子系统。

    2. 双击收敛范围。

  2. 在Simuli万博1manbetxnk模型窗口中,单击跑步

    万博1manbetxSimulink像以前一样运行模型。在模型运行时,切换Adapt和Reset控件并查看Convergence范围以查看它们对过滤器的影响。

    适应重置,然后在切换时重置重置.结果可能看起来像这样:

  3. 停止仿真。

生成代码

你已经证明了你的算法在Simulink中是有效的。万博1manbetx接下来为模型生成代码。在生成代码之前,必须确保MATLAB代码适合代码生成。对于代码生成,必须删除对代码的外部调用。

使您的代码适用于代码生成。要自己修改模型和代码,请完成本节中的练习。否则,打开提供的模型kide_cancel_04.和文件LMS_04.M.在你的万博 尤文图斯子文件夹查看修改。

  1. 重命名MATLAB函数块到lms_filter..选择注释MATLAB函数以下MATLAB函数阻止并替换文本lms_filter.

    的生成代码时MATLAB函数堵塞,万博1manbetxSimulink编码器使用生成的代码中的块的名称。使用有意义的名称是良好的做法。

  2. 在你的kide_cancel_03.模型中,双击MATLAB函数堵塞。

    打开MATLAB函数块编辑器。

  3. 删除外在声明。

    %外在:编码器.Extrinsic('LMS_03');

  4. 删除输出的预分配。

    %输出:Signal_Out = 0 (size(Signal_In));重量= 0(32岁,1);

  5. 修改对滤波器算法的调用。

    %计算LMS: [~, Signal_Out, Weights] =…lms_04(Noise_In, Signal_In, Reset, Adapt);

  6. 将模型保存为kide_cancel_04.

  7. 打开LMS_03.M.

    1. 将函数名修改为lms_04

    2. 添加特定于代码生成的错误检查% # codegen函数声明后的编译指令。

      函数[signal_out, err, weights_out] =…Lms_04 (signal_in, desired, reset, adapt) %#codegen

      右上方的代码分析程序消息指示符变为红色,表明代码分析程序检测到代码生成问题。代码分析程序用红色下划线标出违规代码,并在其右侧放置一个红色标记。

  8. 将指针移动到第一个红色标记上以查看错误信息。

    代码分析器检测代码生成所需的内容signal_out在订购它之前完全定义,并且不支持通过索引的可变大小数据的增长。万博1manbetx

  9. 将指针移到第二个红色标记上,注意代码分析器检测到相同的错误犯错

  10. 要解决这些错误,请将其分配输出signal_out犯错.在过滤器设置之后添加此代码。

    % Output Arguments: %预分配输出和错误信号:signal_out = 0 (FrameSize,ChannelCount);呃= 0 (FrameSize ChannelCount);

    为什么要预先分配输出?

    两行代码的红色错误标记消失了。代码右上角的代码分析器消息指示器变为绿色,这表明您已经修复了代码分析器检测到的所有错误和警告。

    lms_04.m内容

  11. 将文件保存为LMS_04.M.

为noise_cancel_04生成代码

  1. 在生成代码之前,请确保万博1manbetxSimulink编码器创建代码生成报告。此HTML报告提供了对生成文件列表的简单访问,其中包含用于生成代码的配置设置摘要。

    1. 在Simuli万博1manbetxnk模型窗口中,在造型选项卡,单击模型设置

    2. 在“配置参数”对话框的左窗格中,选择代码生成>报告

    3. 在右侧窗格中,选择创建代码生成报告自动打开报告

    4. 点击申请并关闭“配置参数”对话框。

    5. 保存您的模型。

  2. 要为LMS过滤器子系统生成代码:

    1. 在您的模型中,选择LMS Filter子系统。

    2. 从“构建模型”工具菜单中选择构建选择子系统

      子系统的构建代码对话框出现了。单击构建按钮。

      万博1manbetxSimulink编码器软件为子系统生成C代码,并打开代码生成报告。

      有关使用代码生成报告的更多信息,请参阅生成代码生成报告(万博1manbetx仿真软件编码器)

    3. 在代码生成报告的左窗格中,单击LMS_Filter.c链接查看生成的C代码。请注意lms_04函数没有代码,因为默认情况下启用了内联。

  3. 修改您的过滤算法,以禁用内联:

    1. LMS_04.M.,函数声明后,添加:

      coder.inline(“不”)

    2. 将函数名称更改为lms_05并将文件保存为lms_05.m在当前文件夹中。

    3. 在你的kide_cancel_04.模型中,双击MATLAB函数堵塞。

      打开MATLAB函数块编辑器。

    4. 修改要调用的筛选算法的调用lms_05

      %计算LMS: [~, Signal_Out, Weights] =…lms_05(Noise_In, Signal_In, Reset, Adapt);

    5. 将模型保存为kide_cancel_05.

  4. 为更新模型生成代码。

    1. 在模型中,选择LMS Filter子系统。

    2. 从“构建模型”工具菜单中选择构建选择子系统

      子系统的构建代码对话框出现了。

    3. 单击构建按钮。

      万博1manbetxSimulink编码器软件为子系统生成C代码,并打开代码生成报告。

    4. 在代码生成报告的左窗格中,单击LMS_Filter.c链接查看生成的C代码。

      这一次,lms_05函数有代码,因为您禁用了内联。

      /*本地函数的前向声明*/ static void LMS_Filter_lms_05…const real_T signal_in[64],const real_T…desired[64], real_T reset, real_T adapt,…real_T signal_out[64],……real_T err[64], real_T weights_out[32]);/* Function for MATLAB Function Block: 'root/LMS_Filter' */ static void LMS_Filter_lms_05…const real_T signal_in[64], const real_T…desired[64], real_T reset, real_T adapt,…real_T signal_out[64],……real_T err[64], real_T weights_out[32])

优化LMS滤波算法

本教程的这一部分演示了何时以及如何为一个变量预分配内存,而不会导致在生成的代码中初始化内存的开销。

lms_05.m, MATLAB代码不仅声明signal_out犯错是一个FrameSize——- - - - - -ChannelCount.真正的双打传染媒介,但也初始化每个元素signal_out犯错零。在生成的C代码中,这些信号初始化为零。

MATLAB代码 生成的C代码
%预分配输出和错误信号:
signal_out = zeros(框架,channelcount);
呃= 0 (FrameSize ChannelCount);
/*预分配输出和错误信号:*/
79 for (i = 0;我< 64;我+ +){
80信号_out [i] = 0.0;
81 err[i] = 0.0;
82}

这种强制初始化是不必要的,因为两者signal_out犯错在读取之前在MATLAB代码中明确初始化。

笔记

你不应该使用编码器.NULLCOPY.当声明变量时权重先进先出因为这些变量需要在生成的代码中初始化。在读取变量之前,这两个变量都没有在MATLAB代码中显式初始化。

使用编码器.NULLCOPY.在宣言中signal_out犯错为了消除生成代码中不必要的内存初始化:

  1. lms_05.m,预先分配器signal_out犯错使用编码器.NULLCOPY.

    %预分配输出和错误信号:signal_out = coder。nullcopy (0 (FrameSize ChannelCount));呃=编码器。nullcopy (0 (FrameSize ChannelCount));

    警告

    声明变量后编码器.NULLCOPY.,在读取变量之前,必须在MATLAB代码中显式初始化变量。否则,你可能会得到不可预知的结果。

  2. 将函数名称更改为lms_06并将文件保存为lms_06.m在当前文件夹中。

  3. 在你的kide_cancel_05.模型中,双击MATLAB函数堵塞。

    MATLAB功能块编辑器打开。

  4. 修改对滤波器算法的调用。

    %计算LMS: [~, Signal_Out, Weights] =…lms_06(Noise_In, Signal_In, Reset, Adapt);

  5. 将模型保存为koteg_cancel_06.

为更新模型生成代码。

  1. 选择LMS Filter子系统。

  2. 从“构建模型”工具菜单中选择构建选择子系统

    子系统的构建代码对话框出现了。单击构建按钮。

    万博1manbetxSimulink编码器软件,为子系统生成C代码,并打开代码生成报告。

  3. 在代码生成报告的左窗格中,单击LMS_Filter.c链接查看生成的C代码。

    在生成的C代码中,这次没有初始化为0signal_out犯错

另请参阅

相关例子

更多关于