Beepscript Cheat Sheet

Complete syntax reference — print to PDF for a two-page pocket guide

Complete Template

-- A complete Beepscript program showing all major features
{
  bpm=120; div=16;                      -- timing: 120 BPM, 16th-note grid (125ms/cell)
  master_gain(0.25);                    -- ALWAYS set first to prevent clipping

  -- Define atoms (a-z) in Lua: oscillator → filter → envelope
  -- Frequency can be Hz or note strings: "A1", "C4", "F#3", "C4+7"
  k = env(1,80,0,50, lpf(100, sine("A1")));       -- kick drum
  s = env(1,60,0,40, bpf(2000,3, noise()));     -- snare (noise source)
  h = env(1,20,0,10, hpf(8000, noise()));      -- hi-hat
  b = env(5,100,0.6,50, lpf(400, saw("A1")));   -- bass (saw + LPF)

  -- LFO for vibrato on lead
  vib = lfo_sine(5, 1.0, "retrigger");
  l = env(10,80,0.6,60, lpf(2000, saw("A4")));  -- note string for pitch

  master_reverb(0.4, 0.5);           -- global reverb
}

-- PAL: define patterns (ALL must be 16 cells = 1 bar at div=16)
/pa/$kick/k===k===k===k===/         -- 4+12 = 16 cells ✓
/pa/$snare/====s=======s===/        -- 4+1+7+1+3 = 16 cells ✓
/pa/$hats/h=h=h=h=h=h=h=h=/        -- (h=)×8 = 16 cells ✓
/pa/$bass/b===b=====b=b====/        -- 16 cells ✓

-- PAL: assign patterns to tracks
/tr/@kick/+$kick/                   -- + = live reference
/tr/@snare/+$snare/
/tr/@hats/+$hats/
/tr/@bass/+$bass/

-- PAL: start looped playback
/lp/on/                             -- enable looping
/pp/                                -- play all tracks
-- Inline content below provides duration (tracks loop behind it)
=x64                                -- 64 cells = 4 bars of output

Program Structure

ComponentSyntaxPurpose
Lua block{...}Define atoms, timing, effects
Atom streama=b=c=dSequence of sounds + rests
PAL action/cmd/args/Patterns, tracks, playback
Comment-- textIgnored to end of line

Atoms & Naming

FormExampleNotes
Single charazDefined in Lua: {a=saw("A4")}
UppercaseAZLoud variant of lowercase (redefinable)
Complex name$kickLua: {$kick=env(...)}, stream: $kick
Volume (0-9)a5, A3Number overrides case-based volume

Notation Operators

OpCellsEffect
=1Rest (silence)
_2Long rest
__4Extra-long rest
=xNNN cells of rest: =x16
ax44Sustain atom for 4 cells
! or spaceHard cut (no morph)
newlineHard cut
.Staccato (short note)
~Tremolo
| \Pitch bend up / down (+2st each, cumulative)
^Break sustain
tabIgnored (use for indentation)

Transitions

TypeSyntaxResult
SustainaaaaOne voice held 4 beats
MorphabcdSmooth glide a→b→c→d
Hard cuta!b / a bSeparate attacks, no glide
Resta=b=cAttacks with silence gaps

Timing

{bpm=120; div=16}  -- ms/cell = 240000 / (bpm × div)
divNote@120 BPMCells/bar
4Quarter500ms4
8Eighth250ms8
1616th125ms16
3232nd62.5ms32

Legacy: rate=8 = 8 beats/sec = 125ms/cell

BPM LFO Modulation

bpm = 90 + lfo_smooth_random(0.3, 15, "free")  -- drift 75-105 BPM
bpm = 120 + lfo_sine(0.2, 10, "free")          -- breathing 110-130

Tempo LFO: virtual clock stretches/compresses event timing. Keep depth ±10-20 BPM. Use "free" mode.

Oscillators

