Чтобы создать ваш алгоритм как аудио плагин, необходимо соответствовать аудио сменному API. Когда авторские аудио плагины в среде MATLAB®, помните об этих распространенных ошибках и лучшых практиках.
Чтобы узнать больше об аудио плагинах в целом, смотрите Аудио Плагины в MATLAB.
Когда Audio Test Bench запускает аудио плагин, это последовательно:
Вызывает метод сброса
Устанавливает настраиваемые свойства, сопоставленные параметрами
Вызывает метод процесса
При выполнении Audio Test Bench вызывает в цикле метод процесса и затем set
методы для настроенных свойств. Сменный API не задает порядок, что настроенные свойства установлены.
Возможно разрушить нормальную синхронизацию методов путем прерывания очереди событий. Распространенные способы случайно прервать очередь событий включают использование a plot
или drawnow
функция.
Примечание
plot
и drawnow
доступно только в среде MATLAB. plot
и drawnow
не может быть включен в сгенерированные плагины. См. Отдельный Код для Функций, Не Поддерживавших для Сменной Генерации для получения дополнительной информации.
В следующем фрагменте кода усиление применилось к левым и правым каналам, различный если связанный Gain
параметр настраивается во время вызова процесса:
... L = plugin.Gain*in(:,1); drawnow R = plugin.Gain*in(:,2); out = [L,R]; ...
Автор прерывает очередь событий во фрагменте кода, вызывая set
методы свойств сопоставили параметрами, которые будут названы, в то время как метод процесса посреди выполнения.
В зависимости от вашего алгоритма обработки, прерывая очередь событий может привести к противоречивому и ошибочному поведению. Кроме того, set
метод не может быть явным, который может сделать проблему трудной разыскать. Возможные меры для проблемы разрушения очереди событий включают свойства сохранения в локальные переменные и перемещение разрушения очереди к началу или концу метода процесса.
Можно сохранить настраиваемые значения свойств в локальные переменные в начале обработки. Этот метод гарантирует, что значения, используемые во время метода процесса, не обновляются в одном вызове процесса. Поскольку доступ к значению локальной переменной является более дешевым, чем доступ к значению свойства, сохраняя свойства в локальные переменные, к которым получают доступ, многократно лучшая практика.
... gain = plugin.Gain; L = gain*in(:,1); drawnow R = gain*in(:,2); out = [L,R]; ...
Можно переместить разрушение в очередь событий к нижней части или верхней части метода процесса. Этот метод гарантирует, что значения свойств не обновляются посреди вызова.
... L = plugin.Gain*in(:,1); R = plugin.Gain*in(:,2); out = [L,R]; drawnow ...
Среда MATLAB предлагает функциональность, не поддержанную для сменной генерации. Можно отметить код, чтобы проигнорировать во время сменной генерации путем размещения его в условном операторе при помощи coder.target
(MATLAB Coder).
... if coder.target('MATLAB') ... end ...
generateAudioPlugin
, код в операторе if coder.target('MATLAB')
проигнорирован.Например, timescope
не включен для генерации кода. Если при запуске следующий плагин в MATLAB, можно использовать визуализировать функцию, чтобы открыть осциллограф времени, который строит степень ввода и вывода на систему координат.
Распространенная ошибка в аудио сменной авторской разработке неправильно использует метод сброса. Допустимое использование метода сброса включает:
Очистка состояния
Передача вызовов, чтобы сбросить к объектам компонента
Обновление свойств, которые зависят от частоты дискретизации
Недопустимое использование метода сброса включает устанавливание значения любых свойств, сопоставленных параметрами. Не используйте свой метод сброса, чтобы установить свойства, сопоставленные параметрами к их начальным условиям. Установка Directly свойство, сопоставленное параметром, вызывает свойство быть вне синхронизации параметром. Например, следующий плагин является примером неправильного использования метода сброса.
classdef badReset < audioPlugin properties Gain = 1; end properties (Constant) PluginInterface = audioPluginInterface(audioPluginParameter('Gain')); end methods function out = process(plugin,in) out = in*plugin.Gain; end function reset(plugin) % <-- Incorrect use of reset method. plugin.Gain = 1; % <-- Never set values of a property that is end % associated with a plugin parameter. end end
Если ваш плагин состоит из других плагинов, то необходимо передать частоту дискретизации и вызовы, чтобы сбросить к плагинам компонента. Вызовите setSampleRate
в методе сброса, чтобы передать частоту дискретизации к плагинам компонента. К настройкам параметров плагинов компонента создайте аудио сменный интерфейс в составном плагине для настраиваемых параметров плагинов компонента. Затем передайте значения в set
методы для связанных свойств. Следующее является примером сменного состава, который был создан с помощью лучшых практик.
Сменный состав Используя основные плагины
Сменный состав с помощью Системных объектов имеет эти основные отличия от сменного состава с помощью основных плагинов.
Сразу вызовите setup
в вашей Системе компонента object™ после того, как это создается. Конструкция и настройка объекта компонента происходят в конструкторе составного плагина.
Если ваш Системный объект компонента запрашивает информацию частоты дискретизации, то это имеет свойство частоты дискретизации. Установите свойство частоты дискретизации в методе сброса.
Рекомендуется, чтобы вы подавили предупреждение когда авторские аудио плагины.
Следующий фрагмент кода следует плагину, создающему лучшую практику для обработки изменений в свойстве Cutoff
параметра.
classdef highpassFilter < audioPlugin ... properties (Constant) PluginInterface = audioPluginInterface( ... audioPluginParameter('Cutoff', ... 'Label','Hz',... 'Mapping',{'log',20,2000})); end methods function y = process(plugin,x) [y,plugin.State] = filter(plugin.B,plugin.A,x,plugin.State); end function set.Cutoff(plugin,val) plugin.Cutoff = val; [plugin.B,plugin.A] = highpassCoeffs(plugin,val,getSampleRate(plugin)); % <<<< warning occurs here end end ... end
highpassCoeffs
функциональная сила быть дорогой, и должна быть названа только при необходимости. Вы не хотите вызывать highpassCoeffs
в методе процесса, который запускается в цикле обработки аудиоданных в реальном времени. Логическое место, чтобы вызвать highpassCoeffs
находится в set.Cutoff
. Однако mlint
показывает предупреждение для этой практики. Предупреждение предназначается, чтобы помочь вам избежать проблем порядка инициализации при сохранении и загрузке классов. Смотрите Избегают Зависимости от Порядка Инициализации Свойства для получения дополнительной информации. Решение, рекомендуемое предупреждением, состоит в том, чтобы создать зависимое свойство с get
метод и вычисляет значение там. Однако в соответствии с рекомендацией усложняет проект и продвигает расчет назад в метод обработки в режиме реального времени, которого вы стараетесь избегать.
Вы можете также подвергнуться предупреждению при правильной реализации сменного состава. Для примера правильной реализации состава смотрите Состав Плагина Реализации Правильно.
Аудио сменный API требует, чтобы аудио плагины поддержали вводы и выводы переменного размера. Для частичного списка Системных объектов, которые поддерживают сигналы переменного размера, смотрите Системные объекты DSP Поддержки Сигнала Переменного Размера. Вы можете столкнуться с проблемами, при попытке использовать объекты, которые не поддерживают сигналы переменного размера в вашем плагине.
Например, dsp.AnalyticSignal
не поддерживает сигналы переменного размера. BrokenAnalyticSignalTransformer
плагин использует dsp.AnalyticSignal
возразите неправильно, и перестал работать validateAudioPlugin
испытательный стенд:
validateAudioPlugin BrokenAnalyticSignalTransformer
Checking plug-in class 'BrokenAnalyticSignalTransformer'... passed. Generating testbench file 'testbench_BrokenAnalyticSignalTransformer.m'... done. Running testbench... Error using dsp.AnalyticSignal/parenReference Changing the size on input 1 is not allowed without first calling the release() method. Error in BrokenAnalyticSignalTransformer/process (line 13) analyticSignal = plugin.Transformer(in); Error in testbench_BrokenAnalyticSignalTransformer (line 61) o1 = process(plugin, in(:,1)); Error in validateAudioPlugin
Смотрите BrokenAnalyticSignalTransformer
Код
Если вы хотите использовать функциональность Системного объекта, который не поддерживает сигналы переменного размера, можно буферизовать ввод и вывод Системного объекта, или всегда вызывать объект с одной выборкой.
Можно создать цикл вокруг вызова объекта. Цикл выполняет итерации для количества выборок в вашем переменном формате кадра. Вызов объекта в цикле всегда является одной выборкой.
Примечание
В зависимости от вашей реализации и конкретного объекта, вызывая объектную выборку выборкой в цикле может привести к значительной вычислительной стоимости.
Можно буферизовать вход к объекту к сопоставимому формату кадра, и затем буферизовать выход объекта назад к исходному формату кадра. dsp.AsyncBuffer
Системный объект является подходящим для этой задачи.
Примечание
Использование асинхронного объекта буферизации обеспечивает минимальную задержку вашего заданного формата кадра.
Часто полезно сопоставить свойство с набором строк или векторов символов. Однако ограничения на сменную генерацию требуют кэшируемых значений, таких как значения свойств, чтобы иметь статический размер. Чтобы работать вокруг этой проблемы, можно использовать отдельный класс перечисления, который сопоставляет строки с перечислениями, как описано в audioPluginParameter
документация.
В качестве альтернативы, если вы не хотите писать класс перечисления и сохранять весь ваш код в одном файле, можно использовать зависимое свойство сопоставить названия параметра ко множеству значений. В этом сценарии вы сопоставляете свою перечислимую величину со значением, которое можно кэшировать.