Создание аудиоплагинов, часть 12

Все посты серии: Часть 1. Введение и настройкаЧасть 2. Изучение кодаЧасть 3. VST и AUЧасть 4. Цифровой дисторшнЧасть 5. Пресеты и GUIЧасть 6. Синтез сигналовЧасть 7. Получение MIDI сообщенийЧасть 8. Виртуальная клавиатураЧасть 9. ОгибающиеЧасть 10. Доработка GUIЧасть 11. ФильтрЧасть 12. Низкочастотный осцилляторНизкочастотный осциллятор (Low Frequency Oscillator, LFO) — это важная составляющая любого классического синтезатора, и мы добавим ее в свой плагин. Как понятно из названия, это просто осциллятор. Мы используем написанный нами ранее класс Oscillator и зададим ему низкую частоту.Начнем с Synthesis.h. Добавьте в private:

Oscillator mLFO; double lfoFilterModAmount; lfoFilterModAmount обозначает, как сильно LFO будет влиять на фильтр. Этот параметр надо инициализировать в конструкторе в Synthesis.cpp:

lfoFilterModAmount (0.1) Почему именно 0.1? Тут мы просто хотим показать принципиальную легкость создания LFO. Мы добавим отдельные ручки управления этому осциллятору позже, на этапе редизайна. В конец конструктора допишите:

mLFO.setMode (OSCILLATOR_MODE_TRIANGLE); mLFO.setFrequency (6.0); mLFO.setMuted (false); Тут просто выбирается треугольная волна, частота 6 Гц, и снимается флаг isMuted. Если добавлять для LFO элементы управления в интерфейс, то первые две функции должны вызываться из OnParamChange. А флаг isMuted зависит от того, равно ли нулю значение параметра lfoFilterModAmount.

Так как это осциллятор, мы должны сообщать ему об изменениях частоты семплирования в Synthesis: Reset:

mLFO.setSampleRate (GetSampleRate ()); Теперь давайте установим в ProcessDoubleReplacing некоторые значения LFO. Замените цикл for на следующий:

for (int i = 0; i < nFrames; ++i) { mMIDIReceiver.advance(); int velocity = mMIDIReceiver.getLastVelocity(); double lfoFilterModulation = mLFO.nextSample() * lfoFilterModAmount; mOscillator.setFrequency(mMIDIReceiver.getLastFrequency()); mFilter.setCutoffMod((mFilterEnvelopeGenerator.nextSample() * filterEnvelopeAmount) + lfoFilterModulation); leftOutput[i] = rightOutput[i] = mFilter.process(mOscillator.nextSample() * mEnvelopeGenerator.nextSample() * velocity / 127.0); } Значение lfoFilterModulation меняется от -1 до +1. Для аргумента функции setCutoffMod мы складываем контролируемую огибающей частоту среза и величину lfoFilterModulation, то есть срез теперь изменяется под воздействием двух параметров.Вот, собственно, и все! Протестируйте — звук должен быть слегка пульсирующим, это особенно заметно, если выбрать форму волны, отличную от синуса.

Код проекта на данной стадии можно скачать отсюда.

В следующий раз займемся редизайном, чтобы плагин выглядел приятнее:

fb143e653d964044bd118206a44aa7fb.png

Оригинал статьи: martin-finke.de/blog/articles/audio-plugins-014-lfo/

© Habrahabr.ru