Frequency accepts note strings or Hz: saw("A4"), saw("C4+7"), saw(440)

FunctionSoundParameters
sine(f)Pure tone, smoothf: Hz or note string ("A4", "C4+7")
saw(f)Rich harmonics, buzzyf: Hz or note string
square(f)Hollow, clarinet-likef: Hz or note string
tri(f)Soft, flute-likef: Hz or note string
pulse(f, pw)Variable duty cyclef: Hz/note; pw: 0.0–1.0 duty (default 0.5, LFO-modulatable)
osc(type, f)Generic oscillatortype: "sine", "saw", "square", "tri", etc.; f: Hz/note

Note offsets: "C4+7" = G4, "A4-12" = A3. Sharps/flats: "F#3", "Bb4"

Noise Generators

FunctionSpectrum
noise() / white_noise()Flat (equal energy)
pink_noise()−3 dB/oct (natural)
brown_noise() / red_noise()−6 dB/oct (deep rumble)
blue_noise()+3 dB/oct (bright)
violet_noise()+6 dB/oct (very bright)

Filters

FunctionTypeParameters
lpf(cutoff, src)Low-passcutoff: Hz (LFO-modulatable)
hpf(cutoff, src)High-passcutoff: Hz
bpf(cutoff, q, src)Band-passcutoff: Hz; q: quality factor (0.1–30, higher = narrower)
notch(cutoff, q, src)Band-stopcutoff: Hz; q: quality factor
allpass(cutoff, q, src)All-pass (phase shift)cutoff: Hz; q: quality factor
peak(cutoff, q, dB, src)Parametric EQ bellcutoff: Hz; q: bandwidth; dB: gain (+/−)

Optional last param: key_follow (−1.0 to 1.0). 1.0 = cutoff tracks pitch.

Formant (Vowel) Filter

formant("ah", src)           -- single vowel
formant("oh", 3, src)        -- with tract shift (semitones)

Vowels: "ah" "eh" "ee" "oh" "oo" "ae" "uh" "er" "aw" "mm" "nn" "ng"

Envelopes

env(attack_ms, decay_ms, sustain_level, release_ms, source)
env(attack_ms, decay_ms, sustain_level, release_ms, source, curve)

curve (optional): shapes all ADSR segments. 1.0=linear (default), <1.0=convex (fast start, slow tail), >1.0=concave (slow start, fast end; approximates exponential decay). Typical: 0.53.0.

PresetADSRCurve
Instant1500.8100
Pluck21500100
Pad5008000.81000
Organ501.050
Bell11500020002.5
Kick180050
Snare160040
Hi-hat120010

Mixing & Gain

mix(src1, src2, ...)               -- combine sources (auto-normalizes)
gain(0.5, src)                     -- apply volume (0.0-1.0, LFO-modulatable)
compress(ratio, thresh_db, src)    -- per-atom compressor (ratio: e.g. 4; thresh: dB e.g. -12)

Simultaneity Groups (Chords)

(abc)        -- three voices triggered at once (1 cell)
(abc)x4      -- sustain chord for 4 cells
(a)x4        -- sustain single atom for 4 cells
($pat)x4     -- if $pat is a PAL pattern: repeat 4× sequentially

Distortion

FunctionEffectParameters
soft_clip(drive, src)Warm saturationdrive: 0.0–1.0
hard_clip(drive, src)Aggressive clippingdrive: 0.0–1.0
distort(drive, type, src)Generic distortiondrive: 0.0–1.0; type: "soft_clip", "hard_clip", etc.
bitcrush(bits, [rate], src)Lo-fi bit reductionbits: 2–16; rate: 0.0–1.0 sample rate (optional, default 1.0)
wavefold(amount, src)Wave foldingamount: fold threshold

Time-Based Effects

