Отфильтруйте звуковой сигнал Используя код MATLAB

Изучение целей

В этом примере вы будете учиться как:

  • Используйте блок MATLAB Function, чтобы добавить функции MATLAB® в модели Simulink® для моделирования, симуляции и развертывания на встраиваемых процессорах.

    Эта возможность полезна для алгоритмов кодирования, которые лучше утверждаются на текстовом языке MATLAB, чем на графическом языке Simulink.

  • Использование coder.extrinsic вызывать код MATLAB от блока MATLAB Function.

    Эта возможность позволяет вам вызывать существующий код MATLAB от Simulink, сначала не имея необходимость сделать этот код подходящим для генерации кода, допуская быстрое прототипирование.

  • Проверяйте, что существующий код MATLAB подходит для генерации кода.

  • Преобразуйте алгоритм MATLAB от пакетной обработки данных до потоковой передачи.

  • Используйте персистентные переменные в коде, который подходит для генерации кода.

    Необходимо сделать веса фильтра персистентными так, чтобы алгоритм фильтра не сбрасывал их значения каждый раз, когда он запускается.

Учебные необходимые условия

Что необходимо знать

Чтобы работать через этот пример, у вас должно быть основное знакомство с программным обеспечением MATLAB. Необходимо также изучить, как создать основную модель Simulink и как симулировать ту модель. Для получения дополнительной информации смотрите, Создают Простую Модель.

Необходимые продукты

Чтобы завершить этот пример, необходимо установить следующие продукты:

Для получения инструкций по установке продуктов MathWorks® обратитесь к документации по установке. Если вы установили MATLAB и хотите проверять, который установлены другие Продукты Mathworks, введите ver в командном окне MATLAB. Для получения инструкций по установке и подготовке компилятор C, смотрите Подготовку C или Компилятора C++ (MATLAB Coder).

Пример: фильтр LMS

Описание

Фильтр наименьшее количество средних квадратичных (LMS) является адаптивным фильтром, который настраивает его передаточную функцию согласно алгоритму оптимизации. Вы предоставляете фильтру пример желаемого сигнала вместе с входным сигналом. Фильтр затем вычисляет веса фильтра или коэффициенты, которые производят наименьшее количество средних квадратичных ошибки между выходным сигналом и желаемым сигналом.

Этот пример использует фильтр LMS, чтобы удалить шум в звукозаписи. Существует два входных параметров. Первый вход является искаженным сигналом: звукозапись плюс отфильтрованный шум. Второй вход является желаемым сигналом: неотфильтрованный шум. Фильтр работает, чтобы устранить различие между выходным сигналом и желаемым сигналом и выводит различие, которое, в этом случае, является чистой звукозаписью. Когда вы запускаете симуляцию, вы слышите и шум и музыку. В зависимости от времени адаптивный фильтр удаляет шум, таким образом, вы слышите только музыку.

Алгоритм

Этот пример использует алгоритм наименьшее количество средних квадратичных (LMS), чтобы удалить шум из входного сигнала. LMS-алгоритм вычисляет отфильтрованный выход, ошибку фильтра и веса фильтра, учитывая искаженные и желаемые сигналы.

В начале примера LMS-алгоритм использует процесс пакетной обработки, чтобы отфильтровать аудиовход. Этот алгоритм подходит для MATLAB, где вы, вероятно, загрузите в целом сигнале и обработаете все это целиком. Однако процесс пакетной обработки не подходит для обработки сигнала в режиме реального времени. Когда вы работаете через пример, вы совершенствовали проект фильтра, чтобы преобразовать алгоритм от пакетного до поточной обработки.

Базовая функциональная подпись для алгоритма:

function [ signal_out, err, weights ] = ...
    lms_01(signal_in, desired)

Фильтрация выполняется в следующем цикле:

for n = 1:SignalLength
  % Compute the output sample using convolution:
  signal_out(n,ch) = weights' * signal_in(n:n+FilterLength-1,ch);
  % Update the filter coefficients:
  err(n,ch) = desired(n,ch) - signal_out(n,ch) ;
  weights = weights + mu*err(n,ch)*signal_in(n:n+FilterLength-1,ch);
