- PVSM.RU - https://www.pvsm.ru -
Все посты серии:
Часть 1. Введение и настройка [1]
Часть 2. Изучение кода [2]
Часть 3. VST и AU [3]
Часть 4. Цифровой дисторшн [4]
Часть 5. Пресеты и GUI [5]
______________________________________________________________
Давайте добавим несколько предустановок для плагина и создадим [относительно] симпатичный интерфейс.
Пресет — это настройки, позволяющие хранить конкретные значения параметров. На данный момент в нашем коде пресеты состоят из названия и значений для всех параметров, но, как мы увидим позже, тут можно хранить и другие данные. Пресеты еще иногда называют программами (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», но в выпадающем списке все пресеты на месте и все работает как надо. Сохранение пресетов в плагине работает иначе — мы не можем импортировать и экспортировать банки пресетов. Процессы сохранениязагрузки описаны Оли Ларкиным более детально в этом посте [6].
Пора, наконец, приступать к созданию красивого интерфейса!
Такого результата мы хотим добиться:
Это конечно не офигительно круто, но мы узнаем как можно добавлять графику и, что еще интереснее, как можно сделать вращающуюся ручку.
Скачайте этот TIFF [7] с дизайном. Откройте в Фотошопе (или в чем вам больше нравится) и взгляните на разные слои и группы.
Как видим, единственное, что меняется — это ручка. Так что остальное можно просто сохранить в одном png:
Сохраните картинку выше себе на рабочий стол. В Xcode в Project Navigator раскройте папку Resources и перетяните туда фоновую картинку:
Надо поставить галочку напротив Copy items into folder и добавить наше изображение для всех таргетов:
В Visual Studio добавление ресурсов (типа графики) немного отличается. Добавление для всех таргетов на Маке означает, что картинка будет включена в файлы .app, .vst и .component, которые вы предоставляете своим пользователям. В Visual Studio для этого надо сначала кинуть нашу картинку в подпапку проекта resourcesimg, а затем отредактировать файл .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. Это бесплатная программа, специально для создания ручек. Скачайте [8], запустите, и откройте в ней файл [9], который я подготовил:
Все, что я тут сделал — добавил три слоя и немного поменял некоторые координаты, чтобы металлическая текстура вращалась правильно. Если хотите разобраться с программой получше, прочитайте руководство [10].
Экспортируйте эту ручку (Cmd+E на Mac, Ctrl+E на Windows) и назовите файл knob.png (или скачайте мой [11]). В этом 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
.
С минимальным количеством теоретических наворотов мы создали работающий дисторшн с кастомным интерфейсом. Это дало нам общее представление о том, что включает в себя разработка плагина.
Теперь, когда у нас есть это понимание, можно приступить к более интересным вещам. В следующий раз я расскажу о синтезе звуковых волн.
Файлы со всеми результатами работы можно скачать [12].
Существует много бесплатных примеров для KnobMan тут [13] и тут [14].
При создании GUI я пользовался вот этим уроком [15] по Фотошопу. Спасибо автору!
И спасибо g200kg [16] за KnobMan!
Автор: 1eqinfinity
Источник [5]
Сайт-источник PVSM.RU: https://www.pvsm.ru
Путь до страницы источника: https://www.pvsm.ru/interfejsy/61932
Ссылки в тексте:
[1] Часть 1. Введение и настройка: http://habrahabr.ru/post/224911/
[2] Часть 2. Изучение кода: http://habrahabr.ru/post/225019/
[3] Часть 3. VST и AU: http://habrahabr.ru/post/225457/
[4] Часть 4. Цифровой дисторшн: http://habrahabr.ru/post/225751/
[5] Часть 5. Пресеты и GUI: http://habrahabr.ru/post/225755/
[6] этом посте: http://forum.cockos.com/showpost.php?p=969598
[7] этот TIFF: http://martin-finke.de/blog/articles/audio-plugins-007-gui/gui.tif
[8] Скачайте: http://www.g200kg.com/en/software/knobman.html
[9] файл: http://martin-finke.de/blog/articles/audio-plugins-007-gui/knob.knob
[10] руководство: http://www.g200kg.com/en/docs/knobman/overview.html
[11] мой: http://martin-finke.de/blog/articles/audio-plugins-007-gui/knob.png
[12] скачать: http://martin-finke.de/blog/articles/audio-plugins-007-gui/DigitalDistortion_Finished.zip
[13] тут: http://www.kvraudio.com/forum/viewtopic.php?t=232629
[14] тут: http://radorec.com/-skins/20-free-vst-knobs
[15] вот этим уроком: http://psd.tutsplus.com/tutorials/interface-tutorials/creating-a-cool-brushed-metal-surface-in-photoshop/
[16] g200kg: http://www.g200kg.com/
Нажмите здесь для печати.