diff --git a/docs/engine_distortion.md b/docs/engine_distortion.md new file mode 100644 index 0000000..6295e9e --- /dev/null +++ b/docs/engine_distortion.md @@ -0,0 +1,65 @@ +# Distortion + +Distortion effects add harmonics by nonlinearly shaping the waveform. + +## Saturation + +Soft saturation using the transfer function `x / (1 + k|x|)`. + +```forth +saw 2 distort . +saw 8 distort 0.5 distortvol . ( with volume compensation ) +``` + +| Parameter | Range | Description | +|-----------|-------|-------------| +| `distort` | 0+ | Saturation amount | +| `distortvol` | 0-1 | Output volume | + +## Wavefolding + +Wavefolding reflects the signal when it exceeds ±1, using `sin(x × amount × π/2)`. + +```forth +sine 4 fold . +``` + +| Parameter | Range | Description | +|-----------|-------|-------------| +| `fold` | 0+ | Fold amount | + +## Wavewrapping + +Wavewrapping applies modulo to wrap the signal into the -1 to 1 range. + +```forth +saw 3 wrap . +``` + +| Parameter | Range | Description | +|-----------|-------|-------------| +| `wrap` | 0+ | Number of wraps | + +## Bit Crushing + +Bit crushing quantizes the signal to fewer amplitude levels. + +```forth +snare 6 crush . ( 6-bit = 32 levels ) +``` + +| Parameter | Range | Description | +|-----------|-------|-------------| +| `crush` | 1-16 | Bit depth | + +## Sample Rate Reduction + +Sample rate reduction holds each sample for multiple output samples. + +```forth +hat 4 coarse . ( 1/4 effective sample rate ) +``` + +| Parameter | Range | Description | +|-----------|-------|-------------| +| `coarse` | 1+ | Reduction factor (1 = bypass) | diff --git a/docs/engine_filters.md b/docs/engine_filters.md new file mode 100644 index 0000000..f773578 --- /dev/null +++ b/docs/engine_filters.md @@ -0,0 +1,131 @@ +# Filters + +Filters attenuate frequencies above or below a cutoff point. + +## Lowpass Filter + +The lowpass filter (`lpf`) attenuates frequencies above the cutoff. + +```forth +saw 1000 lpf . ( cut above 1000 Hz ) +saw 500 lpf 0.8 lpq . ( with resonance ) +``` + +| Parameter | Range | Description | +|-----------|-------|-------------| +| `lpf` | Hz | Cutoff frequency | +| `lpq` | 0-1 | Resonance (peak at cutoff) | + +## Highpass Filter + +The highpass filter (`hpf`) attenuates frequencies below the cutoff. + +```forth +kick 200 hpf . ( cut below 200 Hz ) +pad 400 hpf 0.3 hpq . ( with resonance ) +``` + +| Parameter | Range | Description | +|-----------|-------|-------------| +| `hpf` | Hz | Cutoff frequency | +| `hpq` | 0-1 | Resonance | + +## Bandpass Filter + +The bandpass filter (`bpf`) attenuates frequencies outside a band around the center frequency. + +```forth +noise 1000 bpf 0.7 bpq . ( narrow band around 1000 Hz ) +``` + +| Parameter | Range | Description | +|-----------|-------|-------------| +| `bpf` | Hz | Center frequency | +| `bpq` | 0-1 | Resonance (narrower band) | + +## Filter Slope + +The `ftype` parameter sets the filter slope (rolloff steepness). + +| Value | Slope | +|-------|-------| +| `1` | 12 dB/octave | +| `2` | 24 dB/octave (default) | +| `3` | 48 dB/octave | + +```forth +saw 800 lpf 3 ftype . ( 48 dB/oct lowpass ) +``` + +## Filter Envelope + +Filters can be modulated by an ADSR envelope. The envelope multiplies the base cutoff: + +``` +final_cutoff = lpf + (lpe × envelope × lpf) +``` + +When the envelope is at 1.0 and `lpe` is 1.0, the cutoff doubles. When the envelope is at 0, the cutoff equals `lpf`. + +```forth +saw 200 lpf 2 lpe 0.01 lpa 0.3 lpd . ( cutoff sweeps from 600 Hz down to 200 Hz ) +``` + +| Parameter | Description | +|-----------|-------------| +| `lpe` | Envelope depth (multiplier, 1.0 = double cutoff at peak) | +| `lpa` | Attack time in seconds | +| `lpd` | Decay time in seconds | +| `lps` | Sustain level (0-1) | +| `lpr` | Release time in seconds | + +The same pattern works for highpass (`hpe`, `hpa`, etc.) and bandpass (`bpe`, `bpa`, etc.). + +## Ladder Filters + +Ladder filters use a different algorithm (Moog-style) with self-oscillation at high resonance. + +```forth +saw 800 llpf 0.7 llpq . ( ladder lowpass ) +saw 300 lhpf 0.5 lhpq . ( ladder highpass ) +saw 1000 lbpf 0.8 lbpq . ( ladder bandpass ) +``` + +| Parameter | Range | Description | +|-----------|-------|-------------| +| `llpf` | Hz | Ladder lowpass cutoff | +| `llpq` | 0-1 | Ladder lowpass resonance | +| `lhpf` | Hz | Ladder highpass cutoff | +| `lhpq` | 0-1 | Ladder highpass resonance | +| `lbpf` | Hz | Ladder bandpass cutoff | +| `lbpq` | 0-1 | Ladder bandpass resonance | + +Ladder filters share the lowpass envelope parameters (`lpe`, `lpa`, etc.). + +## EQ + +The 3-band EQ applies shelf and peak filters at fixed frequencies. + +```forth +kick 3 eqlo -2 eqhi . ( +3 dB at 200 Hz, -2 dB at 5000 Hz ) +snare 2 eqmid . ( +2 dB at 1000 Hz ) +``` + +| Parameter | Frequency | Type | +|-----------|-----------|------| +| `eqlo` | 200 Hz | Low shelf (dB) | +| `eqmid` | 1000 Hz | Peak (dB) | +| `eqhi` | 5000 Hz | High shelf (dB) | + +## Tilt EQ + +Tilt EQ applies a high shelf at 800 Hz with up to ±6 dB gain. + +```forth +pad -0.5 tilt . ( -3 dB above 800 Hz ) +hat 0.5 tilt . ( +3 dB above 800 Hz ) +``` + +| Parameter | Range | Description | +|-----------|-------|-------------| +| `tilt` | -1 to 1 | High shelf gain (-1 = -6 dB, 0 = flat, 1 = +6 dB) | diff --git a/docs/engine_modulation.md b/docs/engine_modulation.md new file mode 100644 index 0000000..58d5f66 --- /dev/null +++ b/docs/engine_modulation.md @@ -0,0 +1,132 @@ +# Modulation + +Modulation effects vary parameters over time using LFOs or envelopes. + +## Vibrato + +Vibrato modulates pitch with an LFO. + +```forth +saw 5 vib 0.5 vibmod . ( 5 Hz, 0.5 semitone depth ) +``` + +| Parameter | Range | Description | +|-----------|-------|-------------| +| `vib` | Hz | LFO rate | +| `vibmod` | semitones | Modulation depth | +| `vibshape` | shape | LFO waveform (sine, tri, saw, square) | + +## Pitch Envelope + +The pitch envelope applies an ADSR to the oscillator frequency. + +```forth +sine 100 freq 24 penv 0.001 patt 0.1 pdec . +``` + +| Parameter | Description | +|-----------|-------------| +| `penv` | Envelope depth in semitones | +| `patt` | Attack time in seconds | +| `pdec` | Decay time in seconds | +| `psus` | Sustain level (0-1) | +| `prel` | Release time in seconds | + +## Glide + +Glide interpolates between pitch changes over time. + +```forth +saw c4 0.1 glide . ( 100ms glide ) +``` + +| Parameter | Range | Description | +|-----------|-------|-------------| +| `glide` | seconds | Glide time | + +## FM Synthesis + +FM modulates the carrier frequency with a modulator oscillator. + +```forth +sine 440 freq 2 fm 2 fmh . ( modulator at 2× carrier frequency ) +``` + +| Parameter | Range | Description | +|-----------|-------|-------------| +| `fm` | 0+ | Modulation index | +| `fmh` | ratio | Harmonic ratio (modulator / carrier) | +| `fmshape` | shape | Modulator waveform | + +FM has its own envelope (`fme`, `fma`, `fmd`, `fms`, `fmr`). + +## Amplitude Modulation + +AM multiplies the signal by an LFO. + +```forth +pad 4 am 0.5 amdepth . ( 4 Hz tremolo ) +``` + +| Parameter | Range | Description | +|-----------|-------|-------------| +| `am` | Hz | LFO rate | +| `amdepth` | 0-1 | Modulation depth | +| `amshape` | shape | LFO waveform | + +## Ring Modulation + +Ring modulation multiplies two signals, producing sum and difference frequencies. + +```forth +saw 150 rm 0.8 rmdepth . ( ring mod at 150 Hz ) +``` + +| Parameter | Range | Description | +|-----------|-------|-------------| +| `rm` | Hz | Modulator frequency | +| `rmdepth` | 0-1 | Modulation depth | +| `rmshape` | shape | Modulator waveform | + +## Phaser + +Phaser sweeps notches through the frequency spectrum using allpass filters. + +```forth +pad 0.5 phaser 0.6 phaserdepth . +``` + +| Parameter | Range | Description | +|-----------|-------|-------------| +| `phaser` | Hz | Sweep rate | +| `phaserdepth` | 0-1 | Sweep depth | +| `phasersweep` | cents | Sweep range | +| `phasercenter` | Hz | Center frequency | + +## Flanger + +Flanger mixes the signal with a short modulated delay (0.5-10ms). + +```forth +pad 0.3 flanger 0.7 flangerdepth 0.5 flangerfeedback . +``` + +| Parameter | Range | Description | +|-----------|-------|-------------| +| `flanger` | Hz | Modulation rate | +| `flangerdepth` | 0-1 | Modulation depth | +| `flangerfeedback` | 0-0.95 | Feedback amount | + +## Chorus + +Chorus uses multiple modulated delay lines with 120° phase offset for stereo width. + +```forth +pad 1 chorus 0.4 chorusdepth 20 chorusdelay . +``` + +| Parameter | Range | Description | +|-----------|-------|-------------| +| `chorus` | Hz | Modulation rate | +| `chorusdepth` | 0-1 | Modulation depth | +| `chorusdelay` | ms | Base delay time | diff --git a/docs/engine_space.md b/docs/engine_space.md new file mode 100644 index 0000000..c00796e --- /dev/null +++ b/docs/engine_space.md @@ -0,0 +1,118 @@ +# Space & Time + +Spatial effects position sounds in the stereo field and add depth through delays and reverbs. + +## Pan + +Pan positions a sound in the stereo field. + +```forth +hat -0.5 pan . ( slightly left ) +perc 1 pan . ( hard right ) +kick 0 pan . ( center ) +``` + +| Parameter | Range | Description | +|-----------|-------|-------------| +| `pan` | -1 to 1 | Stereo position (-1 = left, 0 = center, 1 = right) | + +## Width + +Width controls the stereo spread using mid-side processing. + +```forth +pad 1.5 width . ( wider stereo ) +pad 0 width . ( mono ) +``` + +| Parameter | Range | Description | +|-----------|-------|-------------| +| `width` | 0+ | Stereo width (0 = mono, 1 = unchanged, 2 = exaggerated) | + +## Haas Effect + +The Haas effect delays one channel slightly, creating a sense of stereo width and spatial placement. + +```forth +snare 15 haas . ( 15ms delay on right channel ) +``` + +| Parameter | Range | Description | +|-----------|-------|-------------| +| `haas` | ms | Delay time (1-10ms = subtle width, 10-35ms = distinct echo) | + +## Delay + +Delay is a send effect that creates echoes. The `delay` parameter sets how much signal is sent to the delay bus. + +```forth +snare 0.3 delay 0.25 delaytime 0.5 delayfeedback . +``` + +| Parameter | Range | Description | +|-----------|-------|-------------| +| `delay` | 0-1 | Send level | +| `delaytime` | seconds | Delay time | +| `delayfeedback` | 0-0.95 | Feedback amount | +| `delaytype` | type | Delay algorithm | + +### Delay Types + +| Type | Description | +|------|-------------| +| `standard` | Clean digital repeats | +| `pingpong` | Bounces between left and right | +| `tape` | Each repeat gets darker (analog warmth) | +| `multitap` | 4 taps with swing control via feedback | + +```forth +snare 0.4 delay pingpong delaytype . +pad 0.3 delay tape delaytype . +``` + +## Reverb + +Reverb is a send effect that simulates acoustic spaces. The `verb` parameter sets the send level. + +```forth +snare 0.2 verb 2 verbdecay . +pad 0.4 verb 4 verbdecay 0.7 verbdamp . +``` + +| Parameter | Range | Description | +|-----------|-------|-------------| +| `verb` | 0-1 | Send level | +| `verbdecay` | seconds | Reverb tail length | +| `verbdamp` | 0-1 | High frequency damping | +| `verbpredelay` | ms | Initial delay before reverb | +| `verbdiff` | 0-1 | Diffusion (smears transients) | +| `verbtype` | type | Reverb algorithm | + +### Reverb Types + +| Type | Description | +|------|-------------| +| `dattorro` | Plate reverb, bright and metallic shimmer | +| `fdn` | Hall reverb, dense and smooth | + +```forth +snare 0.3 verb dattorro verbtype . ( plate ) +pad 0.5 verb fdn verbtype . ( hall ) +``` + +## Comb Filter + +The comb filter creates resonant pitched delays, useful for Karplus-Strong string synthesis and metallic tones. + +```forth +white 0.5 comb 220 combfreq 0.9 combfeedback . ( plucked string ) +``` + +| Parameter | Range | Description | +|-----------|-------|-------------| +| `comb` | 0-1 | Send level | +| `combfreq` | Hz | Resonant frequency | +| `combfeedback` | 0-0.99 | Feedback (higher = longer decay) | +| `combdamp` | 0-1 | High frequency damping | + +Higher feedback creates longer, ringing tones. Add damping for more natural string-like decay. diff --git a/docs/engine_words.md b/docs/engine_words.md new file mode 100644 index 0000000..91a0f03 --- /dev/null +++ b/docs/engine_words.md @@ -0,0 +1,43 @@ +# Words & Sounds + +Word definitions let you abstract sound design into reusable units. + +## Defining Sounds + +```forth +: lead "saw" s 0.3 gain 1200 lpf ; +``` + +Use it with different notes: + +```forth +c4 note lead . +e4 note lead . +``` + +## Self-Contained Words + +Include the emit to make the word play directly: + +```forth +: kk "kick" s 1 decay . ; +: hh "hihat" s 0.5 gain 0.5 decay . ; +``` + +Steps become simple: + +```forth +kk +0.5 at hh +``` + +## Effect Presets + +```forth +: dark 800 lpf 0.6 lpq ; +: wet 0.7 verb 8 verbdiff ; +``` + +```forth +c4 note saw s dark wet . +``` diff --git a/src/views/help_view.rs b/src/views/help_view.rs index 3cd63fd..59b7981 100644 --- a/src/views/help_view.rs +++ b/src/views/help_view.rs @@ -48,6 +48,17 @@ const DOCS: &[DocEntry] = &[ Topic("Sources", include_str!("../../docs/engine_sources.md")), Topic("Samples", include_str!("../../docs/engine_samples.md")), Topic("Wavetables", include_str!("../../docs/engine_wavetable.md")), + Topic("Filters", include_str!("../../docs/engine_filters.md")), + Topic( + "Modulation", + include_str!("../../docs/engine_modulation.md"), + ), + Topic( + "Distortion", + include_str!("../../docs/engine_distortion.md"), + ), + Topic("Space & Time", include_str!("../../docs/engine_space.md")), + Topic("Words & Sounds", include_str!("../../docs/engine_words.md")), // Reference Section("Reference"), Topic("Audio Engine", include_str!("../../docs/audio_engine.md")),