end
где SignalLength длина входного сигнала, FilterLength длина фильтра и mu размер шага адаптации.

 Каков размер шага адаптации?

Фильтрация процесса

Процесс фильтрации имеет три фазы:

  • Свертка

    Свертка для фильтра выполняется в:

    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);

Ссылка

Haykin, Саймон. Адаптивная теория фильтра. Верхний Сэддл-Ривер, NJ: Prentice-Hall, Inc., 1996.

Файлы для примера

Об учебных файлах

Пример использует следующие файлы:

  • Файлы модели Simulink для каждого шага примера.

  • Файлы кода MATLAB для каждого шага примера.

    В этом примере вы работаете с моделями Simulink, которые вызывают файлы MATLAB, которые содержат простой алгоритм фильтра наименьшее количество средних квадратичных (LMS).

Местоположение файлов

Учебные файлы доступны в следующей папке: docroot\toolbox\simulink\examples\lms. Чтобы запустить пример, необходимо скопировать эти файлы в локальную папку. Для инструкций смотрите Копирование Файлов Локально.

Имена и описания файлов

ВводИмяОписание
Файлы MATLABlms_01Базовая реализация MATLAB пакетного фильтра. Не подходящий для генерации кода.
lms_02Фильтр, измененный от пакета до потоковой передачи.
lms_03Основанный на системе координат фильтр потоковой передачи со Сбросом и Адаптирует средства управления.
lms_04Основанный на системе координат фильтр потоковой передачи со Сбросом и Адаптирует средства управления. Подходящий для генерации кода.
lms_05Отключенное встраивание для генерации кода.
lms_06Демонстрирует использование coder.nullcopy.
Файлы модели Simulinkacoustic_environmentМодель Simulink, которая предоставляет обзор акустической среды.
noise_cancel_00Модель Simulink без блока MATLAB Function.
noise_cancel_01Полный noise_cancel_00 модель включая блок MATLAB Function.
noise_cancel_02Модель Simulink для использования с lms_02.m.
noise_cancel_03Модель Simulink для использования с lms_03.m.
noise_cancel_04Модель Simulink для использования с lms_04.m.
noise_cancel_05Модель Simulink для использования с lms_05.m.
noise_cancel_06Модель Simulink для использования с lms_06.m.
design_templatesМодель Simulink, содержащая, Адаптируется и средства управления Сбросом.

Шаги примера

Копирование файлов локально

Скопируйте учебные файлы в локальную папку:

  1. Создайте локальный solutions папка, например, c:\test\lms\solutions.

  2. Превратитесь в docroot\toolbox\simulink\examples папка. В командной строке MATLAB, введите:

    cd(fullfile(docroot, 'toolbox', 'simulink', 'examples')) 

  3. Скопируйте содержимое lms подпапка к вашему solutions папка, задавая имя полного пути solutions папка:

    copyfile('lms', 'solutions')
    Ваш solutions папка теперь содержит полный набор решений для примера. Если вы не хотите выполнять шаги для каждой задачи, можно просмотреть предоставленное решение, чтобы видеть, как код должен выглядеть.

  4. Создайте локальный work папка, например, c:\test\lms\work.

  5. Скопируйте следующие файлы со своего solutions папка к вашему work папка.

    • lms_01

    • lms_02

    • noise_cancel_00

    • acoustic_environment

    • design_templates

    Ваш work папка теперь содержит все файлы, что необходимо начать.

    Вы теперь готовы настроить свой компилятор C.

Подготовка вашего компилятора C

Создание вашего блока MATLAB Function требует поддерживаемого компилятора. MATLAB автоматически выбирает тот как компилятор по умолчанию. Если у вас есть несколько поддерживаемых MATLAB компиляторов, установленных в вашей системе, можно изменить значение по умолчанию с помощью mex -setup команда. См. Компилятор Значения по умолчанию Изменения и список Поддерживаемых Компиляторов.

Выполнение acoustic_environment Модели