delay(ms, feedback, src)               -- ms: delay time; feedback: 0.0-1.0
delay(ms, feedback, mix, src)          -- mix: wet/dry 0.0-1.0
reverb(size, src)                      -- size: room 0.0-1.0
reverb(size, damping, wet, width, src) -- damping/wet/width: 0.0-1.0
chorus(depth, src)                     -- depth: 0.0-1.0
chorus(mix, delay_ms, depth_ms, rate, src)
flanger(depth, src)                    -- depth: 0.0-1.0
flanger(mix, depth_ms, rate, fb, src)  -- fb: feedback 0.0-1.0

Master Effects

master_gain(0.25)                   -- output volume (SET FIRST!)
master_reverb(size, damping)        -- size/damping: 0.0-1.0
master_delay(ms, feedback, mix)     -- ms: time; feedback/mix: 0.0-1.0
master_limiter(threshold)           -- threshold: dB (LFO-modulatable)
master_compress(ratio, threshold)   -- both params LFO-modulatable
master_lpf(cutoff)                  -- cutoff: Hz
master_hpf(cutoff)                  -- cutoff: Hz
master_bpf(cutoff, q)               -- cutoff: Hz; q: quality
master_notch(cutoff, q)             -- cutoff: Hz; q: quality
master_peak(cutoff, q, gain_db)     -- parametric EQ
master_lpf_bypass()                 -- disable default master LPF
master_chain("filter","delay","reverb") -- processing order
master_parallel(true)              -- parallel filter+reverb

Group Effects (Bus Processing)

group("drums", {"k", "s", "h"})       -- define group
group_reverb("drums", size, damp)       -- size/damp: 0.0-1.0
group_lpf("drums", cutoff)              -- cutoff: Hz
group_hpf("drums", cutoff)              -- cutoff: Hz
group_bpf("drums", cutoff, q)           -- cutoff: Hz; q: quality
group_notch("drums", cutoff, q)         -- cutoff: Hz; q: quality
group_peak("drums", cutoff, q, gain_db) -- parametric EQ
group_compress("drums", ratio, thresh)  -- ratio: e.g. 4; thresh: dB

LFOs (Low Frequency Oscillators)

name = lfo_sine(rate, depth, "mode")
a = sine(440 + 20 * name)  -- modulate frequency

Waveforms

FunctionShape
lfo_sineSmooth sine
lfo_squareGating / stepped
lfo_sawRising ramp
lfo_rsawFalling ramp
lfo_triTriangle (linear)
lfo_randomSample & hold
lfo_smooth_randomSmooth random drift
lfo_expExponential (sidechain)

Unipolar: append _uni for 0-to-depth range (e.g., lfo_sine_uni)

Trigger Modes

ModeBehavior
"retrigger"Reset phase per voice
"free"Continuous (global phase)
"sync"Tempo-synced (rate = cycles/beat)
"oneshot"One cycle, then hold
"key"Phase seeded by MIDI note

Shape Options

lfo_square(4,1,"sync", {pulsewidth=0.25})
lfo_exp(4,1,"sync", {direction="rise", curve_amount=3})
lfo_smooth_random(0.1,1,"free", {smoothness=0.2}) -- slow drift
lfo_tri(2,1,"retrigger", {skew=0.2})

Params: pulsewidth, curve, skew, slew, smoothness (0=smooth, 1=instant), octaves, direction, curve_amount, phase

Envelope-Wrapped LFO

vib_raw = lfo_sine(6, 1.0, "retrigger")
vib = env_lfo(0, 200, 1.0, 50, vib_raw) -- fades in over 200ms

Common LFO Recipes

-- Vibrato
vib = lfo_sine(5,1,"retrigger"); a = sine(440+20*vib)
-- Filter wobble (tempo-synced)
w = lfo_sine(2,1,"sync"); a = lpf(300+1200*w, saw(55))
-- Sidechain pump
p = lfo_exp(4,1,"sync",{direction="rise",curve_amount=3})
a = gain(0.2+0.7*p, saw(110))
-- Tremolo
t = lfo_sine(4,0.3,"retrigger"); a = gain(0.5+0.3*t, sine(440))
-- Tempo drift (BPM modulation)
bpm = 90 + lfo_smooth_random(0.3,15,"free")

