Files
Cagire/docs/forth/prelude.md
Raphaël Forment 82e5f47933
Some checks failed
Deploy Website / deploy (push) Failing after 20s
Feat: adapt cagire to doux v0.0.12
2026-03-14 12:43:18 +01:00

3.3 KiB

Preludes

Cagire has two levels of prelude: a project prelude shared by all banks, and bank preludes that travel with each bank.

Bank Prelude

Each bank can carry its own prelude script. Press p to open the current bank's prelude editor. Press Esc to save, evaluate, and close.

Bank preludes make banks self-contained. When you share a bank, its prelude travels with it — recipients get all the definitions they need without merging anything into their own project.

: bass pulse sound 0.8 gain 400 8000 0.01 0.3 0.5 0.3 env lpf 0.6 width . ;
: pad sine sound 0.5 gain 2 spread 1.5 attack 0.4 verb . ;

Every step in that bank can now use bass and pad. Share the bank and the recipient gets these definitions automatically.

Project Prelude

The project prelude is a global script shared across all banks. Press P (Shift+p) to open it. Use it for truly project-wide definitions, variables, and settings that every bank should see.

c2 !root
0 !mode
42 seed

Evaluation Order

When preludes are evaluated (on playback start, project load, or pressing d):

  1. Project prelude runs first
  2. Bank 0 prelude runs next (if non-empty)
  3. Bank 1 prelude, then Bank 2, ... up to Bank 31

Only non-empty bank preludes are evaluated. Last-evaluated wins for name collisions — a bank prelude can override a project-level definition.

Keybindings

Key Action
p Open current bank's prelude editor
P Open project prelude editor
d Re-evaluate all preludes (project + all banks)

Naming Your Sounds

The most common use of a bank prelude is to define words for your instruments. Without a prelude, every step that plays a bass has to spell out the full sound design:

pulse sound c2 note 0.8 gain 400 8000 0.01 0.3 0.5 0.3 env lpf 0.6 width .

In the bank prelude, define it once:

: bass pulse sound 0.8 gain 400 8000 0.01 0.3 0.5 0.3 env lpf 0.6 width . ;

Now every step just writes c2 note bass. Change the sound in one place, every step follows.

Building a Vocabulary

;; instruments
: bass pulse sound 0.8 gain 400 8000 0.01 0.3 0.5 0.3 env lpf 0.6 width . ;
: pad sine sound 0.5 gain 2 spread 1.5 attack 0.4 verb . ;
: lead tri sound 0.6 gain 5000 lpf 2 decay . ;

;; musical helpers
: octup 12 + ;
: octdn 12 - ;
: quiet 0.3 gain ;
: loud 0.9 gain ;

Steps become expressive and short. The prelude carries the design decisions; steps carry the composition.

Setting Initial State

The project prelude is the right place for global state:

c2 !root
0 !mode
42 seed

Every step can then read @root and @mode. And 42 seed makes randomness reproducible.

When Preludes Run

Preludes evaluate at three moments:

  1. When you press Space to start playback
  2. When you load a project
  3. When you press d manually

They run once at these moments, not on every step. If you edit a prelude while playing, press d to push changes into the running session.

What Not to Put Here

Preludes have no access to sequencer state. Words like step, beat, iter, and phase are meaningless here because no step is playing yet. Use preludes for definitions and setup, not for logic that depends on timing. Preludes also should not emit sounds — any . calls here would fire before the sequencer clock is running.