Запустите acoustic_environment модель предоставила пример, чтобы изучить проблему, что вы пытаетесь решить использование фильтра LMS. Эта модель добавляет ограниченный полосой белый шум в звуковой сигнал и выводит получившийся сигнал динамику.

Симулировать модель:

  1. Откройте acoustic_environment модель в Simulink:

    1. Установите свою текущую папку MATLAB на папку, которая содержит ваши рабочие файлы для этого примера. В командной строке MATLAB, введите:

      cd work
      где work имя полного пути папки, содержащей ваши файлы. Смотрите Находят Файлы и Папки для получения дополнительной информации.

    2. В командной строке MATLAB, введите:

      acoustic_environment

  2. Убедитесь, что ваши динамики работают.

  3. Чтобы симулировать модель, от окна модели Simulink, нажимают Run.

    Когда Simulink запускает модель, вы слышите звуковой сигнал, искаженный шумом.

  4. Во время симуляции дважды кликните Manual Switch, чтобы выбрать источник аудиосигналов.

    Теперь вы слышите желаемый аудиовход без любого шума.

Цель этого примера состоит в том, чтобы использовать алгоритм фильтра LMS MATLAB, чтобы удалить шум из шумного звукового сигнала. Вы делаете это путем добавления блока MATLAB Function в модель и вызова кода MATLAB от этого блока.

Добавление блока MATLAB function к модели

Чтобы изменить модель и код самостоятельно, выполните упражнения в этом разделе. В противном случае откройте предоставленную модель noise_cancel_01 в вашем solutions подпапка, чтобы видеть модифицированную модель.

В целях этого примера вы добавляете блок MATLAB Function в noise_cancel_00 модель предоставляется примером. На практике необходимо было бы разработать собственный испытательный стенд начиная с пустой модели Simulink.

Добавить блок MATLAB Function в noise_cancel_00 модель:

  1. Открытый noise_cancel_00 в Simulink.

    noise_cancel_00

  2. Добавьте блок MATLAB Function в модель:

    1. В командной строке MATLAB введите slLibraryBrowser открыть Браузер Библиотеки Simulink.

    2. Из списка Библиотек Simulink выберите User-Defined Functions библиотека.

    3. Кликните по блоку MATLAB Function и перетащите его в noise_cancel_00 модель. Поместите блок чуть выше красной текстовой аннотации Place MATLAB Function Block here.

    4. Удалите красные текстовые аннотации из модели.

    5. Сохраните модель в текущей папке как noise_cancel_01.

       Лучшая практика — сохранение инкрементных обновлений кода

Вызов кода MATLAB как внешняя функция для быстрого прототипирования

В этой части примера вы используете coder.extrinsic функционируйте, чтобы вызвать ваш код MATLAB от блока MATLAB Function для быстрого прототипирования.

Почему Вызов код MATLAB Как Внешняя Функция?.  При вызове кода MATLAB, когда внешняя функция предоставляет эти преимущества:

  • Для быстрого прототипирования вы не должны делать код MATLAB подходящим для генерации кода.

  • Используя coder.extrinsic позволяет вам отладить свой код MATLAB в MATLAB. Можно добавить одну или несколько точек останова в lms_01.m файл, и затем запускает симуляцию в Simulink. Когда механизм выполнения MATLAB сталкивается с точкой останова, он временно останавливает выполнение так, чтобы можно было смотреть рабочее пространство MATLAB и просмотреть текущие значения всех переменных в памяти. Для получения дополнительной информации об отладке кода MATLAB, смотрите Отладку программа MATLAB.

Как Вызвать код MATLAB Как Внешнюю Функцию.  Вызывать ваш код MATLAB от блока MATLAB Function:

  1. Дважды кликните блок MATLAB Function, чтобы открыть Редактор блока MATLAB function.

  2. Удалите код по умолчанию, отображенный в Редакторе блока MATLAB function.

  3. Скопируйте следующий код в блок MATLAB Function.

    function [ Signal_Out, Weights ] = LMS(Noise_In, Signal_In) %#codegen   
        % Extrinsic:
        coder.extrinsic('lms_01');
        
        % Compute LMS:
        [ ~, Signal_Out, Weights ] = lms_01(Noise_In, Signal_In);
    end

     Почему использование тильда (~) оператор?

  4. Сохраните модель.

    lms_01 входные параметры функции Noise_In и Signal_In теперь появитесь как входные порты с блоком и функциональными выходными параметрами Signal_Out и Weights появитесь как выходные порты.

