Keyboard shortcuts

Press or to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

Oscillators

Oscillators are the sound sources in any synthesizer—they generate the raw waveforms that filters and effects shape.

VCO (Voltage-Controlled Oscillator)

The primary sound source for subtractive synthesis.

let vco = patch.add("vco", Vco::new(44100.0));

Inputs

PortSignalRangeDescription
voctV/Oct±5VPitch (0V = C4)
fmBipolar CV±5VExponential FM (±5V ≈ ±5 octaves)
pwUnipolar CV0-10VPulse width, default 50%
syncGate0/5VHard sync reset
fm_linBipolar CV±5VLinear through-zero FM (±5V ≈ ±100% of base freq)

Outputs

PortSignalDescription
sinAudioSine wave
triAudioTriangle wave (bandlimited, PolyBLAMP)
sawAudioSawtooth wave (bandlimited, PolyBLEP)
sqrAudioSquare/pulse wave (bandlimited, PolyBLEP)

Waveform Mathematics

Sine: $$y(t) = A \sin(2\pi f t)$$

Sawtooth (BLIT): $$y(t) = 2 \left( \frac{t}{T} - \lfloor \frac{t}{T} + 0.5 \rfloor \right)$$

Triangle: $$y(t) = 2 \left| 2 \left( \frac{t}{T} - \lfloor \frac{t}{T} + 0.5 \rfloor \right) \right| - 1$$

Square/Pulse: $$y(t) = \text{sign}(\sin(2\pi f t) - \cos(\pi \cdot \text{PW}))$$

Usage Example

// Basic VCO with external pitch
patch.connect(pitch_cv.out("out"), vco.in_("voct"))?;

// FM synthesis
patch.connect(modulator.out("sin"), vco.in_("fm"))?;

// PWM (pulse width modulation)
patch.connect(lfo.out("tri"), vco.in_("pw"))?;

LFO (Low-Frequency Oscillator)

Sub-audio oscillator for modulation.

let lfo = patch.add("lfo", Lfo::new(44100.0));

Inputs

PortSignalRangeDescription
rateUnipolar CV0-10VFrequency (0.01-30 Hz)
depthUnipolar CV0-10VOutput amplitude
resetTrigger0/5VPhase reset

Outputs

PortSignalDescription
sinBipolar CVSine wave (±5V)
triBipolar CVTriangle wave
sawBipolar CVSawtooth wave
sqrBipolar CVSquare wave
sin_uniUnipolar CVUnipolar sine (0-10V)

Rate Mapping

Default rate curve: $$f = 0.01 \cdot e^{(\text{CV}/10) \cdot \ln(3000)}$$

CVFrequency
0V0.01 Hz
5V~1 Hz
10V30 Hz

Noise Generator

White and pink noise sources with a CV-controllable stereo second channel.

let noise = patch.add("noise", NoiseGenerator::new());

Inputs

PortSignalRangeDescription
correlationUnipolar CV0-10VStereo correlation (0 = independent, 1 = identical), default 0.3

Outputs

PortSignalDescription
whiteAudioWhite noise
pinkAudioPink noise
white2AudioSecond white channel, correlated with white
pink2AudioSecond pink channel, correlated with pink

Noise Spectra

White noise: Equal energy per frequency (flat spectrum)

$$S(f) = \text{constant}$$

Pink noise: Equal energy per octave (-3dB/octave)

$$S(f) \propto \frac{1}{f}$$

Pink noise is generated using the Voss-McCartney algorithm.


AnalogVco

VCO with analog imperfections for authentic vintage sound.

use quiver::analog::AnalogVco;

let vco = patch.add("vco", AnalogVco::new(44100.0));

Additional Features

  • V/Oct tracking errors
  • Component tolerance variation
  • High-frequency rolloff
  • Soft saturation

See Analog Modeling for details.


Supersaw

JP-8000-style stack of seven detuned PolyBLEP saws with an octave-down sub. type_id: supersaw.

let saw = patch.add("saw", Supersaw::new(44100.0));

Inputs

PortSignalRangeDescription
voctV/Oct±5VPitch (0V = C4)
detuneUnipolar CV0-10VDetune spread of the 7 voices, default 50%
mixUnipolar CV0-10VBlend between center voice and full supersaw, default 50%

