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

  • Tutorial
Все посты серии:
Часть 1. Введение и настройка
Часть 2. Изучение кода
Часть 3. VST и AU
Часть 4. Цифровой дисторшн
Часть 5. Пресеты и GUI
Часть 6. Синтез сигналов
Часть 7. Получение MIDI сообщений
Часть 8. Виртуальная клавиатура
Часть 9. Огибающие
Часть 10. Доработка GUI
Часть 11. Фильтр
Часть 12. Низкочастотный осциллятор
Часть 13. Редизайн
Часть 14. Полифония 1
Часть 15. Полифония 2
Часть 16. Антиалиасинг



Низкочастотный осциллятор (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, то есть срез теперь изменяется под воздействием двух параметров.
Вот, собственно, и все! Протестируйте — звук должен быть слегка пульсирующим, это особенно заметно, если выбрать форму волны, отличную от синуса.

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

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



Оригинал поста.
Поделиться публикацией

Похожие публикации

Комментарии 2

    0
    Огромное спасибо за этот замечательный цикл статей! По этой теме очень мало хороших материалов, практически нет (по крайней мере на русском)…
      0
      Пожалуйста :)
      Надеюсь, это подтолкнет русскоязычных разработчиков к написанию своих статей.

    Только полноправные пользователи могут оставлять комментарии. Войдите, пожалуйста.

    Самое читаемое