Соединение вводов и выводов блока MATLAB function

  1. Соедините вводы и выводы блока MATLAB Function так, чтобы ваша модель выглядела так.

  2. В блочном коде MATLAB Function предварительно выделите выходные параметры путем добавления следующего кода после внешнего вызова:

    % Outputs:
    Signal_Out = zeros(size(Signal_In));
    Weights = zeros(32,1);
    Размер Weights набор должен совпадать с коэффициентами Числителя Цифрового фильтра в Акустической подсистеме Среды.

     Почему предварительно выделяют Выходные параметры?

     Модифицированный код блока MATLAB function

  3. Сохраните модель.

    Вы теперь готовы проверить свою модель на наличие ошибок.

Симуляция noise_cancel_01 Модели

Симулировать модель:

  1. Убедитесь, что вы видите графики Time Domain.

    Просмотреть графики, в noise_cancel_01 модель, откройте блок Analysis and Visualization и затем откройте блок Time Domain.

  2. В окне модели Simulink нажмите Run.

    Когда Simulink запускает модель, вы видите и слышите выходные параметры. Первоначально, вы слышите звуковой сигнал, искаженный шумом. Затем фильтр постепенно ослабляет шум, пока вы не слышите только, что музыка вопроизводит с очень мало шумовым остающийся. После двух секунд вы слышите искаженный сигнал с шумом снова, и фильтр ослабляет шум снова. Этот цикл повторяется постоянно.

    MATLAB отображает следующий график, показывающий этот цикл.

  3. Остановите симуляцию.

 Почему фильтр сбрасывает каждые 2 секунды?

Изменение фильтра, чтобы использовать потоковую передачу

Что Передает потоком?.  Фильтр потоковой передачи неоднократно называется к фрагментам фиксированного размера процесса входных данных или системам координат, пока он не обработал целый входной сигнал. Формат кадра может как быть малым как одна выборка, в этом случае фильтр действовал бы в основанном на выборке режиме, или до нескольких тысяч выборок, для основанной на системе координат обработки.

Почему Потоковая передача Использования?.  Проект алгоритма фильтра в lms_01 имеет следующие недостатки:

  • Алгоритм не использует память эффективно.

    Предварительное выделение установленной суммы памяти для каждого входного сигнала в течение времени жизни программы означает, что больше памяти выделяется, чем используется.

  • Необходимо знать размер входного сигнала в то время, когда вы вызываете функцию.

    Если бы входной сигнал прибывает в режиме реального времени или как поток выборок, необходимо было бы ожидать, чтобы накопить целый сигнал, прежде чем вы могли передать его, как пакет, к фильтру.

  • Размер сигнала ограничивается максимальным размером.

Во встраиваемом приложении фильтр, вероятно, будет обрабатывать непрерывный входной поток. В результате входной сигнал может быть существенно более длинным, чем максимальная длина, которую мог возможно обработать фильтр, работающий в пакетном режиме. Чтобы заставить фильтр работать на любую длину сигнала, это должно запуститься в режиме реального времени. Одно решение состоит в том, чтобы преобразовать фильтр от пакетной обработки до поточной обработки.

Просмотр Модифицированного кода MATLAB.  Преобразование в потоковую передачу включает:

  • Представление метода "первым пришел - первым вышел" (FIFO) очередь

    Очередь FIFO действует как буфер временного хранения, который содержит небольшое количество выборок от потока входных данных. Количество выборок, сохраненных очередью FIFO, должно быть точно тем же самым как количеством выборок в импульсной характеристике фильтра, так, чтобы функция могла выполнить операцию свертки между коэффициентами фильтра и входным сигналом.

  • Создание очереди FIFO и персистентных весов фильтра

    Фильтр неоднократно называется, пока он не обработал целый входной сигнал. Поэтому очередь FIFO и веса фильтра должны сохраниться так, чтобы процесс адаптации не запускался снова после каждого последующего вызова функции.

