Русский
Русский
English
Статистика
Реклама

VSTi-плагин ASIO-хоста для подключения входа дополнительного ASIO-драйвера в DAW

Столкнулся я как-то с ситуацией, когда, при наличии основной звуковой карты со своим ASIO-драйвером, необходимо было в DAW подключить USB-микрофон со своим ASIO-драйвером. А DAW не поддерживает подключение двух ASIO-драйверов одновременно. Поиском наткнулся на VST-плагин "VST interfaced ASIO-Host", написанный на Delphi. К сожалению, хоть и плагин увиделся через jBridge, нормально он так и не заработал. Таким образом, пришлось писать подобный плагин самому. В итоге, за 10 дней был написан плагин ASIOInput с открытым исходным кодом. В этой статье я расскажу о некоторых особенностях его разработки и архитектуры.

Сам VST-плагин технически является .dll, которая экспортирует единственную функцию

SVSTPlugin* VSTPluginMain(void*)

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

  • InputCount и OutputCount - количество входных и выходных каналов. Количество каналов - это строго заданная величина на этапе загрузки плагина, и в дальнейшем она меняться не может. Поэтому здесь я задаю 0 входных каналов и 2 выходных канала. Если потребуется 1 реальный канал, то он будет продублирован по обоим выходам плагина.

  • PluginProperties - флаги свойств плагина. Здесь задаем 3 флага: наличие собственного интерфейса, поддержка колбэка UpdateBufferData() и то, что плагин является инструментом - в некоторых DAW для инструментов заводятся отдельные дорожки в микшере, что удобно.

  • Колбэк RequestFromHost() - эту функцию будет вызывать DAW, чтобы проинформировать плагин о некоторых событиях. Минимально реализованный в плагине набор событий следующий: инициализация и де-инициализация плагина, приостановка и возобновление работы плагина, изменение частоты семплирования, изменение размера буфера семплов, а также события для графического интерфейса плагина: показать и скрыть окно редактора, получить размер окна редактора, и событие простоя - для перерисовки элементов интерфейса окна редактора.

  • Колбэк UpdateBufferData() - DAW вызывает эту функцию, когда ему нужно получить значения очередного набора звуковых семплов. Здесь же, в параметрах, указывается, сколько именно семплов хочет получить DAW при каждом вызове этой функции.

Дочерний же ASIO драйвер является Windows COM-объектом. Доступ к нему осуществляется по GUID-ам. Список всех ASIO-драйверов (имена и GUID-ы) хранится в реестре по адресу HKEYLOCALMACHINE\SOFTWARE\ASIO. Для работы с ASIO-драйвером, после инициализации COM-объекта по GUID-у функцией CoCreateInstance(), нужно инициализировать сам ASIO-драйвер, создать буферы для семплов, и непосредственно запустить ASIO-драйвер. Причем при вызове функции создания буферов семплов, необходимо также передать указатели на колбэки обновления данных в буфере и запросов от ASIO-драйвера к хосту.

Таким образом получается, что у плагина вызываются извне две функции: DAW вызывает функцию, где плагин должен заполнить данные выходных семплов от плагина в DAW - VSTPluginCallUpdateBufferData(), и дочерний ASIO-драйвер вызывает функцию, где отдает плагину очередную порцию данных семплов со входа звуковой карты - ASIOHostCallUpdateBufferDataEx(). Причем эти функции вызываются независимо друг от друга. А в случае, если размеры буферов семплов DAW и дочернего ASIO-драйвера разные, то еще и разное количество раз в секунду. Нам же необходимо передать данные от дочернего ASIO-драйвера в DAW, причем сделать это с минимальной задержкой.

В случае с одинаковым размером буфера семплов я применил синхронизацию двух вызовов. Таким образом, при запросе DAW-ом семплов от плагина, вызов функции приостанавливается до ближайшего вызова из дочернего ASIO-драйвера, в котором происходит обновление буфера DAW напрямую, только после чего функция запроса DAW-ом семплов от плагина отпускается и завершается. Технически синхронизация обеспечивается ожиданием событий ОС Windows (функции CreateEvent(), SetEvent() и WaitForSingleObject()).

Если же размер буферов DAW и дочернего ASIO-драйвера разный, то применяется кольцевой буфер. Колбэк дочернего ASIO-драйвера записывает данные в кольцевой буфер, а колбэк DAW-а считывает данные. Чтобы чтение не происходило во время записи, используется мютекс OC Windows. Размер кольцевого буфера выбирается как максимальный из размеров буферов DAW и дочернего ASIO-драйвера, и может настраиваться пользователем х2, х3 и х4.

Подводные камни при разработке плагина.

  • У COM-объекта ASIO-драйвера все функции возвращают 0 в случае успеха. Все, кроме функции инициализации. Она, в случае успеха, возвращает 1. Минус один вечер отладки.

  • DAW передает в плагин дескриптор родительского окна. Если после события скрытия окна редактора, не снять привязку окна редактора с этим дескриптором, то окно редактора плагина продолжает отображаться, но, в случае с DAW Cubase 9.5, поверх системного меню DAW - т.е. поверх "Файл, Правка" и т.д.

  • Если при создании буферов семплов указать ASIO-драйверу некорректное значение, то буферы создадутся с нужными ASIO-драйверу корректными размерами, но частота вызова колбэка будет рассчитана некорректно, и колбэк будет вызываться неверное количество раз в секунду. При этом функция создания буферов вернет 0. Еще минус один вечер отладки.

  • Не стоит де-инициализировать COM-объект дочернего ASIO-драйвера из колбэка самого ASIO-драйвера.

Скриншот ранней версии плагина с дополнительной отладочной информацией.

Скачать последнюю версию плагина (VST2, x86 и x64): тыц.

Исходники на гитхабе: тыц.

Источник: habr.com
К списку статей
Опубликовано: 15.11.2020 02:05:31
0

Сейчас читают

Комментариев (0)
Имя
Электронная почта

Программирование

Звук

Asio

Vst

Daw

Синхронизация потоков

Категории

Последние комментарии

  • Имя: Макс
    24.08.2022 | 11:28
    Я разраб в IT компании, работаю на арбитражную команду. Мы работаем с приламы и сайтами, при работе замечаются постоянные баны и лаги. Пацаны посоветовали сервис по анализу исходного кода,https://app Подробнее..
  • Имя: 9055410337
    20.08.2022 | 17:41
    поможем пишите в телеграм Подробнее..
  • Имя: sabbat
    17.08.2022 | 20:42
    Охренеть.. это просто шикарная статья, феноменально круто. Большое спасибо за разбор! Надеюсь как-нибудь с тобой связаться для обсуждений чего-либо) Подробнее..
  • Имя: Мария
    09.08.2022 | 14:44
    Добрый день. Если обладаете такой информацией, то подскажите, пожалуйста, где можно найти много-много материала по Yggdrasil и его уязвимостях для написания диплома? Благодарю. Подробнее..
© 2006-2024, personeltest.ru