Files
Cagire/docs/forth/prelude.md
2026-03-05 22:14:28 +01:00

104 lines
3.3 KiB
Markdown

# 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.
```forth
: bass pulse sound 0.8 gain 400 lpf 1 lpd 8 lpe 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.
```forth
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:
```forth
pulse sound c2 note 0.8 gain 400 lpf 1 lpd 8 lpe 0.6 width .
```
In the bank prelude, define it once:
```forth
: bass pulse sound 0.8 gain 400 lpf 1 lpd 8 lpe 0.6 width . ;
```
Now every step just writes `c2 note bass`. Change the sound in one place, every step follows.
## Building a Vocabulary
```forth
;; instruments
: bass pulse sound 0.8 gain 400 lpf 1 lpd 8 lpe 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:
```forth
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.