Откройте предоставленный файл lms_02.m в вашем work подпапка, чтобы видеть модифицированный алгоритм.

 Содержимое lms_02.m

Сводные данные Изменений в Алгоритме Фильтра.  Обратите внимание на следующие важные изменения к алгоритму фильтра:

  • Веса фильтра и очередь FIFO объявляются как персистентные:

    persistent weights;
    persistent fifo;

  • Очередь FIFO инициализируется:

    fifo = zeros(FilterLength,ChannelCount);

  • Очередь FIFO используется в цикле обновления фильтра:

    % For each channel:
    for ch = 1:ChannelCount
                
       % For each sample time:
       for n = 1:FrameSize
                    
         % Update the FIFO shift register:
         fifo(1:FilterLength-1,ch) = fifo(2:FilterLength,ch);
         fifo(FilterLength,ch) = signal_in(n,ch);
                    
         % Compute the output sample using convolution:
         signal_out(n,ch) = weights' * fifo(:,ch);
    
         % Update the filter coefficients:
         err(n,ch) = desired(n,ch) - signal_out(n,ch) ;
         weights = weights + mu*err(n,ch)*fifo(:,ch);
                    
       end
    end

  • Вы не можете вывести персистентную переменную. Поэтому новая переменная, weights_out, используется, чтобы вывести веса фильтра:

    function [ signal_out, err, weights_out ] = ...
      lms_02(distorted, desired)
    weights_out = weights;

Изменение Модели, чтобы Вызвать Обновленный Алгоритм.  Чтобы изменить модель самостоятельно, выполните упражнения в этом разделе. В противном случае откройте предоставленную модель noise_cancel_02 в вашем solutions подпапка, чтобы видеть модифицированную модель.

  1. В noise_cancel_01 модель, дважды кликните блок MATLAB Function, чтобы открыть Редактор блока MATLAB function.

  2. Измените блочный код MATLAB Function, чтобы вызвать lms_02.

    1. Измените внешний вызов.

      % Extrinsic:
      coder.extrinsic('lms_02');

    2. Измените вызов алгоритма фильтра.

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

       Модифицированный код блока MATLAB function

  3. Измените формат кадра от 16384 к 64, который представляет более реалистическое значение.

    1. Щелкните правой кнопкой в окне модели и выберите Model Properties.

    2. Выберите вкладку Callbacks.

    3. В списке Model callbacks выберите InitFcn.

    4. Измените значение FrameSize к 64.

    5. Нажмите Apply и закройте диалоговое окно.

  4. Сохраните свою модель как noise_cancel_02.

Симуляция Алгоритма Потоковой передачи.  Симулировать модель:

  1. Убедитесь, что вы видите графики Time Domain.

  2. Запустите симуляцию.

    Когда Simulink запускает модель, вы видите и слышите выходные параметры. Первоначально, вы слышите звуковой сигнал, искаженный шумом. Затем в течение первых нескольких секунд фильтр постепенно ослабляет шум, пока вы не слышите только, что музыка вопроизводит с очень мало шумовым остающийся. MATLAB отображает следующий график, показывающий сходимость фильтра только после нескольких секунд.

  3. Остановите симуляцию.

Алгоритм фильтра теперь подходит для Simulink. Вы готовы разработать свою модель, чтобы использовать Adapt и Reset средства управления.

Добавление адаптируется и средства управления сбросом

Почему Добавляют, Адаптируются и Средства управления Сбросом?.  В этой части примера вы добавляете, Адаптируются и средства управления Сбросом к вашему фильтру. Используя эти средства управления, можно включить и выключить фильтрацию. Когда Adapt включен, фильтр постоянно обновляет веса фильтра. Когда Adapt отключен, веса фильтра остаются в своих текущих значениях. Если Reset установлен, фильтр сбрасывает веса фильтра.

