Отфильтруйте звуковой сигнал Используя код 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. См. Компилятор Значения по умолчанию Изменения (MATLAB) и список Поддерживаемых Компиляторов.

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

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

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

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

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

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

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

      acoustic_environment

  2. Гарантируйте, что ваши динамики работают.

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

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

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

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

Цель этого примера состоит в том, чтобы использовать алгоритм фильтра 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 от блока 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 и Visualization и затем открывают блок Time Domain.

  2. В окне модели Simulink выберите Simulation> 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. Вы готовы разработать свою модель, чтобы использовать средства управления Reset и Adapt.

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

Почему Добавляют, Адаптируются и Средства управления Сбросом?.  В этой части примера вы добавляете, Адаптируются и средства управления Сбросом к вашему фильтру. Используя эти средства управления, можно включить и выключить фильтрацию. Когда 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 выберите Simulation> 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 выберите Simulation> Model Configuration Parameters.

    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-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 открывается.

  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.

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

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

Больше о