3.3 KiB
Introduction
Cagire includes an audio engine called Doux. No external software is needed to make sound. Doux is an opinionated, semi-modular synthesizer. It was designed for live coding environments and works by receiving command strings that describe sounds. Despite its fixed architecture,Doux is extremely versatile and will likely cover most of the audio needs of a live coder.
How It Works
When you write a Forth script and emit (.), the script produces a command string. This command travels to the audio engine, which interprets it and creates a voice. The voice plays until its envelope finishes or until it is killed by another voice. You can also spawn infinite voices, but you will need to manage their lifecycle manually, otherwise they will never stop.
saw s c4 note 0.8 gain 0.3 verb .
Voices
Each emit (.) creates or manages a voice by sending parameters. Voices are independent sound generators with their own oscillator, envelope, and effects. The engine can run many voices at once (up to 128, default 32). When you exceed the voice limit, the oldest voice is stolen (a process called round robin scheduling). You can monitor voice usage on the Engine page:
- Active voices: how many are playing right now.
- Peak voices: the maximum reached since last reset.
Press r on the Engine page to reset the peak counter.
Parameters
After selecting a sound source, you add parameters. Each parameter word takes a value from the stack and stores it in the command register:
saw s
c4 note ;; pitch
0.5 gain ;; volume
0.1 attack ;; envelope attack time
2000 lpf ;; lowpass filter at 2kHz
0.3 verb ;; reverb mix
.
Parameters can appear in any order. They accumulate until you emit. You can clear the register using the clear word.
Global Parameters
Use all to apply parameters globally. Global parameters persist across all patterns and steps until cleared with noall. They work both prospectively (before sounds) and retroactively (after sounds):
;; Prospective: set params before emitting
500 lpf 0.5 verb all
kick s 60 note . ;; gets lpf=500 verb=0.5
hat s 70 note . ;; gets lpf=500 verb=0.5
;; Retroactive: patch already-emitted sounds
kick s 60 note .
hat s 70 note .
500 lpf 0.5 verb all ;; both outputs get lpf and verb
Per-sound parameters override global ones:
500 lpf all
kick s 2000 lpf . ;; lpf=2000 (per-sound wins)
hat s . ;; lpf=500 (global)
Use noall to clear global parameters:
500 lpf all
kick s . ;; gets lpf
noall
hat s . ;; no lpf
Controlling Existing Voices
You can emit without a sound name. In this case, no new voice is created. Instead, the parameters are sent to control an existing voice. Use voice with an ID to target a specific voice:
0 voice 500 freq . ;; change frequency on voice 0
This is useful for modulating long-running or infinite voices. Set up a drone on one step with a known voice ID, then tweak its parameters from other steps.
Hush and Panic
Two emergency controls exist on the Engine page:
h- Hush: gracefully fade out all voicesp- Panic: immediately kill all voices
Use hush when things get too loud. Use panic when things go wrong.