Изменение Вашего кода MATLAB.  Чтобы изменить код самостоятельно, выполните упражнения в этом разделе. В противном случае откройте предоставленный файл lms_03.m в вашем solutions подпапка, чтобы видеть модифицированный алгоритм.

Изменить ваш код фильтра:

  1. Открытый lms_02.m.

  2. В Set up разделите, замена

    if ( isempty(weights) )
    с
    if ( reset || isempty(weights) )

  3. В цикле фильтра обновите коэффициенты фильтра только если Adapt ON.

    if adapt
      weights = weights + mu*err(n,ch)*fifo(:,ch);
    end

  4. Измените функциональную подпись, чтобы использовать Adapt и Reset входные параметры и изменяют название функции на lms_03.

    function [ signal_out, err, weights_out ] = ...
      lms_03(signal_in, desired, reset, adapt)

  5. Сохраните файл в текущей папке как lms_03.m:

 Содержимое lms_03.m

 Сводные данные изменений в алгоритме фильтра

Изменение Модели, чтобы Использовать Сброс и Адаптировать Средства управления.  Чтобы изменить модель самостоятельно, выполните упражнения в этом разделе. В противном случае откройте предоставленную модель noise_cancel_03 в вашем solutions подпапка, чтобы видеть модифицированную модель.

  1. Откройте noise_cancel_02 модель.

  2. Дважды кликните блок MATLAB Function, чтобы открыть Редактор блока MATLAB function.

  3. Измените блочный код MATLAB Function:

    1. Обновите объявление функции.

      function [ Signal_Out, Weights ] = ...
         LMS(Adapt, Reset, Noise_In, Signal_In )
    2. Обновите внешний вызов.

      coder.extrinsic('lms_03');

    3. Обновите вызов LMS-алгоритма.

      % Compute LMS:
      [ ~, Signal_Out, Weights ] = ...
         lms_03(Noise_In, Signal_In, Reset, Adapt);

    4. Закройте редактор блока MATLAB function.

      lms_03 входные параметры функции Reset и Adapt теперь появитесь как входные порты с блоком MATLAB Function.

  4. Откройте design_templates модель.

  5. Скопируйте блок Settings от этой модели до вашего noise_cancel_02 модель:

    1. От design_templates меню модели, выберите Edit> Select All.

    2. Выберите Edit> Copy.

    3. От noise_cancel_02 меню модели, выберите Edit> Paste.

  6. Соедините Adapt и Reset выходные параметры подсистемы Настроек к соответствующим входным параметрам на блоке MATLAB Function. Ваша модель должна теперь появиться следующей.

  7. Сохраните модель как noise_cancel_03.

Симуляция Модели с Адаптируется и Средства управления Сбросом.  Симулировать модель и видеть эффект средств управления Адаптированием и Сбросом:

  1. В noise_cancel_03 модель, просмотрите осциллограф Сходимости:

    1. Дважды кликните подсистему Анализа и Визуализации.

    2. Дважды кликните осциллограф Сходимости.

  2. В окне модели Simulink нажмите Run.

    Simulink запускает модель как прежде. В то время как модель запускается, переключите средства управления Адаптированием и Сбросом и просмотрите осциллограф Сходимости, чтобы видеть их эффект на фильтре.

    Фильтр сходится когда Adapt ON и Reset OFF, затем сброс, когда вы toggleReset. Результаты могут выглядеть примерно так:

  3. Остановите симуляцию.

Генерация кода

Вы доказали, что ваш алгоритм работает в Simulink. Затем вы генерируете код для своей модели. Прежде, чем сгенерировать код, необходимо гарантировать, что код MATLAB подходит для генерации кода. Для генерации кода необходимо удалить внешний вызов кода.

