Данная страница содержит основные сведения для разработки собственного плагина. Плагин - это фактически отдельный фильтр.
Перед разработкой собственного плагина рекомендуется к прочтению страница о принципе работы приложения SoundPipe.
- Для начала следует придумать идею нового фильтра, какую задачу он выполняет и при этом иметь примерное понимание достижимости этого посредством инструментария SoundPipe.
- Разработку рекомендуется вести в IDE Visual Studio 2022. Разработка плагинов ведется на языке C#, поэтому через Visual Studio Installer перед разработкой необходимо установить рабочую нагрузку
Разработка классических приложений .NET. - Для удобства склонируйте себе репозиторий SoundPipe на локальную машину, затем откройте решение
SoundPipe.sln - Создание плагина начинается с создания проекта фильтра. Фильтры рекомендуется создавать в папке решения
SP.Filters. В ней создайте проект с типомБиблиотека классов (Майкрософт), рекомендуемый namespace и имя проекта -SP.Filters.FilterName. - Созданный проект должен иметь доступ к SDK для разработки плагинов, для этого добавьте созданному проекту зависимость от проекта
SP.SDK. - Для того чтобы проект сделать именно проектом плагина SoundPipe, создайте публичный класс наследуемый от
IFilterEntry(интерфейс определения фильтра). Сам новый класс принято называтьEntry.cs. Данный интерфейс является точкой входа для приложения когда оно пытается загрузить плагин. - Реализуйте созданный ранее класс определения фильтра. Про это подробнее ниже.
- Интерфейс определения фильтра в методе
ConstructFilterтребует класс реализующий интерфейсISoundFilter(интерфейс звукового потока). Создайте этот класс. - Реализуйте созданный ранее класс звукового потока фильтра. Про это подробнее ниже.
Для примера разберем уже существующий фильтр - SP.Filters.Volume.
Анализ разберем на два блока -
- Реализация класса определения фильтра
- Реализация класса звукового потока фильтра
Чтобы приступить к разбору выполните шаги из раздела "Описание процесса" до 3 пункта включительно. Исходный код разбираемого фильтра лежит в папке SP.Filters.
Определение фильтра хранится в файле Entry.cs и являет собой реализацию интерфейса IFilterEntry. Фактически, когда SoundPipe видит очередной фильтр, он в нем ищет именно реализации этого интерфейса, и по ним понимает какого типа фильтр перед ним, какое у него имя, описание, параметры и связи.
Разберемся с списком методов этого интерфейса и их функциями (а также его реализацией в фильтре Volume):
-
string FilterName()
Имя фильтра строкой, в нашем случае это "Volume". Отметим что имя фильтра должно быть уникальным, оно используется для идентификации фильтра среди остальных. -
string FilterDescription()
Описание фильтра. Оно будет высвечено в UI при наведении на имя фильтра. Желательно не более 2-3 предложений, кратко описывающих задачу вашего фильтра. В нашем примере указано что фильтр используется для изменения громкости входного звукового потока. -
int FilterVersion()
Версия фильтра, задается целым числом начиная с 1. Если вы решите выпустить обновление для фильтра, следует увеличить это значение для новой версии. Сразу отметим политику открытия схемы с плагином старой версии - если сигнатура (множество связей, параметров) фильтра старой версии отличается от сигнатуры фильтра новой версии, такой фильтр будет поставлен на схеме без связей и параметров (т.е. их придется задать заново). В нашем примере фильтр Volume имеет фильтр версии 1. -
FilterType GetFilterType()
Тип фильтра, их бывает 3 -- Consumer -
Фильтр потребитель. Их особенность - отсутствие входных звуковых потоков. К примеру, таким фильтром является Speaker. Фильтры потребители являются инициаторами запросов чанков.
Следует отметить, что такие фильтры первыми проходят деструкцию во время процесса закрытия схемы. - Provider - Фильтр посредник. Является звуковым потоком. Их особенность - они пропускают чанки через себя, определенным образом их модифицируя. Наш фильтр Volume как раз таким и является.
- SequentialProvider - Фильтр серийный посредник. Является звуковым потоком, в основном схож с Provider. Отличительная особенность - выход такого фильтра (звуковой поток) может быть прочитан двумя другими фильтрами (в то время как у Provider лишь одним). Таким фильтром является Hub, разделяющий (фактически дублирующий) входной поток.
- Consumer -
Фильтр потребитель. Их особенность - отсутствие входных звуковых потоков. К примеру, таким фильтром является Speaker. Фильтры потребители являются инициаторами запросов чанков.
-
FilterGroupType GetGroupType()
Группа для отображения фильтра на UI. В данный момент существует 6 групп -- Input - Фильтры имеющие только выходной поток, фактически фильтры источники как микрофон, файл, генератор тона.
- Consumer - Фильтры потребители, не имеющие выходного потока. К ним относятся такие фильтры как воспроизведение (Speaker), запись в файл и т.д.
- Filter - Фильтры обработчики звука. К ним относится, например, Volume (рассматриваемый фильтр), сложение каналов (Add), фильтр низких частот (LowPass) и другие.
- Analyzer - Фильтры анализаторы, показывающие различные метрики потока. Например фильтр замера уровня громкости (VolumeLevel), отображения звуковой волны (WaveVisualizer) и анализ фурье последнего чанка (FurieVisualizer).
- Logic - Фильтры логической обработки. Например генераторы условия для блока Condition, такие как VolumeGate (посылает сигнал если уровень громкости выше заданного) или ButtonGate (посылает сигнал пока кнопка в нажатом состоянии).
Отметим, что в основе работы того-же фильтра Condition лежит логика того, что его первый входной звуковой поток представляет собой условие, при соблюдении которого выход фильтра будет равен второму потоку, иначе третьему. Для превращения первого звукового потока в поток условия принято обозначение что 1.0 в семплах означает его соблюдение, в то время как 0.0 несоблюдение. Таким образом первый его поток является служебным, и не подлежит интерпретации как звуковой (т.е. например, для воспроизведения). - Other - Остальные фильтры. Фильтры которые не подходят для обозначенных ранее групп следует располагать тут. В данной группе находится фильтр Hub.
Отметим, что данный тип никак не сказывается на функционале, а лишь на UI группе, в которую будет помещен ваш фильтр.
-
Uri GetSourceCodeLink()
Ссылка исходного кода плагина. Рекомендуется использовать ссылку на GitHub. Более того, при разработке собственного плагина, можете создать PR и после прохождения ревью он может быть добавлен в репозиторий проекта SoundPipe. -
DynamicParameter[] ConstructorParamaters()
Множество параметров инициализации фильтра. Каждый параметр содержит имя, описание, тип и значение по умолчанию.
Про существующие типы можно подробнее прочитать в разделе SP.SDK на странице для разработчиков.
Рассматриваемый фильтр Volume имеет два инициирующих параметра:- input - имя входного файла.
- volume - изначальный множитель уровня громкости.
Отметим, что инициализирующие параметры необходимо задать до начала симуляции.
DynamicParameter[] HotParamaters()
Множество динамических параметров фильтра. Порядок установки соответствует инициализирующим параметрам. Также параметр может быть настроен как "только для чтения" или "только для записи". Основное отличие от инициирующих - их можно задавать/читать только во время симуляции. Чтение происходит периодически (по умолчанию каждые 100мс).
В нашем примере фильтр Volume имеет такой один параметр - level (уровень громкости, который можно динамически задавать во время симуляции).ISoundFilter ConstructFilter()
Класс звукового потока. Именно данная реализация класса определяет логику инициализации, возвращения чанка на запрос, установку/чтение динамического параметра, деструкцию фильтра. В нашем случае это классVolume.cs. Подробнее будет рассмотрено ниже.
Каждый фильтр должен реализовать класс звукового потока.
Перед рассмотрением сигнатуры методов этого интерфейса рассмотрим основную идею фильтра Volume:
Задача этого фильтра - изменение громкости входного потока. Вспоминаем что звуковой поток работает с чанками (последовательность семплов). Для изменения громкости достаточно умножить значение каждого семпла чанка на заданный коэффициент, и это и будет ответом (т.к. семпл показывает относительную амплитуду, то мы ее умножив, например на 2, увеличим и громкость в 2 раза).
Теперь рассмотрим интерфейс звукового потока -
void Initialize(object[] args)
Инициализирует фильтр изначальными параметрами. На типы этих параметров как раз указывает упомянутый ранее метод ConstructFilter у описанного интерфейса IFilterEntry.
В нашем случае фильтр Volume запоминает переданный ему звуковой поток источник (который слева) а также изначальный коэффициент модификатора громкости.void SetHotValue(string key, object value)
Установка динамического параметра. Отметим что множество динамических параметров как раз было ранее описано в методе HotParamaters интерфейса IFilterEntry.
В случае Volume в данном методе происходит обновление коэффициента громкости (посредством параметра level).object GetHotValue(string key)
Получение динамического параметра.
В случае Volume происходит возврат параметра level (коэффициент громкости).SoundData ReadPart(int length)
Запрос очередного чанка заданной длины. Отметим, что длина задана в семплах, а также что этот метод будет вызван другим подключенным фильтром (справа), когда ему понадобится очередная порция данных.
В случае Volume, мы сначала считываем данные из фильтра источника (который от нас слева), т.к. мы являемся посредником. Далее применяем к этим данным фильтр громкости (умножаем каждый семпл чанка на заданный коэффициент) и возвращаем результат.void Destroy()
Метод деструкции фильтра. В случае Volume он пустой, однако может быть полезен если следует выполнить какие-либо действия при высвобождении фильтра (например закрытие файла у фильтра Input).
Также рекомендуем вам обратиться к исходному коду и других фильтров в папке SP.Filters.
Для отладки разрабатываемого плагина рекомендуем настроить его копирование в папку фильтров SoundPipe, например bat скриптом:
copy SP.Filters.Volume\bin\Debug\net6.0\SP.Filters.Volume.dll %appdata%\SoundPipe\Filters
Порядок действий -
- Сборка плагина
Можно через ПКМ проекта, собрать. - Запуск BAT
Скопирует собранный dll плагин в папку фильтров SoundPipe. - Запуск SoundPipe
Будет содержать отлаживаемый плагин.
Для установки плагина на сторонней машине достаточно отправить dll файл вашего плагина и установить его на удаленной машине через меню "Плагины", "Установить новый".
Также можно создать PR в папку SP.Filters репозитория SoundPipe.