Notation System
Beepscript's notation is a text-based system where individual characters trigger sounds, character adjacency controls timbral morphing, and whitespace defines phrasing. It sits between traditional music notation (which describes pitch and rhythm) and programming languages (which describe process): Beepscript notation describes what it sounds like in a compact, typeable format.
Characters and atoms
Each character in the notation stream maps to a sound atom defined in a Lua configuration block. Atoms are synthesizer configurations: oscillator type, frequency, filter settings, envelope, effects chain. When the renderer encounters a character, it looks up its atom and triggers a voice with that configuration.
Single ASCII characters (a–z, A–Z, 0–9) are the most common atoms. Multi-character atom names use the $name syntax for longer, descriptive identifiers.
Morphing and adjacency
When two characters are adjacent — no space between them — the synthesizer crossfades smoothly from one atom's timbre to the next. Writing ab produces a morph from atom a to atom b. Writing a b (with a space) produces a hard cut: atom a stops, then atom b starts after a silence gap.
This adjacency-based morphing is the core of Beepscript's timbral expressiveness. Longer sequences like abcba create smooth timbral arcs. Repeating a character like aaa sustains the same timbre. The morph behavior uses a 5ms crossfade window to avoid clicks.
Timing
Two Lua parameters control timing: bpm (beats per minute) and div (subdivisions per beat). At bpm=120; div=16, each character occupies 1/16th of a beat at 120 BPM. The equals sign = inserts a one-unit rest (silence). This gives precise rhythmic control without needing explicit duration values.
Operators
Special characters modify the behavior of adjacent notes:
~— Tremolo: amplitude modulation on the following note.— Staccato: shortens the note duration|— Pitch bend up: +2 semitones per|, cumulative\— Pitch bend down: −2 semitones per\, cumulative^— Break sustain: cuts the current note to retrigger
Chords and simultaneity
Parentheses group characters for simultaneous playback. Writing (abc) triggers atoms a, b, and c at the same time — a chord. Each voice in the chord runs independently, so a chord can combine atoms from different synthesis engines.
Dynamics and expression
Beepscript supports per-note dynamics through multiple mechanisms:
- Case dynamics — Uppercase letters play louder than lowercase:
Ais a louder version ofa(when both are defined) - Velocity levels — Numeric suffixes or expression syntax control velocity per note
- Inline pitch override — Backtick expression syntax allows per-note frequency or parameter changes without defining new atoms
Pattern Arrangement Language (PAL)
For longer compositions, PAL provides a track-based structure within the same text file. PAL operates above the character-level notation, organizing it into named patterns and tracks.
Patterns
Named sequences of notation that can be referenced and reused. Define a pattern with /pa/ and reference it by name. Patterns can be copied (*$pattern for an independent copy) or referenced (+$pattern for a shared reference that updates when the source changes).
Tracks
Named channels that play patterns in sequence or in parallel. Define tracks with /tr/. Each track has its own playback position, loop settings, and mute/solo state. Multiple tracks play simultaneously, enabling layered arrangements.
Arpeggio builder
The /ar/ directive generates arpeggiated patterns from chord definitions, with configurable direction (up, down, up-down), rate, and octave range.
Transport and control
Per-track loop points, quantization flags, and mute/solo toggles provide arrangement-level control. The PAL system turns Beepscript from a single-voice sequencer into a multi-track composition environment.
How it differs
Traditional music notation describes pitch, duration, and dynamics. Piano rolls describe note-on/off events in a time grid. Programming languages like SuperCollider or Csound describe synthesis processes in code. Beepscript's notation describes timbral identity and transitions: which sound (atom), how it connects to the next sound (adjacency), and what modifies it (operators). The compact format means a few characters of text can encode complex timbral behavior that would take many lines of code in a traditional synthesis language.
The documentation covers the full notation syntax. The tour walks through it step by step with editable, playable examples.
← Back to About