Создание Кода, Подходящего для Генерации кода.  Чтобы изменить модель и код самостоятельно, выполните упражнения в этом разделе. В противном случае откройте предоставленную модель noise_cancel_04 и файл lms_04.m в вашем solutions подпапка, чтобы видеть модификации.

  1. Переименуйте блок MATLAB Function в LMS_Filter. Выберите аннотацию MATLAB Function ниже блока MATLAB Function и замены текст с LMS_Filter.

    Когда вы генерируете код для блока MATLAB Function, Simulink Coder использует имя блока в сгенерированном коде. Это - хорошая практика, чтобы использовать понятное имя.

  2. В вашем noise_cancel_03 модель, дважды кликните блок MATLAB Function.

    Редактор блока MATLAB function открывается.

  3. Удалите внешнее объявление.

    % Extrinsic:
    coder.extrinsic('lms_03');

  4. Удалите предварительное выделение выходных параметров.

    % Outputs:
    Signal_Out = zeros(size(Signal_In));
    Weights = zeros(32,1);

  5. Измените вызов алгоритма фильтра.

    % Compute LMS:
    [ ~, Signal_Out, Weights ] = ...
       lms_04(Noise_In, Signal_In, Reset, Adapt);

  6. Сохраните модель как noise_cancel_04.

  7. Открытый lms_03.m

    1. Измените имя функции к lms_04.

    2. Включите проверку ошибок, характерную для генерации кода путем добавления %#codegen директива компиляции после объявления функции.

      function [ signal_out, err, weights_out ] = ...
          lms_04(signal_in, desired, reset, adapt) %#codegen

      Индикатор сообщения анализатора кода в правом верхнем покраснел, чтобы указать, что анализатор кода обнаружил проблемы генерации кода. Анализатор кода подчеркивает незаконный код красного цвета и помещает красный маркер справа от него.

  8. Переместите указатель через первый красный маркер, чтобы просмотреть информацию об ошибке.

    Анализатор кода обнаруживает ту генерацию кода, требует signal_out быть полностью заданным прежде, чем преобразовать его в нижний индекс и не поддерживает рост переменных данных о размере посредством индексации.

  9. Переместите указатель через второй красный маркер и обратите внимание, что анализатор кода обнаруживает те же ошибки для err.

  10. Чтобы исправить эти ошибки, предварительно выделите выходные параметры signal_out и err. Добавьте этот код после настройки фильтра.

     % Output Arguments:
            
     % Pre-allocate output and error signals:
     signal_out = zeros(FrameSize,ChannelCount);
     err = zeros(FrameSize,ChannelCount);

     Почему предварительно выделяют Выходные параметры?

    Красные ошибочные маркеры для этих двух строк кода исчезают. Индикатор сообщения анализатора кода в правом верхнем ребре кода становится зеленым, который указывает, что вы зафиксировали все ошибки и предупреждения, обнаруженные анализатором кода.

     Содержимое lms_04.m

  11. Сохраните файл как lms_04.m.

Генерация Кода для noise_cancel_04

  1. Прежде, чем сгенерировать код, гарантируйте, что Simulink Coder создает отчет генерации кода. Этот отчет HTML обеспечивает, быстрый доступ к списку сгенерированных файлов со сводными данными параметров конфигурации раньше генерировал код.

    1. В окне модели Simulink, во вкладке Modeling, нажимают Model Settings.

    2. На левой панели диалогового окна Configuration Parameters выберите Code Generation> Report.

    3. На правой панели выберите Create code generation report и Open report automatically.

    4. Нажмите Apply и закройте диалоговое окно Configuration Parameters.

    5. Сохраните свою модель.

  2. Сгенерировать код для подсистемы Фильтра LMS:

    1. В вашей модели выберите подсистему Фильтра LMS.

    2. Из меню инструментов Build Model выберите Build Selected Subsystem.

      Диалоговое окно Build code for subsystem появляется. Нажмите кнопку Build.

      Программное обеспечение Simulink Coder генерирует код С для подсистемы и открывает отчет генерации кода.

      Для получения дополнительной информации об использовании отчета генерации кода смотрите, Генерируют Отчет Генерации кода (Simulink Coder).

    3. На левой панели отчета генерации кода нажмите LMS_Filter.c соединитесь, чтобы просмотреть сгенерированный код C. Обратите внимание на то, что lms_04 функция не имеет никакого кода, потому что встраивание включено по умолчанию.

  3. Измените свой алгоритм фильтра, чтобы отключить встраивание:

    1. В lms_04.m, после объявления функции добавьте:

      coder.inline('never')

    2. Поменяйте имя функции на lms_05 и сохраните файл как lms_05.m в текущей папке.

    3. В вашем noise_cancel_04 модель, дважды кликните блок MATLAB Function.

      Редактор блока MATLAB function открывается.

    4. Измените вызов алгоритма фильтра, чтобы вызвать lms_05.

      % Compute LMS:
      [ ~, Signal_Out, Weights ] = ...
         lms_05(Noise_In, Signal_In, Reset, Adapt);

    5. Сохраните модель как noise_cancel_05.

  4. Сгенерируйте код для обновленной модели.

    1. В модели выберите подсистему Фильтра LMS.

    2. Из меню инструментов Build Model выберите Build Selected Subsystem.

      Диалоговое окно Build code for subsystem появляется.

    3. Нажмите кнопку Build.

      Программное обеспечение Simulink Coder генерирует код С для подсистемы и открывает отчет генерации кода.

    4. На левой панели отчета генерации кода нажмите LMS_Filter.c соединитесь, чтобы просмотреть сгенерированный код C.

      На этот раз lms_05 функция имеет код, потому что вы отключили встраивание.

      /* Forward declaration for local functions */
         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 и err быть FrameSize- ChannelCount вектор из действительных удваивается, но также и инициализирует каждый элемент signal_out и err обнулять. Эти сигналы инициализируются, чтобы обнулить в сгенерированном коде C.

