exponenta event banner

Фильтрация аудиосигнала с использованием кода MATLAB

Цели обучения

В этом учебном пособии вы узнаете, как:

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

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

  • Использовать coder.extrinsic вызов кода MATLAB из функционального блока MATLAB.

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

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

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

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

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

Предварительные условия учебного пособия

Что нужно знать

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

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

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

Инструкции по установке продуктов MathWorks ® см. в документации по установке. Если вы установили MATLAB и хотите проверить, какие другие продукты MathWorks установлены, введитеver в окне команд MATLAB. Инструкции по установке и настройке компилятора C см. в разделе Настройка компилятора C или C++ (кодер MATLAB).

Пример: Фильтр 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);

Ссылка

Хайкин, Саймон. Адаптивная теория фильтров. Река Верхнее Седло, Нью-Джерси: Прентис-Холл, Инк., 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Отключено вложение для создания кода.
lms_06Демонстрирует использование coder.nullcopy.
Файлы модели Simulinkacoustic_environmentМодель Simulink, которая предоставляет обзор акустической среды.
noise_cancel_00Модель Simulink без функционального блока MATLAB.
noise_cancel_01Полный noise_cancel_00 модель, включающая функциональный блок MATLAB.
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

Для создания функционального блока MATLAB требуется поддерживаемый компилятор. 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 model) щелкните Выполнить (Run).

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

  4. Во время выполнения моделирования дважды щелкните переключатель вручную, чтобы выбрать источник звука.

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

Целью данного учебного пособия является использование алгоритма фильтра MATLAB LMS для удаления шума из шумного звукового сигнала. Для этого необходимо добавить в модель функциональный блок MATLAB и вызвать код MATLAB из этого блока.

Добавление функционального блока MATLAB в модель

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

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

Добавление функционального блока MATLAB к noise_cancel_00 модель:

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

    noise_cancel_00

  2. Добавьте в модель функциональный блок MATLAB:

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

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

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

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

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

       Рекомендации - сохранение инкрементных обновлений кода

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

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

Почему вызов кода MATLAB как внешней функции?.  Вызов кода MATLAB как внешней функции обеспечивает следующие преимущества:

  • Для быстрого создания прототипов не требуется использовать код MATLAB для создания кода.

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

Вызов кода MATLAB в качестве внешней функции.  Для вызова кода MATLAB из функционального блока MATLAB:

  1. Дважды щелкните по функциональному блоку MATLAB, чтобы открыть редактор функциональных блоков MATLAB.

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

  3. Скопируйте следующий код в функциональный блок MATLAB.

    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. Сохраните модель.

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

Подключение входов и выходов функционального блока MATLAB

  1. Подключите входы и выходы функционального блока MATLAB, чтобы модель выглядела следующим образом.

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

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

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

     Измененный код функционального блока MATLAB

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

    Теперь можно проверить модель на наличие ошибок.

Моделирование модели noise_cancel_01

Для моделирования модели:

  1. Убедитесь, что вы можете видеть графики временной области.

    Для просмотра графиков в разделе noise_cancel_01 откройте блок Анализ и визуализация (Analysis and Visualization), а затем откройте блок Временная область (Time Domain).

  2. В окне Модель симулятора (Simulink model) щелкните Выполнить (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, чтобы открыть редактор функциональных блоков MATLAB.

  2. Изменение кода функционального блока MATLAB для вызова lms_02.

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

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

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

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

       Измененный код функционального блока MATLAB

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

    1. Щелкните правой кнопкой мыши внутри окна модели и выберите Свойства модели (Model Properties).

    2. Выберите вкладку Обратные вызовы.

    3. В списке Обратные вызовы модели выберите InitFcn.

    4. Изменение значения FrameSize кому 64.

    5. Нажмите кнопку Применить (Apply) и закройте диалоговое окно.

  4. Сохранение модели как noise_cancel_02.

Моделирование алгоритма потоковой передачи.  Для моделирования модели:

  1. Убедитесь, что вы можете видеть графики временной области.

  2. Запустите моделирование.

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

  3. Остановите моделирование.

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

Добавление элементов управления Adapt и Reset

Зачем добавлять элементы управления Adapt и 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

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

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

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

  2. Дважды щелкните по функциональному блоку MATLAB, чтобы открыть редактор функциональных блоков MATLAB.

  3. Измените код функционального блока MATLAB:

    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.

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

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

  5. Скопируйте блок «Настройки» из этой модели в noise_cancel_02 модель:

    1. От design_templates выберите «Правка» > «Выбрать все».

    2. Выберите меню «Правка» > «Копировать».

    3. От noise_cancel_02 выберите меню «Редактирование» > «Вставить».

  6. Подключите выходы Adapt и Reset подсистемы Settings к соответствующим входам функционального блока MATLAB. Теперь модель должна выглядеть следующим образом.

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

Моделирование модели с помощью элементов управления Adapt и Reset.  Чтобы смоделировать модель и увидеть влияние элементов управления Адаптировать (Adapt) и Сбросить (Reset), выполните следующие действия.

  1. В noise_cancel_03 просмотрите область сходимости:

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

    2. Дважды щелкните область Сходимость (Convergence).

  2. В окне Модель симулятора (Simulink model) щелкните Выполнить (Run).

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

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

  3. Остановите моделирование.

Создание кода

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

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

  1. Переименование функционального блока MATLAB в LMS_Filter. Выберите аннотацию MATLAB Function под функциональным блоком MATLAB и заменить текст на LMS_Filter.

    При создании кода для функционального блока MATLAB кодер Simulink использует имя блока в сгенерированном коде. Рекомендуется использовать значимое имя.

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

    Откроется редактор функциональных блоков MATLAB.

  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. На левой панели диалогового окна «Параметры конфигурации» выберите «Создание кода» > «Отчет».

    3. На правой панели выберите Создать отчет о создании кода и Открыть отчет автоматически.

    4. Нажмите кнопку Применить (Apply) и закройте диалоговое окно Параметры конфигурации (Configuration Parameters).

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

  2. Для генерации кода для подсистемы фильтра LMS:

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

    2. В меню инструмента Модель сборки (Build Model) выберите команду Построить выбранную подсистему (Build Selected Subsystem).

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

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

      Дополнительные сведения об использовании отчета о создании кода см. в разделе Создание отчета о создании кода (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.

    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. Нажмите кнопку «Построить».

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

    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 до нуля. Эти сигналы инициализируются до нуля в сгенерированном коде С.

Код 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.

  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. Нажмите кнопку «Построить».

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

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

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

См. также

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

Подробнее