Часть 1. Введение и настройка
Часть 2. Изучение кода
Часть 3. VST и AU
Часть 4. Цифровой дисторшн
Часть 5. Пресеты и GUI
______________________________________________________________
Давайте добавим несколько предустановок для плагина и создадим [относительно] симпатичный интерфейс.
Пресеты
Пресет — это настройки, позволяющие хранить конкретные значения параметров. На данный момент в нашем коде пресеты состоят из названия и значений для всех параметров, но, как мы увидим позже, тут можно хранить и другие данные. Пресеты еще иногда называют программами (programs).
Для начала давайте сделаем окно GUI пошире. Поменяйте соответствующую константу в resource.h:
// GUI default dimensions #define GUI_WIDTH 400
В DigitalDistortion.h объявим private
функцию-член класса:
private: double mThreshold; void CreatePresets(); А в DigitalDistortion.cpp добавим void DigitalDistortion::CreatePresets() { MakePreset("clean", 100.0); MakePreset("slightly distorted", 80.0); MakePreset("woooo", 40.0); MakePreset("waaaa", 20.0); MakePreset("buzzz!!!", 0.01); }
MakePreset
в качестве аргументов берет имя пресета и значения для всех параметров. Порядок следования аргументов определен в enum EParams
вверху файла.
Обратите внимание, что значения параметров меняются от 0 до 100, а не от 0 до 1. Эти значения относятся к параметру kThreshold
, а не к переменной mThreshold
.
Вместо вызова функции MakeDefaultPreset
в конце конструктора напишите вызов CreatePresets
:
DigitalDistortion::DigitalDistortion(IPlugInstanceInfo instanceInfo) : IPLUG_CTOR(kNumParams, kNumPrograms, instanceInfo), mThreshold(1.) { // ... CreatePresets(); }
Наконец, нам надо изменить константу, которая передается при вызове конструктора базового класса (это где-то в окрестностях 13-й строки):
const int kNumPrograms = 5;
Если значение этой константы больше, чем реальное количество пресетов, остальные просто будут называться «Empty».
Запустите сборку VST2. Возможно придется удалить плагин с дорожки и подгрузить его повторно, чтобы появились свеженаписанные пресеты. Их можно менять, используя выпадающий список, который находится прямо над GUI плагина. Попробуйте разные — ручка поворачивается в соответствии со значением в пресете.
Напомню, что OnParamChange
вызывается при изменении каждого параметра.
Справа от выпадающего меню есть кнопка, открывающая меню пресетов:
Попробуйте переименовать пресет и покрутить ручку. Ее положение не запомнится, если удалить плагин с дорожки и загрузить снова. Чтобы сохранить эти данные, щелкните “Export VST patch/bank file (.fxp/.fxb)…” и сохраните файл test.fxb на рабочий стол. Теперь удалите плагин, снова добавьте его и подгрузите этот файл с настройками.
Плагины VST для хранения отдельного пресета используют формат FXP, а для хранения банка пресетов — FXB.
Запустите таргет AU (возможно сначала придется зайти в Edit Scheme, чтобы он запускался вместе с хостом). REAPER по умолчанию пишет «No preset», но в выпадающем списке все пресеты на месте и все работает как надо. Сохранение пресетов в плагине работает иначе — мы не можем импортировать и экспортировать банки пресетов. Процессы сохранения\загрузки описаны Оли Ларкиным более детально в этом посте.
Пора, наконец, приступать к созданию красивого интерфейса!
GUI
Такого результата мы хотим добиться:
Это конечно не офигительно круто, но мы узнаем как можно добавлять графику и, что еще интереснее, как можно сделать вращающуюся ручку.
Скачайте этот TIFF с дизайном. Откройте в Фотошопе (или в чем вам больше нравится) и взгляните на разные слои и группы.
Как видим, единственное, что меняется — это ручка. Так что остальное можно просто сохранить в одном png:
Добавление фона для сборок на Mac
Сохраните картинку выше себе на рабочий стол. В Xcode в Project Navigator раскройте папку Resources и перетяните туда фоновую картинку:
Надо поставить галочку напротив Copy items into folder и добавить наше изображение для всех таргетов:
Добавление фона для сборок на Windows
В Visual Studio добавление ресурсов (типа графики) немного отличается. Добавление для всех таргетов на Маке означает, что картинка будет включена в файлы .app, .vst и .component, которые вы предоставляете своим пользователям. В Visual Studio для этого надо сначала кинуть нашу картинку в подпапку проекта resources\img, а затем отредактировать файл .rc в проекте. В данном случае, DigitalDistortion.rc. Его шапка выглядит так:
#include "resource.h" KNOB_ID PNG KNOB_FN
Сначала подключается resource.h, так что все #define
из него доступны и в этом файле. Следующая строка объявляет, что будет добавлена ручка. Чтобы добавить фон, допишите это строку:
BACKGROUND_ID PNG BACKGROUND_FN
Через минутку добавим BACKGROUND_ID
и BACKGROUND_FN
в resource.h.
Каждый раз при добавлении изображения к проекту нам нужно добавлять подобную строчку.
Фоновое изображение
Давайте подцепим нашу картинку в плагин. Где-то в районе 60-й строки в файле resource.h нужно изменить размер окна:
// GUI default dimensions #define GUI_WIDTH 280 #define GUI_HEIGHT 230
и добавить уникальный ID и имя файла изображения:
// Unique IDs for each image resource. #define KNOB_ID 101 #define BACKGROUND_ID 102 // Image resource locations for this plug. #define KNOB_FN "resources/img/knob.png" #define BACKGROUND_FN "resources/img/background.png"
В DigitalDistortion.cpp надо изменить конструктор, чтобы использовать наш файл вместо красного цвета:
// pGraphics->AttachPanelBackground(&COLOR_RED); pGraphics->AttachBackground(BACKGROUND_ID, BACKGROUND_FN);
Это было несложно. Давайте соберем APP и полюбуемся на картинку:
Ручка
Ручка немного сложнее. У нее есть текстура и отражения, она состоит из нескольких слоев. Когда крутишь ручку, металл вращается, а лампа на потолке — нет (будем надеяться). Так что какие-то составляющие должны вращаться, а какие-то, имеющие отношение к освещению, не должны. Поэтому мы не сможем сохранить ручку как одну картинку и крутить ее в процессе.
Я сделал так: у ручки есть основа, которая не вращается; поверх нее металлическая текстура, которая вращается; и сверху всего этого — отражения, которые не вращаются. Все три части представлены по отдельности (тут я добавил черный фон, просто чтобы было видно границы и светлые части):
Для нашей задачи есть очень хороший инструмент: KnobMan. Это бесплатная программа, специально для создания ручек. Скачайте, запустите, и откройте в ней файл, который я подготовил:
Все, что я тут сделал — добавил три слоя и немного поменял некоторые координаты, чтобы металлическая текстура вращалась правильно. Если хотите разобраться с программой получше, прочитайте руководство.
Экспортируйте эту ручку (Cmd+E на Mac, Ctrl+E на Windows) и назовите файл knob.png (или скачайте мой). В этом png есть 128 кадров для разных положений ручки, и вращаются только металл со стрелкой. То, что надо.
В Xcode удалите существующий knob.png (правый клик, Delete). В появивщемся диалоге выберите Move to Trash. Теперь перетяните новый knob.png в папку img и проделайте все то же самое, что мы делали с фоновым изображением.
Так как имя файла не поменялось, нам нет необходимости менять resource.h. Переключайтесь сразу на DigitalDistortion.cpp изменяйте enum ELayout
:
enum ELayout { kWidth = GUI_WIDTH, kHeight = GUI_HEIGHT, kThresholdX = 79, kThresholdY = 62, kKnobFrames = 128 };
Как видно, нам даже не приходится указывать для WDL, что новая ручка больше. Нам нужно только указать количество кадров и задать координаты.
Запускайте VST2 и посмотрите, как при вращении ручки меняются кадры. Однако меня смущает то, что плагин называется дисторшн, а при ручке, выкрученной на 100%, у нас чистый звук.
Направление ручки
Где-то около 90-й строки надо внести изменения:
mThreshold = 1 - (GetParam(kThreshold)->Value() / 100.);
Чтобы предотвратить деление на ноль, о котором мы говорили ранее, надо изменить значение по умолчанию на 0
, и максимальное значение на 99.99
(примерно 30-я строка):
GetParam(kThreshold)->InitDouble("Threshold", 0.0, 0.0, 99.99, 0.01, "%");
Теперь все должно работать как надо. С семантической точки зрения хорошо бы еще переименовать переменную Threshold
во что-то типа DistortionAmount
, так как единственное, что представляет пороговое значение, это переменная mThreshold
.
Промежуточные результаты
С минимальным количеством теоретических наворотов мы создали работающий дисторшн с кастомным интерфейсом. Это дало нам общее представление о том, что включает в себя разработка плагина.
Теперь, когда у нас есть это понимание, можно приступить к более интересным вещам. В следующий раз я расскажу о синтезе звуковых волн.
Файлы со всеми результатами работы можно скачать.
Дополнительные материалы
Существует много бесплатных примеров для KnobMan тут и тут.
При создании GUI я пользовался вот этим уроком по Фотошопу. Спасибо автору!
И спасибо g200kg за KnobMan!
ссылка на оригинал статьи http://habrahabr.ru/post/225755/
Добавить комментарий