Fix: update docs about snd

This commit is contained in:
2026-03-06 08:40:41 +01:00
parent f273470eaf
commit d055d2bfc6
23 changed files with 228 additions and 200 deletions

View File

@@ -7,19 +7,19 @@ Every step has a duration. By default, sounds emit at the very start of that dur
`at` drains the entire stack and stores the values as timing offsets. Each value is a fraction of the step duration: 0 = start, 0.5 = halfway, 1.0 = next step boundary.
```forth
0.5 at kick s . ;; kick at the midpoint
0.5 at kick snd . ;; kick at the midpoint
```
Push multiple values before calling `at` to get multiple emits from a single `.`:
```forth
0 0.5 at kick s .
0 0.5 at kick snd .
```
Two kicks: one at start, one at midpoint.
```forth
0 0.25 0.5 0.75 at hat s .
0 0.25 0.5 0.75 at hat snd .
```
Four hats, evenly spaced.
@@ -28,10 +28,10 @@ The deltas persist across multiple `.` calls until `clear` or a new `at`:
```forth
0 0.5 at
kick s . ;; 2 kicks
hat s . ;; 2 hats (same timing)
kick snd . ;; 2 kicks
hat snd . ;; 2 hats (same timing)
clear
snare s . ;; 1 snare (deltas cleared)
snare snd . ;; 1 snare (deltas cleared)
```
## Cross-product: at Without arp
@@ -40,7 +40,7 @@ Without `arp`, deltas multiply with polyphonic voices. If you have 3 notes and 2
```forth
0 0.5 at
c4 e4 g4 note 1.5 decay sine s .
c4 e4 g4 note 1.5 decay sine snd .
```
6 emits: 3 notes x 2 deltas. A chord played twice per step.
@@ -51,7 +51,7 @@ c4 e4 g4 note 1.5 decay sine s .
```forth
0 0.33 0.66 at
c4 e4 g4 arp note 0.5 decay sine s .
c4 e4 g4 arp note 0.5 decay sine snd .
```
C4 at 0, E4 at 0.33, G4 at 0.66.
@@ -60,7 +60,7 @@ If the lists differ in length, the shorter one wraps around:
```forth
0 0.25 0.5 0.75 at
c4 e4 arp note 0.3 decay sine s .
c4 e4 arp note 0.3 decay sine snd .
```
C4, E4, C4, E4 — the shorter list wraps to fill 4 time points.
@@ -74,25 +74,25 @@ You rarely type deltas by hand. Use generators:
Evenly spaced via `.,`:
```forth
0 1 0.25 ., at hat s . ;; 0 0.25 0.5 0.75 1.0
0 1 0.25 ., at hat snd . ;; 0 0.25 0.5 0.75 1.0
```
Euclidean distribution via `euclid`:
```forth
3 8 euclid at hat s . ;; 3 hats at positions 0, 3, 5
3 8 euclid at hat snd . ;; 3 hats at positions 0, 3, 5
```
Random timing via `gen`:
```forth
( 0.0 1.0 rand ) 4 gen at hat s . ;; 4 hats at random positions
( 0.0 1.0 rand ) 4 gen at hat snd . ;; 4 hats at random positions
```
Geometric spacing via `geom..`:
```forth
0.0 2.0 4 geom.. at hat s . ;; exponentially spaced
0.0 2.0 4 geom.. at hat snd . ;; exponentially spaced
```
## Gating at
@@ -101,14 +101,14 @@ Wrap `at` expressions in quotations for conditional timing:
```forth
( 0 0.25 0.5 0.75 at ) 2 every
hat s .
hat snd .
```
16th-note hats every other bar.
```forth
( 0 0.5 at ) 0.5 chance
kick s .
kick snd .
```
50% chance of double-hit.

View File

