modulation.h
The modulation family: an LFO, and the four effects that are nothing but one.
#include <sonore/modulation.h>- 6types
- Guides: Getting started, MIDI and MPE
On this page
Design notes
A tremolo is a gain multiplied by an LFO; an auto-panner is a constant- power pan driven by one; a vibrato is a delay read at a moving point; a ring modulator is a multiply by a sine. None of that is hard, and every one of them has been written from scratch, slightly wrong, on demand: a tremolo whose depth changes its centre level, a pan that dips 3 dB in the middle, a vibrato read with the linear tap (a lowpass that sweeps with it), a ring modulator with the carrier leaking through. This is the family, once, on the rules the rest of the SDK already keeps.
The LFO itself is the part worth having: free-running at a rate in hertz with the shapes people keep re-implementing -- sine, triangle, saw, square, sample-and-hold, and the SMOOTHED random that a sample-and-hold through a one-pole gives (the "drift" every analogue-modelled plugin offers). All shapes run -1..1, unipolar() maps them to 0..1, and a phase offset lets a stereo pair be a quarter turn apart. For an LFO locked to the host's bars, transport.h's SyncedLfo is the one to use; this one is for the rate knob.
Included by dsp.h.
Types 6
A free-running low-frequency oscillator: sine, triangle, saw, square, sample-and-hold and smoothed random, every shape -1..1 (see the file comment; for one locked to the host's bars use transport.h's SyncedLfo).
Call setSampleRate() in prepare() -- the rate in hertz is kept and worked out again for the new sample rate, clamped to 0.45 of it -- and reset() to start the cycle and the random sequence from the seed, so that two renders match. next() is one sample. The setters are cheap enough to call every block, and all of it runs on the audio thread. The random shapes draw a new value each cycle from a Random seeded with setSeed().
Tremolo. The gain swings between 1 and 1 - depth, so depth 0 is silence- free unity and the level never exceeds the input; a stereo phase puts the right channel's swing anywhere from in step to opposite.
Auto-pan: a constant-power pan swept by the LFO, so the sum of the two channels' powers is the input's at every instant -- no dip in the middle.
template <int MaxSamples = 8192> class Vibrato
Vibrato: a short delay read at a point that moves with the LFO, cubic tap. Depth in CENTS, converted to the delay swing that produces it: a sinusoidal delay of amplitude D samples at rate f gives a peak pitch deviation of 2 pi f D / fs, so D follows from the cents asked for.
Ring modulator: the signal times a carrier sine, mixed against the dry. Sidebands at f +/- carrier; the carrier itself does not appear, because a multiply has no additive term.
Flanger: the Chorus machine at a flanger's settings -- a delay under ten milliseconds swept from near zero, with feedback, so the comb's notches are audible and move. Positive feedback emphasises the peaks, negative the notches (the "hollow" flange). One class rather than a preset, because a plugin asks for it by name.