Write some amount of documentation

This commit is contained in:
2026-01-31 01:46:18 +01:00
parent e1c4987db5
commit 8cd0ec92c0
57 changed files with 2096 additions and 198 deletions

View File

@@ -1,18 +0,0 @@
# About
Cagire is an experimental step sequencer built by BuboBubo (Raphaël Maurice Forment). It is a free and open-source project licensed under the AGPL-3.0 License. Cagire has been developed as a side project. I wanted to learn more about using Forth and needed a playground for experimentating with this audio engine! You are free to contribute to the project by making direct contributions to the codebase or by providing feedback and suggestions.
## Credits
- **Doux** (audio engine) is a Rust port of Dough, originally written in C by Felix Roos.
- **mi-plaits-dsp-rs** is a Rust port of the code used by the Mutable Instruments Plaits.
* _Author_: Oliver Rockstedt [info@sourcebox.de](info@sourcebox.de).
* _Original author_: Emilie Gillet [emilie.o.gillet@gmail.com](emilie.o.gillet@gmail.com).
## About live coding
Live coding is a technique where a programmer writes code in real-time in front of an audience. It is a way to experiment with code, to share things and thoughts openly, to express yourself through code. It can be technical, poetical, weird, preferably all at once. Live coding can be used to create music, visual art, and other forms of media. Learn more about live coding on [https://toplap.org](https://toplap.org) or [https://livecoding.fr](https://livecoding.fr). Live coding is an autotelic activity: it is an activity that is intrinsically rewarding, and the act of doing it is its own reward. There are no errors, only fun to be found by playing music.
## About the tool
I do not want to pair it with a DAW, I do not want to make it fit with other commercial software. I'm not interested in VSTs or other proprietary workstations. Please, try to think of Cagire as an alternative to other tools.

84
docs/arithmetic.md Normal file
View File

@@ -0,0 +1,84 @@
# Arithmetic
Basic math operations. All arithmetic words pop their operands and push the result.
## Basic Operations
```
3 4 + ( 7 )
10 3 - ( 7 )
3 4 * ( 12 )
10 3 / ( 3.333... )
10 3 mod ( 1 )
```
Division always produces a float. Use `floor` if you need an integer result.
## Negative Numbers
```
5 neg ( -5 )
-3 abs ( 3 )
```
## Rounding
```
3.7 floor ( 3 )
3.2 ceil ( 4 )
3.5 round ( 4 )
```
## Min and Max
```
3 7 min ( 3 )
3 7 max ( 7 )
```
## Power and Root
```
2 3 pow ( 8 )
9 sqrt ( 3 )
```
## Examples
Calculate a frequency ratio:
```
440 2 12 / pow * ( 440 * 2^(1/12) ≈ 466.16 )
```
Clamp a value between 0 and 1:
```
1.5 0 max 1 min ( 1 )
-0.5 0 max 1 min ( 0 )
```
Scale a 0-1 range to 200-800:
```
0.5 600 * 200 + ( 500 )
```
## Words
| Word | Stack | Description |
|------|-------|-------------|
| `+` | (a b -- sum) | Add |
| `-` | (a b -- diff) | Subtract |
| `*` | (a b -- prod) | Multiply |
| `/` | (a b -- quot) | Divide |
| `mod` | (a b -- rem) | Modulo |
| `neg` | (a -- -a) | Negate |
| `abs` | (a -- \|a\|) | Absolute value |
| `floor` | (a -- n) | Round down |
| `ceil` | (a -- n) | Round up |
| `round` | (a -- n) | Round to nearest |
| `min` | (a b -- min) | Minimum |
| `max` | (a b -- max) | Maximum |
| `pow` | (a b -- a^b) | Power |
| `sqrt` | (a -- √a) | Square root |

51
docs/banks_patterns.md Normal file
View File

@@ -0,0 +1,51 @@
# Banks & Patterns
Cagire organizes all your patterns and data following a strict hierarchy:
- **Projects** contain **Banks**.
- **Banks** contain **Patterns**.
- **Patterns** contain **Steps**.
## Structure
```
Project
└── 32 Banks
└── 32 Patterns (per bank)
└── 128 Steps (per pattern)
```
A single project gives you 32 banks, each holding 32 patterns. You get 1024 patterns in each project, ~131.000 steps.
## Patterns
Each pattern is an independent sequence of steps with its own properties:
| Property | Description | Default |
|----------|-------------|---------|
| Length | Steps before the pattern loops (`1`-`128`) | `16` |
| Speed | Playback rate (`1/8x` to `8x`) | `1x` |
| Quantization | When the pattern launches | `Bar` |
| Sync Mode | Reset or Phase-Lock on re-trigger | `Reset` |
Press `e` in the patterns view to edit these settings.
## Patterns View
Access the patterns view with `Ctrl+Up` from the sequencer. The view shows all banks and patterns in a grid. Indicators show pattern state:
- `>` Currently playing
- `+` Staged to play
- `-` Staged to stop
### Keybindings
| Key | Action |
|-----|--------|
| `Arrows` | Navigate banks and patterns |
| `Enter` | Select and return to sequencer |
| `Space` | Toggle pattern playback |
| `e` | Edit pattern properties |
| `r` | Rename bank or pattern |
| `c` / `v` | Copy / Paste |
| `Delete` | Reset to empty pattern |

2
docs/chaining.md Normal file
View File

@@ -0,0 +1,2 @@
# Chaining

2
docs/chords.md Normal file
View File

@@ -0,0 +1,2 @@
# Chords

41
docs/comparison.md Normal file
View File

@@ -0,0 +1,41 @@
# Comparison
Compare values and produce boolean results (0 or 1).
## Equality
```forth
3 3 = ( 1 - equal )
3 4 = ( 0 - not equal )
3 4 != ( 1 - not equal )
3 4 <> ( 1 - not equal, alternative )
```
## Ordering
```forth
2 3 lt ( 1 - less than )
3 2 gt ( 1 - greater than )
3 3 <= ( 1 - less or equal )
3 3 >= ( 1 - greater or equal )
```
## With Conditionals
```forth
step 4 lt { "kick" s . } ? ( kick on first 4 steps )
beat 8 >= { 0.5 gain } ? ( quieter after beat 8 )
```
## Words
| Word | Stack | Description |
|------|-------|-------------|
| `=` | (a b -- bool) | Equal |
| `!=` | (a b -- bool) | Not equal |
| `<>` | (a b -- bool) | Not equal (alias) |
| `lt` | (a b -- bool) | Less than |
| `gt` | (a b -- bool) | Greater than |
| `<=` | (a b -- bool) | Less or equal |
| `>=` | (a b -- bool) | Greater or equal |

2
docs/conditionals.md Normal file
View File

@@ -0,0 +1,2 @@
# Conditionals

2
docs/context.md Normal file
View File

@@ -0,0 +1,2 @@
# Context

2
docs/cycles.md Normal file
View File

@@ -0,0 +1,2 @@
# Cycles

2
docs/definitions.md Normal file
View File

@@ -0,0 +1,2 @@
# Custom Words

51
docs/delay_reverb.md Normal file
View File

@@ -0,0 +1,51 @@
# Delay & Reverb
Add space and depth to your sounds with time-based effects.
## Delay
```forth
"snare" s 0.3 delay . ( delay mix )
"snare" s 0.25 delaytime . ( delay time in seconds )
"snare" s 0.5 delayfeedback . ( feedback amount )
"snare" s 1 delaytype . ( delay type )
```
## Reverb
```forth
"pad" s 0.3 verb . ( reverb mix )
"pad" s 2 verbdecay . ( decay time )
"pad" s 0.5 verbdamp . ( high frequency damping )
"pad" s 0.02 verbpredelay . ( predelay time )
"pad" s 0.7 verbdiff . ( diffusion )
"pad" s 1 size . ( room size )
```
## Combined Example
```forth
"keys" s
c4 note
0.2 delay
0.375 delaytime
0.4 delayfeedback
0.25 verb
1.5 verbdecay
.
```
## Words
| Word | Stack | Description |
|------|-------|-------------|
| `delay` | (f --) | Set delay mix |
| `delaytime` | (f --) | Set delay time |
| `delayfeedback` | (f --) | Set delay feedback |
| `delaytype` | (n --) | Set delay type |
| `verb` | (f --) | Set reverb mix |
| `verbdecay` | (f --) | Set reverb decay |
| `verbdamp` | (f --) | Set reverb damping |
| `verbpredelay` | (f --) | Set reverb predelay |
| `verbdiff` | (f --) | Set reverb diffusion |
| `size` | (f --) | Set reverb size |

43
docs/dictionary.md Normal file
View File

@@ -0,0 +1,43 @@
# The Dictionary
Cagire includes a built-in dictionary of all Forth words. Press `Ctrl+Down` repeatedly to reach the **Dict** view, or navigate directly with `Ctrl+Arrow` keys.
## Using the Dictionary
The dictionary shows every available word organized by category:
- **Stack**: Manipulation words like `dup`, `swap`, `drop`
- **Arithmetic**: Math operations
- **Sound**: Sound sources and emission
- **Filter**, **Envelope**, **Effects**: Sound shaping
- **Context**: Sequencer state like `step`, `beat`, `tempo`
- And many more...
## Navigation
| Key | Action |
|-----|--------|
| `Tab` | Switch between categories and words |
| `↑/↓` or `j/k` | Navigate items |
| `PgUp/PgDn` | Page through lists |
| `/` or `Ctrl+F` | Search |
| `Esc` | Clear search |
## Word Information
Each word entry shows:
- **Name** and aliases
- **Stack effect**: `( before -- after )`
- **Description**: What the word does
- **Example**: How to use it
## Search
Press `/` to search across all words. The search matches word names, aliases, and descriptions. Press `Esc` to clear and return to browsing.
## Tips
- Use the dictionary while writing scripts to check stack effects
- Categories group related words together
- Some words have shorter aliases (e.g., `sound``s`)

2
docs/effects.md Normal file
View File

@@ -0,0 +1,2 @@
# Effects

48
docs/emitting.md Normal file
View File

@@ -0,0 +1,48 @@
# Emitting Sounds
The core of Cagire is emitting sounds. Every step script builds up sound commands and emits them to the audio engine.
## The Sound Register
Before emitting, you must select a sound source using `sound` (or its alias `s`):
```forth
"kick" sound
"kick" s ( same thing, shorter )
```
This sets the current sound register. All subsequent parameter words modify this sound until you emit or clear it.
## Emitting
The `.` word emits the current sound:
```forth
"kick" s . ( emit one kick )
"kick" s . . . ( emit three kicks )
```
Use `.!` to emit multiple times:
```forth
"kick" s 4 .! ( emit four kicks )
```
## Clearing
The `clear` word resets the sound register and all parameters:
```forth
"kick" s 0.5 gain . clear "hat" s .
```
This is useful when you want to emit different sounds with independent parameters in the same step.
## Words
| Word | Stack | Description |
|------|-------|-------------|
| `sound` / `s` | (name --) | Set sound source |
| `.` | (--) | Emit current sound |
| `.!` | (n --) | Emit current sound n times |
| `clear` | (--) | Clear sound register and params |

2
docs/envelopes.md Normal file
View File

@@ -0,0 +1,2 @@
# Envelopes

65
docs/eq_stereo.md Normal file
View File

@@ -0,0 +1,65 @@
# EQ & Stereo
Shape the frequency balance and stereo image of your sounds.
## Three-Band EQ
```forth
"mix" s
3 eqlo ( boost low shelf by 3dB )
-2 eqmid ( cut mids by 2dB )
1 eqhi ( boost high shelf by 1dB )
.
```
## Tilt EQ
A simple one-knob EQ that tilts the frequency balance:
```forth
"bright" s 0.5 tilt . ( brighter )
"dark" s -0.5 tilt . ( darker )
```
Range: -1 (dark) to 1 (bright)
## Gain and Pan
```forth
"kick" s 0.8 gain . ( volume 0-1 )
"hat" s 0.5 pan . ( pan right )
"hat" s -0.5 pan . ( pan left )
"snare" s 1.2 postgain . ( post-processing gain )
"lead" s 100 velocity . ( velocity/dynamics )
```
## Stereo Width
```forth
"pad" s 0 width . ( mono )
"pad" s 1 width . ( normal stereo )
"pad" s 2 width . ( extra wide )
```
## Haas Effect
Create spatial positioning with subtle delay between channels:
```forth
"vocal" s 8 haas . ( 8ms delay for spatial effect )
```
## Words
| Word | Stack | Description |
|------|-------|-------------|
| `eqlo` | (f --) | Set low shelf gain (dB) |
| `eqmid` | (f --) | Set mid peak gain (dB) |
| `eqhi` | (f --) | Set high shelf gain (dB) |
| `tilt` | (f --) | Set tilt EQ (-1 dark, 1 bright) |
| `gain` | (f --) | Set volume (0-1) |
| `postgain` | (f --) | Set post gain |
| `velocity` | (f --) | Set velocity |
| `pan` | (f --) | Set pan (-1 to 1) |
| `width` | (f --) | Set stereo width |
| `haas` | (f --) | Set Haas delay (ms) |

2
docs/filters.md Normal file
View File

@@ -0,0 +1,2 @@
# Filters

65
docs/generators.md Normal file
View File

@@ -0,0 +1,65 @@
# Generators
Create sequences of values on the stack.
## Arithmetic Range
The `..` operator pushes an arithmetic sequence:
```forth
1 4 .. ( pushes 1 2 3 4 )
60 67 .. ( pushes 60 61 62 63 64 65 66 67 )
```
## Geometric Range
The `geom..` operator creates a geometric sequence:
```forth
1 2 4 geom.. ( pushes 1 2 4 8 )
100 0.5 4 geom.. ( pushes 100 50 25 12.5 )
```
Stack: `(start ratio count -- values...)`
## Generate
The `gen` word executes a quotation multiple times:
```forth
{ 1 6 rand } 4 gen ( 4 random values from 1-6 )
{ coin } 8 gen ( 8 random 0/1 values )
```
## Examples
Random melody:
```forth
"pluck" s
{ 48 72 rand } 4 gen 4 choose note
.
```
Chord from range:
```forth
"pad" s
60 67 .. 8 choose note ( random note in octave )
.
```
Euclidean-style rhythm values:
```forth
0 1 0 0 1 0 1 0 ( manual )
{ coin } 8 gen ( random 8-step pattern )
```
## Words
| Word | Stack | Description |
|------|-------|-------------|
| `..` | (start end -- values...) | Arithmetic sequence |
| `geom..` | (start ratio count -- values...) | Geometric sequence |
| `gen` | (quot n -- results...) | Execute quotation n times |

54
docs/grid.md Normal file
View File

@@ -0,0 +1,54 @@
# The Sequencer Grid
The sequencer grid is the heart of Cagire. Each cell represents a step that can contain a Forth script to generate sound.
## Structure
- **Steps**: Up to 128 per pattern, displayed 32 at a time
- **Patterns**: Up to 32 per bank
- **Banks**: Up to 32 per project
## Navigation
Use arrow keys to move between steps. The grid wraps around at pattern boundaries.
## Selection
Hold `Shift` while pressing arrow keys to select multiple steps. Press `Esc` to clear the selection.
## Editing Steps
- `Enter` - Open the script editor
- `t` - Toggle step active/inactive
- `r` - Rename a step
- `Del` - Delete selected steps
## Copy & Paste
- `Ctrl+C` - Copy selected steps
- `Ctrl+V` - Paste as copies
- `Ctrl+B` - Paste as linked steps
- `Ctrl+D` - Duplicate selection
- `Ctrl+H` - Harden links (convert to copies)
Linked steps share the same script as their source. When you edit the source, all linked steps update automatically.
## Pattern Controls
- `<` / `>` - Decrease/increase pattern length
- `[` / `]` - Decrease/increase pattern speed
- `L` - Set length directly
- `S` - Set speed directly
## Playback
- `Space` - Toggle play/stop
- `+` / `-` - Adjust tempo
- `T` - Set tempo directly
- `Ctrl+R` - Run current step once (preview)
## Visual Indicators
- **Highlighted cell** - Currently playing step
- **Colored backgrounds** - Linked steps share colors by source
- **Arrow prefix** (→05) - Step is linked to step 05

58
docs/how_it_works.md Normal file
View File

@@ -0,0 +1,58 @@
# How Does It Work?
Cagire is a step sequencer where each step contains a **Forth script** instead of the typical note data. When the sequencer reaches a step, it runs the script. A script _can do whatever it is programed to do_, such as producing sound commands sent to an internal audio engine. Everything else is similar to a step sequencer: you can `toggle` / `untoggle`, `copy` / `paste` any step or group of steps, etc. You are completely free to define what your scripts will do. It can be as simple as playing a note, or as complex as triggering random audio samples with complex effects. Scripts can also share code and data with each other.
## Project / session organization
Cagire can run multiple patterns concurrently. Each pattern contains a given number of steps. Every session / project is organized hierarchically:
- **32 Banks**
- **32 Patterns** per bank
- **128 Steps** per pattern
That's over 130,000 possible steps per project. Most of my sessions use 15-20 at best.
## What does a script look like?
Forth is a stack-based programming language. It is very minimalistic and emphasizes simplicity and readability. Using Forth doesn't feel like programming at all. It feels more like juggling with words and numbers or writing bad computer poetry. There is pretty much no syntax to learn, just a few rules to follow. Forth is ancient, powerful, flexible, and... super fun to live code with! Here is a minimal program that will play a middle C note using a sine wave:
```forth
c4 note sine sound .
```
Read the program backwards and you will understand what it does instantly:
- `.`: we want to play a sound.
- `sine sound`: the sound is a sinewave.
- `c4 note`: the pitch is C4 (middle-C).
Scripts can be simple one-liners or complex programs with conditionals, loops, and randomness. They tend to look like an accumulation of words and numbers. Use space and line returns to your advantage. The Forth language can be learned... on the spot. You just need to understand the following basic rules:
- there are `words` and `numbers`.
- they are delimited by spaces.
- everything piles up on the `stack`.
Obviously you will need to understand what the **stack** is, but it will take you five minutes. That's it. See the **Forth** section for details.
## The Audio Engine
Cagire includes a complete synthesis engine. No external software is required to play music. It comes with a large number of sound sources and sound shaping tools: oscillators, sample players, effects, filters, and more. The audio engine is quite capable and versatile, and can accomodate a vast array of genres / styles. Here are a few examples :
```forth
;; sawtooth wave with lowpass filter, chorus and reverb
saw sound 1200 lpf 0.2 chorus 0.8 verb .
```
```forth
;; pure sine wave with vibrato and bit crushing
0.5 vibmod 4 vib sine sound 8 crush 0.8 gain .
```
```forth
;; very loud and pitched-down kick drum using an audio sample
kkick sound 1.5 distort 0.9 postgain 0.8 speed .
```
## Timing & Synchronization
Cagire uses **Ableton Link** to manage timing and synchronization. This means that all devices using the same protocol can be synchronized to the same tempo. Most commercial softwares support this protocol. The playback speed is defined as a BPM (beats per minute) value. Patterns can run at different speeds relative to the master tempo. Most of the durations in Cagire are defined in terms of beats.

View File

@@ -32,6 +32,10 @@
- **Ctrl+C**: Copy step script
- **Ctrl+V**: Paste step script
### Execution
- **Ctrl+R**: Run current step's script immediately (one-shot)
### Tempo
- **+ / =**: Increase tempo
@@ -41,6 +45,7 @@
- **Tab / Esc**: Return to sequencer focus
- **Ctrl+E**: Compile current step script
- **Ctrl+R**: Run script in editor immediately (one-shot)
## Audio Page

47
docs/ladder_filters.md Normal file
View File

@@ -0,0 +1,47 @@
# Ladder Filters
Ladder filters provide a classic analog-style filter sound with stronger resonance character than the standard SVF filters.
## Ladder Lowpass
```forth
"saw" s 2000 llpf . ( ladder lowpass frequency )
"saw" s 0.7 llpq . ( ladder lowpass resonance )
```
## Ladder Highpass
```forth
"noise" s 500 lhpf . ( ladder highpass frequency )
"noise" s 0.5 lhpq . ( ladder highpass resonance )
```
## Ladder Bandpass
```forth
"pad" s 1000 lbpf . ( ladder bandpass frequency )
"pad" s 0.6 lbpq . ( ladder bandpass resonance )
```
## Comparison with SVF
Ladder filters have a different resonance character:
- More aggressive self-oscillation at high resonance
- Classic "squelchy" acid sound
- 24dB/octave slope
Standard SVF filters (`lpf`, `hpf`, `bpf`) have:
- Cleaner resonance
- Full envelope control (attack, decay, sustain, release)
- 12dB/octave slope
## Words
| Word | Stack | Description |
|------|-------|-------------|
| `llpf` | (f --) | Set ladder lowpass frequency |
| `llpq` | (f --) | Set ladder lowpass resonance |
| `lhpf` | (f --) | Set ladder highpass frequency |
| `lhpq` | (f --) | Set ladder highpass resonance |
| `lbpf` | (f --) | Set ladder bandpass frequency |
| `lbpq` | (f --) | Set ladder bandpass resonance |

74
docs/lfo.md Normal file
View File

@@ -0,0 +1,74 @@
# LFO & Ramps
Generate time-varying values synchronized to the beat for modulation.
## Ramp
The `ramp` word creates a sawtooth wave from 0 to 1:
```forth
0.25 1.0 ramp ( one cycle per 4 beats, linear )
1.0 2.0 ramp ( one cycle per beat, exponential curve )
```
Stack: `(freq curve -- val)`
## Shortcut Ramps
```forth
0.5 linramp ( linear ramp, curve=1 )
0.25 expramp ( exponential ramp, curve=3 )
2.0 logramp ( logarithmic ramp, curve=0.3 )
```
## Triangle Wave
```forth
0.5 tri ( triangle wave 0→1→0 )
```
## Perlin Noise
Smooth random modulation:
```forth
0.25 perlin ( smooth noise at 0.25x beat rate )
```
## Range Scaling
Scale a 0-1 value to any range:
```forth
0.5 200 800 range ( 0.5 becomes 500 )
```
## Examples
Modulate filter cutoff:
```forth
"saw" s
0.25 1.0 ramp 500 2000 range lpf
.
```
Random panning:
```forth
"hat" s
0.5 perlin -1 1 range pan
.
```
## Words
| Word | Stack | Description |
|------|-------|-------------|
| `ramp` | (freq curve -- val) | Ramp 0-1: fract(freq*beat)^curve |
| `linramp` | (freq -- val) | Linear ramp (curve=1) |
| `expramp` | (freq -- val) | Exponential ramp (curve=3) |
| `logramp` | (freq -- val) | Logarithmic ramp (curve=0.3) |
| `tri` | (freq -- val) | Triangle wave 0→1→0 |
| `perlin` | (freq -- val) | Perlin noise 0-1 |
| `range` | (val min max -- scaled) | Scale 0-1 to min-max |

2
docs/link.md Normal file
View File

@@ -0,0 +1,2 @@
# Ableton Link

58
docs/lofi.md Normal file
View File

@@ -0,0 +1,58 @@
# Lo-fi Effects
Add grit, warmth, and character with bit crushing, folding, and distortion.
## Bit Crush
Reduce bit depth for digital artifacts:
```forth
"drum" s 8 crush . ( 8-bit crush )
"drum" s 4 crush . ( heavy 4-bit crush )
```
## Wave Folding
Fold the waveform back on itself for complex harmonics:
```forth
"sine" s 2 fold . ( moderate folding )
"sine" s 4 fold . ( aggressive folding )
```
## Wave Wrap
Wrap the waveform for a different flavor of distortion:
```forth
"bass" s 0.5 wrap .
```
## Distortion
Classic overdrive/distortion:
```forth
"guitar" s 0.5 distort . ( distortion amount )
"guitar" s 0.8 distortvol . ( output volume )
```
## Combining Effects
```forth
"drum" s
12 crush
1.5 fold
0.3 distort
.
```
## Words
| Word | Stack | Description |
|------|-------|-------------|
| `crush` | (f --) | Set bit crush depth |
| `fold` | (f --) | Set wave fold amount |
| `wrap` | (f --) | Set wave wrap amount |
| `distort` | (f --) | Set distortion amount |
| `distortvol` | (f --) | Set distortion output volume |

89
docs/logic.md Normal file
View File

@@ -0,0 +1,89 @@
# Logic
Boolean operations and conditional execution.
## Boolean Operators
```forth
1 1 and ( 1 )
0 1 or ( 1 )
1 not ( 0 )
1 0 xor ( 1 )
1 1 nand ( 0 )
0 0 nor ( 1 )
```
## Conditional Execution
Execute a quotation if condition is true:
```forth
{ "kick" s . } coin ? ( 50% chance )
{ 0.5 gain } step 0 = ? ( only on step 0 )
```
Execute if false:
```forth
{ "snare" s . } coin !? ( if NOT coin )
```
## If-Else
```forth
{ "kick" s } { "snare" s } coin ifelse .
```
Stack: `(true-quot false-quot bool --)`
## Pick
Choose from multiple quotations:
```forth
{ 60 } { 64 } { 67 } step 3 mod pick note
```
Stack: `(quot1 quot2 ... quotN n -- result)`
## Apply
Execute a quotation unconditionally:
```forth
{ 2 * } apply ( doubles top of stack )
```
## Examples
Conditional parameter:
```forth
"kick" s
{ 0.8 } { 0.4 } iter 2 mod = ifelse gain
.
```
Multi-way branching:
```forth
"synth" s
{ c4 } { e4 } { g4 } { c5 } step 4 mod pick note
.
```
## Words
| Word | Stack | Description |
|------|-------|-------------|
| `and` | (a b -- bool) | Logical and |
| `or` | (a b -- bool) | Logical or |
| `not` | (a -- bool) | Logical not |
| `xor` | (a b -- bool) | Exclusive or |
| `nand` | (a b -- bool) | Not and |
| `nor` | (a b -- bool) | Not or |
| `?` | (quot bool --) | Execute if true |
| `!?` | (quot bool --) | Execute if false |
| `ifelse` | (t-quot f-quot bool --) | If-else |
| `pick` | (..quots n --) | Execute nth quotation |
| `apply` | (quot --) | Execute unconditionally |

61
docs/mod_fx.md Normal file
View File

@@ -0,0 +1,61 @@
# Modulation Effects
Phaser, flanger, and chorus effects for movement and width.
## Phaser
```forth
"pad" s
1 phaser ( rate in Hz )
0.5 phaserdepth ( depth )
0.5 phasersweep ( sweep range )
1000 phasercenter ( center frequency )
.
```
## Flanger
```forth
"guitar" s
0.5 flanger ( rate )
0.5 flangerdepth ( depth )
0.5 flangerfeedback ( feedback for metallic sound )
.
```
## Chorus
```forth
"keys" s
1 chorus ( rate )
0.5 chorusdepth ( depth )
0.02 chorusdelay ( base delay time )
.
```
## Combining Effects
```forth
"pad" s
c4 note
0.3 phaserdepth
0.5 phaser
0.2 chorus
0.3 chorusdepth
.
```
## Words
| Word | Stack | Description |
|------|-------|-------------|
| `phaser` | (f --) | Set phaser rate |
| `phaserdepth` | (f --) | Set phaser depth |
| `phasersweep` | (f --) | Set phaser sweep |
| `phasercenter` | (f --) | Set phaser center frequency |
| `flanger` | (f --) | Set flanger rate |
| `flangerdepth` | (f --) | Set flanger depth |
| `flangerfeedback` | (f --) | Set flanger feedback |
| `chorus` | (f --) | Set chorus rate |
| `chorusdepth` | (f --) | Set chorus depth |
| `chorusdelay` | (f --) | Set chorus delay |

2
docs/modulation.md Normal file
View File

@@ -0,0 +1,2 @@
# Modulation

39
docs/navigation.md Normal file
View File

@@ -0,0 +1,39 @@
# Navigation
The Cagire application is organized as a grid composed of six views:
```
Dict Patterns Options
Help Sequencer Engine
```
- `Dict` (Dictionary): A comprehensive list of all the `Forth` words used in the application.
- `Help`: Provides detailed information about the application's features and functionalities.
- `Patterns`: Pattern banks and pattern manager. Used to organize a session / project.
- `Sequencer`: The main view, where you edit sequences and play music.
- `Options`: Configuration settings for the application.
- `Engine`: Configuration settings for the internal audio engine.
## Switching Views
Use `Ctrl+Arrow` keys to move between views. A minimap appears briefly showing your position in the grid.
- `Ctrl+Left` / `Ctrl+Right` - move horizontally
- `Ctrl+Up` / `Ctrl+Down` - move vertically
The grid wraps horizontally, so you can cycle through views on the same row.
## Getting Help
Press `?` on any view to see its keybindings. This shows all available shortcuts for the current context.
Press `Esc` to close the keybindings panel.
## Common Keys
These work on most views:
- `Arrow keys` - move or scroll
- `Tab` - switch focus between panels
- `/` or `Ctrl+f` - search (where available)
- `q` - quit (with confirmation)

2
docs/notes.md Normal file
View File

@@ -0,0 +1,2 @@
# Notes & MIDI

75
docs/oscillators.md Normal file
View File

@@ -0,0 +1,75 @@
# Oscillators
Control synthesis oscillator parameters for synth sounds.
## Frequency and Pitch
```forth
"sine" s 440 freq . ( set frequency in Hz )
"saw" s 60 note . ( set MIDI note )
"square" s 0.01 detune . ( slight detune )
"lead" s 12 coarse . ( coarse tune in semitones )
"bass" s 0.1 glide . ( portamento )
```
## Pulse Width
For pulse/square oscillators:
```forth
"pulse" s 0.3 pw . ( narrow pulse )
"pulse" s 0.5 pw . ( square wave )
```
## Stereo Spread
```forth
"pad" s 0.5 spread . ( stereo spread amount )
```
## Harmonics and Timbre
For oscillators that support it (like mutable):
```forth
"mutable" s 4 harmonics . ( harmonic content )
"mutable" s 0.5 timbre . ( timbre control )
"mutable" s 0.3 morph . ( morph parameter )
```
## Multiplier and Warp
```forth
"fm" s 2 mult . ( frequency multiplier )
"wt" s 0.5 warp . ( warp amount )
"wt" s 1 mirror . ( mirror waveform )
```
## Sub Oscillator
```forth
"bass" s 0.5 sub . ( sub oscillator level )
"bass" s 2 suboct . ( sub octave down )
"bass" s 1 subwave . ( sub waveform )
```
## Words
| Word | Stack | Description |
|------|-------|-------------|
| `freq` | (f --) | Set frequency (Hz) |
| `note` | (n --) | Set MIDI note |
| `detune` | (f --) | Set detune amount |
| `coarse` | (f --) | Set coarse tune |
| `glide` | (f --) | Set glide/portamento |
| `pw` | (f --) | Set pulse width |
| `spread` | (f --) | Set stereo spread |
| `mult` | (f --) | Set multiplier |
| `warp` | (f --) | Set warp amount |
| `mirror` | (f --) | Set mirror |
| `harmonics` | (f --) | Set harmonics |
| `timbre` | (f --) | Set timbre |
| `morph` | (f --) | Set morph |
| `sub` | (f --) | Set sub oscillator level |
| `suboct` | (n --) | Set sub octave |
| `subwave` | (n --) | Set sub waveform |

2
docs/parameters.md Normal file
View File

@@ -0,0 +1,2 @@
# Parameters

2
docs/patterns.md Normal file
View File

@@ -0,0 +1,2 @@
# Pattern Management

44
docs/pitch_envelope.md Normal file
View File

@@ -0,0 +1,44 @@
# Pitch Envelope
Control pitch modulation over time with a dedicated ADSR envelope.
## Envelope Amount
```forth
"bass" s 0.5 penv . ( pitch envelope depth )
"bass" s -0.5 penv . ( negative envelope )
```
## Envelope Shape
```forth
"kick" s
1.0 penv ( full envelope depth )
0.001 patt ( instant attack )
0.1 pdec ( fast decay )
0 psus ( no sustain )
0.1 prel ( short release )
.
```
## Classic Kick Drum
```forth
"sine" s
40 note
2.0 penv
0.001 patt
0.05 pdec
0 psus
.
```
## Words
| Word | Stack | Description |
|------|-------|-------------|
| `penv` | (f --) | Set pitch envelope amount |
| `patt` | (f --) | Set pitch attack time |
| `pdec` | (f --) | Set pitch decay time |
| `psus` | (f --) | Set pitch sustain level |
| `prel` | (f --) | Set pitch release time |

2
docs/probability.md Normal file
View File

@@ -0,0 +1,2 @@
# Probability

2
docs/randomness.md Normal file
View File

@@ -0,0 +1,2 @@
# Randomness

76
docs/samples.md Normal file
View File

@@ -0,0 +1,76 @@
# Samples
Control sample playback with timing, looping, and slice parameters.
## Basic Playback
```forth
"break" s . ( play sample from start )
"break" s 0.5 speed . ( half speed )
"break" s -1 speed . ( reverse )
```
## Time and Position
Control where in the sample to start and end:
```forth
"break" s 0.25 begin . ( start at 25% )
"break" s 0.5 end . ( end at 50% )
"break" s 0.1 time . ( offset start time )
```
## Duration and Gate
```forth
"pad" s 0.5 dur . ( play for 0.5 seconds )
"pad" s 0.8 gate . ( gate time as fraction )
```
## Looping
Fit a sample to a number of beats:
```forth
"break" s 4 loop . ( fit to 4 beats )
```
## Repetition
```forth
"hat" s 4 repeat . ( trigger 4 times )
```
## Voice and Routing
```forth
"kick" s 1 voice . ( assign to voice 1 )
"snare" s 0 orbit . ( route to bus 0 )
```
## Sample Selection
```forth
"kick" s 2 n . ( select sample #2 from folder )
"kit" s "a" bank . ( use bank suffix )
1 cut ( cut group - stops other sounds in same group )
```
## Words
| Word | Stack | Description |
|------|-------|-------------|
| `time` | (f --) | Set time offset |
| `repeat` | (n --) | Set repeat count |
| `dur` | (f --) | Set duration |
| `gate` | (f --) | Set gate time |
| `speed` | (f --) | Set playback speed |
| `begin` | (f --) | Set sample start (0-1) |
| `end` | (f --) | Set sample end (0-1) |
| `loop` | (n --) | Fit sample to n beats |
| `voice` | (n --) | Set voice number |
| `orbit` | (n --) | Set orbit/bus |
| `n` | (n --) | Set sample number |
| `bank` | (str --) | Set sample bank suffix |
| `cut` | (n --) | Set cut group |
| `reset` | (n --) | Reset parameter |

2
docs/scales.md Normal file
View File

@@ -0,0 +1,2 @@
# Scales

62
docs/selection.md Normal file
View File

@@ -0,0 +1,62 @@
# Selection
Cycle through values over time for evolving patterns.
## Step Cycle
`cycle` cycles through values based on step runs:
```forth
60 64 67 3 cycle note ( cycle through C, E, G )
```
Each time the step runs, it picks the next value.
## Pattern Cycle
`pcycle` cycles based on pattern iteration:
```forth
60 64 67 3 pcycle note ( change note each pattern loop )
```
## Emit-Time Cycle
`tcycle` creates a cycle list resolved at emit time, useful with `.!`:
```forth
60 64 67 3 tcycle note 3 .! ( emit C, E, G in sequence )
```
## Examples
Rotating bass notes:
```forth
"bass" s
c3 e3 g3 b3 4 cycle note
.
```
Evolving pattern over loops:
```forth
"lead" s
0.5 1.0 0.75 0.25 4 pcycle gain
.
```
Arpeggiated chord:
```forth
"pluck" s
c4 e4 g4 c5 4 tcycle note 4 .!
```
## Words
| Word | Stack | Description |
|------|-------|-------------|
| `cycle` | (v1..vn n -- val) | Cycle by step runs |
| `pcycle` | (v1..vn n -- val) | Cycle by pattern iteration |
| `tcycle` | (v1..vn n -- list) | Create cycle list for emit-time |

2
docs/sound_basics.md Normal file
View File

@@ -0,0 +1,2 @@
# Sound Basics

118
docs/stack.md Normal file
View File

@@ -0,0 +1,118 @@
# The Stack
Forth is a stack-based language. Instead of variables and expressions, you push values onto a stack and use words that consume and produce values.
## How It Works
The stack is a last-in, first-out (LIFO) structure. Values you type get pushed on top. Words pop values off and push results back.
```
3 4 +
```
Step by step:
1. `3` → push 3 onto stack: `[3]`
2. `4` → push 4 onto stack: `[3, 4]`
3. `+` → pop two values, add them, push result: `[7]`
## Values
Three types can live on the stack:
- **Integers**: `42`, `-7`, `0`
- **Floats**: `3.14`, `0.5`, `-1.0`
- **Strings**: `"kick"`, `"hello"`
## Stack Notation
Documentation uses stack effect notation:
```
( before -- after )
```
For example, `+` has effect `( a b -- sum )` meaning it takes two values and leaves one.
## Core Words
### dup
Duplicate the top value.
```
3 dup ( 3 3 )
```
### drop
Discard the top value.
```
3 4 drop ( 3 )
```
### swap
Swap the top two values.
```
3 4 swap ( 4 3 )
```
### over
Copy the second value to the top.
```
3 4 over ( 3 4 3 )
```
### rot
Rotate the top three values.
```
1 2 3 rot ( 2 3 1 )
```
### nip
Drop the second value.
```
3 4 nip ( 4 )
```
### tuck
Copy top value below second.
```
3 4 tuck ( 4 3 4 )
```
## Examples
Build a chord by duplicating and adding:
```
60 dup 4 + swap 7 + ( 64 67 60 )
```
Use `over` to keep a base value:
```
c4 over M3 swap P5 ( e4 g4 c4 )
```
## Words
| Word | Stack | Description |
|------|-------|-------------|
| `dup` | (a -- a a) | Duplicate top |
| `drop` | (a --) | Discard top |
| `swap` | (a b -- b a) | Swap top two |
| `over` | (a b -- a b a) | Copy second to top |
| `rot` | (a b c -- b c a) | Rotate three |
| `nip` | (a b -- b) | Drop second |
| `tuck` | (a b -- b a b) | Copy top below second |

50
docs/staging.md Normal file
View File

@@ -0,0 +1,50 @@
# Stage / Commit
Cagire requires you to `stage` changes you wish to make to the playback state and then `commit` it. It is way more simple than it seems. For instance, you mark pattern `04` and `05` to start playing, and _then_ you send the order to start the playback (`commit`). The same goes for stopping patterns. You mark which pattern to stop (`stage`) and then you give the order to stop them (`commit`). Why is staging useful? Here are some reasons why this design choice was made:
- **To apply multiple changes**: Queue several patterns to start/stop, commit them together.
- **To get clean timing**: All changes happen on beat/bar boundaries.
- **To help with live performance**: Prepare the next section without affecting current playback.
Staging is an essential feature to understand to be effective when doing live performances:
1. Open the **Patterns** view (`Ctrl+Up` from sequencer)
2. Navigate to a pattern you wish to change/play
3. Press `Space` to stage it. The pending change is going to be displayed:
- `+` (staged to play)
- `-` (staged to stop)
4. Repeat for other patterns you want to change
5. Press `c` to commit all changes
6. Or press `Esc` to cancel
A pattern might not start immediately depending on the sync mode you have chosen. It might wait for the next beat/bar boundary.
## Status Indicators
| Indicator | Meaning |
|-----------|---------|
| `>` | Currently playing |
| `+` | Staged to play |
| `-` | Staged to stop |
A pattern can show both `>` (playing) and `-` (staged to stop).
## Quantization
Committed changes don't execute immediately. They wait for a quantization boundary:
| Setting | Behavior |
|---------|----------|
| Immediate | Next sequencer tick |
| Beat | Next beat |
| 1 Bar | Next bar (default) |
| 2/4/8 Bars | Next 2, 4, or 8-bar boundary |
Edit quantization in pattern properties (press `e` on a pattern).
## Sync Mode
When a pattern starts, its playback position depends on sync mode:
- **Reset**: Always start at step 0
- **Phase-Lock**: Start at the current beat-aligned position (stays in sync with other patterns)

2
docs/tempo.md Normal file
View File

@@ -0,0 +1,2 @@
# Tempo & Speed

2
docs/timing.md Normal file
View File

@@ -0,0 +1,2 @@
# Timing

2
docs/variables.md Normal file
View File

@@ -0,0 +1,2 @@
# Variables

44
docs/vibrato.md Normal file
View File

@@ -0,0 +1,44 @@
# Vibrato
Add pitch vibrato to oscillator sounds.
## Basic Vibrato
```forth
"lead" s
60 note
5 vib ( vibrato rate in Hz )
0.5 vibmod ( vibrato depth )
.
```
## Vibrato Shape
Control the LFO waveform:
```forth
"pad" s
c4 note
4 vib
0.3 vibmod
0 vibshape ( 0=sine, other values for different shapes )
.
```
## Subtle vs Expressive
```forth
( subtle vibrato for pads )
"pad" s 3 vib 0.1 vibmod .
( expressive vibrato for leads )
"lead" s 6 vib 0.8 vibmod .
```
## Words
| Word | Stack | Description |
|------|-------|-------------|
| `vib` | (f --) | Set vibrato rate (Hz) |
| `vibmod` | (f --) | Set vibrato depth |
| `vibshape` | (f --) | Set vibrato LFO shape |

55
docs/wavetables.md Normal file
View File

@@ -0,0 +1,55 @@
# Wavetables
Control wavetable synthesis parameters for scanning through waveforms.
## Scan Position
The `scan` parameter controls which waveform in the wavetable is active:
```forth
"wt" s 0.0 scan . ( first waveform )
"wt" s 0.5 scan . ( middle of table )
"wt" s 1.0 scan . ( last waveform )
```
## Wavetable Length
Set the cycle length in samples:
```forth
"wt" s 2048 wtlen . ( standard wavetable size )
```
## Scan Modulation
Animate the scan position with an LFO:
```forth
"wt" s 0.2 scanlfo . ( LFO rate in Hz )
"wt" s 0.4 scandepth . ( LFO depth 0-1 )
"wt" s "tri" scanshape . ( LFO shape )
```
Available shapes: `sine`, `tri`, `saw`, `square`, `sh` (sample & hold)
## Example
```forth
"wavetable" s
60 note
0.25 scan
0.1 scanlfo
0.3 scandepth
"sine" scanshape
.
```
## Words
| Word | Stack | Description |
|------|-------|-------------|
| `scan` | (f --) | Set wavetable scan position (0-1) |
| `wtlen` | (n --) | Set wavetable cycle length in samples |
| `scanlfo` | (f --) | Set scan LFO rate (Hz) |
| `scandepth` | (f --) | Set scan LFO depth (0-1) |
| `scanshape` | (s --) | Set scan LFO shape |

View File

@@ -1,19 +1,31 @@
# Welcome to Cagire
Cagire is a terminal-based step sequencer for live coding music. Each step in a pattern contains a **Forth** script that produces sound and create events. It is made by BuboBubo (Raphaël Maurice Forment): [https://raphaelforment.fr](https://raphaelforment.fr). Cagire is open-source (AGPL-3.0 licensed) and available on GitHub : [https://github.com/BuboBubo/cagire](https://github.com/BuboBubo/cagire). This help view will teach you everything you need to know to start using Cagire and and to live code with it. To use Cagire, you will need to understand two things:
Cagire is a terminal-based step sequencer for live coding music. Each step on the sequencer is defined by a **Forth** script that produces sound and create events. The documentation you are currently reading acts both as _tutorial_ and _reference_. It contains everything you need to know to use Cagire effectively. We recommend you to dive in and explore by picking subjects that interest you before slowly learning about everything else. Here are some recommended topics to start with:
1) How the sequencer works: dealing with steps, patterns and banks.
2) How to write a script: how to make sound using code.
1) How the sequencer works? Banks, patterns and steps.
* the sequencer model, the pattern model, the step sequencer.
2) How to write a script? How to make sound using code.
* how to write simple scripts that play `musical events`.
* how to extend these scripts with `logic` and/or `randomness`.
* how define `WORDS`, `variables`, and share data between steps.
3) What can I do with the audio engine?
* audio sources: samples, oscillators, wavetables, noise generators.
* audio effects: filters, delay, reverb, distortion, modulations.
4) How far can it go?
* how to live code with Cagire.
* how fast can I break things?
## Pages
## What is live coding?
Cagire is organized in several views. Navigate between them using **Ctrl+Left/Right/Up/Down**:
Live coding is a technique where a programmer writes code in real-time in front of an audience. It is a way to experiment with code, to share things and thoughts openly, to express yourself through code. It can be technical, poetical, weird, preferably all at once. Live coding can be used to create music, visual art, and other forms of media. Learn more about live coding on [https://toplap.org](https://toplap.org) or [https://livecoding.fr](https://livecoding.fr). Live coding is an autotelic activity: it is an activity that is intrinsically rewarding, and the act of doing it is its own reward. There are no errors, only fun.
- **Sequencer**: Main view. Edit or preview patterns and scripts. Write Forth scripts.
- **Patterns**: Project patterns management. 32 banks of 32 patterns per project. Edit pattern properties (name, length, etc).
- **Engine**: Internal audio engine management: device selection, sample loading, performance options and voice / state monitoring.
- **Options**: General application settings.
- **Dict**: Forth word dictionary, organized by category. Learn about the internal programming language and its features.
- **Help**: Documentation. This is the page view you are looking at right now.
## About
Have fun with Cagire! Remember that live coding is all about experimentation and exploration!
Cagire is built by BuboBubo (Raphaël Maurice Forment, [https://raphaelforment.fr](https://raphaelforment.fr)). It is a free and open-source project licensed under the `AGPL-3.0 License`. You are free to contribute to the project by making direct contributions to the codebase or by providing feedback and suggestions.
### Credits
* **Doux** (audio engine) is a Rust port of Dough, originally written in C by Felix Roos.
* **mi-plaits-dsp-rs** is a Rust port of the code used by the Mutable Instruments Plaits.
* _Author_: Oliver Rockstedt [info@sourcebox.de](info@sourcebox.de).
* _Original author_: Emilie Gillet [emilie.o.gillet@gmail.com](emilie.o.gillet@gmail.com).