@@ -48,7 +48,7 @@ Contrast with `times`, which executes for side effects and does not collect. `ti
```forth
4 ( @i ) times ;; 0 1 2 3 (pushes @i each iteration)
4 ( @i 60 + note sine s . ) times ;; plays 4 notes, collects nothing
4 ( @i 60 + note sine snd . ) times ;; plays 4 notes, collects nothing
```
The distinction: `gen` is for building data. `times` is for doing things.
@@ -124,9 +124,9 @@ c4 4 dupn ;; c4 c4 c4 c4
Build a drone chord -- same note, different octaves:
```forth
c3 note 0.5 gain sine s .
c3 note 12 + 0.5 gain sine s .
c3 note 24 + 0.3 gain sine s .
c3 note 0.5 gain sine snd .
c3 note 12 + 0.5 gain sine snd .
c3 note 24 + 0.3 gain sine snd .
```
Or replicate a value for batch processing:

View File

@@ -7,17 +7,17 @@ This tutorial covers everything pitch-related: notes, intervals, chords, voicing
A note name followed by an octave number compiles to a MIDI integer:
```forth
c4 note sine s .
c4 note sine snd .
```
That plays middle C (MIDI 60). `a4` is concert A (69), `e3` is 52. Sharps use `s` or `#`, flats use `b`:
```forth
fs4 note 0.5 decay saw s .
fs4 note 0.5 decay saw snd .
```
```forth
eb4 note 0.8 decay tri s .
eb4 note 0.8 decay tri snd .
```
`fs4` and `f#4` both mean F sharp 4 (MIDI 66). `bb3` is B flat 3 (58). Octave range is -1 to 9.
@@ -29,13 +29,13 @@ Notes are just integers. They work anywhere an integer works — you can do arit
An interval duplicates the top of the stack and adds semitones. Stack two intervals to build a chord by hand:
```forth
c4 M3 P5 note 1.5 decay sine s .
c4 M3 P5 note 1.5 decay sine snd .
```
That builds a C major triad from scratch: C4 (60), then a major third above (64), then a perfect fifth above the root (67). Three notes on the stack, all played together.
```forth
a3 m3 P5 note 1.2 decay va s .
a3 m3 P5 note 1.2 decay va snd .
```
A minor triad: A3, C4, E4.
@@ -78,7 +78,7 @@ A minor triad: A3, C4, E4.
Custom voicings with wide intervals:
```forth
c3 P5 P8 M10 note 1.5 decay sine s .
c3 P5 P8 M10 note 1.5 decay sine snd .
```
C3, G3, C4, E4 — an open-voiced C major spread across two octaves.
@@ -88,21 +88,21 @@ C3, G3, C4, E4 — an open-voiced C major spread across two octaves.
Chord words replace a root note with all the chord tones. They're shortcuts for what intervals do manually:
```forth
c4 maj note 1.5 decay sine s .
c4 maj note 1.5 decay sine snd .
```
That's the same C major triad, but in one word instead of `M3 P5`. A few more:
```forth
d3 min7 note 1.5 decay va s .
d3 min7 note 1.5 decay va snd .
```
```forth
e3 dom9 note 1.2 decay saw s .
e3 dom9 note 1.2 decay saw snd .
```
```forth
a3 sus2 note 1.5 decay tri s .
a3 sus2 note 1.5 decay tri snd .
```
Common triads:
@@ -140,19 +140,19 @@ Four words reshape chord voicings without changing the harmony.
`inv` moves the bottom note up an octave (inversion):
```forth
c4 maj inv note 1.5 decay sine s .
c4 maj inv note 1.5 decay sine snd .
```
The root C goes up, giving E4 G4 C5 — first inversion. Apply it twice for second inversion:
```forth
c4 maj inv inv note 1.5 decay sine s .
c4 maj inv inv note 1.5 decay sine snd .
```
G4 C5 E5. `dinv` does the opposite — moves the top note down an octave:
```forth
c4 maj dinv note 1.5 decay sine s .
c4 maj dinv note 1.5 decay sine snd .
```
G3 C4 E4. The fifth drops below the root.
@@ -160,13 +160,13 @@ G3 C4 E4. The fifth drops below the root.
`drop2` and `drop3` are jazz voicing techniques for four-note chords. `drop2` takes the second-from-top note and drops it an octave:
```forth
c4 maj7 drop2 note 1.2 decay va s .
c4 maj7 drop2 note 1.2 decay va snd .
```
From C4 E4 G4 B4, the G drops to G3: G3 C4 E4 B4. `drop3` drops the third-from-top:
```forth
c4 maj7 drop3 note 1.2 decay va s .
c4 maj7 drop3 note 1.2 decay va snd .
```
E drops to E3: E3 C4 G4 B4. These create wider, more open voicings common in jazz guitar and piano.
@@ -176,13 +176,13 @@ E drops to E3: E3 C4 G4 B4. These create wider, more open voicings common in jaz
`tp` shifts every note on the stack by N semitones:
```forth
c4 maj 3 tp note 1.5 decay sine s .
c4 maj 3 tp note 1.5 decay sine snd .
```
C major transposed up 3 semitones becomes Eb major. Works with any number of notes:
```forth
c4 min7 -2 tp note 1.5 decay va s .
c4 min7 -2 tp note 1.5 decay va snd .
```
Shifts the whole chord down 2 semitones (Bb minor 7).
@@ -190,14 +190,14 @@ Shifts the whole chord down 2 semitones (Bb minor 7).
`oct` shifts a single note by octaves:
```forth
c4 1 oct note 0.3 decay sine s .
c4 1 oct note 0.3 decay sine snd .
```
C5 (one octave up). Useful for bass lines:
```forth
0 2 4 5 7 5 4 2 8 cycle minor note
-2 oct 0.8 gain sine s .
-2 oct 0.8 gain sine snd .
```
## Scales
@@ -205,7 +205,7 @@ C5 (one octave up). Useful for bass lines:
Scale words convert a degree index into a MIDI note. By default the root is C4 (MIDI 60):
```forth
0 major note 0.5 decay sine s .
0 major note 0.5 decay sine snd .
```
Degree 0 of the major scale: C4. Degrees wrap with octave transposition — degree 7 gives C5 (72), degree -1 gives B3 (59).
@@ -213,13 +213,13 @@ Degree 0 of the major scale: C4. Degrees wrap with octave transposition — degr
Walk through a scale with `cycle`:
```forth
0 1 2 3 4 5 6 7 8 cycle minor note 0.5 decay sine s .
0 1 2 3 4 5 6 7 8 cycle minor note 0.5 decay sine snd .
```
Random notes from a scale:
```forth
0 7 rand pentatonic note 0.8 decay va s .
0 7 rand pentatonic note 0.8 decay va snd .
```
### Setting the key
@@ -227,13 +227,13 @@ Random notes from a scale:
By default scales are rooted at C4. Use `key!` to change the tonal center:
```forth
g3 key! 0 major note 0.5 decay sine s .
g3 key! 0 major note 0.5 decay sine snd .
```
Now degree 0 is G3 (55) instead of C4. The key persists across steps until changed again:
```forth
a3 key! 0 3 5 7 3 cycle minor note 0.8 decay tri s .
a3 key! 0 3 5 7 3 cycle minor note 0.8 decay tri snd .
```
A minor melody starting from A3.
@@ -261,19 +261,19 @@ Jazz, symmetric, and modal variant scales are listed in the Reference section.
`triad` and `seventh` build chords from scale degrees. Instead of specifying a chord type, you get whatever chord the scale produces at that degree:
```forth
0 major triad note 1.5 decay sine s .
0 major triad note 1.5 decay sine snd .
```
Degree 0 of the major scale, stacked in thirds: C E G — a major triad. The scale determines the chord quality automatically. Degree 1 gives D F A (minor), degree 4 gives G B D (major):
```forth
4 major triad note 1.5 decay sine s .
4 major triad note 1.5 decay sine snd .
```
`seventh` adds a fourth note:
```forth
0 major seventh note 1.2 decay va s .
0 major seventh note 1.2 decay va snd .
```
C E G B — Cmaj7. Degree 1 gives Dm7, degree 4 gives G7 (dominant). The diatonic context determines everything.
@@ -281,7 +281,7 @@ C E G B — Cmaj7. Degree 1 gives Dm7, degree 4 gives G7 (dominant). The diatoni
Combine with `key!` to play diatonic chords in any key:
```forth
g3 key! 0 major triad note 1.5 decay sine s .
g3 key! 0 major triad note 1.5 decay sine snd .
```
G major triad rooted at G3.
@@ -291,7 +291,7 @@ A I-vi-IV-V chord progression using `pcycle`:
```forth
( 0 major seventh ) ( 5 major seventh )
( 3 major seventh ) ( 4 major seventh ) 4 pcycle
note 1.2 decay va s .
note 1.2 decay va snd .
```
Combine with voicings for smoother voice leading:
@@ -299,13 +299,13 @@ Combine with voicings for smoother voice leading:
```forth
( 0 major seventh ) ( 5 major seventh inv )
( 3 major seventh ) ( 4 major seventh drop2 ) 4 pcycle
note 1.5 decay va s .
note 1.5 decay va snd .
```
Arpeggiate diatonic chords using `arp` (see the *Timing with at* tutorial for details on `arp`):
```forth
0 major seventh arp note 0.5 decay sine s .
0 major seventh arp note 0.5 decay sine snd .
```
## Frequency Conversion
@@ -313,7 +313,7 @@ Arpeggiate diatonic chords using `arp` (see the *Timing with at* tutorial for de
`mtof` converts a MIDI note to frequency in Hz. `ftom` does the reverse:
```forth
c4 mtof freq sine s .
c4 mtof freq sine snd .
```
Useful when a synth parameter expects Hz rather than MIDI.

View File

@@ -21,7 +21,7 @@ Press `Enter` to focus the editor. Write Forth code as you would in any step. Pr
```forth
;; a simple drone
saw s c2 note 0.3 gain 0.4 verb .
saw snd c2 note 0.3 gain 0.4 verb .
```
## Speed and Length

View File

@@ -17,15 +17,15 @@ sine sound
`rand` takes a range and returns a random value. If both bounds are integers, the result is an integer. If either is a float, you get a float:
```forth
60 72 rand note sine s .5 decay . ;; random MIDI note from 60 to 72
0.3 0.9 rand gain sine s .5 decay . ;; random gain between 0.3 and 0.9
60 72 rand note sine snd 0.5 decay . ;; random MIDI note from 60 to 72
0.3 0.9 rand gain sine snd 0.5 decay . ;; random gain between 0.3 and 0.9
```
`exprand` and `logrand` give you weighted distributions. `exprand` is biased toward the low end, `logrand` toward the high end:
```forth
200.0 8000.0 exprand freq sine s .5 decay . ;; mostly low frequencies
200.0 8000.0 logrand freq sine s .5 decay . ;; mostly high frequencies
200.0 8000.0 exprand freq sine snd 0.5 decay . ;; mostly low frequencies
200.0 8000.0 logrand freq sine snd 0.5 decay . ;; mostly high frequencies
```
These are useful for parameters where perception is logarithmic, like frequency and duration.
@@ -35,8 +35,8 @@ These are useful for parameters where perception is logarithmic, like frequency
The probability words take a quotation and execute it with some chance. `chance` takes a float from 0.0 to 1.0, `prob` takes a percentage from 0 to 100:
```forth
( hat s . ) 0.25 chance ;; 25% chance
( kick s . ) 75 prob ;; 75% chance
( hat snd . ) 0.25 chance ;; 25% chance
( kick snd . ) 75 prob ;; 75% chance
```
Named probability words save you from remembering numbers:
@@ -52,9 +52,9 @@ Named probability words save you from remembering numbers:
| `never` | 0% |
```forth
( hat s . ) often ;; 75%
( snare s . ) sometimes ;; 50%
( clap s . ) rarely ;; 25%
( hat snd . ) often ;; 75%
( snare snd . ) sometimes ;; 50%
( clap snd . ) rarely ;; 25%
```
`always` and `never` are useful when you want to temporarily mute or unmute a voice without deleting code. Change `sometimes` to `never` to silence it, `always` to bring it back.
@@ -62,8 +62,8 @@ Named probability words save you from remembering numbers:
Use `?` and `!?` with `coin` for quick coin-flip decisions:
```forth
( hat s . ) coin ? ;; execute if coin is 1
( rim s . ) coin !? ;; execute if coin is 0
( hat snd . ) coin ? ;; execute if coin is 1
( rim snd . ) coin !? ;; execute if coin is 0
```
## Selection
@@ -71,21 +71,21 @@ Use `?` and `!?` with `coin` for quick coin-flip decisions:
`choose` picks randomly from n items on the stack:
```forth
kick snare hat 3 choose s . ;; random drum hit
60 64 67 72 4 choose note sine s .5 decay . ;; random note from a set
kick snare hat 3 choose snd . ;; random drum hit
60 64 67 72 4 choose note sine snd 0.5 decay . ;; random note from a set
```
When a chosen item is a quotation, it gets executed:
```forth
( 0.1 decay ) ( 0.5 decay ) ( 0.9 decay ) 3 choose
sine s .
sine snd .
```
`wchoose` lets you assign weights to each option. Push value/weight pairs:
```forth
kick 0.5 snare 0.3 hat 0.2 3 wchoose s .
kick 0.5 snare 0.3 hat 0.2 3 wchoose snd .
```
Kick plays 50% of the time, snare 30%, hat 20%. Weights don't need to sum to 1 -- they're normalized automatically.
@@ -103,7 +103,7 @@ Combined with `note`, this gives you a random permutation of a chord every time
`every` runs a quotation once every n pattern iterations:
```forth
( crash s . ) 4 every ;; crash cymbal every 4th iteration
( crash snd . ) 4 every ;; crash cymbal every 4th iteration
```
`except` is the inverse -- it runs a quotation on all iterations *except* every nth:
@@ -115,22 +115,22 @@ Combined with `note`, this gives you a random permutation of a chord every time
`every+` and `except+` take an extra offset argument to shift the phase:
```forth
( snare s . ) 4 2 every+ ;; fires at iter 2, 6, 10, 14...
( snare s . ) 4 2 except+ ;; skips at iter 2, 6, 10, 14...
( snare snd . ) 4 2 every+ ;; fires at iter 2, 6, 10, 14...
( snare snd . ) 4 2 except+ ;; skips at iter 2, 6, 10, 14...
```
Without the offset, `every` fires at 0, 4, 8... The offset shifts that by 2, so it fires at 2, 6, 10... This lets you interleave patterns that share the same period:
```forth
( kick s . ) 4 every ;; kick at 0, 4, 8...
( snare s . ) 4 2 every+ ;; snare at 2, 6, 10...
( kick snd . ) 4 every ;; kick at 0, 4, 8...
( snare snd . ) 4 2 every+ ;; snare at 2, 6, 10...
```
`bjork` and `pbjork` use Bjorklund's algorithm to distribute k hits across n positions as evenly as possible. Classic Euclidean rhythms:
```forth
( hat s . ) 3 8 bjork ;; tresillo: x..x..x. (by step runs)
( hat s . ) 5 8 pbjork ;; cinquillo: x.xx.xx. (by pattern iterations)
( hat snd . ) 3 8 bjork ;; tresillo: x..x..x. (by step runs)
( hat snd . ) 5 8 pbjork ;; cinquillo: x.xx.xx. (by pattern iterations)
```
`bjork` counts by step runs (how many times this particular step has played). `pbjork` counts by pattern iterations. Some classic patterns:
@@ -148,7 +148,7 @@ By default, every run produces different random values. Use `seed` to make rando
```forth
42 seed
60 72 rand note sine s . ;; always the same "random" note
60 72 rand note sine snd . ;; always the same "random" note
```
The seed is set at the start of the script. Same seed, same sequence. Useful when you want a specific random pattern to repeat.
@@ -158,7 +158,7 @@ The seed is set at the start of the script. Same seed, same sequence. Useful whe
The real power comes from mixing techniques. A hi-hat pattern with ghost notes:
```forth
hat s
hat snd
( 0.3 0.6 rand gain ) ( 0.8 gain ) 2 cycle
.
```
@@ -170,16 +170,16 @@ A bass line that changes every 4 bars:
```forth
( c2 note ) ( e2 note ) ( g2 note ) ( a2 note ) 4 pcycle
( 0.5 decay ) often
sine s .
sine snd .
```
Layered percussion with different densities:
```forth
( kick s . ) always
( snare s . ) 2 every
( hat s . ) 5 8 bjork
( rim s . ) rarely
( kick snd . ) always
( snare snd . ) 2 every
( hat snd . ) 5 8 bjork
( rim snd . ) rarely
```
A melodic step with weighted note selection and random timbre:
@@ -188,7 +188,7 @@ A melodic step with weighted note selection and random timbre:
c4 0.4 e4 0.3 g4 0.2 b4 0.1 4 wchoose note
0.3 0.7 rand decay
1.0 4.0 exprand harmonics
modal s .
modal snd .
```
The root note plays most often. Higher chord tones are rarer. Decay and harmonics vary continuously.

View File

@@ -19,7 +19,7 @@ Play something -- a pattern, a live input, anything that makes sound. When you'r
The recording is now available as a sample:
```forth
drums s .
drums snd .
```
## Playback
@@ -27,10 +27,10 @@ drums s .
Recorded samples are ordinary samples. Everything you can do with a loaded sample works here:
```forth
drums s 0.5 speed . ;; half speed
drums s 0.25 begin 0.5 end . ;; slice the middle quarter
drums s 800 lpf 0.3 verb . ;; filter and reverb
drums s -1 speed . ;; reverse
drums snd 0.5 speed . ;; half speed
drums snd 0.25 begin 0.5 end . ;; slice the middle quarter
drums snd 800 lpf 0.3 verb . ;; filter and reverb
drums snd -1 speed . ;; reverse
```
## Overdub
@@ -70,7 +70,7 @@ Record a foundation, then overdub to build up:
"loop" dub
;; 4. play the result
loop s .
loop snd .
```
Each overdub pass adds to what's already there. The buffer wraps, so longer passes layer cyclically over the original length.
@@ -80,16 +80,16 @@ Each overdub pass adds to what's already there. The buffer wraps, so longer pass
Once you have a recording, carve it up:
```forth
loop s 0.0 begin 0.25 end . ;; first quarter
loop s 0.25 begin 0.5 end . ;; second quarter
loop s 0.5 begin 0.75 end . ;; third quarter
loop s 0.75 begin 1.0 end . ;; last quarter
loop snd 0.0 begin 0.25 end . ;; first quarter
loop snd 0.25 begin 0.5 end . ;; second quarter
loop snd 0.5 begin 0.75 end . ;; third quarter
loop snd 0.75 begin 1.0 end . ;; last quarter
```
Combine with randomness for variation:
```forth
loop s
loop snd
0.0 0.25 0.5 0.75 4 choose begin
0.5 speed
.

View File

@@ -11,9 +11,9 @@ Drop an `.sf2` file into one of your samples directories. The engine finds and l
Use `gm` as the sound source. The `n` parameter selects a program by name or number (0-127):
```forth
gm s piano n . ;; acoustic piano
gm s strings n c4 note . ;; strings playing middle C
gm s 0 n e4 note . ;; program 0 (piano) playing E4
gm snd piano n . ;; acoustic piano
gm snd strings n c4 note . ;; strings playing middle C
gm snd 0 n e4 note . ;; program 0 (piano) playing E4
```
## Drums
@@ -21,10 +21,10 @@ gm s 0 n e4 note . ;; program 0 (piano) playing E4
Drums live on a separate bank. Use `drums` or `percussion` as the `n` value. Each MIDI note triggers a different instrument:
```forth
gm s drums n 36 note . ;; kick
gm s drums n 38 note . ;; snare
gm s drums n 42 note . ;; closed hi-hat
gm s percussion n 49 note . ;; crash cymbal
gm snd drums n 36 note . ;; kick
gm snd drums n 38 note . ;; snare
gm snd drums n 42 note . ;; closed hi-hat
gm snd percussion n 49 note . ;; crash cymbal
```
## Envelope
@@ -32,8 +32,8 @@ gm s percussion n 49 note . ;; crash cymbal
The soundfont embeds ADSR envelope data per preset. The engine applies it automatically. Override any parameter explicitly:
```forth
gm s piano n 0.01 attack 0.3 decay .
gm s strings n 0.5 attack 2.0 release .
gm snd piano n 0.01 attack 0.3 decay .
gm snd strings n 0.5 attack 2.0 release .
```
If you set `attack`, `decay`, `sustain`, or `release`, your value wins. Unspecified parameters keep the soundfont default.
@@ -43,9 +43,9 @@ If you set `attack`, `decay`, `sustain`, or `release`, your value wins. Unspecif
All standard engine parameters work on GM voices. Filter, distort, spatialize:
```forth
gm s bass n 800 lpf 0.3 verb .
gm s epiano n 0.5 delay 1.5 distort .
gm s choir n 0.8 pan 2000 hpf .
gm snd bass n 800 lpf 0.3 verb .
gm snd epiano n 0.5 delay 1.5 distort .
gm snd choir n 0.8 pan 2000 hpf .
```
## Preset Names
@@ -79,22 +79,22 @@ A simple GM drum pattern across four steps:
```forth
;; step 1: kick
gm s drums n 36 note .
gm snd drums n 36 note .
;; step 2: closed hat
gm s drums n 42 note 0.6 gain .
gm snd drums n 42 note 0.6 gain .
;; step 3: snare
gm s drums n 38 note .
gm snd drums n 38 note .
;; step 4: closed hat
gm s drums n 42 note 0.6 gain .
gm snd drums n 42 note 0.6 gain .
```
Layer piano chords with randomness:
```forth
gm s piano n
gm snd piano n
c4 e4 g4 3 choose note
0.3 0.8 rand gain
0.1 0.4 rand verb
@@ -104,7 +104,7 @@ c4 e4 g4 3 choose note
A bass line with envelope override:
```forth
gm s bass n
gm snd bass n
c2 e2 g2 a2 4 cycle note
0.01 attack 0.2 decay 0.0 sustain
.

View File

@@ -17,13 +17,13 @@ Variables let you name values and share data between steps. They are global -- a
`,name` stores just like `!name` but keeps the value on the stack. Useful when you want to name something and keep using it:
```forth
440 ,freq sine s . ;; stores 440 in freq AND passes it to the pipeline
440 ,freq sine snd . ;; stores 440 in freq AND passes it to the pipeline
```
Without `,`, you'd need `dup`:
```forth
440 dup !freq sine s . ;; equivalent, but noisier
440 dup !freq sine snd . ;; equivalent, but noisier
```
## Sharing Between Steps
@@ -35,7 +35,7 @@ Variables are shared across all steps. One step can store a value that another r
c4 iter 7 mod + !root
;; step 4: read it
@root 7 + note sine s .
@root 7 + note sine snd .
```
Every time the pattern loops, step 0 picks a new root. Step 4 always harmonizes with it.
@@ -46,7 +46,7 @@ Fetch, modify, store back. A classic pattern for evolving values:
```forth
@n 1 + !n ;; increment n each time this step runs
@n 12 mod note sine s . ;; cycle through 12 notes
@n 12 mod note sine snd . ;; cycle through 12 notes
```
Reset on some condition:
@@ -69,7 +69,7 @@ Store a sound name in a variable, reuse it across steps:
"sine" !synth
;; step 1, 2, 3...
c4 note @synth s .
c4 note @synth snd .
```
Change one step, all steps follow.