Expressions (Per-Note Overrides)

`atom:pitch:velocity:duration:modifier=value`
ExampleMeaning
`a:C4`Atom a at C4
`a::100`Default pitch, velocity 100
`a:::2`Duration 2 units
`a:G3:100:1:vib=4`G3, vel 100, 1 unit, 4Hz vibrato

Pitch: note (C4, F#3), offset (+7, -5), Hz (440hz)

Modifiers: vib, pan, att, rel, bend, cut

PAL — Playback Actions Language

Patterns & Tracks

/pa/$kick/k===k===k===k===/    -- define pattern
/tr/@drums/+$kick/              -- track with pattern ref (+)
/tr/@drums/*$kick/              -- track with pattern copy (*)
/tr/@lead/a=b=c=d/              -- track with inline atoms

Playback & Control

ActionEffect
/pp/   /pp/@t/Play all / specific track
/ps/   /ps/@t/Pause all / specific
/st/   /st/@t/Stop all / specific (rewind)
/lp/on/   /lp/off/Enable / disable looping
/tp/120/Set tempo
/qt/16/Set quantize grid
/mu/@t/Mute track
/so/@t/Solo track

Arpeggio Builder

/ar/$arp/u/ceg/       -- up: c!e!g
/ar/$arp/d/ceg/       -- down: g!e!c
/ar/$arp/ud/ceg/      -- up-down (ping-pong)
/ar/$arp/r/ceg/       -- random order
/ar/$arp/u/ceg/=/     -- rested: c=e=g
/ar/$arp/u/ceg//      -- morph: ceg

FM Synthesis

a = fm({carrier=440, modulator=880, index=2.5})
a = fm({carrier=440, modulator=880, index=3.0,
    algorithm="feedback", feedback=0.5})   -- with algorithm

Algorithms

NameRoutingCharacter
stack2Op2 → Op1Standard 2-op (default)
stack3Op3 → Op2 → Op1Brass, rich chain
stack4Op4 → … → Op1Maximum depth
parallelOp2+Op3 → Op1Dual modulator
feedbackOp2(self) → Op1Sawtooth-like
additiveOp1+2+3+4Organ (no mod)
twin(Op2→1)+(Op4→3)Two FM pairs
diamondOp3,4 → Op2 → Op1Complex intermod

Operator Envelopes

a = fm({carrier=330, modulator=660, index=3.5,
    operators={
      {ratio=1.0, level=1.0},              -- carrier: full sustain
      {ratio=2.0, level=1.0,              -- modulator: fast decay
       attack=1, decay=250, sustain=0.05, release=80}
    }})

Modulation Index

IndexCharacterUse
0.1–0.5Subtle shimmerWarm pads
1.0–2.0Classic FME-piano, vibes
3.0–5.0Bright, brassyBrass, leads
5.0–10.0MetallicBells, gongs

FM Ratios

Mod:CarCharacterUse
1:1Saw-likeBass, leads
2:1Bright octaveElectric piano
3:1HollowClarinet, reed
1.41:1Bell-likeBells, chimes

FM Recipes

-- DX7 Electric Piano
e = env(5,600,0.3,300, fm({carrier=330,modulator=660,index=3.5,
  operators={{ratio=1,level=1},{ratio=2,level=1,
    attack=1,decay=250,sustain=0.05,release=80}}}))
-- FM Bass (1:1 ratio + LPF)
b = env(2,150,0.5,100, lpf(600, fm({carrier=55,modulator=55,
  index=4.0,operators={{ratio=1,level=1},{ratio=1,level=1,
    attack=1,decay=80,sustain=0.2,release=50}}})))
-- FM Bell (inharmonic ratio, curve=2.5 for natural decay)
c = env(1,1500,0,800, fm({carrier=880,modulator=1241,index=5.0}), 2.5)

Carrier op sustain=1.0 (Voice env shapes volume). Modulator decay shapes timbre.

Vocal / Apparatus Synthesis

a = apparatus("ah", 120)                -- phoneme at Hz
b = vocal("ee", 220)                    -- alias
c = apparatus("oh", 150, "jitter=1.5;breathiness=0.8")
d = apparatus("mm", 110, "breathy")     -- preset

Phonemes: same as formant vowel list. Params: jitter, breathiness, tremor=RATE,DEPTH. Presets: "breathy", "pressed"

Stringed Instruments

a = stringed(440)                        -- generic pluck
b = stringed{freq=440, material=SILK, body=PAULOWNIA}
c = guitar(330)                          -- nylon, spruce
d = guitar{freq=330, material=STEEL, body=ROSEWOOD}
e = piano_str(261.63)                    -- hammer, steel
f = erhu{freq=440, bow_pressure=0.6}    -- bow, customized
g = sitar{freq=261.63, buzz=0.6}        -- buzz + sympathetic

Presets accept freq OR table: guitar(440) or guitar{freq=440, material=STEEL}. All 15: guitar koto gayageum harp guzheng banjo mandolin bouzouki shamisen piano_str dulcimer erhu violin_str sitar tanpura. Constants: Materials: SILK NYLON GUT STEEL BRONZE BRASS WOUND. Bodies: SPRUCE CEDAR MAPLE PAULOWNIA ROSEWOOD MAHOGANY GOURD METAL MEMBRANE BAMBOO BODY_NONE. Modes: PLUCK HAMMER BOW

Strumming (Inline Syntax)

(abc/D)       -- down strum, default 30ms delay
(abc/U/25)   -- up strum, 25ms delay between strings
(abc/DU)      -- alternating down-up
(abc/T/40)   -- thumb: bass slow, treble fast rake
TypeKeywordDescription
DownD / DOWNLow-to-high
UpU / UPHigh-to-low
Down-UpDUAlternating
Up-DownUDAlternating
RandomR / RANDOMRandom order
FanFANCenter-outward
ThumbT / THUMBBass slow, treble fast

Delay (optional, after 2nd /): ms between strings. Default: 30ms.

Utilities

note_to_hz("C4")   -- returns 261.63
hz_to_note(440)    -- returns "A4"

Lua Helper Functions

function lead(note)
  local f = note_to_hz(note)
  return env(10,80,0.6,60, lpf(2000, saw(f)))
end
a = lead("C4"); b = lead("E4")

Per-Atom Configuration

a.duration = 60          -- sustain time in ms (overrides cell-based)
a.attack = 10            -- attack time in ms (per-atom ADSR override)
a.decay = 20             -- decay time in ms
a.sustain = 0.6          -- sustain level (0.0-1.0)
a.release = 50           -- release time in ms
a.level = {1.0, 2.0}   -- volume: {lowercase, UPPERCASE}
a.poly = 4               -- max simultaneous voices for this atom

Global Configuration

root = 440    -- A4 tuning reference in Hz (default: 440)
              -- affects all note-string pitches; e.g. root=432 for baroque

Cell Counts

ElementCells
Atom (a, k)1
Rest =1
Rest _2
Rest __4
Staccato a.1 (modifier only)
Chord (abc)1
Sustain ax4 / (abc)x44
Rest =x44
Pattern ($pat)x44 × pattern length

One bar = div cells. Patterns in a multi-track composition should be the same cell count (or intentional multiples for polymetric effects).

Frequency Reference

NoteHzNoteHzNoteHz
A155A3220A5880
C265C4262C61047
E282E4330
A2110G4392
C3131A4440
E3165C5523

Note string offsets: "C4+7" = G4, "A4-12" = A3