Outputs

PortSignalDescription
outAudioMixed 7-oscillator supersaw
subAudioOctave-down bandlimited saw sub-oscillator

Wavetable

Mip-mapped, bandlimited wavetable oscillator with 8 tables and smooth crossfade morphing. type_id: wavetable.

let wt = patch.add("wt", Wavetable::new(44100.0));

Inputs

PortSignalRangeDescription
v_octV/Oct±5VPitch (0V = C4)
tableUnipolar CV0-10VTable select across 8 tables
morphUnipolar CV0-10VCrossfade morph between adjacent tables
syncGate0/5VHard sync (resets phase)

Outputs

PortSignalDescription
outAudioWavetable output

The 8 built-in tables are: Sine, Triangle, Saw, Square, Pulse (25%), Pulse (12%), Formant A, Formant O.


FormantOsc

Vocal-synthesis oscillator: a glottal pulse driven through five parallel resonant formant filters. type_id: formant_osc.

let vox = patch.add("vox", FormantOsc::new(44100.0));

Inputs

PortSignalRangeDescription
v_octV/Oct±5VPitch (0V = C4)
vowelUnipolar CV0-10VInterpolates the vowel A → E → I → O → U
formant_shiftBipolar CV±5VShifts all formant frequencies (0.5×–2×)
vibratoUnipolar CV0-10VVibrato depth (up to ±0.5 semitone)

Outputs

PortSignalDescription
outAudioVocal formant output

KarplusStrong

Karplus-Strong physical-model plucked string with damping, brightness, and inharmonicity. type_id: karplus_strong.

let string = patch.add("string", KarplusStrong::new(44100.0));

Inputs

PortSignalRangeDescription
voctV/Oct±5VPitch → string period
triggerTrigger0/5VRising edge plucks the string
dampingUnipolar CV0-10VLoop lowpass amount, default 50%
brightnessUnipolar CV0-10VNoise-vs-impulse excitation blend, default 50%
stretchBipolar CV±5VAll-pass stretch / inharmonicity

Outputs

PortSignalDescription
outAudioPlucked-string output

SamplePlayer

Mono sample playback with V/Oct pitch, selectable start position, one-shot / looping modes, and an end-of-sample trigger. Reads are cubic-interpolated; the audio path is allocation-free (only set_buffer allocates). type_id: sample_player.

// buffer: Vec<f64>, recorded at buffer_sample_rate; engine runs at engine_sample_rate.
let sp = patch.add("sp", SamplePlayer::new(buffer, 44100.0, 44100.0));
// Or start empty and load later with `set_buffer`:
let sp = patch.add("sp", SamplePlayer::empty(44100.0));

Inputs

PortSignalRangeDescription
trigTrigger0/5VRising edge starts one-shot playback
gateGate0/5VGated playback (release stops it)
voctV/Oct±5VPlayback pitch (0V = unity rate)
startUnipolar CV0-10VStart position (0–1 of buffer)
loopGate0/5VEnables looping when high

Outputs

PortSignalDescription
outAudioSample output
eosTriggerFires at end of sample

Common Patterns

Detuned Oscillators

let vco1 = patch.add("vco1", Vco::new(sr));
let vco2 = patch.add("vco2", Vco::new(sr));

// Slight detune for thickness
let detune = patch.add("detune", Offset::new(0.01));  // ~12 cents

patch.connect(pitch.out("out"), vco1.in_("voct"))?;
patch.connect(pitch.out("out"), vco2.in_("voct"))?;
patch.connect(detune.out("out"), vco2.in_("voct"))?;  // Adds to pitch

Hard Sync

// Slave syncs to master
patch.connect(master.out("sqr"), slave.in_("sync"))?;

// Modulate slave pitch for classic sync sweep
patch.connect(lfo.out("sin"), slave.in_("voct"))?;

FM Synthesis

// Carrier:Modulator = 1:1 for harmonic FM
patch.connect(modulator.out("sin"), carrier.in_("fm"))?;

// Control FM depth with envelope
patch.connect(env.out("env"), fm_vca.in_("cv"))?;
patch.connect(fm_vca.out("out"), carrier.in_("fm"))?;