КОД MATLABСгенерированный код C
% Pre-allocate output and error signals:
signal_out = zeros(FrameSize,ChannelCount);
err = zeros(FrameSize,ChannelCount);
/* Pre-allocate output and error signals: */
79 for (i = 0; i < 64; i++) {
80 signal_out[i] = 0.0;
81 err[i] = 0.0;
82 }

Эта принудительная инициализация является ненужной потому что оба signal_out и err явным образом инициализируются в коде MATLAB, прежде чем они будут считаны.

Примечание

Вы не должны использовать coder.nullcopy при объявлении переменных weights и fifo потому что эти переменные должны быть инициализированы в сгенерированном коде. Никакая переменная явным образом не инициализируется в коде MATLAB, прежде чем они будут считаны.

Использование coder.nullcopy в объявлении signal_out и err устранить ненужную инициализацию памяти в сгенерированном коде:

  1. В lms_05.m, предварительно выделите signal_out и err использование coder.nullcopy:

    % Pre-allocate output and error signals: 
    signal_out = coder.nullcopy(zeros(FrameSize, ChannelCount));
    err = coder.nullcopy(zeros(FrameSize, ChannelCount));

    Внимание

    После объявления переменной с coder.nullcopy, необходимо явным образом инициализировать переменную в коде MATLAB прежде, чем считать его. В противном случае вы можете получить непредсказуемые результаты.

  2. Поменяйте имя функции на lms_06 и сохраните файл как lms_06.m в текущей папке.

  3. В вашем noise_cancel_05 модель, дважды кликните блок MATLAB Function.

    Редактор MATLAB Function Block открывается.

  4. Измените вызов алгоритма фильтра.

    % Compute LMS:
    [ ~, Signal_Out, Weights ] = ...
       lms_06(Noise_In, Signal_In, Reset, Adapt);

  5. Сохраните модель как noise_cancel_06.

Сгенерируйте код для обновленной модели.

  1. Выберите подсистему Фильтра LMS.

  2. Из меню инструментов Build Model выберите Build Selected Subsystem.

    Диалоговое окно Build code for subsystem появляется. Нажмите кнопку Build.

    Программное обеспечение Simulink Coder и генерирует код С для подсистемы и открывает отчет генерации кода.

  3. На левой панели отчета генерации кода нажмите LMS_Filter.c соединитесь, чтобы просмотреть сгенерированный код C.

    В сгенерированном коде C на этот раз нет никакой инициализации к нулю signal_out и err.

Смотрите также

Связанные примеры

Больше о

Для просмотра документации необходимо авторизоваться на сайте