Фильтрация аудиосигнала с использованием кода 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);

Ссылка

Хайкин, Симон. Теория адаптивных фильтров. Upper Saddle River, NJ: Prentice-Hall, Inc., 1996.

Файлы для руководства

Сведения о файлах учебных пособий

В руководстве используются следующие файлы:

  • Файлы модели Simulink для каждого шага руководства.

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

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

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

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

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

НапечататьИмяОписание
Файлы MATLABlms_01Базовая реализация пакетного фильтра MATLAB. Не подходит для генерации кода.
lms_02Фильтр изменен от пакета к потоковому.
lms_03Потоковый фильтр на основе фрейма с элементами управления Reset и Adapt.
lms_04Потоковый фильтр на основе фрейма с элементами управления Reset и Adapt. Подходит для генерации кода.
lms_05Отключена установка inlining для генерации кода.
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, содержащая элементы управления Adapt и Reset.

Шаги примера

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

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

  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, чтобы выбрать источник звука.

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

Цель этого руководства состоит в том, чтобы использовать алгоритм фильтра MATLAB LMS, чтобы удалить шум от шумного аудиосигнала. Вы делаете это, добавляя блок 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

     Зачем использовать оператор Tilde (~)?

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

    The 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 устанавливается в соответствии с коэффициентами Numerator цифрового фильтра в подсистеме Acoustic Environment.

     Зачем предварительно выделять выходы?

     Модифицированный блок 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 и Reset

Зачем добавлять элементы управления Adapt and Reset  ?. В этой части руководства вы добавляете элементы управления 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.

      The 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 подсистемы Settings с соответствующими входами на блоке MATLAB Function. Теперь ваша модель должна появиться следующим образом.

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

Симуляция модели с помощью элементов управления Adapt и Reset.  Чтобы симулировать модель и увидеть эффект элементов управления Adapt и Reset:

  1. В noise_cancel_03 модель, просмотрите возможности Сходимости:

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

    2. Дважды кликните возможности сходимости.

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

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

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

  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. На левой панели диалогового окна Параметры конфигурации выберите Code Generation > Report.

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

    4. Нажмите Apply и закройте диалоговое окно Параметров конфигурации.

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

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

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

    2. В меню инструмента «Создать модель» выберите Build Selected Subsystem.

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

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

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

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

  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 Filter.

    2. В меню инструмента «Создать модель» выберите 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-by- 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 Filter.

  2. В меню инструмента «Создать модель» выберите Build Selected Subsystem.

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

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

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

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

См. также

Похожие примеры

Подробнее о