Тремоло (tremolo)тремоло (tremolo) — Эффект периодического изменения амплитуды аудиосигнала. Скорость пульсации задаёт частота управляющего генератора, а диапазон усиления зависит от глубины и способа её преобразования. — эффект, при котором амплитуда (amplitude)амплитуда (amplitude) — Наибольший модуль отклонения колеблющейся величины от равновесного значения. Для синусоиды обозначается A; единицы совпадают с единицами сигнала. звука периодически увеличивается и уменьшается. Например, удерживаемая нота начинает пульсировать: звучит сильнее, затем слабее, и это движение повторяется. Здесь речь об обработке аудиосигнала; исполнительское тремоло, то есть быстрое повторение ноты, — другое употребление слова.
Как управляющее колебание меняет звук
Представьте регулятор усиления, который непрерывно движется между двумя положениями. Низкочастотный генератор (low-frequency oscillator, LFO)низкочастотный генератор (low-frequency oscillator, LFO) — Генератор медленно повторяющегося управляющего сигнала, которым изменяют параметры звука, например усиление, частоту или панораму. Общей строгой верхней границы частоты у LFO нет. делает это автоматически: создаёт медленный сигнал управления, из которого вычисляется линейный коэффициент усиления (linear gain)линейный коэффициент усиления (linear gain) — Безразмерный множитель аудиосигнала: 1 сохраняет амплитуду, значение между 0 и 1 уменьшает её, значение больше 1 увеличивает. Отрицательный множитель также меняет знак сигнала. . При звук проходит без изменения, при его амплитуда уменьшается вдвое, при выход равен нулю.
Входной отсчёт (sample)отсчёт (sample) — Значение сигнала в один момент дискретизации, одно число. В звукозаписи его также называют сэмплом. умножается на текущее усиление: . Например, при и получаем . При неотрицательном усилении знак отсчёта сохраняется.
На рисунке 1 быстрые колебания — звук, а медленная пунктирная граница показывает изменение его амплитуды. Это огибающая (envelope)огибающая (envelope) — Плавная кривая, которая следует за размахом волны и показывает, как уровень сигнала меняется во времени.. Частота (frequency)частота (frequency) — Число полных колебаний за секунду. Обозначается f и измеряется в герцах; 1 Гц означает одно колебание в секунду. LFO задаёт скорость пульсации: при 5 Гц один цикл длится 0,2 с. Глубина модуляции (modulation depth)глубина модуляции (modulation depth) — Величина изменения управляемого параметра. Её единицы и шкала зависят от параметра: например, глубина может задавать отклонение частоты в герцах или долю ослабления звука. задаёт размах изменения усиления.
При тремоло меняется амплитуда; вибрато (vibrato)вибрато (vibrato) — Периодическое изменение высоты тона вокруг основного значения. В синтезаторе его можно получить, направив LFO на частоту звукового генератора. меняет высоту тона (pitch)высота тона (pitch) — Ощущение, по которому звук воспринимают как низкий или высокий. Для чистого тона растёт с частотой; физическая частота и ощущение высоты — разные величины.. Это разные маршруты управления, даже если оба используют LFO.
Вариант 1: только ослабление
Пусть биполярный сигнал (bipolar signal)биполярный сигнал (bipolar signal) — Сигнал, принимающий как положительные, так и отрицательные значения. Нормированный биполярный LFO меняется от −1 до +1 и может управлять отклонением параметра от его центрального значения. LFO меняется от −1 до +1. Преобразование даёт униполярный сигнал (unipolar signal)униполярный сигнал (unipolar signal) — Сигнал, принимающий значения одного знака, включая ноль. Для управления часто используют диапазон от 0 до 1; из биполярного LFO l его получают преобразованием u = (l + 1)/2. от 0 до 1. Тогда глубиной можно задать наибольшую долю ослабления: . После подстановки получается формула (1).
- глубина от 0 до 1, без единицы измерения; 0,4 соответствует 40 %;
- значение LFO от −1 до +1, без единицы измерения;
- линейное усиление в варианте A, от до 1;
- ,
- входной и выходной отсчёты одного канала в условной шкале цифровой амплитуды; — номер кадра.
Когда , ослабления нет: . Когда , оно наибольшее: . При глубине 40 % усиление меняется от 0,6 до 1; при 75 % — от 0,25 до 1. При сигнал проходит без изменения, а при усиление достигает нуля в минимуме.
Такое преобразование использует и пример Analog Devices. Оно удобно, когда эффект должен периодически ослаблять звук, сохраняя наибольшее усиление равным единице.
Вариант 2: колебание вокруг единицы
Можно сначала умножить LFO на глубину, затем прибавить единицу. Получим формулу (2):
- линейное усиление в варианте B, от до ; остальные обозначения те же.
В коде это выражение можно записать как output_sample = input_sample * (modulation_depth * lfo_value + 1). При преобразование проходит три шага, показанные на рисунке 2.
- LFO меняется от −1 до +1.
- Умножение на 0,4 сжимает его диапазон до −0,4…+0,4.
- Прибавление 1 переносит диапазон в 0,6…1,4. Теперь это коэффициент усиления: он остаётся положительным, но может быть больше единицы.
При усиление опять равно 1. При оно меняется от 0 до 2. Ограничение сохраняет неотрицательное усиление; при большей глубине часть цикла меняет знак аудиосигнала. Простое умножение тоже меняет знак и относится к кольцевой модуляции (ring modulation)кольцевая модуляция (ring modulation) — Перемножение двух сигналов с биполярным модулятором без постоянного смещения. При смене знака модулятора меняется и знак произведения., разобранной в том же учебнике Cycling ’74.
Формула выхода использует только текущий входной отсчёт и текущее значение LFO. Предыдущие выходные отсчёты в неё не входят. Состояние нужно генератору LFO: его фаза (phase)фаза (phase) — Положение внутри периода колебания, выраженное углом: полный период соответствует 360°, или 2π радиан. Начальная фаза — её значение в момент t = 0. продолжается от кадра к кадру и от блока к блоку.
Почему одинаковая глубина даёт разные результаты
Число имеет смысл только вместе с формулой. В варианте A оно задаёт наибольшую долю ослабления, в варианте B — отклонение усиления от 1 в каждую сторону. Поэтому надпись «глубина 40 %» сама по себе не определяет диапазон эффекта.
| Глубина D | A: только ослабление | B: вокруг 1 |
|---|---|---|
| 0 % | 1 — без изменения | 1 — без изменения |
| 40 % | 0,6…1 | 0,6…1,4 |
| 75 % | 0,25…1 | 0,25…1,75 |
| 100 % | 0…1 | 0…2 |
На рисунке 3 частота, фаза и шкала одинаковы. С увеличением глубины у A опускается минимум, а максимум остаётся равным 1. У B минимум опускается, а максимум поднимается. При одинаковом максимум одного варианта совпадает с минимумом другого: перед LFO в формуле A стоит минус, в B — плюс.
Для синусоидального LFO среднее усиление за целый цикл у A равно , а у B — 1. Это среднее коэффициента усиления; оно не означает сохранения среднеквадратичного уровня звука или воспринимаемой громкости (loudness)громкость (loudness) — Ощущение того, насколько сильным кажется звук. Зависит от звукового давления, частотного состава и условий восприятия.. У волны LFO с ненулевым средним значения будут другими.
Если разделить вариант B на его максимум , диапазон станет …1. Он совпадёт с вариантом A при глубине и противоположном знаке LFO. Для синусоиды смена знака соответствует сдвигу фазы на половину периода (period)период (period) — Время одного полного повторения периодического колебания. Обозначается T, измеряется в секундах и связано с частотой как T = 1/f.. Например, после такого уменьшения общего уровня даёт диапазон примерно 0,429…1; в варианте A этому соответствует глубина примерно 57,1 %, а не 40 %.
Пример на C++ и JUCE
Класс ниже реализует вариант A: синусоидальный LFO 5 Гц и глубину 75 %. Он сам задаёт функцию (function)функция (function) — Правило, сопоставляющее каждому допустимому значению аргумента ровно одно выходное значение. Запись h(u) обозначает результат функции h при аргументе u. синуса (sine)синус (sine) — Вертикальная координата точки на единичной окружности под заданным углом от положительного направления горизонтальной оси. Для острого угла прямоугольного треугольника равен отношению противолежащего катета к гипотенузе. и не требует копировать waveform из статьи о LFO. Нужен модуль juce::juce_dsp. API и листинг проверены с JUCE 9.0.3.
// Тремоло: 5 Гц, глубина 75 %, одно значение усиления для всех каналов кадра.
#include <cmath>
#include <juce_dsp/juce_dsp.h>
class Tremolo
{
public:
Tremolo()
{
lfo.initialise ([] (double phase) { return std::sin (phase); });
}
void prepare (double sampleRate, int maximumBlockSize)
{
lfo.prepare ({ sampleRate,
static_cast<juce::uint32> (maximumBlockSize), 1 });
lfo.setFrequency (5.0, true);
}
void reset() noexcept { lfo.reset(); }
void process (juce::AudioBuffer<float>& buffer) noexcept
{
constexpr double depth = 0.75;
for (int frame = 0; frame < buffer.getNumSamples(); ++frame)
{
const double modulation = lfo.processSample (0.0);
const float gain = static_cast<float>
(1.0 - 0.5 * depth * (1.0 + modulation));
for (int channel = 0; channel < buffer.getNumChannels(); ++channel)
buffer.getWritePointer (channel)[frame] *= gain;
}
}
private:
juce::dsp::Oscillator<double> lfo;
};Объект Tremolo tremolo хранится как член аудиопроцессора. В prepareToPlay вызвать tremolo.prepare (sampleRate, samplesPerBlock), в processBlock — tremolo.process (buffer). Передать буфер с совпадающими входными и выходными аудиоканалами (audio channel)аудиоканал (audio channel) — Отдельная последовательность отсчётов аудиосигнала. Моно содержит один канал, стерео — два, обычно левый и правый.; выходные каналы без входа предварительно очистить по правилам processBlock. Подготовка и создание функции выполняются вне аудиоколбэка (audio callback)аудиоколбэк (audio callback) — Функция, которую аудиосистема вызывает для передачи очередного блока входных данных и получения выходных. Обработчик должен завершиться до срока, когда нужны данные..
Вызов processSample (0.0) даёт значение генератора: метод JUCE прибавляет его к аргументу. Передача сюда аудиоотсчёта добавила бы LFO к звуку вместо вычисления усиления. Значение LFO вычисляется один раз на кадр и применяется ко всем каналам. Если вызывать генератор внутри цикла каналов, в стерео (stereo)стерео (stereo) — Аудиоформат с двумя каналами, обычно левым и правым. Кадр несжатых стереоданных содержит два отсчёта одного момента времени. его фаза продвинется дважды за кадр, а левый и правый каналы получат разные значения.
Цикл использует фактическую длину блока, включая нулевую. Фаза сохраняется между блоками; reset() вызывается по выбранному событию перезапуска, а не в начале каждого блока. После сброса синус в JUCE 9.0.3 начинается около нуля и движется вниз: первое усиление здесь равно примерно 0,625, а не 1.
Для варианта B при глубине 40 % изменить depth на 0.4, а выражение для gain — на static_cast<float> (1.0 + depth * modulation). Для варианта без dsp::Oscillator можно использовать класс Lfo из статьи о генераторе: получать lfo.nextSample (WaveShape::sine), готовить через prepare (sampleRate) и setFrequency (5.0). Формулы усиления сохраняются.
Форма LFO и переходы
Синус даёт плавное изменение усиления, треугольник — линейные подъём и спад. Прямоугольная волна переключает два уровня; при полной глубине вариант A будет чередовать исходный звук и нулевой выход. Резкая смена усиления может дать щелчки. Пила содержит скачок при переносе фазы.
Листинг использует фиксированные параметры. Если добавить ручки глубины и частоты, изменения нужно сглаживать; переключение формы и сброс фазы также могут резко поменять усиление. Это отдельные переходы, которые простой пример не обрабатывает. При повышении скорости LFO пульсация может восприниматься уже как изменение тембра (timbre)тембр (timbre) — Свойство слухового ощущения, по которому различают два звука одинаковой высоты и громкости. Зависит от состава спектра и его изменения во времени. — такое поведение амплитудной модуляции описывает Cycling ’74.
Самопроверка
При глубине 40 % LFO равен +1. Какое усиление дадут два варианта?
Вариант A: . Вариант B: . В первом случае звук ослаблен, во втором усилен. При LFO = −1 получились бы соответственно 1 и 0,6.
Что изменится, если частоту LFO увеличить с 5 до 10 Гц, сохранив глубину?
Пульсация ускорится вдвое: период сократится с 0,2 до 0,1 с. Диапазон усиления останется прежним, поскольку он задаётся глубиной и выбранной формулой.
Почему вариант B с глубиной 100 % может перегрузить выход, хотя его усиление не бывает отрицательным?
Его усиление меняется от 0 до 2. Входной отсчёт 0,8 при усилении 2 превращается в 1,6. Неотрицательное усиление сохраняет знак, но не ограничивает выходной уровень.
Источники
- Analog Devices. Tutorial: Implementing a Tremolo Effect, раздел Basic Tremolo with Fixed Parameters — синусоидальное управление и формула варианта с ослаблением.
- Cycling ’74. MSP Tutorial 9: Amplitude Modulation — смещение управляющего сигнала, глубина, различие амплитудной и кольцевой модуляции, переход к изменению тембра при высокой скорости.
- JUCE. Oscillator и исходник 9.0.3 — подготовка, сброс, начальная фаза и прибавление генератора к входу.
- JUCE. AudioBuffer — число каналов, длина блока и запись отсчётов.
Рисунки построены по формулам статьи и показывают расчётные сигналы.
Связи
Связи списком
Ссылается на
- Аудиоданные в программах: представление отсчётов, каналы, кадры и буферы
- Математика для аудио
- Огибающая ADSR и VCA: как нота начинается и затихает
- Уровень сигнала: децибелы, dBFS, пик, RMS и LUFS
- C++ в аудиопотоке: выделение памяти, общие объекты и инструменты JUCE
- LFO: низкочастотный генератор и модуляция