Cheat sheets
The tables from every tool page plus the per-tool ### sections of every technique page, collected by tool. Pick a tool, or open the standalone version to print it.
Asterion Sid Tracker cheat sheet
Reference
Cheat sheet#
From s-sidin06-asterion-sid-tracker.
Keys: F3 sound table · F6 middle screen (macro positions for 9x/Ax) · Track&Macros screen for tracks and the WAV/ARP tables · SHIFT+L load · SHIFT+S save · F8 directory.
Sound table (one instrument; instrument-tables):
| field | meaning |
|---|---|
A/D, S/R | attack/decay, sustain/release (adsr-envelope) |
WAV | start position in the wave macro table |
ARP | start position in the arpeggio macro table |
WAS | wave / arpeggio execution speed (separate for the two) |
VDE | vibrato delay |
VDS | vibrato depth / speed (vibrato) |
PWM | pulse starting speed |
PLM | pulse lower / upper limit (pulse-width-modulation) |
SCP | cutoff / pulse speed |
MCP | multi-cutoff / multiple speed (its nibbles also decide how Bx/Cx behave) |
FCT | filter starting cutoff |
FLM | filter lower / upper limit (filter-programming) |
R/T | resonance; filter type 1 2 4; 8 = hard restart on/off (hard-restart) |
Macro tables (WAV = control-register values, ARP = value added to the note; wavetable-programming, chord-arpeggio): ARP entries $00–$7F relative, $80–$DF absolute, $E0 "skydrive"; $FE ends the macro; $FF loops to the position in the next byte. The two tables run independently at their WAS speeds.
| WAV → 30, ARP → 32 | WAV → 20, ARP → 20 |
|---|---|
30: 41 00 | 20: 41 00 |
31: 21 00 | 21: FE 0C |
32: FE FE | 22: 00 FF |
$41 then $21 at the same pitch | 23: 00 20 — an octave arpeggio (00, 0C looping) under a single $41 |
Tracks (three columns; orderlist): $01–$7F pattern number · $80–$FE transpose the following pattern ("C0-middle"; Tognon reads 8C as +$0C) · $FF n loop to position n.
Pattern effects (one byte per step):
| effect | meaning |
|---|---|
00 | none |
0x–1x | instrument (restarts the ADSR values) |
2x | 1 tie note · 2 sync · 4 ring modulation · 8 no pulse restart |
3x | portamento to the note at speed x (pitch-slide-and-portamento) |
4x | vibrato depth x at the VDS speed (0 = VDS depth) |
5x / 6x / 7x / 8x | attack / decay / sustain / release |
9x | run the wave macro from index x (0 = normal) |
Ax | run the arpeggio macro from index x (0 = normal) |
Bx | pulse: 0 = instrument LFO; MCP low nibble 0 → absolute pulse (x = pulse MSB), else x = second pulse value |
Cx | cutoff: 0 = instrument LFO; MCP high nibble 0 → absolute cutoff (x = cutoff MSB), else x = second cutoff value |
Dx | volume (default F) — fades |
Ex | filter type 1 low · 2 band · 4 high · 8 no cutoff restart |
Fx | tempo: 0 stop · 1–E tempo · F end of pattern for all tracks |
Catweasel Mk4 cheat sheet
Reference
Cheat sheet#
Linux commands and options as printed in the two articles (2005–06 software; kept as a record):
| step | command / setting |
|---|---|
| build the driver | make in the hardsid directory, make install as root; on kernel 2.6 udev creates /dev/sid (the readme's mknod /dev/sid0 c 60 0 … is obsolete) |
| firmware | copy cmk4.fw to /lib/firmware (Fedora Core 3), restart the driver; check /proc/hardsid → "Catweasel MK4 configured for port 0xe800 (firmware 0.029) / SID type 6581" |
| build the players | in each module: ./bootstrap, ./configure, make, make install |
| sidplay2 | --hardsid (shown only when a card is detected); -fd force dual SID; -ns[0|1] 8580 waveforms; -nf[filter] filter emulation; -s[l|r] stereo / one channel |
| VICE 1.18 | compiled with hardsid support auto-detected; choose Hardsid in the SID settings |
| record the card | amixer set CD cap, play through aRts, record with KRec |
(sources: s-sidin08-catweasel-mk4, s-sidin09-catweasel-6581)
CheeseCutter cheat sheet
Reference
Cheat sheet#
From the recovered site Guide (source: s-cheesecutter-guide, all rows, except where noted).
Keys
| key | function |
|---|---|
F1 | play from the playback mark (blue bar, Backspace; tracks must be aligned there — Ctrl-L resets a misaligned sequencer) |
F3 | play from the cursor — "advisable to use it" |
SHIFT+F1 / SHIFT+F2 | followplay (the stacked view scrolls with the tune; source: s-sidin14-scarzix-interview) |
Ctrl-Backspace | set the wrap point (purple bar) — where playback returns at song end |
Keypad +/- | select the active instrument (auto-inserted with notes; ; toggles that) |
1 / ! or a (note column) | gate off / gate on ("works mostly like in GT2") |
| shifted note key | tied note (purple) |
Ctrl-T / Ctrl-R | note display absolute (JCH-style) vs transpose-relative (SDI-style) · row counters |
Ctrl-Tab / Enter (instr. table) / Alt-T | navigate sequencer↔tables · instrument descriptions · edit info strings |
CTRL+F9 / ALT+H | Hypercut only: oscilloscope vs SID register view · hide quick-help (source: s-cheesecutter-repo-and-releases) |
Sequence command column: 01–3F command-table entry · 40–5F pulse pointer · 60–7F filter pointer · 80–9F chord · A0–DF set A/D/S/R nibble for the note · E0–EF global volume · F0–FF song speed (0/1 = swing tempo from chord program 0).
Command table (cmd + 2 parameters; row 0's value bytes = the hard-restart ADSR, default 0F 00): 0/1 slide up/down · 2 vibrato (JCH 20.G4-style delta; "try 2-00 32") · 3 16-bit detune · 4 set ADSR · 5 lowfi vibrato · 6 set waveform · 7 portamento (set it before the tied notes) · 8 stop slide/portamento.
Instrument (bytes A–H): ADSR · restart nibble + wave delay — 0x note restart, 4x soft (best with release ≥ 8), 8x hard restart, Ax "Laxity restart" (AD untouched) · HR waveform (0 or 8) · filter program · pulse program · (unused) · wave pointer.
Tables: wave — transpose 00–5F relative / 80–DF absolute / 7E stop / 7F wrap; waveform 00 keep, 01–0F wave-delay override, E0–EF = $00–$0F. Pulse — duration (bit 7 = direction), add, init (FF keep), jump (00 next, 7F stop). Filter — byte A ≥ $80 = init row (type, resonance+voice mask, cutoff); sweeps are two's-complement adds at 10-bit accuracy ("4 times as fine as those on JCH players"). Chord — 00–3F up, 40–7F down (7F = −1), 80–FF wrap; indexed via the chord index column.
Workflow tips: keep sequence 00 empty (reserved dummy); build parts as subtunes, combine at the end; a subtune of all-A000 voices is skipped by the packer.
Techniques
Chord arpeggio (the 0 3 7 trick) › CheeseCutter #
An indexed chord table, activated per note with 80–9F in the sequence's command column (the value points to an index that holds each chord program's start): entries 00–3F = semitones up ("the familiar major chord would be 0-4-7"), 40–7F = semitones down (7F = −1, 7E = −2 — the Guide's SID cheat sheet includes a full up/down transpose table), 80–FF = wrap. Chords are read in tandem with the wave table, so the wave-delay value also paces the chord; they work over any wave program except absolute notes (80–DF). Chord program 0 is reserved as the swing-tempo program (shuffle-funktempo) (cheesecutter; source: s-cheesecutter-guide).
Detune › CheeseCutter #
Detune is command 3 of the command table (the descendant of JCH's "Super Table"), and it is 16-bit — two parameter bytes, so the offset is a full frequency value rather than a low-byte nudge. Being a command rather than a table column, it can be attached to a single note or left running (source: s-cheesecutter-guide).
Filter programming on the SID › CheeseCutter #
"All filter settings can only be controlled from the filter table" — there are no filter commands, only the per-note filter-pointer range 60–7F in the sequence command column (cheesecutter). A table row with byte A ≥ $80 is a filter init: type, resonance + voice bitmask, initial cutoff (90 F1 10 7F = low-pass $10, resonance $F on voice 1, cutoff $10, stop; C0 07 FF 04 = type $40, all voices, keep the cutoff, jump to row 4). Sweep rows are (duration, add) pairs where the add is two's-complement ("add value of FF actually subtracts by one"), and the sweeps have 10-bit accuracy — "4 times as fine as those on JCH players". An instrument's filter byte 00 means the voice keeps playing whatever filter program another instrument set — the shared-filter idiom again (source: s-cheesecutter-guide).
Hard restart › CheeseCutter #
The restart is a per-instrument type nibble (byte C's high nibble, "works mostly as in NP21.G5"), a menu of four flavours (cheesecutter; source: s-cheesecutter-guide):
| type | behaviour |
|---|---|
0x | note restart: gate off 3 frames before the next note, waveform cleared 1 frame before |
4x | soft restart: gate off 2 frames before — "usually works best (least buggy) with big (>= 8) release values" |
8x | regular hard restart: gate off + HR ADSR 2 frames before; instrument byte D goes to the waveform register 1 frame before |
Ax | "Laxity restart": like 8x but "the AD part of the volume envelope is not touched" |
"Restart types 0x and 8x are the ones to use for most of the time." The HR ADSR value lives in the Command Table's first row (default 0F 00 — the GoatTracker default again); byte D (the HR waveform) is "usually values 0 & 8", the gate bit added automatically.
Multispeed (framespeed) › CheeseCutter #
CheeseCutter 2 supports multispeed, with the guide's own caveat that it "doesn't work well past 4x" (source: s-cheesecutter-guide) — the practical ceiling for an editor whose player is written for "features/comfort over speed". The 2024–25 arch0N fork lists a multispeed buffer overrun among its fixes (credited to Isildur), so tunes written above 1× in older builds are worth re-checking there (source: s-cheesecutter-repo-and-releases).
Pitch slides and tone portamento › CheeseCutter #
Slides live in the command table, not in the note column: entry 0 slides up, 1 slides down, 7 is tone portamento and 8 stops either. Two rules matter — portamento must be activated before the target notes and "works only on tied notes", and it resets an ongoing slide. The guide's known-quirks list adds that a slide or vibrato placed on a tied-note row is not executed at all (source: s-cheesecutter-guide).
Pulse width modulation (PWM) › CheeseCutter #
Four-byte pulse-table rows in the JCH mould ("works like byte C/B/A/D in JCH's players"): duration with the sweep direction in bit 7 (00–7F up, 80–FF down; the Guide's cheat sheet tabulates durations in frames and ms — $10 = 16 frames = 320 ms), add value, init value (FF = keep the previous width), jump (00 = next row, 7F = stop — implemented as a jump to row 0's 00 00 FF 7F self-wrap). Change the running note's pulse program with 40–5F in the sequence command column (cheesecutter; source: s-cheesecutter-guide).
Ring modulation and oscillator sync › CheeseCutter #
The same two nibbles, read off the editor's own SID cheat sheet: the waveform high nybble (with LOCK flagged on $9–$F, the noise combinations that silence the generator until a test bit) and the gate / sync / ring / test low nybble, entered in the wave program. Its note beside them is the one that decides whether a sound survives the wrong machine: "Waveforms $3, $6 and $7 are audible only on new SID (8580)" — the combined waveforms, not the ring and sync bits, are what varies between chips (source: s-cheesecutter-guide; sid).
Shuffle, swing and FunkTempo › CheeseCutter #
Swing hides in the chord table: chord program 0 doubles as the swing-tempo program (a list of tick lengths), enabled by setting the song speed to 0 or 1 — from the editor or with sequence command F0/F1 (cheesecutter). Caveat from the site's own bug list: "Changing between swing tempo and regular tempo mid-song can mess the timing" (source: s-cheesecutter-guide).
Vibrato and delayed vibrato › CheeseCutter #
Vibrato is a command-table entry, not an instrument setting: in the command table (JCH called it "the Super Table") 2 is vibrato — "the usual delta vibrato as found in JCH's players from 20.G4 upwards; try $21 $05" — and 5 is a second vibrato taking speed and depth. One player quirk to know: a slide or vibrato on a tied-note row is not executed, and a portamento resets an ongoing slide (source: s-cheesecutter-guide; pitch-slide-and-portamento).
Wavetable programming (waveform / arp tables) › CheeseCutter #
The wave table is two columns, transpose and waveform, read one row per frame (source: s-cheesecutter-guide):
| column | values |
|---|---|
| transpose | 00–5F relative semitones · 80–DF absolute · 7E stop · 7F wrap (byte B holds the wrap point) |
| waveform | 00 keep · 01–0F override the wave delay for the previous row · 10–DF SID waveform/control byte · E0–EF the inaudible values $00–$0F |
The 01–0F delay applying backwards to the row above is the unusual part — it lets one row hold for several frames without a second table entry. Pulse, filter and chord live in separate tables, each with its own jump/stop convention, and chord program 0 doubles as the swing-tempo program when song speed is 0/1 (shuffle-funktempo).
David Whittaker's player (the Panther driver) cheat sheet
Reference
Cheat sheet#
All from the Panther disassembly (source: s-realdmx-fredgray-kimmel-whittaker).
Track = list of pattern addresses, !wo 0 loops it; the three tracks have different lengths (53 / 65 / 53 entries). Pattern = byte stream; FLAGS is cleared at every note, so arpeggio, slide and drum must be re-issued per note.
| byte | meaning |
|---|---|
$00–$7f | note (index into a 95-entry table, $0116 = C-0); ends the step |
$80–$93 | command (below) |
$b8–$bf | tempo = value − $b7 (1–8 frames per tick) |
$c0–$cc | arpeggio list 0–12 |
$d0 aa ss | ADSR follows (two bytes) |
$e0–$ff | duration = value − $df (1–32 ticks) |
| command | effect |
|---|---|
$80 | hold the current note for another duration (no retrigger) |
$81 / $82 | vibrato off / on |
$83 v | volume / mode byte |
$84 lo,hi,delay / $85 | slide down / up: after delay frames the step accumulates every frame (a quadratic sweep) |
$86 / $87 | bend down / up one semitone per tick |
$88 | end of pattern |
$89 speed,depth | vibrato parameters |
$8a / $8b / $8c / $8d | waveform noise / pulse / sawtooth / triangle |
$8e | drum: on odd frames control $80 (noise) with the frequency high byte + $31 |
$8f n | pulse width high byte |
$90 min,max,speed | pulse bounce between two high bytes |
$91 | stop music |
$92 / $93 | triangle + ring modulation / pulse + sync |
Arpeggio lists (one step per frame; any byte ≥ $54 restarts): $00,$03,$07,$88 · $00,$04,$07,$88 · $00,$03,$07,$0c,$88 · $00,$04,$07,$0c,$88 · $07,$0c,$0f,$88 · $07,$0c,$10,$88 · $03,$07,$0c,$88 · $04,$07,$0c,$88 · $00,$0c,$88 · $00,$04,$88 · $00,$03,$88 · $00,$05,$88 · $00,$07,$88 (chord-arpeggio).
"Instruments" as they appear in the data: PC_PULSE,$90,$02,$08,$28,$d0,$0a,$40 (pulse bouncing between $02xx and $08xx at speed $28, AD $0a, SR $40); $92,$90,$02,$08,$14,$89,$7f,$fe,$82,$d0,$df,$00,$ff,$84,$80,$00,$01 (ring-triangle, pulse bounce, deep vibrato, slide down — a siren); $8d,$89,$28,$50,$82,$d0,$0d,$70 / $f7,$c0,$3c,$e7,$c1,$3a (triangle, vibrato, then 24 ticks of a minor arpeggio on $3c and 8 of a major one on $3a); $be,$d0,$00,$00,$ff,$80,$88 (tempo 7, ADSR $00/$00, 32 ticks, hold — a silent pattern).
defMON cheat sheet
Reference
Cheat sheet#
Three screens: seqED + seqLIST (main), sidTAB, disk menu. All numbers are hex. Full key map (transcribed from the wiki's keys_seqed_v3.png) in s-defmon-wiki-manual; iLKke's reference card in s-defmon-wiki-defmoning-101.
| key | function |
|---|---|
← | toggle seqED / sidTAB (C=+← jump to sidtab position, CTRL+← switch SID 1/2) |
RUN/STOP | toggle seqED / seqLIST |
F1 / F3 | play from cursor / from start (CTRL+F1/F3 = defSYNC two-C64 start) |
F5 / F7 | follow on/off · stop (second press: back to top) |
F2 F4 F6 F8 | multispeed 1x/2x/4x/8x; C=+F-keys adjust the CIA timer (BPM) |
CTRL+F5/F7 | nudge the playing tune one tick back/forward |
[ ] = | mute voice 1/2/3 |
C= / SHIFT (held) | edit sidCall column 1 / 2; CTRL+C= edit speed column |
CTRL+C=+SPACE | insert pattern break |
SHIFT+N / SHIFT+U | clone sequence to next empty / next unused number (U is riskier) |
SHIFT+X | disk menu (S save, SHIFT+S overwrite, SHIFT+P pack → Executable or Raw) |
CTRL+G twice | go to the −1 step (the hard-restart row) |
CTRL+S n / CTRL+R n / CTRL+W n | Super Commands: apply edits to n steps / n times per step / every n-th step |
CTRL+Z A | ZONE ALL — edit every sequence at once; CTRL+ENTER exits Super Command mode |
CTRL+SHIFT+. / , | DIN/MIDI sync delay ($04–$05 typical; goto80: $05 against a TR-808) |
sidTAB columns (JP DL WG WG AD SR TR AF PW PS RE FV CP ACID):
| col | meaning | |
|---|---|---|
JP / DL | jump to table line · ticks to wait before the next line (ST = stay forever) | |
WG (1st digit) | waveform: 1x triangle, 2x saw, 4x pulse, 8x noise | |
WG (2nd digit) | gate +1, hardsync +2, [[ring-modulation-and-sync | ring mod]] +4, test bit +8; the two WG columns are ORA'd |
AD SR | the adsr-envelope | |
TR | transpose: $00–$7F semitones up (arpeggios), $80–$FF absolute pitch | |
AF | $00–$19 finetune ($19 = semitone), $80–$BF/$C0–$FF bend up/down speed | |
PW / PS | pulse width ($08 = 50 %) · sweep $00–$7F left, $80–$FF right | |
RE | resonance digit + voice mask digit; mask 8 = "filter the calling voice" | |
FV | filter type (first digit): 1x LP, 2x BP, 4x HP, combinable | |
CP | relative cutoff offset (add/subtract) | |
ACID | cutoff: $0000–$7FFF set, $8000–$BFFF slide up, $C000–$FFFF slide down; floor 200 "Acids" |
- Its opposite number on sync: where defMON drives the rig — user-port adapter, MIDI clock and DIN out — sid-wizard-vessel makes the C64 a slave, taking MIDI clock in and turning the tracker into a pattern launcher; both lock the tick grid to the external clock at one canonical tempo (defMON's six ticks per two steps, Vessel's tempo 6) (sync, live-tracking; source: s-sid-wizard-vessel-readme).
- Wikipedia's goto80 article does not name the program, but its "post-2009 improvised C64 work" is this editor: the two-C64 jams and live sets that its first user built on it (source: s-wikipedia-goto80).
Techniques
Chord arpeggio (the 0 3 7 trick) › defMON #
There is no chord command: a sidTAB row's arpeggio is the note-transpose (TR, $00–$7F semitones added to the sequence note) stepped by the table itself, with JP (Step Jump) looping it — the manual names arpeggios and vibratos as the two things those loops exist "for". Because a sequence step can execute two sidTAB chunks at once, an arpeggio can run under a second program doing something else entirely (source: s-defmon-wiki-manual).
Detune › defMON #
The AF column (Finetune/Bend) is one byte doing three jobs, and the split is what to remember: $00–$19 is finetune, with $19 = one whole semitone up — so a single step is 1/25 of a semitone, about 4 cents, and a fat-lead offset is $01–$03. Above that, $21–$7F continues as pitch up (wrapping), $80–$BF is bend-up speed and $C0–$FF bend-down speed (pitch-slide-and-portamento). Detune and portamento therefore live in the same column and cannot both be active on a row; transpose is a separate column (TR), so a detuned copy of a part is TR unchanged and AF $01–$02 (sources: s-defmon-wiki-manual, s-defmon-wiki-defmoning-101).
Filter programming on the SID › defMON #
Four sidTAB columns instead of a filter table (defmon): RE = resonance nibble + voice-mask nibble, with the defMON-only mask value 8 = "activates the filter for the Voice the Sound Program is called from" — so one filter chunk works from any voice (F8 = resonance $F, filter on, this voice); FV = filter type (first digit, combinable low/band/high); CP = a relative cutoff offset added or subtracted from the base value; ACID = a four-digit absolute cutoff that doubles as a slide command — $0000–$7FFF set, $8000–$BFFF slide up, $C000–$FFFF slide down — with the minimum locked at 200 "Acids" "so you don't blow your speakers/eardrums". Two cutoff controls means a filter envelope can be offset without rewriting it. Two internals worth knowing: defMON never writes $D415, so the two rightmost digits of a set value do nothing (anarkiwi's register dump, 2018-12-22), and on a detected 8580 the player floors the cutoff at $0200 ($0000 on a 6581) to make the chips behave more alike (sources: s-defmon-wiki-manual, s-defmon-wiki-defmoning-101, s-chipmusic-defmon-thread).
Hard restart › defMON #
The only editor that automates nothing — frantic (2018-02-22): "You can do any kind of hardrestart in defMON, whereas most other editors only feature one type of built in hardrestart and no reasonable way to do it manually." Automated HR would need look-ahead sequence parsing, which costs rastertime; instead every sequence has a −1 step before line 0 (reach it with CTRL+G twice) where the restart rows go, ~2 frames before the note (source: s-chipmusic-defmon-thread). The field guide new users are pointed at says the same thing as a boast: "Most flexible hard restart ever, period. Because you do it all yourself." (source: s-defmon-wiki-defmoning-101).
- The common idiom (used by goto80 and Amelinium): on the restart line waveform/gate
00 00with ADSR$0F00, wait 2 ticks (DL), then gate09(test + gate) with the instrument's real ADSR, then the waveform — the GoatTracker recipe, typed by hand in the sidTAB (source: s-chipmusic-defmon-thread). - iLKke's compendium (2015-08-03) names four HR shapes — old school (one frame gate-off, ADSR
$0000), new school (gate-off with ADHR, then$09+ real ADSR, then waveform+gate+note), hybrid, "heatbeat" — and the known ADHR values:$0000"hardest",$0F00"most common",$0F18Drax,$0F20GRG,$0FF0Randall/Jammer,$F000Linus,$FF00Jeff. Sustain$F"is especially buggy (try E then?)"; a soft restart wants release ≥$8(sources: s-chipmusic-defmon-thread, s-defmon-wiki-defmoning-102). - How much HR you need: F7sus4 — the full test-bit restart is "obligatory only with drums and snares"; leads, bass and arps are fine soft-restarted. 4mat's minimal recipe: "$08 on the first frame before you set the gate … ($08,$41,$41,$40)". Bonus trick: vary the AD nibble on the HR line (
$01–$0F) to scale a drum's volume per hit (source: s-chipmusic-defmon-thread).
Multispeed (framespeed) › defMON #
defMON does 1x/2x/4x/8x, but the multiplication lives in the editor, not the player: F2/F4/F6/F8 set a CIA timer ($4CC7+1 cycles = one PAL frame; $2663 = 2x, $1331 = 4x), and C=+F-keys nudge or halve/double the timer — which doubles as defMON's free-form BPM control. Because of that design a per-pattern multispeed command is impossible without breaking packed tunes. Odd rates work by typing the timer by hand: $1997 gives 3x — frantic's favourite, "Just enough to be enough" — and a CSDb compo tune ran at 25 Hz, the player called every second frame. A host program plays a multispeed defMON tune by calling $1003 once per frame and the sound-only entry $1006 the remaining 1/3/7 times (sid-player-routine). Switching 1x↔8x live works as a performance effect, though frantic warns it can "also sound crappy in some cases" (sources: s-defmon-wiki-defmoning-102, s-defmon-wiki-calling-the-player, s-chipmusic-defmon-thread). The full preset set is $4CC7/$2663/$1331/$0998 for 1×/2×/4×/8× (source: s-defmon-wiki-sync-and-stereo), and the 2014-06-15 release fixed multispeed toggling so that switching while playing no longer drifts out of sync — which is what makes it usable live (source: s-defmon-wiki-releases). The wiki's field guide states the payoff plainly: "Up to 8x multispeed means nearly any SID tune except sample playback can be covered in defMON" (source: s-defmon-wiki-defmoning-101) — a claim that only holds because the player is cheap enough to call eight times, "relatively low CPU usage… DefMON tunes can be, and have been, used in various demos and games" (source: s-defmon-wiki-manual).
Pitch slides and tone portamento › defMON #
defMON has no slide command, by design: you write the bend as a sidTAB chunk and call it in a step's second sound-program column, beside the instrument in the first (instrument-tables). The pitch columns are TR and AF. AF packs finetune and bend into one byte — $00–$19 finetunes up with $19 equal to one semitone, $21–$7F continues upward (wrapping), $80–$BF sets the speed of a bend up and $C0–$FF the speed of a bend down — while TR is $00–$7F relative semitones (for arpeggios) and $80–$FF absolute pitches, so a slide's destination can be written either way (sources: s-defmon-wiki-manual, s-defmon-wiki-defmoning-101; detune).
Pulse width modulation (PWM) › defMON #
Two sidTAB columns (defmon): PW sets the width, PS sweeps it — $00–$7F "slide left (to 0%, lowering PW value in time)", $80–$FF "slide right (to 100%)". The two digits XY typed into PW expand to the 12-bit value $YXY (e.g. 83 → $383), so the closest squares are $08 → $808 ≈ 50 %, $0C → $C0C ≈ 75 %, $04 → $404 ≈ 25 % (or $F7/$FB/$F3 from the other side); "If pulSEWIDTH is set near to 0% or 100%, the pulse waveform is inaudible" (sources: s-defmon-wiki-defmoning-101, s-defmon-wiki-defmoning-102). The manual states the same landmark more simply — "PW (Pulse Width) — $08 equals the 50% pulse" — and the sweep direction as $00–$7F left, $80–$FF right (source: s-defmon-wiki-manual).
Ring modulation and oscillator sync › defMON #
Ring and sync live in the gate nibble of the sidTAB's second WG column: +1 gate, +2 sync, +4 ring mod, +8 test bit — additive, so 07 = ring + sync + gate and 05 = ring + gate. defMONing 102 states the pairing: "1+2, 2+3, 3+1 … e.g. used in channel 1 means channel 3 modifies channel 1". Because the two WG columns are ORA'd together before the register write, $55 can be entered as 5401 or 5005 — so you can hold the ring-mod bit in one column while switching waveforms per line in the other, a per-line ring-mod switch (Amelinium's technique, 2018-12) (sources: s-defmon-wiki-defmoning-102, s-defmon-wiki-defmoning-101, s-chipmusic-defmon-thread). The manual states the column split that makes this work: of the two WG columns, the yellow one is the waveform and you "use only the first digit" (1x triangle, 2x saw, 4x pulse, 8x noise), while the green one is gate plus hardsync and ring modulation and you "use only the second digit" (source: s-defmon-wiki-manual).
Shuffle, swing and FunkTempo › defMON #
defMON has no groove list and no funktempo: every sequence step carries its own speed value, per channel, and the value is ticks − 1 (a 2 in the column means 3 ticks). Swing is therefore written by hand into the column — and because the columns are per channel, the drums can run 5 3 5 3 against a straight melody, with everything re-aligning at each sequence break (source: s-chipmusic-defmon-thread).
Under hardware sync that freedom narrows to one choice. The user-port adapter sends six pulses per two sequence steps, so a synced tune has to spend exactly 6 ticks on every two steps: 3+3 straight or 4+2 swung, and nothing else; tempo changes then have to come from the player-call rate rather than from the speed columns (source: s-defmon-wiki-sync-and-stereo).
Vibrato and delayed vibrato › defMON: no vibrato at all #
defMON has no vibrato command, on purpose. The sidTAB is the whole effect language — "you would create a vibrato the way you like it, rather than calling a pre-programmed vibrato" — so a vibrato is a few sidTAB rows that step the pitch up and down, and a step can run two sidTAB chunks at once, one holding the note and one running the wobble. The design argument is the same one frantic makes about hard-restart: fewer built-ins, more flexibility, and no CPU spent on a routine a given tune may not want (source: s-defmon-wiki-manual; sid-player-routine).
DigiOrganizer cheat sheet
Reference
Cheat sheet#
From s-sidin06-digiorganizer.
Keys: M,M load a sample module (e.g. MODULE/DEMO) · M,L load a 3-voice tune (e.g. MUSIC/DEMO) + its play address · F1 play · S sample menu, L load a sample by name / delete the last one · CTRL+2 sample definitions · SHIFT+A..I global tune speed.
Track (left): pairs pattern, repeats−1 — 01 04 = pattern 1 five times, 02 00 = pattern 2 once; $FF restart; $FE stop (orderlist).
Pattern (right): 32 steps; value = sample definition to trigger, 00 = let the previous sample continue, $FF = end early. 01 00 00 02 03 FF.
Sample definition (CTRL+2): nn: start end speed with start/end as address high bytes and speed = the CIA timer A low byte — 01: A7 AE A0 plays $A700–$ADFF; a definition may span several loaded samples (A0 A9 A0 = samples 1–3 in a row).
Making a sample: WAV → 8-bit mono 6 kHz — sox sample16.wav -c1 -b -v .8 -r 6000 sample8.wav (add a low-pass while downsampling) → 4-bit packed "low nibble, high nibble of 2 samples" with the DOS tool S64_ENG by Reiter/Apidya → load in the sample menu.
Your own 4-voice program:
init: JSR $1000 ; the 3-voice tune
JSR $9000 ; DigiOrganizer
play: JSR $1003
JSR $9003
Inside: init clears memory, sets CIA #2 timer A ($70) and timer B ($DD0E = $11, $DD0F = $51), enables the timer-B NMI ($DD0D = $82), writes $18 (low-pass, volume 8) to $D418 and points the NMI vector at nmi_null. Three NMI handlers: nmi_sx writes the high nibble (lsr ×4 / ora #$10 / sta $D418), nmi_dx the low nibble (and #$0F / ora #$10), then advances the pointer and compares the page with the sample's end page; nmi_null idles. The IRQ side steps the track/pattern every SPEED = $05 countdown and starts a sample by copying its start page, end page and speed into the NMI code. Layout: code $9000, track $9200, digiSound table $9300 (4 bytes per definition), patterns $9500 (32 bytes each), samples $A000 (sid-player-routine).
Techniques
Multisampling and drum-kit instruments › C64: Digi-Organizer #
The 1980s C64 equivalent, from the other direction: sample definitions are (start page, end page, rate) triples into one block of memory, so a single "instrument" can chain several raw blocks — a poor man's multisample of drum hits, with the map living in the sample table rather than in a note column (source: s-sidin06-digiorganizer).
DUET cheat sheet
Reference
Cheat sheet#
| keys | do |
|---|---|
F5 / F8 | play / stop (F7 from cursor) |
F2/F4/F11/F12, TAB | pattern / instruments / mixer / project, next column |
Ctrl+V · Ctrl+T · Ctrl+W | grid view IT/UNITY/POLY/SWM · split · column width |
ALT+B / ALT+D / ALT+L | mark block / grow mark (beat→bar→rest→channel→side) / mark channel (twice: side) |
ALT+C/Z/P, ALT+SHIFT+P | copy/cut/paste, translate paste |
ALT+S | stamp instrument onto block |
ALT+SHIFT+C/Z/V/M/T | system clipboard copy/cut/paste (M mix, T types) |
Ctrl+M / ALT+F9 / ALT+F10 | mute (voice) / mute / solo |
ALT+G | sync marker |
a–d $00–$64 in FX | send to DELAY/REVERB/CHORUS/DRIVE |
Ctrl+E / Ctrl+B | export mix/stems / bounce block |
Ctrl+U | undo history |
? | key help on any screen |
(source: s-duet-docs-grid-and-sides, s-duet-docs-clipboard, s-duet-docs-sounds-mixer-bounce; the full generated key and CLI reference lives un-ingested in raw/duet/docs/keys.md and cli.md.)
Techniques
Hard restart › DUST (DUET) #
- duet's DUST synth makes hard restart a patch parameter: RESTART OFF / SOFT (gate down for the window) / FULL (gate down and the envelope slammed to zero) over a 1–200 ms window spent before the note; the engine peeks at the next row so the attack, not the restart, lands on the beat (source: s-duet-docs-dust-dusk).
Sound effects and game audio › DUET #
duet takes the same road explicitly: duet_engine_note_on fires an instrument by family — a PCM instrument, or a SID-Wizard instrument from the project's pool routed through a chip — with jam = 1 building a chip on demand, no pattern needed. The docs call it "a game's instruments-as-sound-effects road" (source: s-duet-docs-libduet).
Wavetable programming (waveform / arp tables) › DUSK (DUET) #
- duet's DUSK plays a P## sample as a row of equal single-cycle frames (frames = sample length / FRAME; "2048 is the Polyend standard") and morphs between the two nearest frames; a slow LFO routed to
morph"is the classic wavetable sweep"; ALIASrawkeeps the aliasing on purpose (source: s-duet-docs-dust-dusk).
FastTracker 2 cheat sheet
Reference
Cheat sheet#
Timing#
A tick is "number of VBL's to wait until playing next row"; the first tick plays the note, the rest run the effect; fine effects act once per row. Fxx: 01–1F speed (ticks per row), 20–FF tempo in BPM; ticks per second = BPM × 2 ÷ 5 (125 BPM = 50 Hz); "the BPM is correct at speed 06". The linear frequency table makes slides constant across pitch — switch it off (Amiga table) only for MOD export (source: s-ft2-manual).
Effect column (hex)#
| cmd | effect | cmd | effect |
|---|---|---|---|
0xy | arpeggio: tick 1 note, tick 2 +x, tick 3 +y (FT2 plays it backwards — a known bug) | E1x / E2x | fine portamento up / down, once per row |
1xx / 2xx | portamento up / down per tick | E3x | glissando: portamento in semitones |
3xx | tone portamento to the note (300 continues; stops at the target) | E4x / E7x | vibrato / tremolo waveform 0 sine, 1 ramp down, 2 square; +4 = no retrigger |
4xy | vibrato speed x depth y | E5x | finetune (with a note) |
5xy / 6xy | tone portamento / vibrato + volume slide | E60 / E6x | loop start / loop x times (bug: the next pattern starts at the loop row — end with D00) |
7xy | tremolo | E9x | retrigger every x ticks |
8xx | pan 00 left – FF right (reset by the next instrument's default pan) | EAx / EBx | fine volume up / down |
9xx | sample offset × $100 (samples < 64 KB) | ECx | note cut ("only set the volume to zero") |
Axy | volume slide up x / down y ("one of the data fields must be 0") | EDx | note delay x ticks |
Bxx | jump to song position | EEx | pattern delay x rows |
Cxx | volume 00–40 | Gxx / Hxy | global volume / slide |
Dxx | pattern break to position xx (hex; OpenMPT: stay ≤ 3F) | Kxx | key off after xx ticks |
Lxx | set envelope position | Pxy | pan slide right x / left y |
Rxy | multi-retrig every x with volume change y (1 −1 … 5 −16, 6 ×⅔, 7 ×½, 9 +1 … D +16, E ×3/2, F ×2; "very buggy") | Txy | tremor on x / off y ("for STM compatibility") |
X1x / X2x | extra-fine portamento (speed ÷ 4) | E0x | Amiga filter — "not implemented … totally useless" |
(sources: s-ft2-manual, s-openmpt-manual-effect-reference, s-openmpt-manual-compatible-playback)
Volume column#
00–40 volume · +x / -x slide up / down · Ux / Dx fine up / down · Sx vibrato speed · Vx vibrato · Px pan · Rx / Lx pan slide right / left · Mx tone portamento (source: s-ft2-manual).
Instruments and samples#
An instrument = 1 volume envelope, 1 panning envelope, 1 auto-vibrato, 1–16 samples, 1 keyboard split, 1 MIDI definition; a sample = volume, panning, finetune (−128…+127, audible in steps of 8), relative tone, waveform. Envelopes: one pixel = one tick (50 per second at 125 BPM), a sustain point holds until key-off (Caps Lock), then fadeout; predefine 1 is applied to every loaded sample; turning the envelope off leaves the vibrato on. Sample editor: X-Fade (smooth loops), Minimise, 8/16-bit, Backwards, Convert, Echo, Morph, Resample, Mix, draw mode (right mouse button); copy/paste masks with transparency. Main screen: BPM, Spd, Add, pattern length up to $100, Expand/Shrink (source: s-ft2-manual; see instrument-envelopes, multisampling).
Keys#
F1–F7 octave · Right Ctrl play song, Alt Gr play pattern, Right Shift record, Space stop/edit · Shift/Alt/Ctrl+F3/F4/F5 cut/copy/paste track/pattern/block · Shift/Ctrl/Alt+F7/F8 and F1/F2 transposes · Ctrl+A advanced edit, C config, D disk, I instrument editor, S sample editor, E sample editor extension, T transpose, X main screen, Z full-screen edit · keypad picks instruments · Alt+1…0 write and Shift+Alt+1…0 read command macros (source: s-ft2-manual).
Known traps#
Amiga L-R-R-L stereo must be typed as P0/PF per channel ("That's very boring!"); MOD saving fails with the linear table or envelopes; no random LFO waveform; note delay and retrigger interact strangely; period slides can wrap to a very high note (sources: s-ft2-manual, s-openmpt-manual-compatible-playback). And the .MOD it does save cannot be trusted on an Amiga compo machine: it can write 32-channel .MOD (Psibelius), it gives no warning, and a friend of zalt's entered a chiptune whose sixth-octave notes "all became Bs in the 5th" and placed last — both wished for a real Amiga ProTracker on the PC (December 1995; source: s-tw040-interview-zalt; see mod-format).
Techniques
Multisampling and drum-kit instruments › FastTracker 2 #
An instrument holds 1–16 samples with a key split "drawn" on the piano keyboard; each sample has its own volume, pan, finetune and relative tone; the FAQ warns that the instrument, not the sample, is what carries envelopes (source: s-ft2-manual).
Furnace cheat sheet
Reference
Cheat sheet#
Effects (C64)#
| effect | meaning |
|---|---|
10xx | change wave: 00 nothing · 01 triangle · 02 saw · 03 triangle+saw · 04 pulse · 05 pulse+triangle · 06 pulse+saw · 07 pulse+triangle+saw · 08 noise |
3xxx | set duty cycle, 000–FFF |
4xxx | set filter cutoff, 000–7FF |
13xx | set resonance, 00–0F |
14xx | filter mode: 00 off · 01 low pass · 02 band pass · 03 low+band · 04 high pass · 05 notch (band reject) · 06 high+band · 07 all pass |
15xx | envelope reset time in ticks (00, or more than the song speed, = no reset) |
1Axx | disable envelope reset for this channel |
1Bxy | reset cutoff: x ≠ 0 on new note, y ≠ 0 now (unneeded with an absolute cutoff macro) |
1Cxy | reset duty cycle: x ≠ 0 on new note, y ≠ 0 now (unneeded with an absolute duty macro) |
20xy | set attack x / decay y |
21xy | set sustain x / release y |
22xx / 23xx | pulse-width slide up / down at speed xx (00 stops) |
24xx / 25xx | cutoff slide up / down at speed xx (00 stops) |
11xx | coarse cutoff 00–64 — compatibility only, use 4xxx |
12xx | coarse duty 00–64 — compatibility only, use 3xxx |
1Exy | compatibility: x = 0 attack · 1 decay · 2 sustain · 3 release (y = 0–F) · 4 ring mod · 5 sync · 6 disable channel 3 (y = 0/1) |
Instrument fields (C64 tab)#
| field | range / meaning |
|---|---|
| Waveform | triangle, saw, pulse, noise; several at once = AND mix (never with noise) |
| Attack · Decay · Sustain · Release | 0–15 each; larger = slower (sustain is a level) |
| Duty | 0–4095 (2048 = square) |
| Reset duty on new note | reload the instrument's duty on each note — for relative duty macros |
| Ring Modulation · Oscillator Sync | with the previous channel as modulator |
| Enable filter · Initialize filter | route through the filter; set cutoff 0–2047, resonance 0–15, mode low / high / band / ch3off (combinable; low + high = notch) |
| Absolute Cutoff Macro · Absolute Duty Macro | cutoff macro 0–2047 / duty macro 0–4095 as absolute values instead of relative ones |
| Don't test before new note | skip "the one-tick hard reset and test bit before a new note" |
Macros#
| macro | notes |
|---|---|
| Volume | global — the chip's volume register, affects all channels |
| Arpeggio | pitch sequence in semitones (chord-arpeggio) |
| Duty · Waveform · Pitch | pulse width (pulse-width-modulation) · waveform (wavetable-programming) · fine pitch, per tick |
| Cutoff · Filter mode · Resonance | the filter, per tick (filter-programming) |
| Special | ring mod, sync, the gate bit (0→1 starts or restarts the envelope, 1→0 releases it, otherwise nothing) and the test bit (1 mutes the channel at once and suspends ring/sync for channels using it as a source; 0 restores) (ring-modulation-and-sync) |
| Attack · Decay · Sustain · Release | change the running envelope immediately; sustain can only go down while sustaining |
Chip configuration#
| option | meaning |
|---|---|
| Clock rate | the SID clock |
| Global parameter priority | whose macros win for global parameters (volume, filter): Left to right (channels 1→3 in order, the last to run wins) or Last used channel (the channel with the latest note-on wins) |
| Hard reset envelope | the ADSR used during the pre-note reset — the HR ADSR of other trackers |
| Envelope reset time | ticks of gate-off before a note: 0 none (notes do not trigger), 1 short but may bug, 2 good |
(source: s-furnace-c64-docs)
Techniques
Chord arpeggio (the 0 3 7 trick) › Furnace #
The instrument's Arpeggio macro is a per-tick "pitch sequence" in semitones — the same table idea, with the waveform and duty in parallel macros (furnace; source: s-furnace-c64-docs).
Filter programming on the SID › Furnace #
furnace sets the filter from the pattern with 4xxx (cutoff 000–7FF), 13xx (resonance 00–0F), 14xx (mode: 00 off, 01 low, 02 band, 03 low+band, 04 high, 05 notch, 06 high+band, 07 all), 24xx/25xx (cutoff slide up/down at speed xx, 00 stops) and 1Bxy (reset the cutoff on the next note / now); 11xx is a discouraged coarse cutoff 00–64. Per instrument: Enable filter routes the voice, Initialize filter sets cutoff 0–2047, resonance 0–15 and the mode (low, high, band, ch3off — "selecting both 'low' and 'high' results in a bandstop (notch) filter"), and Absolute Cutoff Macro makes the cutoff macro write 0–2047 directly instead of relative steps. Because the filter is global, the chip configuration decides whose macros win: Left to right (channels 1→3, the last wins) or Last used channel (the latest note-on wins) — a third policy beside SID-Wizard's leftmost-channel rule and its "latest instrument takes over" (source: s-furnace-c64-docs).
Hard restart › Furnace #
furnace calls it envelope reset: in the chip configuration, Hard reset envelope is the ADSR "used during the short reset before a note" and Envelope reset time the number of ticks — "0 disables reset, which prevents notes from triggering. 1 is short, but may exhibit SID envelope bugs. 2 is a good value." From the pattern, 15xx sets the reset time (00, or more than the song speed, = no reset) and 1Axx disables it for the channel; per instrument, Don't test before new note "disables the one-tick hard reset and test bit before a new note" — so Furnace, like GoatTracker's $09, sets the test bit during the reset (source: s-furnace-c64-docs).
Pulse width modulation (PWM) › Furnace #
furnace: instrument Duty 0–4095 (2048 = square) and a duty macro per tick, Absolute Duty Macro to write widths directly instead of relative steps, Reset duty on new note to reload the instrument's width; from the pattern 3xxx sets the width 000–FFF, 22xx/23xx slide it up/down at speed xx (00 stops), 1Cxy resets it on the next note / now, and 12xx is a discouraged coarse setting 00–64 (source: s-furnace-c64-docs).
Ring modulation and oscillator sync › Furnace #
Instrument checkboxes Ring Modulation ("the channel's output will be multiplied with the previous channel's") and Oscillator Sync ("as the previous channel's oscillator finishes a cycle, it resets the period of the channel's oscillator"), a Special macro that switches ring, sync, the gate bit and the test bit per tick, and the compatibility effects 1E4y (ring) and 1E5y (sync). Its test-bit semantics: set = "immediately mute channel", and "if the channel is a source of ring mod and/or hard sync, those stop working until the bit is reset" — a test bit on the modulator silences the modulated voice's effect too (source: s-furnace-c64-docs).
Wavetable programming (waveform / arp tables) › Furnace #
furnace does the same with a per-tick waveform macro in the instrument (plus arpeggio and pitch macros for the note column) and, from the pattern, 10xx — 01 triangle, 02 saw, 04 pulse, 08 noise, sums for combinations (source: s-furnace-c64-docs).
GoatTracker cheat sheet
Reference
Cheat sheet#
Keys#
| key | action |
|---|---|
F1 / F2 / F3 / F4 | play from start / from position / one pattern / stop (SHIFT+F1–F3 with follow play) |
F5 / F6 / F7 / F8 | pattern editor / song (orderlist) editor / instrument & table editor / songname |
F9 / F10 / F11 / F12 | pack & relocate & save PRG/BIN/SID / load / save .SNG or .INS / online help |
SHIFT+F4 | mute current channel |
SHIFT+F7 | edit the hard-restart ADSR parameter |
SHIFT+F8 | switch 6581 / 8580 |
TAB | cycle editing modes |
SPACE | jam / edit mode (pattern); play test note (instrument/table) |
RETURN | insert key-off; enter the table or instrument under the cursor |
SHIFT+RETURN | insert key-on; convert an old-style portamento/vibrato/funktempo value into a speedtable entry |
BACKSPACE | insert rest |
- + / / * / < > / backquote | instrument / octave / pattern (subtune in song mode) / channel or table |
SHIFT+Q/A, SHIFT+W/S | transpose halfstep / octave (in tables: portamento speed; pulse/filter speed ×2 ÷2) |
SHIFT+O/P | shrink / expand pattern (÷2 / ×2) |
SHIFT+J/K | join with next pattern / split at cursor |
SHIFT+X/C/V, SHIFT+E/R | cut/copy/paste; copy/paste commands only |
SHIFT+L | mark whole pattern/orderlist; in tables: convert limit-based step to time-based |
SHIFT+H | precalculate a "hifi" note-independent portamento/vibrato speedtable entry |
SHIFT+N | instrument name; in tables: negate speed / relative note |
SHIFT+O (table) / SHIFT+R (table) / SHIFT+U | optimise table / absolute↔relative note / unlock table scrolling |
SHIFT+INS (table) | insert rows without moving pointers to row 1 |
SHIFT+DEL (instrument) | delete instrument and its table data |
SHIFT+ESC / ESC | optimise or clear music data / exit |
Note entry (Protracker mode): lower octave Z X C V B N M , . (sharps S D G H K L), upper Q W E R T Y U I O P (sharps 2 3 5 6 7 9 0); octave with / and *.
Pattern commands#
| cmd | effect |
|---|---|
0XY | nothing (stops a running vibrato/portamento) |
1XY / 2XY | portamento up / down; XY = speedtable index of a 16-bit speed |
3XY | tone portamento to the note; 300 = tie note (instant) |
4XY | vibrato; speedtable index (left = speed, right = depth) |
5XY / 6XY | set attack/decay / sustain/release register |
7XY | set waveform register (ineffective while the wavetable changes waveforms) |
8XY / 9XY / AXY | set wave / pulse / filter table pointer (00 stops) |
BXY | filter control: X resonance, Y channel bitmask (B00 = filter off) |
CXY | filter cutoff |
DXY | master volume Y (X = 0); otherwise XY is a timing mark |
EXY | funktempo from speedtable (alternates two tempos row by row) |
FXY | tempo $03–$7F all channels, $83–$FF this channel, 00/01 recall funktempo |
No effect memory: a 00 databyte never means "repeat". One-shot commands 5–F leave a running 1–4 command or instrument vibrato intact.
Instrument parameters#
| parameter | meaning |
|---|---|
| Attack/Decay, Sustain/Release | 0 fastest / F slowest; sustain 0 silent … F loudest. All zero = "just a very short click" |
| Wavetable / Pulsetable / Filtertable pos | start rows (00 stops wave execution; 00 leaves pulse/filter untouched) |
| Vibrato param, Vibrato delay | speedtable index; ticks before it starts (00 = off) |
| HR/Gate timer | ticks before the next note for note fetch, gate-off and hard-restart; ≤ tempo−1; $80 disables HR, $40 disables gate-off |
| 1stFrame Wave | waveform on the note's first frame, "usually $09 (gate + testbit)"; $00/$FE/$FF = keep waveform and leave gate / gate off / gate on |
Instrument legato: timer bit $40 + 1stFrame $00. Examples from the readme: 09/00 full volume then fade; 00/8A instant to sustain 8; CC/AF slow swell.
Tables#
Wavetable — left: 00 keep waveform · 01–0F delay 1–15 frames · 10–DF waveform/control · E0–EF inaudible values $00–$0F (E9 = test + gate) · F0–FE run pattern command 0–E with the right byte (not 0, 8, E) · FF xx jump to xx (00 = stop). Right: 00–5F semitones up · 60–7F semitones down · 80 keep frequency · 81–DF absolute C#0–B-7. Never put a delay or "no change" in an instrument's first row; never jump onto a jump row.
Pulsetable — 01–7F xx modulate for that many ticks at signed speed xx · 8X xx set width $Xxx · FF xx jump. Example sweep: 80 10, 20 40, 40 E0, 40 20, FF 03.
Filtertable — 00 xx set cutoff · 01–7F xx modulate · 80–F0 xx set passband (90 low, A0 band, C0 high) + resonance/channel mask · FF xx jump. A set-parameters row directly followed by a set-cutoff row runs in one frame.
Speedtable — shared by vibrato (speed depth), portamento (16-bit step) and funktempo (tempoA tempoB); high bit in the left byte = realtime note-independent calculation, right byte = divisor. Examples: vibrato 03 40 (old $34), 05 04 "slow shallow vibrato, suitable for bass notes"; portamento 00 20 (old $08), 4F FF a "SEUCK-like space effect"; funktempo 09 06 (old $96), 24 18 for 4×.
Orderlist and song keys#
< > subtune · - + transpose down/up entry · SHIFT+R repeat · SPACE/BACKSPACE start/end position for F2 · SHIFT+1/2/3 swap channel orderlists.
Techniques
Chord arpeggio (the 0 3 7 trick) › GoatTracker #
GoatTracker 2 removed v1's arpeggio command: "Everything that this command does can also be done with wavetables". A looping arp is a wavetable whose right bytes are the semitone offsets and whose left bytes keep the waveform: 41 00 / 00 04 / 00 07 / 00 0C / 00 00 / FF 02 (4-note pulse arpeggio, waveform unchanged in the loop); with delays in the left byte the arp slows — 21 00 / 02 03 / 02 07 / 02 00 / FF 02 is "a delayed minor chord arpeggio with sawtooth waveform. Each step takes 3 ticks". Because the wavetable "is never skipped", arps keep time at any tempo (source: s-goattracker-readme).
Filter programming on the SID › GoatTracker #
The filtertable: 00 xx set cutoff, 01–7F xx modulate for that many ticks at signed speed, 80–F0 xx set passband (left high nibble 9 low-pass, A band-pass, C high-pass) with the right byte = resonance nibble + channel bitmask (as in command BXY), FF xx jump. A set-parameters row directly followed by a set-cutoff row executes in the same frame. Examples: 90 F1 / 00 40 / FF 00 — low-pass, resonance F, channel 1 only, cutoff $40; A0 87 / 00 00 / 7F 01 / 7F 01 / 7F FF / 7F FF / FF 03 — band-pass on all channels sweeping up 254 ticks and back; C0 F2 / 00 F0 / 90 F2 / 00 50 — high-pass then low-pass on the next frame. From the pattern: AXY sets the filtertable pointer, BXY filter control (X resonance, Y bitmask; B00 = off and stop), CXY cutoff. "In most cases it makes sense to have a filter-controlling instrument only on one channel at a time"; the filtertable runs on every tick, and the test note plays filtered only on a channel selected in the filter parameters (source: s-goattracker-readme).
Hard restart › GoatTracker #
- Per instrument: HR/Gate timer = how many ticks before the next note the note fetch, gate-off and hard restart happen (at most tempo−1; with tempo 6 and timer 2 they happen on tick 4, "2 ticks before first frame"); bit
$80disables hard restart,$40disables gate-off. 1stFrame Wave is "usually$09(gate + testbit)". - Global: the HR ADSR value (
-Axx,SHIFT+F7), default0F00— "0000 is probably too hard to be useful, except perhaps with gateoff timer value 1. 0F00 (default) is a lot softer, and 0F01 adds also a little bit of release to the gateoff phase for even softer sound. 000F makes the note start very pronounced." AttackFenables an alternative playroutine that writes the waveform before ADSR, "more reliable note triggering, especially for very fast releases 0 & 1". - Legato without restart: timer bit
$40and 1stFrame$00(tables and ADSR still re-initialise). - Multispeed: multiply the timer with the speed (2 → 4 at 2×). If a packed tune still bugs: make note-init take more cycles (nonzero pulse start position, 1stFrame
$09→$0B), use buffered writes, or attackF; since v2.68 notes with attack 0 and release 1 are the sensitive case.
(source: s-goattracker-readme)
Instrument design beats note count › GoatTracker #
Nine parameters per instrument (ADSR, three table pointers, vibrato + delay, HR/gate timer, 1st-frame waveform) and everything else lives in the tables (goattracker). The readme's own recipes (source: s-goattracker-readme): ADSR 09/00 self-fading pluck, 00/8A organ-like sustain, CC/AF slow pad; wavetable "flute" 41 00 / 11 00, "koto" 41 01 / 40 00, a snare 81 D0 / 41 AA / 41 A4 / 80 D4 / 80 D1 ("use pulsewidth 800"), hi-hat-then-pulse 81 DF / 41 00; pulse sweep 80 10 / 20 40 / 40 E0 / 40 20 / FF 03; speedtable vibrato 05 04 "slow shallow vibrato, suitable for bass notes"; low-pass bass filter 90 F1 / 00 40. Stop an unused pulse program (80 00 / FF 00) under sawtooth instruments to save rastertime.
Multispeed (framespeed) › GoatTracker #
The speed multiplier is -Sxx on the command line or SHIFT+F5/F6 (0 = 25 Hz, 1 = 1×, 2 = 2× …). Because the whole player runs faster: multiply tempos and gate-off timers (timer 2 → 4 at 2×, also when importing v1 multispeed songs); to keep a vibrato the same, multiply its speed and divide its depth by the multiplier; divide portamento and pulse/filter modulation speeds; funktempo 24 18 is 09 06 at 4×. With attack 0 "the very silent first row of the wavetable" may vanish — raise the attack or add E9 00 (test + gate) rows at the start (source: s-goattracker-readme).
Octave bass › GoatTracker #
Type it, or put it in the instrument: a wavetable whose right byte alternates 00 and 0C (+12 semitones) with the waveform kept (00 left byte) and an FF jump back — the readme's 4-note arpeggio example (41 00 / 00 04 / 00 07 / 00 0C / 00 00 / FF 02) shrunk to two rows; add left-byte delays (01–0F) to slow it to 8ths (derived from the documented table semantics, source: s-goattracker-readme).
Pitch slides and tone portamento › GoatTracker #
1XY / 2XY slide up / down and 3XY tone portamento all take a speedtable index holding a 16-bit pitch step per tick; 300 is a tie note (instant pitch change, no retrigger). Speedtable examples: 00 20 (old parameter $08), 01 00 (old $40), 4F FF "loops the pitch highbyte very fast so that a SEUCK-like 'space' effect is heard"; a high bit in the left byte (80 01) makes the speed note-independent (divisor 1 = half). SHIFT+H on a command precalculates a note-independent speed from the frequency difference of adjacent notes (00110 = double the C-3→C#3 difference). Portamento is a realtime command: it continues under one-shot commands and stops at 0XY (source: s-goattracker-readme).
Pulse width modulation (PWM) › GoatTracker #
The pulsetable: 01–7F xx = modulate for that many ticks at signed speed xx (right byte), 8X xx = set width $Xxx, FF xx = jump (00 stops). Readme examples: 88 00 / FF 00 sets $800 and stops; 80 10 (very thin), 20 40 (32 ticks up at speed 64), 40 E0 (64 ticks down at −32), 40 20 (64 ticks up at 32), FF 03 (loop from row 3) — "a nice loop". Enter sweeps as limit-based steps (84 00, C0 10 modulate to $C00, 40 10 back to $400) and convert them with SHIFT+L; the player only understands time-based steps. Speeds doubled in v2.4. Pulse execution is skipped on note-init ticks unless -O0; 900 or a 80 00 / FF 00 program stops an unused pulse program under non-pulse instruments (source: s-goattracker-readme).
Ring modulation and oscillator sync › GoatTracker #
Set the bits in the wavetable byte: $02 sync, $04 ring ("most effective with the triangle waveform"), $08 test — e.g. 15 = triangle + ring + gate. The inaudible values $00–$0F are typed as E0–EF, so test + gate is E9; the instrument's 1stFrame Wave is normally $09 (gate + test) (source: s-goattracker-readme).
Shuffle, swing and FunkTempo › GoatTracker #
EXY = funktempo from a speedtable entry whose two bytes are the alternating tempos (09 06 corresponds to the old parameter $96; 24 18 is the same feel at 4× multispeed); it applies to all channels, and FXY with $83–$FF overrides the tempo on one channel (F00/F01 recall the funktempo values). Tempo 3 is normally the fastest, but a funktempo entry 02 02 with gate-off timer 1 in every instrument and pulse skipping disabled gives tempo 2 (source: s-goattracker-readme).
Vibrato and delayed vibrato › GoatTracker #
4XY and the instrument's vibrato parameter both index the speedtable: left byte = how many ticks until the direction changes (speed), right byte = pitch added each tick (depth). 03 40 equals the old one-byte parameter $34; 05 04 is "slow shallow vibrato, suitable for bass notes. Not possible to achieve with old parameters"; 83 04 (high bit set) makes the depth note-independent with a divisor of 4 right-shifts. The instrument's vibrato delay is the tick count before it starts (00 = off) — a delayed vibrato without any pattern command, which also packs smaller. Realtime commands are skipped on tick 0 of each row unless -R0; a one-shot command (5XY–FXY) between vibrato rows leaves the vibrato running, but 0XY stops it; SHIFT+H precalculates "hifi" note-independent depths from the frequency difference of adjacent notes (source: s-goattracker-readme).
Wavetable programming (waveform / arp tables) › GoatTracker #
Wavetable rows are left right bytes: left 00 keep waveform, 01–0F delay 1–15 frames, 10–DF waveform/control, E0–EF the inaudible values $00–$0F (E9 = test + gate), F0–FE execute pattern command 0–E (right = parameter; not 0, 8, E), FF xx jump (00 = stop); right 00–5F semitones up, 60–7F down, 80 keep frequency, 81–DF absolute C#0–B-7. A delay or "no change" must not be the instrument's first row. Rows with a delay or 80 let vibrato and realtime commands run underneath (rastertime!). Examples from the readme (from table row 1):
| rows | sound |
|---|---|
21 00 / FF 00 | sawtooth on the note's pitch |
41 00 / 11 00 / FF 00 | "flute": pulse on the first tick, triangle after |
41 01 / 40 00 / FF 00 | "koto": one halfstep up on the first tick, then the note with the gate cleared |
81 D0 / 41 AA / 41 A4 / 80 D4 / 80 D1 / FF 00 | snare drum, all absolute notes — "use pulsewidth 800 for best result" |
81 DF / 41 00 / FF 00 | pulse note preceded by a short noise at B-7, "like a hi-hat" |
41 00 / 00 04 / 00 07 / 00 0C / 00 00 / FF 02 | 4-note looping arpeggio, waveform unchanged in the loop |
21 00 / 02 03 / 02 07 / 02 00 / FF 02 | delayed minor-chord arpeggio, three ticks per step |
41 00 / 03 80 / 11 80 / 03 80 / 41 80 / FF 02 | pulse ↔ triangle every 5 ticks with frequency untouched (vibrato and slides keep working) |
81 CF / 21 00 / 08 00 / F6 2A / FF 00 | noise, then saw, then after 8 frames set sustain/release $2A from inside the table |
Instrument pointers select the start row; 8XY in a pattern jumps into a table mid-way; "Wavetable is never skipped" at any tempo (source: s-goattracker-readme).
Impulse Tracker cheat sheet
Reference
Limits and formats#
99 samples, 99 instruments, 200 patterns of 32–200 rows, 256 orders, 64 channels plus up to 256 virtual channels; samples 8/16-bit to ~4 MB with forward, ping-pong and sustain loops. Loads MOD, 669, MTM, S3M, XM, IT; saves IT and S3M (with restrictions — see it-format); imports WAV, S3I, IFF, ITS, RAW, GUS PAT, Kurzweil KRZ and samples/instruments out of other modules. A GUS plays 32 channels, an AWE32 30; software mixing on a SB16 does all 64 (source: s-it-manual).
Screens and keys#
| key | screen |
|---|---|
F1 | help (also context help for the pattern editor, sample/instrument lists, info page) |
F2 | pattern editor (F2 again: pattern config — rows, base octave, skip value, highlights) |
F3 / F4 | sample list / instrument list (Ctrl-F3 / Ctrl-F4: sample / instrument library) |
F5 / F8 | play / stop; F6 play pattern, Ctrl-F6 from the current row, F7 from the Ctrl-F7 mark |
F9 / F10 | load / save (Delete removes files) |
F11 | order list, initial channel pan (Space mutes, S surround) and — F11 again — channel volumes |
F12 | song variables: tempo, speed, global/mix volume, separation, Old Effects, Control: Samples / Instruments, mono/stereo, Amiga/Linear slides |
F5+info page | PgUp/PgDn views, Insert/Delete windows, s solo, q toggle, Alt-R swap L/R; columns Frequency, Position, Smp, FVl, CV, SV, VE, Fde, Pn, PE, NNA, Tot (virtual channels) |
Pattern editor#
A row is note · instrument · volume/pan · effect: C-5 01 23 A02. Notes C-0–B-9, middle C is C-5 (one octave up from 037-lab's C-4; source: s-037-lab); two keyboard rows give two octaves above the base octave (/ *). 1 enters note cut ^^^, ` note off === (releases sustain loops). The volume column (0–64, linear — one note at 64 is as loud as four at 10+30+20+4) toggles to pan (0 left, 64 right) with `; from 2.08 it also takes Ax/Bx fine volume up/down, Cx/Dx volume slides, Ex/Fx pitch slides, Gx portamento and Hx vibrato. To get volume and pan and an effect on one note, set the channel volume with Mxx on the row before. Only the effect column is hexadecimal (source: s-it-manual).
Effect memory: a 00 parameter repeats the last value; these groups share one memory: (D/K/L), (E/F/G), (H/U), and I J N O S T W each their own. Use it — D10, D00, D00; G03, G00; Q43, Q00 — for smaller files and faster typing, "especially important for chip songs" (sources: s-it-manual, s-tw058-the-finishing-touches).
Effects#
| cmd | effect | cmd | effect |
|---|---|---|---|
Axx | speed = frames per row (default 06; ~50 frames/s) | Qxy | retrigger every y frames, volume change x (0 none, 1–5 −1/−2/−4/−8/−16, 6 ×⅔, 7 ×½, 9–D +1/+2/+4/+8/+16, E ×1½, F ×2) |
Bxx | jump to order xx | Rxy | tremolo (speed, depth) |
Cxx | break to row xx (hex) of the next pattern | S3x S4x S5x | vibrato / tremolo / panbrello waveform: 0 sine, 1 square, 2 ramp down, 3 random |
Dxy | volume slide: D0y down, Dx0 up, per frame (y × (speed−1) per row); DFx/DxF fine; D0F/DF0 every frame (S3M) | S6x | pattern delay x ticks |
Exx / Fxx | pitch slide down / up (values to DF); EFx/FFx fine, EEx/FEx extra fine (¼) | S70 S71 S72 | past-note cut / off / fade (instrument mode) |
Gxx | portamento to note (may switch sample, which restarts) | S73–S76 | NNA for this note: cut / continue / note off / note fade |
Hxy | vibrato speed x depth y (per-tick, "two times finer" than ST3) | S77 / S78 | volume envelope off / on |
Ixy | tremor on x / off y frames | S8x | pan 0–F (obsolete, use Xxx) |
Jxy | arpeggio +x, +y semitones — "similar to old C-64 chords" (J47 major) | S91 | surround |
Kxy / Lxy | vibrato + volume slide / portamento + volume slide | SAy | high byte for Oxx |
Mxx | channel volume 00–40 ("convenient for making echoes") | SB0 / SBx | loop point / loop x times (per channel) |
Nxy | channel volume slide | SCx | note cut after x frames |
Oxx | sample offset to the xx00-th sample (SAy extends) | SDx | note delay x frames |
Pxy | pan slide (P0x right, Px0 left) | SEx | pattern delay x rows |
Txx | tempo 20–FF (frames/s = 0.4 × tempo; 125 → 50); T0x/T1x slide | Vxx / Wxy | global volume 00–80 (affects playing notes) / slide |
Uxy | fine vibrato (¼ depth) | Xxx / Yxy | pan 00–FF (= volume-column pan × 4) / panbrello (speed, depth; random waveform: speed = delay) |
(sources: s-it-manual, s-tw106-a-little-panning, s-tw058-the-finishing-touches, s-ittech)
Editing and block keys#
Ctrl-Backspace ten-level undo · Space re-enter previous data · 4/8 play note/row · Alt-0…9 skip value (0 = jump to the next channel, for chords; Alt-N multichannel) · Alt-B/Alt-E mark, Alt-L column (×2 pattern), Alt-D by highlight · Alt-C copy, Alt-P paste, Alt-O overwrite, Alt-M mix, Alt-Z cut, Alt-Y swap, Alt-U unmark · Alt-Q/Alt-A transpose ± semitone · Alt-F/Alt-G double/halve block length · Alt-J amplify volumes 0–200 %, Alt-K slide volumes between block ends (×2 clear), Alt-X slide effect values (×2 erase), Alt-S set instrument, Alt-V/Alt-W set volumes / remove volumes without notes · Alt-I templates: copy a block, switch to Template: Overwrite, and every note you type stamps the block transposed — sequences of effects, octaves, sample pairs, stereo pairs (C-4 01 X30 | C-5 01 XC0), open fifths · Alt-T track views, Alt-H no divisions (36 channels on screen) · Alt-F10 solo (sources: s-it-manual, s-tw081-it-tip-of-the-week).
Samples#
Each sample has a default volume, a global volume (scales every use; the right way to attenuate 8-bit samples), vibrato (speed 0–64, best ~24–48; depth; rate = how fast it sets in; waveform), loop and sustain loop (looped only until note off, then the tail plays — "fingers lifting off guitar strings"; keep it < 1/20 s) and the C-5 frequency (Alt-± octave, Ctrl-± semitone). Functions: Alt-O rip from a module, Alt-A signed/unsigned, Alt-Q 8/16-bit, Alt-B/Alt-L cut before/after loop (also click removal), Alt-G reverse, Alt-E/Alt-F resize with/without interpolation (Graham: ±1 sample as a crude low-pass), Alt-M amplify (default = maximum without clipping), Alt-H centre, Alt-X/Alt-S swap. Load one channel of a stereo WAV by halving with Ctrl-F; render new samples with the WAV-writer driver (/S20) (sources: s-it-manual, s-it-hints, s-tw086-wrecking-samples-with-impulse-tracker, s-tw081-it-tip-of-the-week). See chip-samples, sample-looping.
Instruments#
Turn on Control: Instruments in F12. An instrument = a note translation table (each note → sample + note: drum kits, multisampling), a fadeout, three 25-node envelopes (volume, pan, pitch — the last can act as a filter envelope in later versions) with loops and sustain loops (instrument-envelopes), a New Note Action — cut, continue, note off, note fade (new-note-actions), duplicate check type/action, pitch-pan separation, default pan, volume swing (random volume variation) and a panning-swing field, and MIDI settings. Instruments are cheap: make several per sample for different articulations (Pulse). "Update Pattern Data" converts sample-per-drum patterns to a kit instrument. Warning: NNA fade with fadeout 0, or continue on a looped sample, can hang the machine (sources: s-it-manual, s-ittech, s-it-hints).
Song variables that change the sound#
Separation 128 for speakers side by side, 80 far apart, ~40 for headphones; Old Effects = ST3 vibrato (double depth, per non-row tick) and offset-past-end behaviour; Linear slides make F08 at speed 5 always a whole tone and keep intervals between sliding notes constant; global volume 0–80h — keep it high for headroom and smooth fades (Nacho); mixing volume for software mixers (sources: s-it-manual, s-it-hints).
Pulse on IT, in TraxWeekly (1997)#
jeffrey-lim in #98 and #100 (sources: s-tw098-impulse-tracker-investment, s-tw100-tracking-on-impulse): IT "was created because I track … not because Necros wanted a ST3 interface with more advanced features", and released "without any shareware or crippleware restrictions" out of pride — "Impulse Tracker is my work of art"; "easily over 1500 hours, probably closer to 2000" of work; no price tags or nag screens, donations of any size welcome, but the stereo ITWAV.DRV (noiseless WAV rendering for CD burning) was a US$30 extra for non-profit use and was being pirated; contemporaries he names: PolyTracker and Imago Orpheus. In May 1997 he announced that IT213 would be "the very final public release" with new features, bug fixes and drivers only afterwards — 2.14 nevertheless followed on 1997-09-02 as "the FINAL public release" with on-the-fly sample compression (source: s-tracker-history-notes); an IT213 preview fixed IT212's EMS stability problems. Asked for his own Interwave driver source, he instead defended Triton against users demanding Interwave support in FT2: make it worth their while or don't demand.
MIDI, stereo samples and sound cards#
- MIDI output: instruments can drive a synthesizer; controllers go through macros —
Z80–ZFFstatic messages,SF0–SFFparametered templates fed byZ00–Z7F— the volume column is sent as velocity, and NOTE OFF leaves when the note's volume reaches zero, so NNA and fade-out settings decide the timing (midi-in-trackers; source: s-tw098-impulse-tracker-midi). - Stereo samples: IT loads a stereo file as two mono samples — it asks for LEFT or RIGHT — which Zinc pans hard apart and plays on two channels for true-stereo kicks and bass; "the only tracker I know of that can load stereo samples" (1997) (source: s-tw094-stereo-samples-in-impulse-tracker). The WAV driver also renders a one-pattern drum loop into an original breakbeat at the song's tempo (source: s-tw096-studio-tracking-tips).
- Sound cards: the documentation's reason for autodetecting the SB16 first — software mixing "can support 64 channels at 45454Hz" while "the most the GUS can support is 32 channels at 19kHz" — compares CPU mixing with the GUS's hardware voices, as Random pointed out in 1996 (source: s-tw044-impulse-tracker-trivia); the manual's own figures are GUS 32 channels, AWE32 30, SB16 software mixing 64 (source: s-it-manual).
In the scene's words (1996–97)#
skaven in 1997: "All praise to Pulse. It is practically Scream Tracker 4, and lots more. It does certain things no other tracker at the moment can" (source: s-tw109-interview-skaven). catspaw was wary of the IT format at first because no player existed, and suggested to Pulse a command-line play switch — Pulse was already writing a player (source: s-tw057-interview-catspaw). A 1997 beginner chose IT for its higher order and channel limits — "it gives me a feeling of power" — while ST3 remained the entry tracker (source: s-tw105-newbie-interviews); the #trax joke prize of December 1996 was "a year's supply of IT bugfixes" (source: s-tw080-trax-mass-interview). Maz dates IT's NNAs as the scene's "revolutionary" moment of 1996; a Canberra duo signed to a dance label worked in IT on an AWE64 Gold; and Behemoth's image of live-tracking is hitting F5 and waiting (source: s-tw114-commercial-tracking-debate; see commercial-tracking).
The interviews, 1996–98. fisherman (May 1996) called IT "a new hybrid of a pear and an apple — so new to the market, it is taking everyone by surprise" (source: s-tw060-interview-fisherman). clef (April 1996), an ST3 user's upgrade path: "just like ST3 but better… It also plays better on my SB16" (source: s-tw055-interview-clef); vadimvs used "itracker" sometimes beside ST3 (source: s-tw050-interview-vadimvs). The format lagged the program: vegas (June 1996) used IT but saved as .s3m "until .IT's are supported by a couple popular players", saw no FT2 advantage "other than interface preference. 32 channels or 64, whats the difference", and had heard the claim that NNAs "reduce GUS sound quality" but could not judge it on his Pro Audio Spectrum 16 (source: s-tw062-interview-vegas; see new-note-actions); ryan-sprott (July 1996) said IT users had an advantage in Music Contest 4 because no standalone IT player existed — consistent with Catspaw's remark above that Pulse was still writing one — and wished Pulse "would stop changing the damn tracker so much, and put in mouse/ems support" (source: s-tw063-interview-ryan-sprott); liam-the-lemming (August 1996) had a musicdisk delayed because some tracks were .IT and "support for the format is... uh... sparse" (source: s-tw066-interview-liam-the-lemming; see it-format). perisoft (January 1997) chose IT for "120 channels on a fast computer, great support behind it, great advancement, and is the only tracker that can make a truely CD quality song (by diskwriting and support of huge samples)" (source: s-tw087-interview-perisoft) — his channel count is a user's figure; the manual's limits are 64 pattern channels plus up to 256 virtual channels (source: s-it-manual). mikmak (June 1997): tracked music was better than two years before — "2 words: impulse tracker"; he was using ST3 that month only for S3M replay research (source: s-tw103-interview-mikmak). mental-floss (February 1998) praised the newly added filter and wished for a basic sample editor "like in FT2" (cut the start, normalise), "more MIDI<->Tracker capabilities" and the ability to synchronise or start IT from MIDI for console mixdowns (source: s-tw119-interview-mental-floss; see midi-in-trackers, sync).
Techniques
Chip samples — tiny looped waveforms › Impulse Tracker's sample tools #
Alt-E/Alt-F resize with/without interpolation (Graham the Happy Scum: +1 then −1 sample as a crude low-pass "smoothing"), Alt-G reverse, Alt-A/Alt-Q signed and 8/16-bit conversion, Alt-B/Alt-L cut before/after the loop — Onix4MAN loops the first 50–100 bytes and pre-loop-cuts to remove start clicks; a crude noise gate is Alt-A, Alt-M at 103–104 %, Alt-A; quarter-tone scales come from loading a sample twice with one copy's rate × 1.0293 (2^(1/24)). IT can render new samples of itself: put a break in one pattern, restart with the WAV-writer driver, play, reload the WAV as a sample. One channel of a stereo WAV: Ctrl-F halves the sample keeping every second byte (cut the first and last byte first for the right channel), then double the frequency (sources: s-tw086-wrecking-samples-with-impulse-tracker, s-it-hints, s-it-manual).
Chip samples — tiny looped waveforms › One composer's digi voice, and why it stayed private (1991) #
JCH added samples to his own editor in June 1991 by the $D418 volume-click trick driven from an NMI — the same route as the 1986–88 drivers above — and sampled Korg M1 sounds with an SFX Sound Sampler cartridge. His first digi tune was "Better Late than Never" (1991-06-23) and he made only four in total, because the jch-editor was merely "hacked" for the digi voice and was "too hairy to be used by anyone else but me". It is a useful counterweight to the 1986–88 firsts: by 1991 the technique was reachable by a bedroom composer, but productising it — making it survive in an editor other people use — was still the hard part (source: s-chordian-my-computer-chronicles; multispeed).
Chord arpeggio (the 0 3 7 trick) › Impulse Tracker / Scream Tracker 3 #
Jxy cycles base, +x, +y once per tick — the IT manual calls it "an effect similar to old C-64 chords" (source: s-it-manual): the Modsquad's chip lead has a chord channel of J47 (major) and J37 (minor) at volume 64 with J00 to stop, and their rules are "chords in one channel — never two — and no percussion inside them" (source: s-tw077-chip-off-the-block). Pinion admits that for "really neato chords" Jxx is "a bit… shitty sounding" in a sample tracker — but on a looped noise sample with a long falling pitch envelope a column of Jxx makes analog-style sweeps (instrument-envelopes; source: s-tw081-it-tip-of-the-week). Trixter's reminder that "a chord isn't a thing, it's any combination of notes" applies: an arp is a chord spread in time (source: s-tw039-chord-theory-debate).
MOD and XM use 0xy for the same command: ProTracker's help calls it "used to simulate chords … noisy and grainy on most samples, but ok on monotone ones" — C-3 00047 C major, 037 C minor — and FT2 plays the note on tick 1, +x on tick 2, +y on tick 3 (sources: s-protracker-23d-help, s-ft2-manual). ST3's manual says the same in its own letters: Jxy changes the pitch "50 times per second … best to use it with clear or tight-looped (chip) instruments. Old users of the Commodore 64 remember this effect which was used to make chords" (J37 = C minor) (source: s-st3-manual). Two quirks players emulate: Fasttracker 2's arpeggio runs backwards (the second parameter's note comes first), and in ProTracker mode arpeggios that leave the Amiga range wrap around an octave (sources: s-openmpt-manual-compatible-playback, s-openmpt-manual-song-properties).
One command-memory trap when porting a part between formats: in S3M the effect memory is mostly global to the column, so a bare J00 recalls the last non-zero parameter of any command in that column, not just the last arpeggio — where MOD's 0xy has no memory at all and IT keeps per-command memory. Only vibrato and tone portamento have their own memory in S3M (source: s-openmpt-manual-effect-reference; effect-command-crosswalk).
Chord arpeggio (the 0 3 7 trick) › Who invented it, and the PWM trick #
- SIDwave credits martin-galway: "In the process, Martin invented the chord, aka arpeggio — to play 3 or more notes in the same voice, very fast, one after another, so that it sounds like a chord. People from the UK called it the arpeggio, it was also known as wibble, or wibbles" (1984–85; source: s-recollection-brief-history-of-sid). de.wikipedia describes Soundmonitor's arpeggios the same way — "sehr oft zu hören" in C64 games (source: s-soundmonitor-lineage-wikis).
- matt-gray: "the note or chord plex where you go very quickly between 2,3 or even 4 notes to give the impression of a full chord being played. That sound became unique almost to the SID and everyone is using it as a retro sound now … And if you put a pulse width mod on it such as a sweep, the bubbling chord took on a life of it's own" (pulse-width-modulation; source: s-rvg-matt-gray-interview).
Fake echo / delay › Impulse Tracker #
Pulse's own hint: copy the column and set a channel volume M20 at the top of the echo channel — "you won't have to modify the echoing channel from the original", the Dxx slides stay right. StereoMan's reverb-like version: copy the sequence one or two rows later, zero its volumes (Alt-V, Alt-W) and fade every echo note in with Dx0 slides; pan the pair apart (X22/XDD or X80 + S91) for "stunning" results (sources: s-it-manual, s-it-hints).
Filter programming on the SID › Impulse Tracker / OpenMPT (resonant filter) #
The PC-tracker equivalent of the SID filter table is a column of Zxx macros (source: s-openmpt-manual-zxx-macros): by default Z00–Z7F set the cutoff (00 lowest … 7F highest; the top is about 5 kHz, or 10 kHz with Extended Filter Range) and Z80–Z8F the resonance; the underlying messages are F0F000xx cutoff, F0F001xx resonance, F0F00200 lowpass and F0F00210 highpass (mutually exclusive), so a fixed macro can switch filter type. Instruments carry default cutoff, resonance and (MPTM) filter mode; cutoff at maximum with resonance at minimum turns the filter off; the pitch envelope can act as a filter envelope (S7D/S7E force one or the other in MPTM); S9C makes filters stay until switched off (Impulse Tracker behaviour), S9D resets them on every note; MPTM adds cutoff and resonance swing per instrument; the filter never touches plugins (sources: s-openmpt-manual-instruments, s-openmpt-manual-effect-reference). On OPL instruments the cutoff macro scales the modulator — "effectively … a lowpass filter" (opl-fm-instruments; source: s-openmpt-manual-samples). The Amiga's only filter is the LED low-pass toggled by E0x — "connects filter (turns power LED on)" — which OpenMPT calls "muffled" and emulates only with the Amiga resampler (sources: s-protracker-23d-help, s-openmpt-manual-effect-reference).
Lead articulation (velocity, legato, late vibrato, drop-off) › Scream Tracker 3 / Impulse Tracker #
Necros's worked example (E minor run; ST3 letters, identical in IT/OpenMPT; source: s-tw012-advanced-tracking-tips):
- Velocity in the volume column — ramp a run up to its held peak and back:
E-4 40 · G-4 40 · A-4 50 · B-4 60 · E-5 64 … G-5 60 · F#5 50 · B-4 40 · C-5 40 → 50 → 64 · A-4 50. Multiples of 10 are quick to type; the volume column, notD20, so the effect column stays free. - Legato with tone portamento so the sample is not restarted:
GF0for any jump over three semitones ("practically instant"),G20/G06for a slow slide over a small step, and aGF0on the row after a slow slide to guarantee it lands, "since some players tend to play Gxx/3xx effects too slowly" (pitch-slide-and-portamento). - Late vibrato on the held notes only:
HA1a row or two after the note, thenHA2, never the main event except in hard up-tempo tunes; fade it back or fade the note (vibrato). - Echo track: copy the lead column,
ALT-Jits volumes down to a third at most (22 from 64), shift it 2–3 rows at speed 6 (4–6 at speed 3), pan it the same distance on the other side of the lead (fake-echo, stereo-panning). - Drop-off ("made infamous by Purple Motion and other siner junkies"): slide up into the top note, sustain it with vibrato, and at the very end fall away with an accelerating down-slide and falling volume:
| row | note / vol / cmd | what happens |
|---|---|---|
| 0 | B-4 01 50 | approach note |
| 1 | C-5 01 64 G05 | the big note, sliding up into it |
| 2 | GF0 | make sure it arrives |
| 3 | HA1 | vibrato in |
| 4 | HA2 | deeper |
| 5 | H00 | continue |
| 6 | HA1 | lessen |
| 7 | 50 E04 | slow fall starts |
| 8 | 30 E06 | faster, quieter |
| 9 | 10 E10 | fast fall, nearly silent |
| A | 00 | kill |
Catspaw's version of the same shape mixes volume-column values with K/H/E commands (C#6 02 33 UC3 → K20 → 44 H82 → K01 → 32 H71 → 20 E0E; source: s-tw058-the-finishing-touches; see volume-slides). The cheapest cousin of the drop-off is vegas's release tip of 1996: "Dont use a ^^^ to kill a note in the lead, just drop the volume to 10, 15, or 20 and volume slide the rest away. It leaves a reverb-ish effect thats really good on flutes, piano's and violins" — no pitch fall, just a volume-column 10–20 on the release row and a D0x slide to silence (source: s-tw062-interview-vegas).
Staccato and grace notes (Dan Hartrell's funk sax run, source: s-tw021-tracking-tips): D0F on a note and the row after it for "4 staccato" notes, G90 on each note of a phrase for a "wavey" pipe-or-reed sound, SD1 (note delay) to turn a note into a grace note that slips into the next, and alternating A05/A08 speeds so the run swings (shuffle-funktempo). Greg Heo's definition: a note cut SCx after x ticks is staccato, the absence of it legato (source: s-tw074-intro-to-musical-theory).
MIDI output from trackers (Impulse Tracker macros) › Impulse Tracker #
From Airon's 1997 guide (source: s-tw098-impulse-tracker-midi); all values hex, c = MIDI channel, z = the macro's data byte (00–7F):
| job | message | how to write it |
|---|---|---|
| volume (level, controller 07) | Bc 07 z | an SFx parametered macro, driven by Z00–Z7F; he could not make the volume line of MIDI Output Config behave |
| modulation (controller 01, usually vibrato depth) | Bc 01 z | SFx macro |
| pan (controller 0A; 00 left, 40 centre, 7F right) | Bc 0A z | SFx macro, or the pan line as Bc 0A x |
| bank select (00 = MSB, 20 = LSB) | Bc 00 a Bc 20 b | static macro Z80–ZFF |
| program change | Cc pp | static macro |
| reverb / chorus send (some synths) | Bc 5B z / Bc 5D z | SFx macro |
| breath 0B, sostenuto 42 (00–3F off, 40–7F on), soft pedal 43, balance 08 | Bc nn z | as above |
| hold pedal, GM mode, patch/performance mode, sysex | synth-specific | static macros Z80–ZFF |
- Static macros
Z80–ZFFhold fixed messages; parametered macrosSF0–SFFselect one of sixteen templates whosezbyte comes fromZ00–Z7F— the mechanism OpenMPT documents in full (source: s-openmpt-manual-zxx-macros). - Velocity: the volume column is sent as NOTE ON velocity (timbre, "how hard you hit"); MIDI volume (controller 07) is a separate level, "the distance to the listener".
- Note-off timing and legato: NOTE OFF is sent when the note's tracker volume reaches zero. A sample-style instrument with NNA note fade and a fade-out around 120 therefore sends NOTE OFF late; use NNA note cut and fade-out 0 for tight playing, or NNA note fade with a small fade-out on purpose — "the greater the VOLUME FADE, the less LEGATO" (new-note-actions).
^^^(note cut) sends NOTE OFF at once; most synths retrigger a repeated note without killing the previous one.
Multisampling and drum-kit instruments › Impulse Tracker #
The instrument's note translation table maps every note to a (note, sample) pair, so C-5 01 can play sample 1 while D-5 01 plays sample 3 at D-4. Two uses: a drum kit in one instrument (each note a different drum, one NNA/envelope/fadeout for all; "Update Pattern Data" converts old sample-per-drum patterns), and a high-quality multisampled piano — "if you don't run out of memory first. Or patience." Saving an instrument saves its samples with it (source: s-it-manual).
The kit case is where IT's NNAs pay off: with NNA continue, "put a bass drum in the very next row after [a snare] — the snare will still complete playing" from one instrument on one channel (source: s-it-manual).
New Note Actions (NNA) › Impulse Tracker #
- Set the default NNA in the instrument (with a sensible fade-out so virtual channels are freed).
- Override per note with
S73cut ·S74continue ·S75note off ·S76note fade — the setting applies to the note following the command. Correction from IT's author: a note left withS74keeps ringing until anS70past-note cut;^^^only affects the latest note; check the info page's Tot column to see how many virtual channels you are burning (source: s-tw081-it-tip-of-the-week). - Instruments cost almost nothing in file size, so keep several per sample with different NNAs and fades.
- MIDI instruments: IT sends NOTE OFF when the note's tracker volume reaches zero, so NNA note fade with a fade-out (Airon's was 120) delays every note-off; use note cut and fade-out 0 for tight timing, or keep note fade with a small fade-out as a deliberate legato — "the greater the VOLUME FADE, the less LEGATO";
^^^sends NOTE OFF at once (midi-in-trackers; source: s-tw098-impulse-tracker-midi). - Continue is for drums and short unlooped samples; a looped sample with continue and no cut "will annoy the listener into deleting your song" and can crash the player. Zinc: use NNAs, but "don't cram your instruments into one or two channels" (source: s-tw075-it-percussion-tips).
- The 1996 objection: kal-zakath relayed the view that NNAs "encourage inefficient tracking, and reduce GUS sound quality"; vegas did not use them but called them "definitely not useless", citing FutureAssassin's NAID '96 entry as the good example (source: s-tw062-interview-vegas). The manual supports the second half of the complaint mechanically — on a gravis-ultrasound the playback rate falls as active channels rise (source: s-it-manual) — and Pulse's own hope (below) that NNAs would not kill four-channel craft answers the first.
The Modsquad's drum-sampling comparison (1997): a kick-plus-snare combination sample versus playing the two with NNA continue — "almost the same" result, minus the interaction of the two waveforms, the "subharmonics and resounding frequencies" that a single recording keeps (source: s-tw087-music-theory-a-modern-approach; see instrument-design).
New Note Actions (NNA) › How IT allocates channels (from the manual and format doc) #
- Cut stops the old note "like in all other trackers"; continue lets it play on (a snare keeps ringing under the kick placed on the very next row); note off releases it (sustain loops, envelope sustain); note fade fades it with the instrument's fadeout.
S70/S71/S72apply cut/off/fade to all notes the channel left in the background. - Duplicate checks: DCT (off / note / sample / instrument) with DCA (cut / off / fade) stop a repeated note from piling up — the manual's guitar example: NNA continue, DCT sample, DCA fade, one sample per string, so replaying a string fades its previous note like a finger landing on it.
- Allocation: when a channel already plays, its note is flagged background and its NNA fires; the new note takes the first free virtual channel, else the quietest background channel, else it is dropped (IT 2.03+ chooses more cleverly). Background channels die when the sample ends, the envelope ends at 0, the fadeout is silent, or their volume is 0 — so always give fading notes a real fadeout; NNA fade with fadeout 0 or continue on looped samples "can easily hang a slow computer".
- Pulse: "I sincerely hope that these options do not cause the death of brilliant 4 channel music … There is truly an art in making a decent sound in as few channels as possible!"
(sources: s-it-manual, s-ittech)
Octave bass › Impulse Tracker / OpenMPT #
Jxy is an arpeggio over three notes — "the note playing, a note x halftones above, and a note y halftones above", an effect the manual itself compares to "old C-64 chords". So there is no single command for a strict 0 12 alternation: JCC gives 0 12 12 and J0C gives 0 0 12. For an exact 8th-note octave, type the two rows (source: s-it-manual). See effect-command-crosswalk for the same effect's number in MOD/XM (0xy).
Pitch slides and tone portamento › Impulse Tracker details #
Exx/Fxx slide down/up (values up to DF); EFx/FFx are fine slides and EEx/FEx extra-fine (a quarter of fine); Gxx may target a different sample, which then starts from its beginning; E, F and G share one effect memory. Linear slides (F12) make a value mean the same interval at any pitch — F08 at speed 5 raises a whole tone whether from C-4 or C-5 — because the frequency is multiplied by 2^(value/768): 64 units per semitone, Exx steps 4 units per frame, EEx 1 unit. With Amiga slides you must experiment per octave (sources: s-it-manual, s-ittech).
Randomization and probability (MayBe, RandomiZe) › Impulse Tracker #
Instruments have volume swing and panning swing — a random variation applied to every note. Zinc uses a small volume swing on hi-hats ("even if you've already changed your hi hat volumes to go 64-24-32-20") and panning swing for barely noticeable movement (source: s-tw075-it-percussion-tips); Pinion turns volume swing up to 100 % on a channel full of scale notes with NNA note-fade and "lets the laws of chaos do the composing" — a novelty, but a real generative tool (source: s-tw081-it-tip-of-the-week).
More IT randomness: the instrument's random volume variation is the volume swing Zinc and Pinion use, but the format doc marks random panning variation "not implemented yet" (so panning swing may not have worked in the versions of the time); S33/S43/S53 set the vibrato/tremolo/panbrello waveform to random — with random panbrello the speed digit becomes a delay in frames between new positions (Y14 fast, Y44 slower) (sources: s-ittech, s-it-manual).
In openmpt the instrument's Random Variation section has volume swing and pan swing (a random percentage of the global volume, a random pan offset) for every format with instruments, and MPTM adds cutoff swing and resonance swing on the resonant filter; the IT-compatible rule is that volume variation is a percentage of the instrument's global volume, not of the note volume (sources: s-openmpt-manual-instruments, s-openmpt-manual-compatible-playback). The random LFO waveform (S33/S43/S53 in IT, E43/E73 in MOD/XM) "is not supported by ProTracker and FastTracker" and should be avoided in those formats (source: s-openmpt-manual-effect-reference).
Retrigger and resync › Impulse Tracker / Scream Tracker 3 #
Qxy replays the sample every y frames with a volume change x per hit: 0 none · 1–5 = −1, −2, −4, −8, −16 · 6 = ×⅔ · 7 = ×½ · 8 none · 9–D = +1, +2, +4, +8, +16 · E = ×1½ · F = ×2 (source: s-it-manual). Catspaw's frame arithmetic: at speed 6, Q03 hits again exactly halfway through the row, Q02 gives three hits, Q04 a lopsided pair; avoid odd speeds (5, 7, 9) because no retrig can land on the half-row — get the feel with tempo instead. vegas's tip of 1996 is the same arithmetic from the other side: "Use EVEN speed values like 2, 4, or 6, to make your retrigs sound smoother" — Qxy intervals that divide a speed-6 row evenly (source: s-tw062-interview-vegas). Recipes: ride cymbal Q43 (32 → 24), a snare roll Q53 then Q43 on consecutive rows, and the tom "thwump" QC2 from volume 04 rising by 8 per hit (source: s-tw058-the-finishing-touches). Q00 reuses the last value (volume-slides). ST3's manual gives the same table (with 8 marked "?") and the worked examples Q72 at speed 8 = 64, 32, 16, 8 and QC2 at speed 6 = 12, 20, 28 (source: s-st3-manual). ProTracker's E9x retrigs every x ticks — "If you retrig with 1 in speed 6 that note will be trigged 6 times in one note slot. Retrig on hi-hats!" — and FT2 keeps E9x and adds Rxy with the volume table, which OpenMPT calls "very buggy" (a volume command in the same cell skips ticks) (sources: s-protracker-23d-help, s-ft2-manual, s-openmpt-manual-compatible-playback). IT-compatible players refuse to retrigger a channel that has already stopped, so a very short hi-hat sample needs a silent loop at its end (source: s-openmpt-manual-compatible-playback).
Sample offset tricks › Impulse Tracker semantics #
Oxx starts at the xx00-th sample (so byte xx00h × 2 for 16-bit samples); SAy supplies the high digit for offsets beyond FF00; an offset past the end is ignored unless Old Effects is on, in which case the sample plays from its end; the manual's own uses are skipping a loud attack or starting speech mid-way (sources: s-it-manual, s-ittech).
Sidechain pump › Impulse Tracker / OpenMPT #
Three levers, in increasing order of tidiness (source: s-it-manual):
Dxyvolume slides typed per row, the crude version (volume-slides).Mxxchannel volume (0–40h) withNxychannel volume slide — one command per channel per beat, no per-note volumes to edit, and it survives copy-paste of the notes. This is the closest thing a tracker has to a sidechain bus: putM20on the beat row andN0xafter it on every channel that should duck. S3M players only supportM/Nas an extension, so a song that needs them should stay.it.Vxxglobal volume withWxyglobal volume slide ducks everything including the kick, so it is a mastering lever rather than a pump — and IT'sVxxaffects notes already playing, unlike ST3's.
Or bake it into the instrument: a volume envelope that starts low and rises, retriggered every beat, pumps without a single command in the pattern (instrument-envelopes; source: s-037-lab). Keep the global volume high while doing any of this — at V05–V08 a volume-column fade jumps instead of sliding (source: s-it-hints).
Song initialisation and looping › ST3 / Impulse Tracker #
Put a silent dummy pattern first in the order list:
1 | ^^^ .. .. X3C | ^^^ .. .. X40 | ^^^ .. .. T7D | ^^^ .. .. A06 |
2 | ... .. .. C00 | ... .. .. .00 | ... .. .. X44 | ... .. .. X40 |
^^^ cuts anything still ringing from the previous loop, Xxx sets each channel's pan (works in S3M too), T7D/A06 set tempo 125 and speed 6, C00 breaks to the real first pattern after a fraction of a second. If you fade the global volume out at the end, reset it here too (volume-slides). At the end, put C00 on the same row as the final AFF so the pause lasts one slow row and the song restarts; give the Cubic player a row or two of AFF before the break because it stops on C00 immediately.
Jumps and breaks by format (sources: s-protracker-23d-help, s-ft2-manual, s-st3-manual, s-openmpt-manual-effect-reference, s-openmpt-manual-compatible-playback): ProTracker Bxx jumps to a hex position and "also perform[s] a pattern-break" — "you can use this command instead of restart as on Noisetracker"; Dxx breaks to a decimal line; F00 stops the song. FT2 Dxx takes a hex row (D16), and its E60 loop start has a bug: the next pattern begins on the loop row unless the pattern ends with D00. ST3 Bxx is hex, Cxx decimal, SB0/SBx loops never cross patterns. IT/OpenMPT: Bxx + Cxx on one row jump into the named pattern at the named row; a Bxx right of a terminating SBx cancels the loop. Song length in MOD is "one more than the last position" and NoiseTracker's restart byte is unused by ProTracker.
Song initialisation and looping › Chip trackers: the loop is in the orderlist, and it does not reset state #
On the C64 there is no song header to fall back on — the tune is code with an init entry point that runs once (init at the load address with the subtune number in A, then play every frame) and an orderlist that jumps back on itself (source: s-sid-wizard-manual; sid-player-routine). Everything the init call does not set is whatever the last pass through the song left behind. Three documented cases, and they agree:
- goattracker: the orderlist ends with an
RSTendmark carrying a restart position, and its TRANSPOSE entries are "reset only at song start" — so a transpose written near the end of the list is still in force on the next lap unless the list re-states it. Two editor rules go with it: TRANSPOSE must precede REPEAT, and the entry beforeRSTmust be a pattern or the editor halts playback (source: s-goattracker-readme). - sid-wizard: orderlist values are
$01–$7Fpattern,$80–$8F/$90–$9Ftranspose down/up ($90= original),$A0–$AFmain volume,$B0–$EFtrack tempo,$FEend (the track halts) and$FF xxjump to position xx — and each track has its own list and advances independently, so each has its own loop point and they need not be the same length (sources: s-sid-wizard-manual, s-duet-research-sidwizard). Transpose, volume and tempo are orderlist entries, which is the cure: re-state them at the jump target rather than trying to undo them at the end. - The drivers do it the same way, bugs included. In Charles Deenen's Maniacs of Noise player
$ffrestarts the sequence without resetting the transpose (source: s-realdmx-deenen-test-tunes); in Johannes Bjerregaard's,$FFrestarts all three voices at once, so one voice's loop point is the song's (source: s-realdmx-bjerregaard-player). The Dominator player separates the two endings outright:$FFrepeats the track,$FEends the music — and$FEtriggers an automatic fade, storing$5FinFADEand decrementing$D418every$5Fframes until the tune-number flag clears (source: s-sidin14-dominator-player).
The rule that follows is the same one catspaw gives for modules, stated in registers: anything sticky — transpose, main volume, tempo, filter state — must be re-stated at the loop target, not merely avoided at the end.
Stereo panning › Impulse Tracker internals and hints #
- Separation (F12): 128 for speakers close together, 80 far apart, about 40 for headphones — the listener's control, so compose at full width (s-tw075-it-percussion-tips agrees). Pan chain: channel pan, overridden by the instrument's default pan, offset by pitch-pan separation (higher notes drift right, lower left, around a centre note) — Pulse: "a very convenient way to achieve a nice pan", and avoid having too many samples at centre.
S91= surround (centre on hardware mixers),Pxyslides the pan,Yxypanbrello withS53random waveform jumps to a new random position every x frames; the GUS only has 16 pan positions (sources: s-it-manual, s-ittech, s-it-hints). - Two-channel width (Onix4MAN): the same note on two channels panned 00/64 — either offset the second by a row, or delay it with
SDx(finer, x < speed), or duplicate the instrument and give one copy a pitch envelope that dips for a tick (leaves volume and effect columns free; bad for pianos). StereoMan's flanging pair atX00/XFF("a smooth three dimensional sound") and echo pairs atX22/XDD(source: s-it-hints).
Vibrato and delayed vibrato › Impulse Tracker details #
Hxy speed x depth y; Uxy is four times finer; S3x picks the waveform (0 sine, 1 square, 2 ramp down, 3 random); Kxy adds a volume slide; H00/U00 reuse the last vibrato of either kind. IT's vibrato is updated every tick and is "two times finer" than ST3's — with Old Effects on it reverts to ST3 depth and timing. Samples also carry their own vibrato (speed 0–64, best 24–48; depth; rate = how quickly it sets in — a built-in delayed vibrato) (sources: s-it-manual, s-ittech).
Volume slides, fades and effect memory › More from the IT manual #
D0F/DF0 slide by 15 on every frame for S3M compatibility — in openmpt that behaviour is a per-song switch rather than a command trick: Fast Volume Slides applies slides on every tick "as Scream Tracker 3.0 did", so an imported S3M keeps its original slide rates (source: s-openmpt-manual-song-properties); Alt-K slides the volume column linearly between the block's ends (twice removes all volumes), Alt-X does the same for effect values (pan, offsets, global volume), Alt-J amplifies a block's volumes 0–200 %; the global volume Vxx (0–80h) affects notes already playing, unlike ST3. Keep the global volume high: at 5–8 a volume-column fade jumps instead of sliding (Nacho) (sources: s-it-manual, s-it-hints).
Iseq (Steve Judd's C64 music editor, 2002) cheat sheet
Reference
Cheat sheet#
Everything from the posts and screenshots in s-sidin01-iseq; the full key list on the help screen is only partly legible there.
| key / value | meaning |
|---|---|
ctrl-h | help, on every screen |
f1 | edit tune |
ctrl-x / ctrl-c / ctrl-p | cut / copy / paste |
shift-t | transpose |
ctrl-t | tempo (CIA timer) values |
ctrl-a | arpeggio editor (from the instrument editor) |
shift-clear | clear tune; detects PAL/NTSC and sets the default timer |
cbm + / cbm - | double / halve playback speed |
$4cc7 | first tempo value for a PAL frame ("behave just like a VIC interrupt") |
$42c6 | NTSC frame |
$417f | old NTSC with the R56A VIC (64 cycles per line) |
JSR $1003 | play call; SYS 4102 plays a tune from BASIC |
Instrument fields (the editor's names): d415 d416 d417 d418 (filter and volume registers), atdk attack/decay, surl sustain/release, pwid pulse-width list, freq fixed-frequency list, creg control-register list, frq+ frequency-add list, fixf restore the note's frequency, gate gate/control byte.
Tune notation (as printed for the Commando cover): voice rows of pattern letters with trans=n (semitones, negative allowed), gate=n, hard+; patterns of inst=n(name), dur=1(6) / dur=3(12), arp=n, gate+ / gate-, notes a1 h a1 a2 (h = hold), rest (orderlist).
Recipes from Judd: vibrato frq+ 0100 0200 0100 0000 ff00 fe00 ff00 0000 looped ("not proportional"); drum = call 1 waveform $81 at frequency $a000, call 2 $11 at $a000, call 3 $41 at the note's frequency with fixf (wavetable-programming).
Techniques
Vibrato and delayed vibrato › Iseq (2002): vibrato as an additive list #
Steve Judd's iseq has no vibrato command; an instrument's frq+ list is added to the current frequency on every player call, so a vibrato is frq+ 0100 0200 0100 0000 ff00 fe00 ff00 0000 looped — Judd's own example, with the caveat that it is "not 'proportional' — you wouldn't use the same modulations at low and high frequencies" and the upside that one list can also carry a rising frequency, an ornament or an "asymmetric" vibrato. His Commando lead uses frq+=0000 0040 0080 00c0 00c0 0080 (source: s-sidin01-iseq).
- Why Galway's middle phase is twice as long: Tognon's figure for the Arkanoid vibrato (
+$14 × 3, −$14 × 6, +$14 × 3after$1Ecycles) shows the first phase climbing from the note's pitch to the top, the double-length second phase crossing to the bottom, the third returning to the centre — "necessary for having the correct up/down sequence" — before flag$05restarts the phases from the current frequency (source: s-sidin04-galway-arkanoid).
Wavetable programming (waveform / arp tables) › Iseq (2002): the three-call drum #
Judd's description of a drum in his register-level editor iseq is the recipe every table player encodes: "1st player call: waveform=$81 freq=$a000 (or whatever); 2nd player call: waveform=$11 freq=$a000; 3rd player call: waveform=$41 freq=original value" — the instrument's fixf "restores the frequency, that's all". His Commando crash is two calls of noise at $0F82 then $1F04 with control $81, $80; crish-v1 runs creg=15 81 81 15 — triangle + ring modulation, noise, noise, back (source: s-sidin01-iseq).
JITT64 (Java Ice Team Tracker) cheat sheet
Reference
Cheat sheet#
All from s-sidin13-jitt64-tracker unless noted.
Track commands (right-click in a track cell)#
| value | meaning |
|---|---|
0..222 | pattern number to play |
REP | repeat the following sequence of commands (up to 16 entries) 2–17 times |
TR | transpose −15..+15 semitones for all following patterns |
RST | always last: index to restart from, or let the voice end |
Pattern commands ($00–$10)#
| cmd | name | parameter |
|---|---|---|
00 | Stop | bit field: 0 arpeggio, 1 portamento up, 2 portamento down, 3 tone portamento, 4 vibrato, 5 pulse up, 6 pulse down |
01 | Set Tempo | new tempo from this row; 0 = the pattern's own |
02 / 03 | Set AD / SR | $xx |
04 | Set Volume | 0–15 (starts at 15) |
05 | Set Arpeggio | bits 7–6 speed (0–3), bits 5–3 first offset, bits 2–0 second offset added to the first note (source: s-sidin13-inside-jitt64) |
06 / 07 | Portamento up / down | amount, applied ×2 per tick to the 16-bit frequency |
08 | Tone Portamento | amount, same units; target = the note on the same row |
09 | Set Vibrato | low nibble + 1 = speed in ticks, (high nibble + 1) × 16 = frequency units per tick (source: s-sidin13-inside-jitt64) |
0A / 0B | Pulse slide up / down | amount per tick on the 12-bit pulse width |
0C | Auto fade out | delay in ticks between volume steps |
0D / 0E / 0F | Filter type / resonance / cut-off | type = high/band/low + voices; resonance 0–15; cut-off high byte |
10 | Gate Sustain/Release | new SR with the gate released ("you can go up in volume level") |
Planned but not implemented in 2010: a hard-restart command, a pointer command into an instrument, note-independent ("hifi") portamento and vibrato, a vibrato slider.
Instrument: restart of note#
| field | meaning |
|---|---|
| none | no action at note change — "all is left to you for preventing ADSR bugs" |
| Gate off + N. ticks | gate bit cleared N ticks before the end of the note |
| Hard Restart + N. ticks | N ticks before the end: Attack/Decay HR, Sustain/Release HR and First Control HR are written; on the last tick before the new note, Second Control HR |
| write order | Wave–ADSR or ADSR–Wave per instrument, "for letting you obtain good hardrestart" |
N is capped by the pattern tempo (timing 3, ticks 4 → 3 effective). Test-bit recipes: (a) first control gate off, second control $09, ≥ 2 ticks, ADSR–Wave; (b) both controls gate off, 1 tick, and the instrument table's first row $09 before the real waveform, ADSR–Wave. See hard-restart.
Instrument table (127 rows, column pairs with a D/N field)#
| column | entries |
|---|---|
| D/N | delay | repeats: 0|0 one tick; 2|0 next command after 3 ticks; 2|3 = (2+1)×(3+1) = 12 ticks |
| AD, SR | $00–$FF |
| Wave | control byte $00–$FF (0 = keep) |
| Frequency | absolute note (8 octaves, hard-coded), relative note (±0–31 from the pattern note), relative frequency (±0–32768, editable — instrument-level vibrato/portamento), absolute frequency (0 = silence) |
| Pulse | fixed 0–2048 (editable) or relative ± |
| Filter cut-off | relative or absolute |
| Resonance | fixed, add or subtract, 0–15 |
| Filter type | high / band / low pass, filter on voice 1 / 2 / 3 |
"Set step to here" marks a column's loop row, "Set no step" removes it; loop count 1–255 or inf. The values behind the relative/absolute menus live in the per-instrument Table of Values (red = used), which can be saved as a library. In the player each table is a header of (length, repeats, step position) followed by (value, delay/repeat index) pairs, stepped by one macro for all eight columns (source: s-sidin13-inside-jitt64).
Player structure (source: s-sidin13-inside-jitt64)#
- Init clears the variables, pre-reads the first pattern per track, sets volume 15. The IRQ routine first copies every shadow register to the SID (all voices together, one frame of latency), then per voice from 3 to 1: Play Pattern (only when the pattern tempo has elapsed), Play Instrument (eight table cores), Play Command (continuous commands, then one-shots), and Play Hard-Restart last so that it overrides the rest.
- Instrument record:
HRbyte (low nibble = ticks, bit 7 = hard restart rather than gate off),AD,SR,CTRL1,CTRL2, then 16 table pointers (AD, SR, Wave, Freq, Pulse, Filter, Res, Type, FixFreq, RelFreq, FixPulse, RelPulse, RelFilter, FixFilter, Delay, Repeat).
Techniques
Chord arpeggio (the 0 3 7 trick) › JITT64 (2010) #
Pattern command 05: the parameter byte packs a speed in bits 7–6 (0–3 ticks between steps), a first offset in bits 5–3 and a second offset in bits 2–0 that is added to the first arpeggio note, not to the root — so $23 (offsets 4 and 3) gives root, +4, +7, a major triad; the player cycles root → note 1 → note 2, a new note in the pattern clears the command, and 00 with bit 0 stops it. Chords of more than three notes, or offsets above 7 semitones, need the instrument's relative-note column instead (sources: s-sidin13-inside-jitt64, s-sidin13-jitt64-tracker).
- matt-gray-player, the 2015 readings: in V4.2 the plex is a pattern command,
$FD ci—cnotes from tablei, so$FD,$36plays table 6 as a three-note chord and$FD,$40the first four entries of table 0 — and it persists until the next instrument or slide; Tognon's empty template offers 16 tables (nine of three notes, four of four, three of two: "95% of arpeggio are based into 3 values") (source: s-sidin14-dominator-player). The earlier Serpent Demo build keeps the arpeggio in instrument byte 5 and lists eight four-note chords with the octave on top —$00,$03,$07,$0C,$00,$04,$07,$0C,$00,$05,$07,$0C,$00,$04,$09,$0C,$00,$03,$08,$0C,$00,$05,$09,$0C,$00,$07,$0A,$0C— and one running downward,$13,$0C,$07,$00(source: s-sidin15-serpent-demo-player).
Filter programming on the SID › JITT64 (2010), two tiny players, and an 8580 trick #
- jitt64: three pattern commands —
0Dfilter type (high/band/low pass and the voices to filter),0Eresonance (0–15),0Fcut-off — and three instrument columns: cut-off relative or absolute (values from the instrument's own table), resonance fixed / add / subtract, and a type entry of six checkboxes (HP, BP, LP, voice 1, 2, 3), each with the D/N delay/repeat field; the player keeps them in shadow registers (shadow_FCH,shadow_RES,shadow_TYPE) written after the three voices. The example "filtered bass drum" moves the cut-off per tick (sources: s-sidin13-jitt64-tracker, s-sidin13-inside-jitt64). - 512 and 256 bytes: Plaster sweeps the cut-off high byte between
$3Fand$FFone step per frame with$D417 = $F1and$D418 = $3F; Back To Basics writes the same counter to$D416that it uses for pulse width, with$D417 = $F4and$D418 = $1F(source: s-sidin12-tiny-sid-2-part-3). - freedom's reason to prefer the 8580: "when you change filter type you don't get an unwanted noise as noticeable as the one you hear in 6581. This makes it possible to change filter type on an instrument while a note is being played and you get more sophisticated sounds" — but "way too open filters"; tsm adds that every 8580 sounds the same, unlike the 6581 (source: s-sidin13-tsm-freedom-interview). hermit in 2008: the 6581 "has good bass-filter behavior for older compositions", the 8580 "is more accurate" (source: s-sidin12-hermit-interview).
- Two 1980s filter policies from the SIDin interviews: matt-gray wrote no filter code until after Dominator — "I only started using them post Dominator on Vendetta … I was well aware of the filter inconsistencies and wanted to avoid using them, but eventually I needed the extra palette of sounds" (source: s-sidin15-matt-gray-interview), and elsewhere: "Initially, like others I didn't use the filters because they often sounded very different on another machine, but eventually I simply had to just to move the sound on" (source: s-vandalism63-matt-gray-interview); scarzix's 6581 had "a very light filter", so when the programmer could not hear CombatZone's leads the game got a filter on/off option in its menu (1989/90) (source: s-sidin14-scarzix-interview).
Hard restart › JITT64 (2010): hard restart as five instrument fields #
Tognon's jitt64 makes every part of the restart an explicit per-instrument setting (sources: s-sidin13-jitt64-tracker, s-sidin13-inside-jitt64):
- Three choices: no action ("all is left to you for preventing ADSR bugs"), Gate off N ticks before the end of the note, or Hard Restart — N ticks before the end the player writes Attack/Decay HR, Sustain/Release HR and First Control HR, and on the last tick before the new note Second Control HR. N is capped by the pattern tempo (timing 3, ticks 4 → 3 effective).
- A per-instrument write order, Wave–ADSR or ADSR–Wave, "for letting you obtain good hardrestart (some one need accurate write timing to be achieved)" — the choice GoatTracker makes globally with its attack-
Fplayroutine. - Two test-bit recipes: (a) HR AD/SR set, first control with the gate released, second control
$09(test + gate), at least 2 ticks, order ADSR–Wave; (b) both HR controls gate-off, one tick, and the instrument table's first row sets ADSR and wave$09before the real waveform, order ADSR–Wave. - In the player the instrument record starts with an
HRbyte (low nibble = ticks, bit 7 = full HR rather than gate off) andAD,SR,CTRL1,CTRL2; the hard-restart block runs last in the interrupt so that it overrides every other command, and the SID is written from shadow registers at the start of the next interrupt so that all voices — and the HR frame — land together; Tognon restructured the routine because variable block timing "can cause some hard-restart of note problem too". A hard-restart pattern command was still on the to-do list.
And a hard restart in 512 bytes: GRG's Tiny Sid Compo II winner Plaster writes SR $01 and AD $0F when a note's remaining duration reaches 1 — the 0F01 value — and starts every control sequence with $09 then $81 (source: s-sidin12-tiny-sid-2-part-3); the same GRG is credited above with the "soft restart".
Pitch slides and tone portamento › JITT64 (2010) #
06 xx / 07 xx add or subtract xx twice per tick ("the amount (*2)") to the 16-bit frequency until 00 (bits 1–2) stops them; 08 xx is a tone portamento entered on the same row as the target note: the player takes the new note's frequency as the target, restores the previous frequency as the start, chooses the direction by a 16-bit compare, moves xx × 2 per tick and snaps to the target when it is passed, then clears the command. Portamento at instrument level uses the frequency column's relative-frequency entries; a note-independent "hifi portamento" was planned (sources: s-sidin13-inside-jitt64, s-sidin13-jitt64-tracker).
Pulse width modulation (PWM) › JITT64 (2010) and the 512/256-byte players #
- jitt64: pattern commands
0A xx/0B xxadd or subtractxxper tick to the 12-bit pulse value (carry into the high byte, no bounds) until00with bits 5–6 stops them; in the instrument table the Pulse column takes fixed values (0–2048, from the instrument's own value table) or relative steps, the D/N field setting how many ticks each step holds and repeats — that is how the example instruments do "a 'vibrato' to the pulse" (Emil's string, a Dane lead, Matt Gray's bass) and "a 'portamento' onto the pulse" (the filtered bass drum, the other Dane lead) (sources: s-sidin13-jitt64-tracker, s-sidin13-inside-jitt64). - The 2005 512-byte entries are three variations on a free-running counter (source: s-sidin08-tiny-sid-512b): Crue Gurl steps the pulse high byte for voices 1 and 3 from
pwmMin = 3topwmMax = 6every four frames, wrapping — with the source's own warning that the step counterpwmSpeed = 3 ; must be (n^2)-1!!!!because the code masks rather than compares; laxity's Twone Five gives each voice a start high byte (pulsehi $08,$01,$04) and adds a per-voice constant (pulseadd $00,$10,$3d) to the low byte at every SID write, so voice 3 sweeps fast and voice 1 not at all; 4mat's Empty makes it an instrument parameter — oneinstaddbyte per instrument ($1c,$0c,$00,$15,$00,$74,$a5) added to the pulse low byte each frame, with the pulse high byte packed into the low nibble ofinstpuls. - In GRG's 512-byte Plaster the pulse low byte of each voice is simply incremented by
$18every frame from high bytes$08,$08,$04— a free-running sweep with no bounds; in Jaymz Julian's 256-byte Back To Basics one counter, incremented every four loops, is written as the pulse high byte of all three voices with the voice offset added, and as the filter cut-off at the same time (source: s-sidin12-tiny-sid-2-part-3).
- matt-gray-player V4.2: the bounce limits became part of the instrument — byte 14 holds them as nibbles
$LH, i.e. between$0Lxxand$0Hxx($8E= the Driller$08–$0E;$33keeps the width "around"$03xx;$35=$0300–$0500); byte 0 is the start width as swapped nibbles ($23→$0320), byte 4 the per-frame step. Tognon's worked example: start$0320, step$A0, limits$18→ 800, 960, 1120 … 2080, then down to$01xxand back (source: s-sidin14-dominator-player).
Vibrato and delayed vibrato › JITT64 (2010) #
Command 09 xy: y + 1 ticks per leg, and each tick adds or subtracts (x + 1) × 16 to the raw 16-bit frequency; the first leg lasts one speed count and the following ones two (plus the reload tick), so it starts with a half period — a triangle on the register value, deeper in cents at low pitch like the matt-gray-player's and unlike Bjerregaard's semitone-proportional one; 00 with bit 4 stops it, and a "hifi vibrato … independent from octave/note" was planned. Instrument-level vibrato goes in the frequency column as relative-frequency entries timed by the D/N delay field (sources: s-sidin13-inside-jitt64, s-sidin13-jitt64-tracker).
- matt-gray-player V4.2 adds a per-note vibrato delay: pattern byte
$F9 nncounts down before the instrument's vibrato (step in row byte 8, length in byte 9, the same down / up / up / down / down triangle as Driller) starts (source: s-sidin14-dominator-player). Gray in 2015: "My vibrato routine was very different to his [Hubbard's] and Martin Galway's" (source: s-sidin15-matt-gray-interview).
Wavetable programming (waveform / arp tables) › Two more starts: Plaster's $09,$81 and JITT64's noise drums #
- GRG's 512-byte Plaster keeps its "wavetables" as three control-register sequences shared by five instruments —
$09,$81,$41,$00,$09,$81,$11,$11,$11,$11,$11,$00,$09,$81,$41,$40,$40,$80— every sound opening with a test-bit frame and a noise frame, and a parallel list supplying fixed high-frequency bytes ($8B,$89,$86,$84,$8E,$8C,$8A) for the drum steps (source: s-sidin12-tiny-sid-2-part-3). - jitt64's wave column is one of eight per-instrument columns with a delay/repeat field per row (0 = keep the waveform); its example bank builds bass drums and Matt Gray's snares from "fixed notes" in the frequency column and noise in the wave column, a second bass drum with "more low pitch notes and less noise", and a sea effect from noise with a very long attack/decay and no sustain (source: s-sidin13-jitt64-tracker).
Johannes Bjerregaard's player cheat sheet
Reference
Cheat sheet#
All from the two sources (source: s-realdmx-bjerregaard-player).
Song → tracks → patterns: a song is 8 bytes — !by voices,tempo / !wo V0,V1,V2 (tempo = frames per tick − 1); a track is a list of pattern numbers with prefix bytes; a pattern is a byte stream.
| track byte | meaning |
|---|---|
$00–$7f | pattern number |
$80–$fd | transpose (byte & $7f) − $40 ($c0 = 0, $cc = +12, $bc = −4) |
$fe | stop |
$ff | restart all three voices |
| pattern byte | meaning |
|---|---|
$00–$5f | note (+ transpose); $00 = silence in Myth |
$60–$7f | select arpeggio / note program |
$80–$9f | select instrument |
$a0–$bf | glide speed; next byte = target note |
$c0–$df | note length in ticks ($c0 = 1, $c7 = 8) |
$e0–$fb | rest of that length |
$fc | tie (legato) — working in Myth |
$fe xx | Myth only: override sustain/release for the following notes ($fe,$39) |
$ff | end of pattern |
Example (JB3 S0B): $E1 / $C1,$88,$34,$39,$3B / $3C,$E1,$3E,$E1,$C2 / $A2,$3C,$3B ….
Instrument = 8 bytes — JB3's header ;0=ATK/DCY ;1=SUS1/REL ;2=VIB1 ;3=PULSE/DLY ;4=NOTES ;5=FILTER ;6=WAVES ;7=VIB2/SUS2:
| byte | JB3 | Myth |
|---|---|---|
| 0 | attack/decay | attack/decay |
| 1 | sustain/release (low nibble kept as the note's release) | sustain/release (overridable by $fe) |
| 2 | vibrato: delay (hi nibble × 2 frames), half-period (lo) | vibrato delay/speed |
| 3 | pulse program (lo) + auto-release delay (hi × 2 frames) | pulse-program offset from p0 |
| 4 | default arpeggio/note program | note-program selector; bit 7 = "shutup notes" (hard restart) |
| 5 | filter program (lo) + vibrato ramp-in (hi × 4 frames) | filter-program offset from f0 |
| 6 | waveform program (lo) + second-sustain delay (bits 5–7, frames) | wave-program offset from w0 |
| 7 | vibrato rate (lo) + second sustain level (hi nibble) | vibrato rate (lo) + ramp-in (hi × 4) |
Rows: ;GUITAR $08,$6C,$79,$02,$04,$80,$05,$01 · ;DRUMM $06,$A9,$00,$00,$03,$00,$01,$00 · ;MELODY $06,$50,$17,$04,$04,$20,$07,$51 · ;JEROEN PLOINK $08,$86,$17,$00,$04,$20,$08,$23 (JB3); ;chord $02,$79,$19,p0-p0,$84,f0-f0,w0-w0,$00 · ;bazedrum $08,$66,$00,p1-p0,$05,f0-f0,w2-w0,$00 (Myth).
Programs (one byte per frame; byte 0 = repeat point; JB3 $FE keep last / $FF repeat, filters $7E/$7F; Myth only $ff):
| kind | format | examples |
|---|---|---|
| waveform | control bytes | W0 ;BASSDRUM $01,$81,$41,$40,$FE · W5 ;GUITAR $01,$43,$43,$43,$40,$FE · Myth w2 ;bazedrum $01,$81,$41,$11,$40,$40,$40,$40,$40,$80,$ff |
| note / arpeggio | < $80 semitone offset, ≥ $80 absolute note; JB3 with bit 7 in byte 0 = raw $D401 bytes | N0 $01,$04,$04,$00,$FF · N2 $81 / $58,$08,$06,$04,$03,$02,$03,$04,$03,$FE (drum sweep) · Myth n0 $07,$03,$00,$07,$ff (minor) |
| pulse | byte 1 = initial width, then (delta, frames) pairs, bit 7 of the delta = add | P2 ;GUITAR $01,$E0, $C0,$01, $B0,$01, $A0,$02, $10,$03, $08,$04,$FE · Myth p1 ;skwear polls waive $08,$00,$7f,$ff |
| filter | byte 1 = cutoff, byte 2 = $D418 mode nibble, then signed (delta, frames) on one global cutoff; resonance fixed at $F | F1 $01,$80,$10, $F0,$06,$7E · Myth f1 ;filterbass $90,$10,$d0,$03,$00,$7f,$ff |
Envelope tricks: JB3 — after N frames the gate is dropped and raised in one frame with AD = 0 and a new sustain nibble (second sustain), then auto-released after 2 × M frames; ADSR zeroed two ticks before every note, $F0 to the control register one tick before, $09 (test + gate) on the note frame. Myth — ADSR zeroed one tick early only for "shutup" instruments; no test bit (mask $f7/$f6); bit 3 of a wave entry forces pulse width $0800; AD/SR rewritten every frame (hard-restart, adsr-envelope). Vibrato depth = the semitone distance from the frequency table shifted by the rate — constant in cents (vibrato).
libLSDj cheat sheet
Reference
Cheat sheet#
| command | does |
|---|---|
lsdsng-export -p saves | print the songs of every .sav in a folder (WM = the song in working memory); > songlist.txt keeps a master list |
lsdsng-export saves/X.sav | write every song of the save as .lsdsng |
lsdsng-export -f saves | one folder per song name — collects every version of a song from all backups |
-o FOLDER | output folder (created if missing) |
-n NAME, -i INDEX | select songs by name or 0-based index; repeatable and combinable |
-w | export the working-memory song (recovers unsaved work) |
lsdsng-import a.lsdsng b.lsdsng | build out.sav; -o mysave.sav names it; -s mysave.sav appends to an existing save |
lsdsng-import songs | folder → songs.sav, in file-name order (rename to order a live set) |
lsdj-wavetable-import file.sav synth.snt 0 | patch a .snt wavetable into synth slot 0 of the working-memory song (or of an .lsdsng) |
| no arguments | prints the tool's help |
On Windows, files can be dragged onto the executables (source: s-intense-tech-04-liblsdj). .snt files come from lsdj-wave-cruncher or the lsdjsynths library (sources: s-intense-tech-05-wave-cruncher-instrument-library, s-intense-tech-08-dotcnts-wave-cruncher).
LSDj (Little Sound Dj) cheat sheet
Reference
Screens (SELECT+CURSOR moves between them)#
Project Synth Wave
Song Chain Phrase Instr. Table
Groove
This two-row map dates from version 8 (three rows before); going up returns to the top-row screen last used — up from Song always opens Project, up from a G command the Groove screen (source: s-intense-tech-14-lets-appreciate-version-8). Hidden screens: file, word (speech), help. START plays the current screen's channel; in the song screen, or with SELECT+START, all four. A,A on any parameter or command shows quick help.
- Song — four columns (PU1 PU2 WAV NOI) of chain numbers, played top-down.
Atwice on an empty step creates a new chain/phrase;B+Aon an empty step pulls chains up; mark rows withB,B,Band jump withB+UP/DOWN;B+LEFT/RIGHTpans a channel. - Chain — list of phrases, each with an optional transpose (semitones). Chains are shared between channels; playing one chain on both pulse channels is a classic (detune).
- Phrase — 16 steps of note · instrument · command · value. Phrases are shared between channels.
A+LEFT/RIGHTchanges note,A+UP/DOWNoctave;B+Adeletes; cut the instrument column withB+Ato change a note without retrig (legato). KIT/SPEECH instruments show sample names; NOISE shows a byte value (15-bit) or note (7-bit). - Instrument, Table, Groove, Synth, Wave, Project, File — see below.
Instruments#
Five types; the type must match the channel: PULSE (PU1/PU2), WAVE and KIT (WAV), NOISE (NOI), SPEECH (instrument 40, WAV).
Common parameters: NAME · TYPE · LENGTH · OUTPUT (L/R/both/none) · PITCH — how P, L, V behave: FAST (360 Hz updates), TICK (per tick, vibrato synced to the music), STEP (P sets pitch instantly), DRUM (logarithmic fall-off for kicks); A+L/R picks the vibrato shape (triangle/saw/square, up or down) · TRANSP. (obey chain/project transposes) · CMD/RATE (slows C/R, and P/V in TICK mode; 0 fastest, F slowest) · TABLE (table to run on every note; TICK/STEP — STEP advances one table row per trigger).
The instrument number is the trigger — the note is not (source: s-painperdu-01-instrument-retriggering). "You don't necessarily need to have an instrument value next to a note for it to produce sound": a bare note plays with whatever settings are already running, while the instrument number "reads the settings from here and triggers it every time it reads the instrument value". Everything the instrument owns restarts with it — the envelope, the table, and on WAV the synth's whole wave cycle. Three consequences that shape how songs are written:
- Omitting it is legato. A note without the instrument number does not restart the envelope or the table, which is the general rule behind the slur trick in the phrase screen (lead-articulation).
- Tables advance per trigger, not per tick, when the instrument's TABLE mode is set to do so (the manual's
STEP; the version Pain Perdu demonstrates calls the mode AUTOMATE). So the classicL/Rpanning table gives L R L R when every note carries the instrument number and L L R R when only every second one does — the same table, a different rhythm (stereo-panning). - A slow wave cycle is never heard in full if every note retriggers it. A WAVE instrument at PLAY PINGPONG, LENGTH
Fand a slow SPEED evolves over many notes, but "I cannot actually hear the full range of wave cycles" unless it is triggered sparsely. And since kicks usually share WAV, a kick retriggers the lead when it returns — so size the cycle to the gap: LENGTH3at SPEED6completes between 16th-note kicks.
| type | own parameters |
|---|---|
| PULSE | ENV. = three amplitude/speed pairs (32/AD/10: attack from 3 to A at speed 2, slow decay to 1, hold; speed 0 = hold, 1 fastest); WAVE (duty); SWEEP (PU1 only: time digit, pitch ± digit); PU2 TSP. (transpose PU2); FINETUNE (PU1 down, PU2 up) |
| WAVE | VOLUME 0/25/50/100 % + output; FINETUNE; WAVE or SYNTH; PLAY MANUAL/ONCE/LOOP/PINGPONG; SPEED; LENGTH; LOOP POS |
| KIT | two KITs (left and right note columns); VOLUME; FINETUNE; OFFSET; LEN (ALL = whole sample); LOOP OFF/ON/ATK; SPEED full/half; CLIP HARD/SOFT (tape-like)/FOLD/WRAP, A+(LEFT,LEFT) on HARD = raw memory mix |
| NOISE | ENV. as pulse; PITCH FREE (pitch changes may randomly mute) / SAFE (restart after pitch change) — introduced in 9.1.3 in place of S MODE FREE/STABLE: FREE equals the old STABLE (restart only when going from long-loop to short-loop noise), SAFE restarts on every change and never mutes; TRANSP. setting since 9.2 (source: s-intense-tech-21-whats-new-in-lsdj-92) |
| SPEECH | 14 word slots W-0…W-D built from 59 allophones in the word screen (allophone + duration per row) |
The 22 stock kits, read from a 2014 extraction of the ROM: AA-EL ACIEED ANIMLZ CR-78 CR8000 DMX DR-55 DR-110 DRUMUL EL-KK2 GHETTO KK3-TH KR-55 LINNDR RHYACE TOM TR-606 TR-707 TR-727 TR-808 TR-909 TT-ZZ — mostly drum machines under LSDj's short-name limit, and available as plain WAVs along with a louder TR808L rebuild (source: s-little-scale-lsdj-kit-releases; kit preparation is on chip-samples). The budget a kit has to fit: 3FA0 bytes, "just over two seconds worth of audio per kit", at 11,468 Hz / 8-bit / mono, with each sample named in three characters because that name is what LSDj shows. Two tool quirks worth knowing before blaming a sample: a longer-than-two-second sound can be sped up 2× in the editor and played back with the kit instrument's SPEED at half; and the patcher's preview lies — a click at the end of a long sample "in my experience there is always that click in longer samples when played inside the patcher only. When the kit is loaded into LSDJ and played back on the Game Boy there is no noticeable click." On the perennial complaint that the stock kits are too quiet, the forum's settled answer is turn the other channels down rather than fight it — "if you have the wave instrument volume at 3 already, there's not much else you can do" — or rebuild the kits with gain pushed past normalisation (sources: s-little-scale-lsdj-kits, s-chipmusic-lsdj-kit-threads; levels-and-headroom). The SPEECH instrument's 59 allophones are the same count as the General Instrument SP0256-AL2's complete sounded set, of which little-scale released a sample of every one; no source connects them and the correspondence is (unverified) (source: s-little-scale-chip-sample-packs).
SPEECH in practice (source: s-chipmusic-lsdj-speech-synthesis): slow, unforgiving — "you can't delete wrong letters" — and best scoped to a phrase or a hook rather than a monologue. The workflow that makes it bearable is to write the line in an outside speech program (STSPEECH on an Atari ST emulator) and transcribe the allophones it produces. Intelligibility is a mixing problem: keep the speech centred and pan everything else away from it, and space the syllables musically instead of on every tick.
Sample kits shipped: SP0256-AL2 speech, Roland TR-606/707/727/808/909, CR-78, CR-8000, Boss DR-55/DR-110, E-mu Drumulator, Oberheim DMX, Korg KR-55, LinnDrum, Ace Tone Rhythm Ace FR-1, Sequential Tom, "Acieed" house vocals, "Animals". Kits, fonts, palettes and songs are replaced/managed with lsdpatch (LSDPatcher), which since 2021 also imports and exports songs as .lsdsng and .lsdprj (song plus the kits it uses) and resamples new kit samples with dithering and a fix for the wave-RAM refresh bug (source: s-intense-tech-20-lsdpatch). Sampled tonal instruments take another route: lsdj-wave-cruncher turns a one-note sample into a 16-frame wavetable that liblsdj's lsdj-wavetable-import patches into the save, playable at any pitch (sources: s-intense-tech-05-wave-cruncher-instrument-library, s-intense-tech-08-dotcnts-wave-cruncher).
Tables#
Six columns: envelope (amplitude digit + ticks; loop by putting the target step in the first digit and H in the second — e.g. tremolo), transpose (semitones; the classic table arpeggio), and two command + value pairs. Default speed one tick per step; a G command placed inside a table sets that table's own speed — little known, and it halves what a slow arpeggio costs: "if I wanted to make a long arp that actually took two tables to make, that was a bit of a hassle; thanks to that trick I can now use half the space and control exactly how fast my tables go" (credited to Joe Toye of Chiptune Belgium; source: s-painperdu-06-grooves). A faster groove does the reverse, packing more commands into the same time for percussion. Started by the instrument's TABLE setting or by Axx in a phrase (A20 stops); SELECT+RIGHT on an A command edits that table; B+CURSOR browses tables. See instrument-tables.
Grooves#
Ticks per step for phrases and tables. Default groove 0 = 6/6; at 125 BPM a tick is 1/50 s. 8/5 = swing; A+UP/DOWN changes the swing percentage keeping the total ticks (6/6 = 50 % → 7/5 = 58 %); triplets and odd rhythms likewise. Gxx selects a groove; SELECT+DOWN on a G command edits it. Because grooves are per channel, arpeggios can live in phrases rather than tables — "if you're like me and you overuse tables for arps, using grooves and phrases might be a better idea" (source: s-painperdu-06-grooves). See shuffle-funktempo.
Synth and wave screens#
16 synth sounds × 16 waves (sound 0 = waves 00–0F). Fixed settings: SIGNAL square/saw/triangle/custom (W.FX uses a wave in F0–FF), FILTER low/high/band/all-pass, DIST CLIP/FOLD/WRAP, PHASE PINCH/WARP/RESYNC/RESYN2. Variable settings with a smooth fade from first to last wave: VOLUME, CUTOFF, Q, VSHIFT, LIMIT (0–F lowers volume, 10–FF wraps for overtones), PHASE. The wave screen edits individual waves. See wavetable-programming; for two notes drawn into one wave, ghost-channel.
The instrument side of the synth (sources: s-painperdu-02-wav-channel-walkthrough, s-defensemech-learning-lab-shorts):
- LENGTH is how many of the sixteen waves the cycle uses, LOOP POS (older REPEAT) how many frames at the end of that cycle repeat afterwards — "if you play with this cleverly you can have really interesting rhythmic wave cycles" — and SPEED is ticks per frame, which belongs to the groove rather than to taste: SPEED
6under groove6/6advances one wave per step, SPEED5under5/5, and so on. SPEED1"is more clipping than actual modulation". - MANUAL is the quiet play mode because only one wave is ever read, so no frame change occurs.
- Hand-drawn waves are not restricted to MANUAL — "one of the most common misconceptions is that the hand-drawn waves in LSDj are only accessible when you set this to MANUAL … [they] are available even when you're in PINGPONG and LOOP and ONCE".
Foffsets that run past a synth's sixteen waves bleed into the next synth's waves, which is a way to make one note evolve out of its own timbre — andF10steps a whole synth, so two synths chain into a 32-frame animation.Fis relative and accumulates:F05 F05lands on frame0A. A smallFis also a variation trick in its own right:F3on a three-frame bass "offsets the wave cycle" so the note does not start at its quietest, and different offsets on successive hits "makes a bit of differentiation to something that's really four-to-the-floor, really repetitive" (source: s-painperdu-03-isometric-sav-walkthrough).- VOLUME and LIMIT are not two volume controls. VOLUME scales the signal before the rest of the chain, so turning it down destroys the clipping or wrapping that made the sound — "you can't get it to wrap if the volume isn't high" — while LIMIT constrains the dynamic range afterwards and keeps the shape. There is no LIMIT command for the phrase screen, so different levels mean different synths.
- VSHIFT is to DIST what Q is to the filter: with CLIP it merely squashes the wave against the ceiling ("a sound-bad button"), but with FOLD or WRAP the shifted part folds or wraps back in and "that's almost like a pulse-width modulation thing happening".
- Which end of CUTOFF is bass:
00is the low end andFFthe high, which is why a high-pass instrument left at the defaultFFseems to go silent — "the cutoff is happening at the highest point" (source: s-chipmusic-lsdj-wav-instrument-tutorials). - Re-entering the synth screen regenerates all sixteen of that synth's waves, so copy any hand-drawn frame you mean to keep before touching it; later versions warn first, older ones do it silently. In the WAVE screen a whole wave (or part of one) copies with
SELECT+Btwice and pastes withSELECT+A, which is what makes a hand-drawn bank affordable at all (sources: s-chipmusic-lsdj-wav-channel-release, s-lsdj-and-you-pwm).
What LENGTH actually does (source: s-defensemech-wave-channel-ramble — the author's own chart, not in the manual): a synth always travels from wave 0 to wave F; LENGTH sets how many waves in between are generated, spread evenly, so a shorter LENGTH covers the same sweep in fewer, faster steps.
| LENGTH | waves | LENGTH | waves |
|---|---|---|---|
0 | 0 | 8 | 0 1 3 5 7 9 B D F |
1 | 0 F | 9 | 0 1 3 5 7 8 9 B D F |
2 | 0 7 F | A | 0 1 3 4 6 7 9 B C E F |
3 | 0 5 A F | B | 0 1 2 4 5 7 8 A B D E F |
4 | 0 3 7 B F | C | 0 1 2 3 5 6 7 9 A B D E F |
5 | 0 3 6 9 C F | D | 0 1 2 3 4 6 7 8 9 B C D E F |
6 | 0 2 5 7 A D F | E | 0 1 2 3 4 5 6 7 9 A B C D E F |
7 | 0 2 4 6 9 B D F | F | 0 1 2 3 4 5 6 7 8 9 A B C D E F |
Two notes out of one channel, the ghost-channel, has two recipes: draw a second waveform at 2× or 3× the fundamental on top of the first (sources: s-chipmusic-lsdj-ghost-channel, s-tylerbarnes-ghost-channel-tutorial), or reach the same overtone emphasis with an allpass filter at a low CUTOFF and a high Q — "no matter how much you boost this Q you really never lose the root note", where lowpass isolates the fifth but loses the edge (source: s-defensemech-ghost-channel-allpass).
Drawing waves rather than generating them is its own school, with rules of its own: the wave's overall height is its volume, and "the more angular the wave, the sharper its edges, the sharper and harsher the sound is". roboctopus's LSDJ & You posts are the introduction — an angular saw, a one-sample pulse for arps, a notched sine bass, a hand-narrowed sixteen-wave PWM bank — and his general method is that the picture is the spec: "if you hear a cool waveform you want to replicate in LSDJ, an easy way to achieve it is to do a google image search … and just try to approximate the shape in the WAV screen" (sources: s-lsdj-and-you-collapse-of-the-waveform, s-lsdj-and-you-pwm, s-lsdj-and-you-supersaw-bass; the recipes are on wavetable-programming). His mixing note is the one that keeps coming back: the wave channel is quiet by design, so bring the others down to it — "I rarely have anything on pulse above A8" (levels-and-headroom).
The other roboctopus staple is an echo built as an instrument: the same sound at lower volume with a shorter envelope, typed into the gaps, lagging the melody by two note positions rather than one; pan it, or table-pan it side to side; and a one-tick offset on PU2 with PU FINE TUNE 2 is a chorus rather than an echo (source: s-lsdj-and-you-echo-chamber; fake-echo). Wave-channel dynamics finer than E01/E02/E03 come from ramping LIMIT across a synth, which also makes the instrument duck and recover on every note — the sidechain-pump LSDj has no compressor for (sources: s-defensemech-learning-lab-shorts, s-painperdu-04-sidechaining).
Commands (phrases and tables)#
| cmd | name | effect |
|---|---|---|
Axx | table | start table xx; A20 stop |
Bxy | MayBe | phrase: probability of playing (x = left kit, y = note/right kit; B08 ≈ 50 %); table: hop to row y with probability x — new in version 7 (source: s-intense-tech-12-scoping-out-new-features) |
Cxy | chord | arpeggio base, +x, +y: C37 minor, C47 major, C0C, CC0, CCC; C00 reset; slowed by CMD/RATE; on noise since 9.1.0, limited to the noise notes (F 5 + C12 = F, G#, C) (source: s-intense-tech-19-new-noise-and-910-news) |
Dxx | delay | delay the note by xx ticks |
Exy | envelope | pulse/noise: x initial amplitude, y release (0/8 none, 1–7 decrease, 9–F increase); wave: E00–E03 = 0/25/50/100 % |
Fxy | frame/finetune | pulse: x = PU2 TSP, y = finetune in 1/32 semitones; kit: sample position (00–7F forward, 80–FF back); wave: relative wave frame (F10 = next synth sound) |
Gxx | groove | select groove |
Hxy | hop | phrase: H00–H0F next phrase at step y; H10–HFE hop back x times to step y; HFF stop; table: loop x times (0 = forever) to step y, nestable. Waltz: H00 on step C |
Kxx | kill | stop instantly (click) or after xx ticks; click-free alternatives E00 (wave) / E11 (pulse, noise) |
Lxx | slide | slide to the note over xx (ticks if PITCH = TICK, else xx/360 s); in tables the transpose column sets the target |
Mxy | master volume | x left, y right: 0–7 absolute, 8 none, 9–B up, D–F down (M77 max) |
Oxx | output | pan channel L / R / both / none |
Pxx | pitch bend | speed (PFE = −2); DRUM log, FAST linear, TICK per tick, STEP instant; noise: sweeps the noise notes — since 9.1.0 P01 applies S01 every 4 ticks and P04 every tick (source: s-intense-tech-19-new-noise-and-910-news) |
Rxy | retrig/resync | x volume change (1–7 up, 9–F down), y rate (1 fastest, F slowest, 0 once); R8x resync at high rate (R80 360 Hz, R8F stop; pulse quirk: half an octave deeper); RF4 = echo; R8x came with version 7 and takes a pulse kick about three whole tones below the channel's normal range (source: s-intense-tech-12-scoping-out-new-features) |
Sxy | sweep/shape | pulse: frequency sweep (x time, y pitch ±; PU1 only); kit: loop offset/length; noise: shape (relative) |
Txx | tempo | T28–TFF = 40–255 BPM, T00–T27 = 256–295; exact for 6-tick grooves, else bpm = desired × ticks/step ÷ 6 |
Vxy | vibrato | x speed, y depth in semitones (0=0.125, 1=0.25, 2=0.375, 3=0.5, 4=0.75, 5=1, 6=1.5, 7=2, 8=2.5, 9=3, A=3.5, B=4, C=5, D=6, E=7, F=8); V00 off; on noise since 9.1.0 (always tick-based); since 9.1 the TICK-mode speeds match phrase steps — V0x = 16 steps, V1x = 12, V2x = 32/3, V3x = 8, V4x = 6, V5x = 16/3 … VFx = ½ (source: s-intense-tech-19-new-noise-and-910-news) |
Wxy | wave | pulse: duty (resets the LENGTH timer — hardware oddity); wave: x synth speed, y length |
Zxy | randomize | repeat the last non-Z/H command adding random 0..x / 0..y to its digits — every command except H since version 8 (source: s-intense-tech-14-lets-appreciate-version-8); worked examples in randomization-and-probability |
Editing, cloning, workflow#
B+A cut · SELECT+A paste · SELECT+B + cursor marks a block (SELECT+(B,B) column/row, SELECT+(B,B,B) screen) · A+CURSOR on a marked block changes all values (quick transpose) · SELECT+(B,A) clones a chain/phrase/instrument/table/synth · deep cloning copies the phrases, slim cloning reuses them (project screen) · B+SELECT mute, B+START solo · CLEAN SONG DATA / CLEAN INSTR DATA merge duplicates and free memory · project screen: TEMPO (tap A to tap-tempo), TRANSPOSE, SYNC, CLONE, LOOK, KEY DELAY/REPEAT, PRELISTEN, HELP, WORKED/PLAY/TOTAL clocks · file screen: up to 32 songs, 512-byte blocks, BF blocks = 97,792 bytes, songs compressed on save; SELECT+A loads without leaving the list, START plays — handy for live sets · SELECT+A+B on LOAD/SAVE = total memory reset · back up your songs: cartridge batteries die.
The rule behind all of it (source: s-painperdu-05-shortcuts-and-workflow): "everything you can highlight you can copy, paste and cut, and every value you can select you can clone" — chains, phrases, instruments, tables, transposition values, commands, whole screens, individual table columns, and waveforms. Four things the manual states but few people use:
- Which clone. Slim cloning "clones only the chain but keeps the phrase value intact" — right for a one-note variation or an octave change; deep cloning "clones the chain and clones every phrase inside it" into the next free slots — right when you mean to rework every phrase, "but be careful about not running out of phrases".
- The clipboard survives loading another song ("a feature since version 3 something") — but it carries values only, not what they refer to: chain
1Bpasted into a second song points at that song's1B. It works properly when both songs come from the same template save, "then you copy paste this into your new song, then it'll sound great", which he names as the easy way to build a remix. - Marking is navigation, not selection.
B,B,Bin the song screen marks a block so intro, break, riser and drop are identifiable at a glance mid-set — "it's in the manual but not a lot of people know about it". The number of marks is limited, so spend them. - Live transposition applies on release. In the project screen, hold
Aand press the arrows: the new TRANSPOSE value takes effect only whenAis released, so a key change lands exactly on a bar line — "now I have modulated my whole track one semitone up". The same hold-and-release applies to TEMPO. Caveat: "Lcommands and other pitch bends can react differently, and low notes can wrap to the next octave if you're not careful."
Also: paste blank space rather than cut when separating sections — cutting shifts everything after it and "can screw up your alignment".
Files, tools and cartridges#
- Files:
.sav— a cartridge's or emulator's save (up to 32 songs, one in working memory);.lsdsng— one song;.lsdprj— a song bundled with the kits it uses, the sharing format since LSDPatch's song manager;.snt— a wave-synth wavetable forlsdj-wavetable-import;.lsdpal— a palette (sources: s-intense-tech-04-liblsdj, s-intense-tech-05-wave-cruncher-instrument-library, s-intense-tech-20-lsdpatch). - Tools: lsdpatch (ROM upgrade, kits, fonts, palettes, songs), liblsdj (
lsdsng-export,lsdsng-import,lsdj-wavetable-import), lsdj-wave-cruncher (sample → wavetable); the older LSDManager by johan-kotlinski is superseded (source: s-intense-tech-20-lsdpatch). - Hardware: a flash cartridge with 128 kB SRAM or FRAM — Everdrive GB X5, insideGadgets' carts with the GBxCart flasher; "LSDJ cartridges" on auction sites are unlicensed bootlegs, since the licence forbids selling LSDj on cartridges (source: s-intense-tech-16-cartridge-family; details on game-boy).
- Emulators for 9.2 and later: BGB 1.5.9 or newer, SameBoy, Gambatte, Emulicious — others get the new envelopes wrong (source: s-intense-tech-21-whats-new-in-lsdj-92).
- Inside the ROM: the note column is indexed into a table of game-boy-apu period values, and it is patchable. In 3.8.9 (a 1,048,576-byte ROM) there are two of them, back to back: 216 bytes = 108 notes at
$6D3Afor GB / GBC / GBA, and a second 216 bytes at$6E12recomputed for the Super Game Boy's 2.4 % fast clock. The first bytes of the standard table are2C 00 9C 00 06 01— 12-TET from C2, little-endian. Overwrite them and every note in the tracker moves (rom-retuning, alternative-tunings); the offsets change between versions, and applying the 3.8.9 table to 4.0.5 has been reported to stop a cartridge booting (source: s-little-scale-lsdj-tuning-tables, s-little-scale-underclocking-and-retuning). abrasive'slsdj_tunedoes the same job from the command line, and also rewrites the displayed note names (source: s-little-scale-abrasive-lsdj-tune). Two caveats a retuner meets immediately, from the worked koto retune: a ratio-based scale with fewer than twelve degrees maps several adjacent semitone keys onto the same pitch (the hirajoshi 2 mapping runs 2, 3, 2, 3, 2 keys per octave), and the bottom of the range does not exist — every frequency below about 64 Hz produces a negative period value, so a retuned ROM's lowest octave and a half is unplayable garbage (game-boy-apu) (source: s-little-scale-koto-tuning). The routes into microtuning, as of December 2009:lsdj_tune, "a simple spreadsheet and a hex editor", and the same treatment for nanoloop (source: s-little-scale-microtonal-compilation; alternative-tunings, rom-retuning). - Reading the ROM as audio. The same file the tuning tables live in also holds the kit samples, and the generic way out is Audacity's
File > Import > Raw Data— for a Game Boy Advance ROM, signed 8-bit PCM · no endianness · mono · offset 0 · 100 % · 12000 Hz — then look for "an area of the ROM (in the form of the audio waveform) that looks significantly different to the rest of it". "A similar process can be used for many different types of ROMs" (source: s-little-scale-rom-sample-extraction; chip-samples).
Live mode and sync#
SELECT+LEFT toggles live mode: START starts the selected chain(s), SELECT+START stops them, LEFT+START starts a whole row; changes are queued until the playing chain (or, with a double press, the phrase) finishes.
What live mode is actually for (source: s-chipmusic-lsdj-live-performance): not muting, but per-channel queueing. In song mode every channel advances in step; in live mode "you can queue up, in each individual channel and independently of the others, a chain anywhere before or after the one currently playing … So PU1 can be playing the chain at position 01 while PU2 plays the chain at position 2F" (Bit Shifter). The technique built on that is chain-loop islands: the live sequencer stops rewinding as soon as it hits an empty step, so blocks of chains separated by empty rows each cycle on themselves — "you can be assured that a bassline will only cycle through the parts you want it to, rather than continuing on and advancing through the rest of the song. Until you TELL it to." pain-perdu reaches the same song-screen layout from the workflow side: empty rows between sections air the screen out visually and buy thinking time, "if I'm looking for the next section to jump to, I have time to decide" (source: s-painperdu-05-shortcuts-and-workflow). Chains of deliberately mismatched lengths, left to cycle, then generate material nobody wrote — "string quartet-like" — and H turns the mismatch into polyrhythm. Design the save for the set before the gig; see live-tracking and orderlist. (The chain-loop passage is quoted from an older edition of the manual, "3.5.1 Chain Loops"; the 9.2.6 manual's current wording and section number have not been checked (unverified).)
In use from the start. goto80 "made one of the first Gameboy live performances with LSDj together with Role Model" around 2001, and Wikipedia calls him "an early adopter of live Game Boy music"; when his laptop broke before a Gothenburg show in 2007 he played the whole set on a Game Boy (sources: s-wikipedia-goto80, s-goto80-site-defmon-posts). Sync modes: LSDJ (two Game Boys on a link cable, LEAD/SYNC/WAIT, clipboard transfer between them), MIDI, ANALOG IN/OUT, KEYBD — see sync. A C64 running defmon can act as LSDj's sync master through Scannerboy's user-port adapter, which outputs the LSDj sync signal among others — it shipped on 2015-03-07 at 36 EUR, handling LSDj sync, nanoloop sync, MIDI clock, DIN sync and 24–2 ppqn analogue clock, with a second batch in 2017 (sources: s-defmon-wiki-sync-and-stereo, s-chipmusic-defmon-thread).
On the wire: LSDj syncs on the link connector's SC (serial clock) pin — nanoloop uses SI instead — with a 22k–100k pull-down to ground on the slave side. In master mode it drives that same line at 32 clock transitions per sixteenth-note step, enough for a plain CMOS counter to run an LED or a step sequencer off it. Slaved to an external MIDI clock a DMG tracks "from around 35 to over 200 beats per minute"; press START and the screen shows WAIT until the clock arrives, and after a stop LSDj does not resume where it stopped — reselect the position first (sources: s-little-scale-arduino-gameboy-sync-boxes, s-little-scale-syncing-things-to-lsdj, s-little-scale-teensy-usb-midi-sync; the device landscape is on sync).
Noise shape cheat sheet (versions up to 9.0)#
The NOISE instrument's shape byte: first digit = octave, second digit = clock divisor and loop mode; S, P, C and transposes act on it as described in pitch-slide-and-portamento (source: s-intense-tech-17-the-joys-of-noise).
| digit | as first digit: octave | as second digit: divisor (8–F long-loop = white-noise-like, 0–7 short-loop = tonal, metallic) |
|---|---|---|
F | highest | ×2, long-loop |
E | one lower | ×1, long-loop |
D | two lower | ÷2, long-loop |
C | three lower | ÷3, long-loop |
B | four lower | ÷4, long-loop |
A | five lower | ÷5, long-loop |
9 | six lower | ÷6, long-loop |
8 | seven lower | ÷7, long-loop |
7 | eight lower | ×2, short-loop |
6 | nine lower | ×1, short-loop |
5 | ten lower | ÷2, short-loop |
4 | eleven lower | ÷3, short-loop |
3 | twelve lower | ÷4, short-loop |
2 | thirteen lower | ÷5, short-loop |
1 | no sound | ÷6, short-loop |
0 | no sound | ÷7, short-loop |
Before 8.6.0 the octave of the phrase note selected the first digit (octave 5 = the instrument's digit; octave 6 before 5.1.6) and the pitch class did nothing; since 8.6.0 shapes go directly into phrases. Short-loop pitches follow a "negative harmonic series" (the base frequency divided by 1, 2, 3 …), nearest to C, F, A♭ and D. Going from long-loop to short-loop has a 1-in-256 chance of muting the channel; the instrument's S MODE (earlier S CMD; FREE/STABLE) set to STABLE blocks that direction. 9.1.0 removed FREE/STABLE, and 9.1.3 added PITCH FREE/SAFE after mutes were found to happen even inside one loop mode: FREE behaves like the old STABLE, SAFE restarts the noise on every change and never mutes (sources: s-intense-tech-19-new-noise-and-910-news, s-intense-tech-21-whats-new-in-lsdj-92). The hardware behind it is on game-boy-apu.
Since 9.1.0: ordered noise notes#
Version 9.1.0 replaced the shape byte with values ordered by frequency: the long-loop noises first, lowest to highest, as 00–3B; above them the short-loop noises as note names C, D, F and G# (the pitches each frequency is closest to) in octaves −9 to 8 — all four notes in octaves −9…4, only C in octaves 5–8 plus an extra F in octave 5. Old songs are converted on loading except their transposes and S values; Defense Mechanism's converter (defensem3ch.github.io/noise-convert) maps them. Read from its table: old short-loop shapes X0…X7 become D, F, G#, C, F, C, C, C in rising octaves (90 → D-2, 93 → C-1, 95 → C 0, 97 → C 2, A5 → C 1, 80 → D-3, 70 → D-4), and old long-loop shapes X8…XF become 4·(X−2) plus 0, 1, 2, 3, 5, 7, 11, 15 (98 → 1C, 9F → 2B), compressed near the top (FF → 3B). P, C and V work on the new notes (see the command table) (source: s-intense-tech-19-new-noise-and-910-news).
Version history (from the sources)#
| version | change | source |
|---|---|---|
| ≈ 2000 | first release, for the Game Boy Color; cartridges sold online and through a Stockholm record store | s-intense-tech-13-kotlinski-interview |
| 2001-01 | live mode, inspired by Ableton Live's beta | s-intense-tech-13-kotlinski-interview |
| 1.4.0 | optimised dual-kit sample mixing, fast enough for the DMG | s-intense-tech-13-kotlinski-interview |
| 3.0.0 | file screen with RLE compression: many songs per cartridge | s-intense-tech-13-kotlinski-interview |
| 3.9.2 (2008-12-26) | "purge sequencer/instruments" becomes "free unused data" (also frees tables, synths, waves) | s-chipmusic-lsdj-faq |
| 3.9.5 | prelisten | s-intense-tech-13-kotlinski-interview |
| 3.9.e (2009-07-26) | "free unused data" split into CLEAN SONG DATA and CLEAN INSTR DATA | s-chipmusic-lsdj-faq |
| 5.1.0 | new pitch engine; the old logarithmic slides were lost until version 6 | s-intense-tech-13-kotlinski-interview, s-intense-tech-10-kicks-part-1 |
| 5.1.6 | the phrase octave that selects a noise shape's first digit moves from 6 to 5 | s-intense-tech-17-the-joys-of-noise |
| 6.x (6.9.0, 2019-10) | instrument setting P/L/V: FAST (formerly HF), TICK, STEP, DRUM | s-intense-tech-10-kicks-part-1 |
| 7.0 (7.0.6, 2019-11) | P/L/V renamed PITCH; transpose works with DRUM | s-intense-tech-11-kicks-part-2 |
| 7.7.4 (2020-01) | B (mayBe) probability command; FX/SPEED (later CMD/RATE); wave-channel oscilloscope; silky wave — click-free wave switching, SPEED 01 synths audible; R8x super-fast retrig; wave FINETUNE ±F; maximum tempo 295 (T00–T27); fast load/save. Still crashy: 6.9.0 stayed the stable release | s-intense-tech-12-scoping-out-new-features |
| 8 stable (2020) | accurate vibrato, de-clicked WAV playback, slowed-down C, probability sequencing, higher maximum tempo, wave finetune, optimised playback, high-speed retrig | s-intense-tech-13-kotlinski-interview |
| 8 (2020-03) | two-row screen map; ADSR replaces ENVELOPE on pulse and noise; Z on every command but H; tables PLAY/STEP (STEP = the old Automate); FX/SPEED renamed CMD/RATE; wave LOOP POS instead of REPEAT; R restarts the wave synth from its first frame; wave instruments default to MANUAL; xF in the table volume column hops to row x; synth cloning from the instrument screen; CLEAN SONG/INSTR DATA remove duplicates; V in three channels no longer crashes | s-intense-tech-14-lets-appreciate-version-8 |
| 8.1.0 | ADSR for pulse and noise instruments (8.1.8 by 2020-02) | s-intense-tech-18-adsr-makes-life-easier, s-intense-tech-13-kotlinski-interview |
| 8.5.1 stable / 9.2.A dev | the pair Infu's course was written against; noise notes and the envelope differ between them | s-infu-getting-started-with-lsdj |
| 8.1.9 | Z works with H, G and D (a note added to article 03; article 14 says every command except H — the wiki records both) | s-intense-tech-03-dont-sleep-on-z |
| 8.6.0 | noise shapes can be typed directly in phrases | s-intense-tech-17-the-joys-of-noise |
| 8.8.0 | software volume for pulse and noise: click-free E, table volume column and K | s-intense-tech-18-adsr-makes-life-easier |
| 8.9.3 | R01 retrigs every tick | s-intense-tech-17-the-joys-of-noise |
| 9.0.1 | sprite-based play-position indicators at 60 Hz | s-intense-tech-19-new-noise-and-910-news |
| 9.1.0 (2021-01) | noise channel reorganised into ordered notes (long-loop 00–3B, then short-loop C/D/F/G# by octave); P, C and V on noise; TICK vibrato rates match phrase steps; two-digit FINETUNE and LIMIT (overdrive above 0F); wave F immediate again; FREE/STABLE removed; row bookmarks | s-intense-tech-19-new-noise-and-910-news |
| 9.1.3 | noise PITCH FREE/SAFE | s-intense-tech-21-whats-new-in-lsdj-92 |
| 8.5.1 stable / 9.1.8 dev / 8.4.1 Arduinoboy (2021-02) | the builds LSDPatch 1.10.4 offered for ROM upgrades | s-intense-tech-20-lsdpatch |
| 9.2.H (2021-08) | rewritten kit timing (kits from LSDPatcher ≥ 1.11.5); synth PHASE modes PINCH/WARP/RESYNC/RESYN2; waves no longer inverted; noise TRANSP; ENV visualiser and A,A tooltips; wave instrument RESYNC play mode; LEFT+START queues song rows in SONG mode; song rows FF → BF, 14 speech words; 60 fps screen; needs BGB ≥ 1.5.9, SameBoy, Gambatte or Emulicious | s-intense-tech-21-whats-new-in-lsdj-92 |
| 9.2.6 (2021-05) | the manual ingested in this wiki (its version number precedes 9.2.H in the letter-suffixed 9.2 series) | s-lsdj-manual |
Later than the manual (source: s-defensemech-every-lsdj-kick): the wiki's version history above ends at 9.2.6 because that is where the ingested manual and articles end. A February 2024 video works in 9.4.0 and demonstrates one change directly — the R retrig command now resets the pitch, so the L 00 00 workaround for stutter kicks is no longer needed (retrigger). Nothing else about 9.3 or 9.4 is documented in the sources.
Hardware behind the parameters#
How the instrument screen and commands map onto the game-boy-apu registers documented in pan-docs. The correspondences are inferred from the two descriptions (LSDj's source is not ingested); the hardware column is sourced (sources: s-lsdj-manual, s-pandocs-audio-registers, s-pandocs-audio-details).
| LSDj | hardware |
|---|---|
PULSE instrument WAVE, Wxy on pulse | NRx1 bits 7–6: 12.5 / 25 / 50 / 75 % duty — 25 and 75 % sound the same; the duty shares the register with the length timer, hence the LENGTH reset |
| LENGTH | the length timer: 1/256 s ticks, cuts at 64 steps (256 on WAV) |
ENV first pair, Exy | NRx2: initial volume 0–F, direction, pace 1–7 (× 1/64 s); the second and third ENV pair and speeds above 7 are beyond the hardware ramp, so software |
SWEEP (PU1), Sxy on pulse | NR10: pace, direction, step — an upward sweep that overflows silences the channel |
WAVE VOLUME 0/25/50/100 %, E00–E03 | NR32 output level (a bit shift); the wave channel has no envelope |
synth waves, F frames, kits, speech | wave RAM $FF30–$FF3F, 16 bytes = 32 × 4-bit samples, rewritable only while the channel is stopped |
| NOISE instrument 7-bit / 15-bit values, PITCH FREE / SAFE | NR43 bit 3 LFSR width; switching 15 → 7 can lock the LFSR silent, a retrigger resets it |
OUTPUT, Oxx, B+LEFT/RIGHT | NR51 left/right bits per channel; a change while the channel plays pops |
Mxy | NR50 master volume, 0 = 1/8 … 7 = full per side, never mutes |
Kxx click vs E00/E11 | switching a DAC off pops; volume 0 with the DAC on is silent |
any new note, R retrig | bit 7 of NRx4: switch on, reload period, restart envelope and sweep, reset the LFSR; a pulse channel's phase is never reset |
The scale of what is software here is worth stating plainly: two pulse channels with four timbres each, one wave channel, one noise channel and a master-volume-plus-panning stage is the whole palette, so LSDj's multi-stage envelopes, duty "sweeps", vibrato and tables are all software rewriting a handful of registers every tick — lengths in 1/256 s, envelope steps in 1/64 s. Two hardware notes that surface in the tracker: the cartridge's analog VIN input could have been a fifth channel but "no licensed games used this feature, and it was omitted from the Game Boy Advance"; and a Super Game Boy 1 plays sharp, which is why the ROM carries a second 216-byte note table recomputed for its 2.4 % fast clock (source: s-pandocs-audio-overview).
Techniques
Channel interleaving (one channel, two jobs) › LSDj #
The Game Boy scene's rule, from the LSDJ Advanced Tricks thread (source: s-chipmusic-lsdj-advanced-tricks): never dedicate a channel to one job. "You can have kicks, snares, toms, lead, bass and chords all in one channel and in one pattern if you mix it up and alternate" (SketchMan3); the wave channel carries kick, bass and snare (Saskrotch, Zef); arps and echoes go between pulse kicks (roboctopus); envelopes (E) let a note ring through an instrument switch (defiantsystems); "you'd be surprised at how many gaps in the music the listener's brain fills in on its own" (Victory Road); and "Dont be afraid of silence" (herr_prof). The noise-drum threads add the percussion side: one drum at a time per channel, so introduce instruments one by one and let the ear keep them (Vegasdiamond, borrowed from beatboxing), fit hi-hats on the step before with D02/D05, use the noise channel to accent a pulse bass instead of spending a channel on it (herr_prof), and layer three-channel kicks and snares (Analog) (source: s-chipmusic-noise-drum-threads).
sabrepulse's beginner tutorial teaches the trick in the very first song (source: s-sabrepulse-getting-started-with-lsdj): because the wave-channel kit kicks are "really weak and not very loud", a PULSE kick instrument (envelope F1, duty 50 %, a table with PF1 and a K00 near its end) goes on rows 0, 4, 8, C of PU1 and the bass C3 on rows 2, 6, A, E — "Kick, Bass, Kick, Bass" — leaving PU2 for the lead and NOI for snare and hats; the K00 clears the channel before each bass note (instrument-design).
Chord arpeggio (the 0 3 7 trick) › LSDj #
Cxychord command: runs an arpeggio of base, +x, +y semitones once per tick:C37plays 0, 3, 7, 0, 3, 7… (minor),C47major,C0C= 0, 0, C (octave on every third step),CC0= 0, C alternating,CCC= 0, C, C;C00resets. The instrument's CMD/RATE slows it down (0 fastest, F slowest).- Table arpeggios for anything longer than three notes or with its own rhythm: put semitone offsets in the table's transpose column (the manual's example forms a major chord) and loop with
H; the table speed follows the groove selected withG(instrument-tables). - Chains carry a transpose per phrase, so the same arp phrase serves every chord of a progression (orderlist).
(source: s-lsdj-manual)
Before 9.1.0, C on noise instruments alternates between the base shape and base + value on every tick (C01 on shape FF gives FF, F0, FF …) rather than a pitch interval; the table transpose column is 01–7F up, 80–FF down (sources: s-intense-tech-17-the-joys-of-noise, s-intense-tech-09-lets-table-this-discussion). From 9.1.0, with the noise channel reorganised into ordered notes, C on noise arpeggiates like on pulse and wave, limited to the notes the channel has: F 5 with C12 gives F, G# and C — an F minor triad — and larger values span octaves (source: s-intense-tech-19-new-noise-and-910-news).
Two more intense-tech details: the speed setting began as FX/SPEED in version 7 (7.7.4), renamed CMD/RATE in version 8 (sources: s-intense-tech-12-scoping-out-new-features, s-intense-tech-14-lets-appreciate-version-8); and C37 followed by Z10 on later steps plays the chord randomly as minor or major, possible since version 6 made the Z digits independent (randomization-and-probability; source: s-intense-tech-03-dont-sleep-on-z). sabrepulse's tutorial introduces the command with C07 on the first note of the lead — "magically transformed into a chord" — and suggests trying it on a couple more notes (source: s-sabrepulse-getting-started-with-lsdj).
Community practice (sources: s-chipmusic-tables-and-chords-threads, s-infu-getting-started-with-lsdj, s-intense-tech-06-groove-and-tick-tricks-part-1): LazierGunz's cheat sheet writes chords as hex transposes — the values are interval positions counted from 0, so a major-seventh table is 00 04 07 0B 0C 07 04 00 (C E G B C B G E); slow it with G01 on the table's first line and groove 01 = 2/2 rather than doubling rows; 00 04 00 07 00 0B 00 0C is a texture. The C command's speed is fixed, which is why tables win for anything expressive; danimal cannon: go down, out of order, add octave notes, use five-note patterns over more than an octave — "just don't go up the chord every time the same way". Arpeggios can also be phrases: a 3-tick groove and H71/H5A loops turn one phrase into a long arp. Infu's beginner pair: C47 major, C37 minor.
Grooves are the table's speed control (source: s-painperdu-06-grooves, credited to Joe Toye of Chiptune Belgium). "By default tables run at one tick per step", but a G command inside a table sets that table's speed — which halves what a slow arpeggio costs: "if I wanted to make a long arp that actually took two tables to make, that was a bit of a hassle; thanks to that trick I can now use half the space and control exactly how fast my tables go". A faster groove does the reverse, packing more commands into the same time for a percussion table. The workflow consequence is worth stating: with per-channel grooves, arps can live in phrases instead of tables — "if you're like me and you overuse tables for arps, using grooves and phrases might be a better idea". defense-mechanism makes the same point from the timing side: a table groove of 2, 3 or more ticks slows a table down for arpeggios and duty changes, and groove plus H combine "to create complex timing changes in both phrases and tables" (source: s-intense-tech-07-groove-and-tick-tricks-part-2; shuffle-funktempo).
Why the arpeggio exists at all, on this machine. Asked why C alternates instead of sounding a chord, the chipmusic-org answer is flat: "each channel is really just one channel"; slower table arpeggios come closest; "that's how the medium works, boss" (source: s-chipmusic-lsdj-faq). Hackaday's framing of the same constraint names the two classical escapes side by side — "clever composers evoke the feeling of multiple notes by quickly switching between pitches to make arpeggios that sound convincingly like chords, or switch between very different sound parameters to allow two different 'instruments' to share the same channel" — arpeggio and channel-interleaving, with the ghost-channel as the third (source: s-hackaday-gameboy-channelhacking).
Four notes, then five, then two channels (pain-perdu, source: s-painperdu-03-isometric-sav-walkthrough). C gives three notes at one tick each; writing the arp into a table at two ticks per note (00 44 77 CC — root, major third, fifth, octave) buys a fourth note and enough time to hear each one: "faster arps, you can just hear the click noise between each note and not really the note itself". Put the bass on the relative minor third instead of the root and the same table sounds a five-note chord. Then run both pulse channels on that table, one at 25 % duty and the other at 50 %, with the second offset by three ticks — at two ticks per note there are five usable offsets — and the pair reads as one wide sustained chord: "your brain just kind of glues them all together … you don't even hear the note switch in the arp, you just hear chords." Keeping the same instrument and swapping only the table (the same shape with a minor third for the minor chord) avoids one instrument per chord.
On the wave channel there is a way to get a second note without arpeggiating at all: draw it into the wave. The ghost-channel sounds base + harmonic simultaneously, which no C command can do — at the cost of being limited to the octave and the octave + fifth (source: s-chipmusic-lsdj-ghost-channel).
Detune › LSDj #
The pulse instrument's FINETUNE detunes PU1 downwards and PU2 upwards, and PU2 TSP. transposes pulse 2 — the manual notes these "create interesting phase effects when the same phrase is played on both pulse channels", which is the standard fat-lead recipe: one chain in both pulse columns. Fxy on a pulse instrument sets PU2 TSP (x) and finetune (y, 1/32 semitone per step) from a phrase or table; WAVE instruments have their own FINETUNE (source: s-lsdj-manual).
Version notes: the wave instrument got its own FINETUNE (-F…+F) in lsdj 7.7.4, and from 9.1.0 instrument FINETUNE has two digits — an old value of 01 equals the new 10 (sources: s-intense-tech-12-scoping-out-new-features, s-intense-tech-19-new-noise-and-910-news).
Fake echo / delay › LSDj #
Two native shortcuts: Rxy retrig with a decreasing volume digit — the manual's RF4 "retrig the sound every fourth tick, decreasing amplitude (echo effect)" — gives a same-channel echo without extra rows (retrigger); and a second pulse channel playing the same chain a few steps later with a lower E amplitude or a quieter instrument, panned to the other side with O (stereo-panning). Dxx delays a note by ticks for finer offsets than a step (source: s-lsdj-manual).
Hypnogram's groove delay: give the echoing pulse channel a groove whose first line lasts 0A ticks, so every note after it arrives 4 ticks late; the next phrase returns to groove 0 and keeps the offset; a second groove whose last line lasts 2 ticks cancels it — finetune the two pulses apart to thicken (source: s-intense-tech-07-groove-and-tick-tricks-part-2). danimal cannon's rule for a spare channel: double, echo, octave or detune what is already there, "compensate volume to taste" (source: s-chipmusic-lsdj-advanced-tricks).
A delay inside one channel (source: s-painperdu-03-isometric-sav-walkthrough): two instruments that differ only in panning — one L, one R — alternating in a single channel, playing the same phrase offset by three notes. "It's like a delay of this, offset by three, all in one channel." The alternative he names is an AUTOMATE table with L/R and an H (stereo-panning); he used two instruments because those instruments' tables were already busy with pulse-width modulation and a slight vibrato.
Typed echoes, and the two-position lag (source: s-lsdj-and-you-echo-chamber). Write the echo as notes in the gaps, played by a second instrument with the same sound at a lower volume and a shorter envelope — and pitch each echo to the note before last, not to the note it follows: in a C – B – G – E run, the echo after B is the C, the echo after G is the B. Carry the previous phrase's last note in as the first echo of the next so the loop stays continuous. From there: pan the echo instrument to one side ("panned echoes are often used in professionally produced tracks, and the trick works well in LSDJ"), or run an automated table that pans it left and right on alternate notes. Spending a second channel buys a chorus rather than an echo — copy the phrases into pulse 2, shift them one tick later, lower the volume and set PU FINE TUNE to 2, which "will create a sort of chorus effect when the notes play in unison with pulse channel one" (detune). roboctopus's habit is to leave the echoes to the end: "in the final stages of working on a track, I often look for every bit of free space in the patterns and see if I can add an echo here and there."
Filter programming on the SID › LSDj (the wave synth's filter) #
Not a filter on the output like the sid's, but a filter applied when the synth generates its 16 waves, so what it shapes is the wavetable itself. FILTER is Lowp / Highp / Bandp / Allp, with CUTOFF 00–FF and Q; both interpolate from the synth's first wave to its last (source: s-lsdj-manual).
These are not filters in the sid sense at all — nothing is filtered on the way out: "this is a wavetable synthesizer, it's not a subtractive synthesizer, so the filters that you see here are actually just kind of emulated … it will just generate what you might expect to see from these kinds of filters" (source: s-defensemech-wave-channel-ramble). What they shape is the 16 waves the synth writes.
Two things make it unusually literal. First, CUTOFF is calibrated in harmonics: every multiple of 10 is one partial, so bandpass at 20 sounds the octave, 30 the octave + fifth, 40 two octaves — the filter selects an interval (harmonic-series). Second, lowpass at CUTOFF 10 with Q 3 and VOLUME 08 leaves the fundamental alone, which is how you get a sine out of a channel that has no sine setting (source: s-intense-tech-01-wave-synth-deep-dive-part-1).
Walked up by ear on a bandpass with high Q, the whole series is audible: 10 fundamental, 20 octave, 30 fifth, 40 octave, 50 major third, 60 fifth, 70 an out-of-tune seventh, 80 octave, then 90 a major second, A0 a major third, B0 a sharp fourth, C0 a fifth, D0 a flattened sixth-to-seventh, and nothing much above that — "it probably only generates up to here really". On a square signal the even harmonics are simply absent: CUTOFF 20 changes the volume and nothing else, and the first thing that speaks is the fifth at 30 (source: s-defensemech-wave-channel-ramble). A sweep that must outlast one synth's sixteen waves is built as a chain of synths, one CUTOFF slice each, played in sequence (wavetable-programming; source: s-defensemech-learning-lab-shorts). A sweeping CUTOFF with a high Q is the channel's wah — start high, end low, PLAY ONCE, SPEED 3, LENGTH F.
Q is what makes a sweep audible rather than merely dark: "if you're just going to have a standard lowpass you're just gonna hear more and more bass and less and less treble; with the resonance you're gonna actually have some kind of a sonic cursor" (source: s-painperdu-02-wav-channel-walkthrough).
Because the synth screen is editable while the song runs, Q is also a performance control and not only an instrument setting: "altering Q in wave instruments while a song is playing is a lot of fun for sweepy type stuff" — and Lazerbeat notes it works in song mode, not just live mode (live-tracking; source: s-chipmusic-lsdj-live-performance).
Allpass is the odd one and the useful one for two-note sounds: it passes everything and shifts phase around the cutoff, so a high Q promotes one partial to near-melodic prominence while "no matter how much you boost this Q you really never lose the root note" — defense-mechanism's route to a power chord on one channel, with Q around 8–9 for the fifth. Lowpass gives a cleaner but thinner version of the same, with the harmonics above the fifth rolled away (source: s-defensemech-ghost-channel-allpass; the technique is ghost-channel). Whether the filter overdrives is decided by DIST and LIMIT rather than by the filter itself (wavetable-programming).
Ghost channel (two notes in one wave) › LSDj — drawn by hand (the original method) #
- Draw the base. A sine (Lowp, CUTOFF
10, Q3, VOLUME08is the cleanest sine the channel makes — source: s-intense-tech-01-wave-synth-deep-dive-part-1, collected on wavetable-programming) or any smooth wave, at every volume you want the base to take: "starting from silence all the way to the maximum volume". - Add the rider. On a copy of each base wave, push runs of samples up by a uniform amount — the same operation that turns silence into a square, applied to the sine as a baseline. Tyler Barnes counts "1 2 3, 1 2 3" for a rider three units high; the run length is the
16/xabove. Repeat for each rider octave. - Add rider volumes. From each superimposed wave, "decrease those Peaks by one pixel every time until you get back to that original sine wave". A three-pixel rider gives three ghost volumes — the rider's dynamic range is its height.
- Play it. The wave instrument's PLAY is MANUAL; the note in the phrase sets the base's pitch, the wave frame sets the ghost. "If I want to change the Octave of that square wave I'm going to be changing the frame … the sine wave stays the same octave but only the square wave moves." To move the base under a fixed ghost, do it in reverse: raise the note an octave and step the frame back by the compensating amount.
Fxxsteps frames relatively,F10jumps a whole synth (source: s-lsdj-manual).
Labour savers from the thread (source: s-chipmusic-lsdj-ghost-channel): SELECT+B starts a selection, the cursor extends it and UP/DOWN offsets the whole run — this also copies, and SELECT+A pastes; holding A with LEFT/RIGHT or UP/DOWN mirrors the selection. "By using these tricks and abusing symmetries in the waveforms, you can speed up the manual labor a lot." A saw rider works too (steps of 1, 2, 3, 4), but a square rider was found to give "more octaves and a louder sine".
Ghost channel (two notes in one wave) › LSDj — with the filter (the cheap route) #
Boost the wanted overtone instead of drawing it. In the synth screen, Allp with a low CUTOFF and a high Q lifts one partial into audibility: "the idea that you can have extra notes in the wave channel — it's really talking about this overtone emphasis that sounds like almost two notes … you've got the low note but then also that octave, or three if you use allpass with Q boosting that fifth: the power chord" (source: s-defensemech-ghost-channel-allpass). Allpass over lowpass, because "no matter how much you boost this Q you really never lose the root note"; lowpass when you want the fifth alone and the top rolled off, which is cleaner but thinner. A Q around 8–9 is where the fifth sat for defense-mechanism — lower is "kind of subtle", higher "too much".
CUTOFF is calibrated in overtones, so the interval is choosable rather than hunted: every multiple of 10 is one harmonic — 20 the octave, 30 the octave + fifth, 40 two octaves (source: s-intense-tech-01-wave-synth-deep-dive-part-1). That also makes bandpass at CUTOFF 30 with a high Q a third route to the same power chord (inference from the same source — untested here).
Ghost channel (two notes in one wave) › LSDj — crunched from audio #
Render the two-note chord you want in any synth or DAW, then let lsdj-wave-cruncher reduce it to a 16-frame synth and liblsdj's lsdj-wavetable-import patch it into the song. This is exactly what the 2013 thread asked for and did not have — "i wonder if there's a tool that can autogenerate these waves and spit out an lsdsng" (source: s-chipmusic-lsdj-ghost-channel); the tooling arrived later (sources: s-intense-tech-05-wave-cruncher-instrument-library, s-intense-tech-08-dotcnts-wave-cruncher). The harmonic constraint still applies: a crunched interval that is not a harmonic of the played note will beat against it.
Instrument design beats note count › LSDj #
The manual's synthetic drum recipes (chapter 3.6) — they free the wave channel's kits for other duties:
| drum | channel | recipe |
|---|---|---|
| bass drum | PU1 | ENV C3/0/0 (strong attack, fast decay), WAVE 50-50, SWEEP 63 (high start, fast decay), play at C-6; TRANSP. OFF so chain transposes don't move it; tweak ENV/LENGTH for snap |
| snare | NOI | ENV F1/D3/0, note value around 30 sets the timbre; P/V make it livelier |
| hi-hats / cymbals | NOI | note value around 38 for high-frequency content, shape with ENV; lower notes for rougher cymbals |
| wave bass drum (best) | WAV | PITCH = DRUM, TRANSP. OFF, synth SIGNAL triangle, VOLUME 30; instrument table: step 0 P C0, step 1 transpose 80 + L 30 (slides to the lowest possible note without wrapping); play at C-5/C-6 or above |
Envelopes are ENV. triples of amplitude + speed (32/AD/10: attack from 3 to A at speed 2, slow decay to 1, hold); E and the table envelope column override per note. Kit instruments give real drum-machine samples (TR-808/909/606/707/727, CR-78, LinnDrum, DMX…) with OFFSET/LOOP/CLIP and the S loop-point and F offset commands for timbral tricks. Dxx delays and Rxy retrigs help flams and rolls (retrigger) (source: s-lsdj-manual).
What the chip adds to these recipes (sources: s-pandocs-audio-registers, s-pandocs-audio-details): the noise channel is a 15-bit LFSR clocked at 262144 ÷ (divider × 2^shift) Hz — a lower clock sounds "harder", a higher one "softer" — and its 7-bit mode gives "more regular output; some frequencies sound more like pulse than noise", LSDj's pitched noise. Switching from 15- to 7-bit mode can lock the generator into silence until it is retriggered: the hardware reason for PITCH = SAFE. The PU1 bass drum's SWEEP is register NR10; an upward sweep that overflows switches the channel off, a downward one stops at period 0 (pitch-slide-and-portamento). K clicks because switching a channel's DAC off pops, while volume 0 with the DAC alive is silent — presumably what the click-free E00/E11 do (inference).
Defense Mechanism's recipes (intense-tech, LSDj 6–9; sources: s-intense-tech-10-kicks-part-1, s-intense-tech-11-kicks-part-2, s-intense-tech-17-the-joys-of-noise, s-intense-tech-18-adsr-makes-life-easier, s-intense-tech-12-scoping-out-new-features, s-intense-tech-15-lets-mix-it-up-and-down):
| drum | channel | recipe |
|---|---|---|
| wave kick | WAV | a kit kick, or a sine/square-like synth wave with PC0, note C5–C7 or higher for the attack; PITCH = DRUM for the logarithmic fall; table P (fast) then L with transpose 80 (wavetable-programming) |
| Kyoto kick | WAV | a noisy wave in slot 00 for one tick, clean waves after (F01, or PLAY LOOP / LENGTH 1 / REPEAT 0 / SPEED 01) |
| kick → bass | WAV | LSDj 7: DRUM, start two octaves up, L with transpose E8; LSDj 6: FAST + TRANSPOSE ON, octave transposes in the table; or just a groove |
| wave snare | WAV | P then L to a tuned note, E commands for the decay, layered with a noise snare |
| pulse kick / snare / toms | PU1, PU2 | DRUM pitch; 50 % duty "to get the most impact"; snare = the wave snare table without E (instrument envelope for the decay); toms = shorter LENGTH and P directly in the phrase |
| sweep drums | PU1 | the hardware sweep: S F4 kick, S E3 snare, similar E-values for toms |
| noise kick | NOI | shapes ending in 0–7 (short-loop) are tonal; base shape 95, table transpose 10 on tick one (= A5), then 93, 91, 90, 80, 70, 60; S MODE STABLE; "noise kicks sound great when they are LOUD" |
| layered kick | NOI + PU | a very short noise kick in the lowest octave for the lows plus a pulse kick for the falling pitch and tone (Dox The Fash remix) |
| hi-hat with transient | NOI | ADSR: volume 6 quickly down to 4, then fade — cuts through better than a plain fade from 4; maybe only on downbeats |
| snare (LSDj 8.8+) | NOI | transient stages in the ADSR instead of E commands in a table; stage length 1 = instant decay |
| random crash | NOI | Z after the shape or S command: first digit +0…4 capped below F, second digit F (randomization-and-probability) |
| pitched noise "pulse" | NOI | R01 (8.9.3) or R80–R8F; pitch from rate × tempo × shape; LENGTH or ADSR for loudness (retrigger) |
| deeper pulse kick (7.7.4+) | PU | R8x, the super-fast retrig, on a pulse kick reaches "about 3 whole tones lower than the pulse channel is normally capable of" (source: s-intense-tech-12-scoping-out-new-features) |
| snare with transient (Pain Perdu) | NOI | instrument volume around 90, the table's E pulling it down after the first tick, an E beside the note in the phrase to scale the burst — cuts through "without overpowering the other channels"; works on other noise and even pulse instruments (source: s-intense-tech-15-lets-mix-it-up-and-down) |
The noise shape chart (first digit octave, second digit divisor, 0–7 short-loop, 8–F long-loop) is on lsdj. Heard in: .exe's NOIZE JAMS and a demo by they/them use the noise channel alone (source: s-intense-tech-17-the-joys-of-noise).
Noise drums since 9.1.0 (sources: s-intense-tech-19-new-noise-and-910-news, s-intense-tech-21-whats-new-in-lsdj-92): the shape bytes became ordered notes — long-loop noise as 00–3B from low to high, short-loop noise as the note names C, D, F and G# in octaves −9 to 8 — and P now sweeps them smoothly (P01 applies S01 every 4 ticks, P04 every tick), so a kick, a hi-hat and a crash can come from one instrument with P in the phrase instead of a hand-made S table. Old songs convert their noise notes but not their transposes or S values; read from the article's converter, the noise-kick recipe above becomes C 0 for the base 95, C 1 for the tick-one A5, then C-1, F-2, D-2, D-3, D-4, D-5 — a plain descending line. S MODE FREE/STABLE was removed in 9.1.0 and, after random mutes turned out to happen inside one loop mode as well, replaced in 9.1.3 by PITCH FREE (the old STABLE: restart only when going from long-loop to short-loop) and PITCH SAFE (restart on every value change — rougher, but "guaranteed never to mute"); noise instruments also gained TRANSP, C arpeggios limited to the available notes (F 5 with C12 = F, G#, C) and a tick-based V. Emulators (BGB, SameBoy) and most Game Boy Advance models never mute; many Game Boy models still can.
A beginner's set from sabrepulse's tutorial (undated, pre-8.1 ENVELOPE field; source: s-sabrepulse-getting-started-with-lsdj):
| sound | channel | recipe |
|---|---|---|
| pulse kick | PU1, shared with the bass | KICK: envelope F1, duty 50 %, TABLE 00; table: PF1 in the first command row bends the pitch down, K00 on the second-to-last row kills the tail "to avoid clicking"; C5 on rows 0, 4, 8, C, the bass C3 on 2, 6, A, E (channel-interleaving) — chosen because the kit kicks are "really weak and not very loud"; credited to a recipe on the LSDj wiki |
| bass | PU1 | BASS: envelope D3 ("short and punchy"; the default is A9), duty 50 % ("a good low bassy sound") |
| lead | PU2 | LEAD1: envelope C2, duty 25 %; C07 on a note makes a chord |
| snare | NOI | SNARE: envelope about C3, a snappy LENGTH, shape (the tutorial says "sweep") EF |
| hi-hat | NOI | HAT: envelope A1 or A2, length and shape untouched, before and after each snare |
Community recipes (sources: s-infu-getting-started-with-lsdj, s-chipmusic-noise-drum-threads, s-chipmusic-tables-and-chords-threads, s-chipmusic-kotlinski-interviews):
| sound | channel | recipe |
|---|---|---|
| hi-hat (Infu) | NOI | ENV 75/00/--, R02 on the notes; cymbals from a high metallic note such as C 7 |
| noise kick (Infu) | NOI | ENV F4/00/--, note D 0, PF0 beside it (or in a table); a long release keeps the punch |
| snare (Infu) | NOI | ENV 88/00/-- at volume 9 plus the snare table (instrument-tables) |
| noise kick (Mrwimmer) | NOI | envelope decay 1, shape FC, table --, SF0, SF0, SE0, --, H05 — a quick downward sweep |
| snare (Mrwimmer) | NOI | decay 1–2, shape FE or FD |
| snare (metatronaut) | NOI | ENV A3, shape AE, played at C6; table rows F0 OL-, F0 O-R, -- OLR, H03 on row 8 |
| snare (Victory Road) | NOI | a toned noise (C3/C4) morphed into white noise with a quick S, noise type FREE; a fast L→R pan flick at the top of the table, then centre |
| wave kick → bass (SketchMan3) | WAV | table 12 PEE / 00 / 00 / 00 P00 / 01 / 00 …; snare companion 24 PEE / 12 / 12 / 00 P00 / 01 / 00 |
| wave kick (Infu) | WAV | a high note, table P ≈ D0, PITCH DRUM so low notes do not wrap, K00 on step 6 to clear the way for the bass |
| pulse bass (Kotlinski) | PU | duty 15 or 25 on the first tick, then 50 |
| pulse cymbal (Monodeer, per Dire Hit) | PU | VFF — vibrato so fast it becomes a tone, "noise percussion out of a pulse channel" |
Layering advice from the same threads: a high-toned wave kick under a noise snare "gives a really full and thick tone"; a wave-bass table with a short attack layered under the snare; noise + pulse snares "à la C64"; a loud hi-hat-like first row before a kick's sweep makes hi-hat + kick in one instrument; and "a noise kick is never going to blow out your subwoofer".
Where the wave-channel instrument material lives. Designing a WAV instrument is mostly designing its synth, so that whole body — the synth's SIGNAL/FILTER/DIST/PHASE chain read as harmonic content, LIMIT as the volume control the hardware lacks, the LENGTH interpolation chart, hand-drawn banks, and the sixteen-hand-narrowed-waves PWM instrument — sits on wavetable-programming (sources: s-intense-tech-01-wave-synth-deep-dive-part-1, s-intense-tech-02-wave-synth-deep-dive-part-2, s-lsdj-and-you-pwm). Two design decisions worth restating here: an instrument's envelope can be its own sidechain — on the wave channel E02 is 50 % and E03 100 %, so 02 then 03 on the steps after the kick is an audible pump locked to the 16th, and on the pulse and noise channels a per-beat envelope "that starts from zero and rises at the speed of A" makes hats and pads pump even where no kick plays (sidechain-pump; source: s-painperdu-04-sidechaining) — and the kick and bass sharing WAV is already a sidechain, so what you actually design is the recovery.
The noise channel after 9.1.0 (source: s-defensemech-noise-channel-92l). The channel was rebuilt, so older tutorials no longer apply: shapes now run ordered low to high (00–~$3B are the long-loop, noisy ones; past either end you cross into short-loop pitched noise, labelled with the nearest note name), and C chords, P pitch bends, V vibrato and S all work on it. Design consequences:
- Set the envelope instead of chaining
Ecommands — "a much faster and easier way … and then I can just work on setting transpose commands". A snare is that envelope plus a couple of rising transposes, stopped withA20orK. Ris the dynamics tool the hardware envelope cannot be. Hardware envelopes are one smooth slope, so a decaying repeat cannot be written withE;Rwith a volume digit "will reduce this by one level and keep these numbers" — ghost snares, quieter repeats, and triplet fills at a four-tick retrig (retrigger).- Hardware LENGTH still has one job: it overrides an
Ecommand, "so it kind of puts a cap on how long this envelope can actually be" — useful under a rising envelope. - Why PITCH SAFE exists, in hardware terms: the LFSR "sometimes … creates zeros, and that results in silence", so on real hardware (DMG, old CGB, some GBA units, the GameCube Game Boy Player) a pitch slide can simply cut out with no
K. SAFE re-initialises the channel on every pitch change so it never cuts out, at the cost of a harsher texture — recoverable in part by slowing COMMAND RATE. Current SameBoy and BGB emulate the cutout; older builds do not, so a patch that works in an old emulator can die on hardware.
The SPEECH instrument, from people who have used it (source: s-chipmusic-lsdj-speech-synthesis). Jotie, who has shipped several: "It's slow, difficult and in my opinion, flawed. You can't delete wrong letters." The workflow that makes it tractable is to compose the allophones outside LSDj — "download an Atari ST emulator and write your lines in STSPEECH — it will show you how to do what you just wrote in allophones" (Steem SSE) — and transcribe the result into the word screen. Two craft notes: speech sits in the centre with everything else panned away from it, because "mixing is the only thing that is going to make your speech stand out" (stereo-panning); and phrase it musically — "don't put them on every downbeat tick, try and give them space and change the syllable when it's natural to do so". Scale the ambition to the tool: a hook, not a monologue.
An echo is an instrument, not an effect (source: s-lsdj-and-you-echo-chamber): a second instrument on the same channel, same sound, lower volume and a shorter envelope, with the echo notes typed into the gaps. The pitch rule is what makes it read as an echo — "the echoed note corresponds to not the note it immediately follows but the one before that" — a two-position lag, and the echo of the previous phrase's last note opens the next phrase so a loop stays continuous. Pan the echo instrument to one side, or table-pan it side to side for ping-pong. The expensive version is a chorus: copy the phrases into PU2 shifted one tick, drop the volume and set PU FINE TUNE to 2, "which will create a sort of chorus effect when the notes play in unison with pulse channel one" (fake-echo, detune).
Designing instruments that have to share a channel (source: s-chipmusic-lsdj-advanced-tricks). The thread's consensus is "definitely don't use one channel for just kick drums" (Saskrotch) — the wave channel does kick, bass and snare — which puts requirements on the instruments themselves: E commands so a ringing note survives an instrument switch, tables that end in "wild pitch commands … to add subtle little bleeps and bloops" (defiantsystems), and drums layered across channels rather than owned by one. danimal cannon's use for a free channel is entirely instrument design: double, echo, octave or detune what is already there, volume-compensated. Victory Road's caveat is the reason it works at all — "you'd be surprised at how many gaps in the music the listener's brain fills in on its own" (channel-interleaving).
Lead articulation (velocity, legato, late vibrato, drop-off) › LSDj (wave channel) #
The wave instrument's table does the articulating, and the trick is that a note without an instrument number does not restart the table (source: s-chipmusic-lsdj-wav-instrument-tutorials):
- Attack / tonguing. Make the synth's first frame noticeably louder than the rest, set PLAY to MANUAL and put
F01on the first tick of the instrument's table. Every note that carries the instrument number gets the loud frame as its attack; notes typed without it are slurred into the previous one. - Flutter tonguing. Give a third frame a slightly different volume and shape and alternate between two frames from a second table —
F01forward,FFFback (FFFis −1 inF's relative arithmetic) — started from the phrase with anAcommand. - Breath. A frame or two of near-noise at the start "simulate[s] the attack phase of a musician blowing into the flute" (tyler-barnes); a very quiet noise-channel layer with a slow decay underneath does the same job from outside.
- Vibrato with varied
Vxxspeeds rather than one fixed setting (vibrato). Victory Road's verdict: "it's all about articulation, really. LSDJ is really good for flutey articulation."
Worth reading against the counter-argument in the same thread: chasing an orchestral instrument on the Game Boy mostly disappoints, and "other people will only hear '8bit' anyway" (an0va) — the articulation is worth more than the timbre.
Multisampling and drum-kit instruments › LSDj kits #
The Game Boy's version of a drum-kit instrument, and it is a real map, not a metaphor. A kit instrument names two kits: "the first kit will be used in the left note column in the phrase screen; the second kit will be used in the right note column" — so one instrument addresses two banks of samples, selected by which column the note is typed in (source: s-lsdj-manual). Each kit holds 15 sample slots inside 3FA0 bytes — "just over two seconds worth of audio per kit, so whatever you put in has to count!" — at 11.468 kHz (source: s-little-scale-lsdj-kits; preparation is on chip-samples, patching on lsdpatch).
What that budget forces is the opposite of the IT piano: a themed set is split across slots, not crammed into one. little-scale's own releases show the convention — Mario Paint, "29 samples from the SNES program spread across two kits"; Street Fighter 2, "17 samples in 6 kits"; Street Fighter Alpha, "34 samples in 4 kits with one kit per character". Budget two to six kit slots for a voice or sample set and split by character or function (source: s-little-scale-lsdj-kit-releases).
Octave bass › LSDj #
Two rows of C-2 C-3 work as anywhere else, but the chord command does it in one column: CC0 "plays 0, C, 0, C, 0, C, …" — a true octave alternation at tick rate, slowed with CMD/RATE in the instrument screen. Neighbouring values give the variants: C0C = 0, 0, C (octave every third tick), CCC = 0, C, C, and C00 resets the chord (source: s-lsdj-manual).
The wave channel can also play the octave inside the note: a ghost-channel wave carries a rider at 2× the fundamental, so bass and octave sound together and the octave can be faded or stepped away without touching the bassline (source: s-chipmusic-lsdj-ghost-channel).
A related use of the same interval is the kick that turns into a bass note — start two octaves above and slide down with a P/L pair, or split the two with a groove; the recipes are on wavetable-programming and instrument-design (sources: s-intense-tech-10-kicks-part-1, s-defensemech-every-lsdj-kick).
Pitch slides and tone portamento › LSDj #
Lxxslide: slides to the note in the row over a duration xx — in ticks if the instrument's PITCH is TICK, otherwise in xx/360 seconds. Manual example:C-4, thenF-4 L40, thenC-4 L10bends up to F and snaps back. In a table,Lin the left command column uses the transpose column as target relative to the base note; transposes and slides add independently.Pxxpitch bend: continuous bend at the given speed (P02up 2,PFEdown 2). Behaviour follows PITCH: DRUM = logarithmic at 360 Hz (kicks), FAST = linear at 360 Hz, TICK = per tick, STEP = instant pitch change without bend. On noise instrumentsPappliesSevery tick.- Legato: cut the instrument column with
B+Ato change the note without retriggering. Fxyon pulse instruments sets PU2 transpose and finetune in 1/32-semitone steps — micro-detune rather than a slide (detune).
(source: s-lsdj-manual)
Hardware limits (source: s-pandocs-audio-registers): pitch is an 11-bit "period value" 0–$7FF; pulse frequency = 131072 ÷ (2048 − value) Hz, wave = 65536 ÷ (2048 − value) Hz (one octave lower at the same value). The scale is not linear in pitch: one step at value $500 changes the pitch by about 2 cents, at $7D0 by about a third of a semitone, and near the top by whole semitones (computed from the formula) — high slides step audibly, low ones are smooth. Period writes only take effect when the current sample ends. PU1's hardware sweep (NR10, LSDj's SWEEP and S on pulse): every 1–7 ticks of 1/128 s the period value changes by ± value ÷ 2^step; in the upward direction a result past $7FF switches the channel off (even with the pace at 0), and a downward sweep can never underflow — a rising sweep that goes too far ends in silence rather than at the top.
PITCH modes and their history (sources: s-intense-tech-10-kicks-part-1, s-intense-tech-11-kicks-part-2, s-intense-tech-13-kotlinski-interview): the pitch engine changed in 5.1.0 (johan-kotlinski: "actually a total disaster" at first — "it took way too long until it was on par with what was there before in terms of kick crafting"), losing the old logarithmic slides until version 6 added the instrument setting P/L/V — renamed PITCH in 7.0 — which governs P, L and V: FAST (formerly "HF") at the fastest rate, TICK much slower and tempo-dependent, STEP makes P a pitch offset (fun on kit snares), DRUM emulates the pre-5.1.0 logarithmic slides through a separate frequency lookup table and is not affected by tempo. In version 6 DRUM broke transposes in phrases and tables (turn the instrument's TRANSPOSE off); 7.0 (7.0.6 in November 2019) made transpose work with DRUM. L with transpose 80 in a table slides to the lowest note and stops there without wrapping. On noise instruments the commands act on the shape instead: S adds per digit (S01 on 4F gives 40, SFF gives 3E) and accumulates, whereas a phrase or table transpose changes the whole byte (4F + 01 = 50, + FF = 4E) and reverts when its row ends; P keeps adding every tick (FF, F0, F1, F2 …), C alternates base and added shape per tick (C01: FF/F0); CMD/RATE slows both. Smooth noise sweeps therefore need hand-made S tables (source: s-intense-tech-17-the-joys-of-noise) — that description holds up to 9.0.x; see the next paragraph for 9.1.0.
Later versions (intense-tech): version 7 (7.7.4, January 2020) added the FX/SPEED setting — renamed CMD/RATE in version 8 — which stretches each step of P (in TICK pitch only, like V), a wave-instrument FINETUNE of -F…+F, and the R8x super-fast retrig that restores the old wave-channel pitch wrap: on wave the pitch becomes tunable instead of relying on P, and a pulse kick reaches "about 3 whole tones lower than the pulse channel is normally capable of" (retrigger; sources: s-intense-tech-12-scoping-out-new-features, s-intense-tech-14-lets-appreciate-version-8). In 9.1.0 the noise channel became an ordered scale (long-loop values 00–3B, then short-loop notes by octave), so P on noise now sweeps smoothly through it without a table, with a new speed scale — P01 applies S01 every 4 ticks, P04 every tick — enough for kicks, hi-hats and crashes from one instrument; the instrument FINETUNE also gained a second digit (old 01 = new 10) (source: s-intense-tech-19-new-noise-and-910-news). Contradiction: the 9.2.6 manual as read above says P on noise "applies S every tick", whereas article 19 gives P04 as the every-tick speed from 9.1.0 on (sources: s-lsdj-manual, s-intense-tech-19-new-noise-and-910-news). A beginner's pulse kick from sabrepulse: PF1 in the first command row of the instrument's table, K00 near its end (instrument-design; source: s-sabrepulse-getting-started-with-lsdj).
Forum practice for L (source: s-chipmusic-lsdj-faq): the command goes on the target note — "it bends the previous note to the new one" (A#6 … C 6 L02 down, C 5 … A#5 L02 up); L on an empty step bends the note "down to nil"; in the 2010 versions only L01/L02 sounded musical, and slides ignore the vibrato waveform (only the HF/non-HF setting matters). Without PITCH = DRUM a kick slide played on a low note wraps back to the highest octave (source: s-infu-getting-started-with-lsdj).
Slides as drum design (defense-mechanism, 2024–25; sources: s-defensemech-every-lsdj-kick, s-defensemech-noise-channel-92l):
Palone slides down and wraps if pushed too far, whileLwith transpose80always lands on the lowest note, C1 — so the two together separate the transient's speed from the body's slope, and the note written in the phrase only sets where the slide starts. That is the tuning control: "that allows me to actually tune the transient of the kick using the starting pitch in the note column", with higher octaves adding high end and the difference growing as the slide slows.- Stutters used to need an
L 00 00on the tick where the kick restarts, becauseRdid not reset the pitch; in 9.4.0Rretriggers the pitch too, so a plainRin the table is enough (retrigger). (The version is read off screen in an auto-transcribed video; the wiki's LSDj version history otherwise stops at 9.2.6 — (unverified).) - Why PITCH SAFE exists, in hardware terms: the noise channel is a linear-feedback shift register that "sometimes … creates zeros, and that results in silence", so on real hardware — "especially like the original brick DMG", old CGBs and some Game Boy Advance units — a pitch slide on noise can simply cut out with no
K. SAFE re-initialises the channel at every pitch change so it never drops out, at the price of texture: "it creates a harsher sound, it's just a totally different texture". Slowing the rate of change, or lowering COMMAND RATE with PITCH set to TICK, buys some smoothness back — and on a kick the restart is the sound, giving "almost a tonal aspect" where FREE "just completely loses its impact" (game-boy-apu, instrument-design). Pon noise keeps running after the note ends, so stop it deliberately.
Pulse width modulation (PWM) › LSDj #
The pulse instrument's WAVE parameter selects the duty ("typically 50-50 high/low", other waves for a more distorted sound); the Wxy command changes it from a phrase or table — with the hardware oddity that the instrument's LENGTH timer is reset, possibly extending the sound. A duty sweep is therefore a table with W on successive rows, looped with H (source for the commands: s-lsdj-manual).
What the hardware allows (sources: s-pandocs-audio-registers, s-pandocs-audio-overview): bits 7–6 of NR11/NR21 select one of exactly four duties — 00 12.5 %, 01 25 %, 10 50 %, 11 75 % — and Pan Docs notes that "there is no audible difference between the 25 % and 75 % duty cycle settings", so a W sweep has three timbres to step through; it is a stepped effect, never the continuous sweep of the sid. The W-resets-LENGTH oddity follows from the duty and the initial length timer sharing that register (inference). A pulse channel's phase is "only ever reset by turning the APU off" and the duty setting shifts the phase, which is "usually not noticeable unless changing the duty cycle mid-note" — a duty step can land anywhere in the cycle, so listen to the transition rows.
The W values count 00 = 12.5 %, 01 = 25 %, 02 = 50 %, 03 = 75 %, which is what makes a random duty possible: W on the note and Z03 on its repeats picks any of the four, and Z02 (12.5 / 25 / 50 %) is the better choice because 25 % and 75 % "effectively sound identical"; an added value past the range wraps to the remainder after dividing by 4 (randomization-and-probability; source: s-intense-tech-03-dont-sleep-on-z). A beginner's defaults from sabrepulse's tutorial: 50 % ("a good low bassy sound") for the bass, 25 % for the lead (source: s-sabrepulse-getting-started-with-lsdj).
Three more sources: the wave channel does the sweep the pulse channels cannot — Square with PHASE Normal from 00 to 1F is "a smoothly modulated pulse lead (commonly associated with the C64 SID)" (source: s-intense-tech-02-wave-synth-deep-dive-part-2); johan-kotlinski's own bass duty "depends on the octave. For the base, I go for 15 or 25 first tick, then switch to 50" — a W on the first tick of a table (source: s-chipmusic-kotlinski-interviews); and Dire Hit's reading of Trey Frey's "Dreaming": at the fade-out an H loop over two table steps flips the pulse width while an E release runs (source: s-chipmusic-tables-and-chords-threads).
On the pulse channels themselves the duty is also a drum parameter: for a pulse kick, 50 % is "the beefiest", and the channel's floor of C2 is what makes the wave channel the better home for a kick with real low end (source: s-defensemech-every-lsdj-kick).
A cheaper approximation of the same motion: VSHIFT combined with FOLD or WRAP, where the shifted part of the wave folds or wraps back in — "that's almost like a pulse-width modulation thing happening" (source: s-defensemech-learning-lab-shorts; wavetable-programming).
Hand-drawn PWM on the wave channel#
Before the synth screen could sweep PHASE, the wave channel got its PWM by hand, one wave at a time (source: s-lsdj-and-you-pwm): draw a square in wave 0 at VOLUME 10, then narrow the pulse a little more in each of the synth's remaining fifteen waves — copy a whole wave with SELECT+B twice and paste it into the next frame with SELECT+A, then edit, rather than redrawing. Play it with PLAY PINGPONG, REPEAT F, LENGTH F and a slow SPEED, and the pulse narrows and widens continuously: "PWM will allow your game boy to sound a bit more like a C64, though nowhere near as smooth and classy." The steps are audible — "you can hear the synth stepping through each frame" — but "less noticeable on leads/basses in a full mix … and barely discernible when used in a fast arpeggio". roboctopus's verdict: "It's great for giving a lead line a more organic feel, and it makes a pretty massive bass."
The article predates LSDj 7's silky wave, which removed the click from frame changes (wavetable-programming), so on a current version the stepping should be gentler than he describes (inference).
Randomization and probability (MayBe, RandomiZe) › LSDj #
BxyMayBe in a phrase: probability that the note (or kit sample) to its left plays — first digit for the left kit, second for notes and the right kit.B00never,B0Falways,B08about half the time.Bxyin a table: a hop to row y that only happens with probability x (BF515 times out of 16,B84about 50 %) — a table that sometimes takes a different path.ZxyRandomiZe: repeats the last command that is not Z or H, adding a random 0..x to its first digit and 0..y to its second (Z02adds 0, 1 or 2;Z22any of 0,1,2,10,11,12,20,21,22). Put it after aV,P,EorFcommand for humanised vibrato, pitch, volume or sample offset.
(source: s-lsdj-manual)
- Worked
Zexamples from hypnogram's 2016 post as rewritten by defense-mechanism for intense-tech (source: s-intense-tech-03-dont-sleep-on-z): random vibrato —V00on the note,Z03on every repeat of the note, each acting asV00…V03; random duty —Wvalues count00= 12.5 %,01= 25 %,02= 50 %,03= 75 %, andZ02beatsZ03because 25 % and 75 % "effectively sound identical"; random panning —Ovalues countOLR=00,O__=01,OL_=02,O_R=03, soOL_followed byZ02chooses among left, right and both while a start fromOLRwould include the mute; for these four-valued commands an added value wraps to the remainder after dividing by 4 (Z11= 17 acts as01); since version 6Zalso works in tables, and alternatingOLR/O__in an Automate table gives a random gate; random melody —Fxy's first digit is PU2's transpose in semitones, soZF0after anFre-pitches pulse 2 anywhere up to an octave plus a major third above the note; random chords —C37withZ10yields minor or major, possible since version 6 made the digits independent (in version 4 they were not); random sweep — Hypnogram's signature lead (Phantasm Dragon, at 1:30) randomises a sweep, which only pulse 1 can do. AZnever randomises anotherZ. - Version notes:
Barrived with version 7 (toured at 7.7.4 in January 2020) with the valuesB05never hops,B85about half the time,BF5about 15 times in 16, and on notesB0425 %,B0850 %; on kit instruments the digits are the left and right samples separately —B48= left 25 %, right 50 % (source: s-intense-tech-12-scoping-out-new-features). Since version 8Zworks with every command exceptH(andZ), which makes randomised straight-or-swung grooves possible (source: s-intense-tech-14-lets-appreciate-version-8). Contradiction: the version-6 manual saidZdoes not work with Hop, Groove and Delay; article 03's later footnote claims it does "as of version 8.1.9" including Hop, while article 14 and the 9.2.6 manual (s-lsdj-manual, above) excludeH(sources: s-intense-tech-03-dont-sleep-on-z, s-intense-tech-14-lets-appreciate-version-8). Zon noise shapes for random crash cymbals (a trick defense-mechanism credits to an Exploring Chip Tunes video): becauseZrandomises each digit independently, the variation can be confined to one loop mode and octave — first digit +0…4 at most so it never wraps pastFto0(silence), some rows with a first digit of0, second digitFfor a completely random divisor (source: s-intense-tech-17-the-joys-of-noise). "Probability sequencing" is one of the features johan-kotlinski lists for the stable LSDj 8 (source: s-intense-tech-13-kotlinski-interview).
Retrigger and resync › LSDj #
Rxy: x changes pulse/noise volume per retrig (0 none, 1–7 increase, 9–F decrease), y sets the rate (1 fastest, F slowest, 0 = retrig once). R8x is resync: R80 resyncs at 360 Hz, R8F stops it. Examples from the manual: R01 retrig every tick, RF4 retrig every fourth tick with decreasing amplitude (echo effect). CMD/RATE in the instrument slows R down. Dxx delays a note by ticks, which combines with retrigs for flams (source: s-lsdj-manual).
What a hardware trigger does (bit 7 of NRx4; sources: s-pandocs-audio-registers, s-pandocs-audio-details): the channel is switched on (unless its DAC is off), an expired length timer is reset, the period divider is reloaded, the envelope timer is reset and the volume set from NRx2; on CH1 the sweep restarts, on CH4 the LFSR is reset to 0, on CH3 the wave read index restarts while the last sample stays in the output buffer. A pulse channel's duty step is not reset — only its timer is — so "retriggering a pulse channel often enough will cause its 'duty step' to never advance": very fast retrigs freeze the waveform, which is presumably the mechanism behind the resync pitch drop (inference). Because a trigger zeroes the noise LFSR, retriggering CH4 at a steady rate repeats the same noise burst and turns it into a pitched, pulse-like tone (inference from the LFSR reset); a retrigger is also the cure for a noise generator locked up by a 15→7-bit switch (game-boy-apu).
From Intense Tech (sources: s-intense-tech-17-the-joys-of-noise, s-intense-tech-18-adsr-makes-life-easier): depending on the version R00 retrigs once or every tick — in 8.9.3 R01 retrigs every tick. On the noise channel a fast retrig chops the noise into a pulse wave: the pitch follows the R rate, the tempo (tick length) and the noise shape; a shorter LENGTH or ADSR controls the loudness; R80–R8F, "the super-fast retrig", ignores tempo and LENGTH. With the 8.1.0 ADSR, R's per-retrig volume change gives a tremolo. Infu's hi-hat is a noise instrument with R02 on its notes (source: s-infu-getting-started-with-lsdj); Dire Hit's late discovery: "the first number of an R command is an envelope" (source: s-chipmusic-tables-and-chords-threads).
Version history of R (sources: s-intense-tech-12-scoping-out-new-features, s-intense-tech-14-lets-appreciate-version-8): the "super-fast retrig" R8x arrived in the 7.7.4 development version as the much-requested return of the old wave-channel pitch wrap — the sound generator restarting at a very fast rate; on the wave channel the resulting pitch can be tuned by the R value rather than left to P, and on a pulse kick it reaches "about 3 whole tones lower than the pulse channel is normally capable of" (three whole tones = the manual's half octave). FX/SPEED, the 7.7.4 setting that slows C, P, R and V, became CMD/RATE in version 8; version 8 also made R on the wave channel restart the synth from its first wave frame, and with the version-8 ADSR RFx behaves like a tremolo.
R as the noise channel's dynamics control (source: s-defensemech-noise-channel-92l): the hardware envelope is a single smooth slope, so a decaying repeat cannot be written with E at all. R with a volume digit "will reduce this by one level and keep these numbers" — ghost snares, quieter repeats, and triplet fills from a four-tick retrig; leaving the instrument untriggered and changing only the shape is the variant. On kicks, R did not reset the pitch before LSDj 9.4.0, so a stutter needed an L 00 00 on the restarting tick; since 9.4.0 a plain R retriggers the pitch and the workaround is gone (source: s-defensemech-every-lsdj-kick).
The instrument number is itself a retrigger (source: s-painperdu-01-instrument-retriggering). A note plays without one; what the instrument number does is restart everything the instrument owns — the envelope, its table, and on the wave channel the synth's wave cycle. "It's really important to know that instrument and note are actually independent." Leave it off and a rising envelope keeps rising across the following notes, so triggering once per beat turns a run into a swell that resets on the beat, and a long PINGPONG wave instrument (LENGTH F, slow SPEED) finally gets to complete its cycle instead of restarting every note. With a table set to AUTOMATE the table advances per instrument value rather than per tick, so the stock L/R panning table gives L R L R when every note carries the number and L L R R when only every second one does (stereo-panning). It also costs less: fewer instrument numbers means fewer blocks and less CPU. The trap is drums — a kick on the wave channel is another instrument, so it re-triggers the lead that follows; the fix is to fit the synth's cycle between the hits (LENGTH 3 at SPEED 6 steps a frame every 16th note).
ROM retuning — patching a tracker's pitch table › LSDj — by hand #
Offsets verified on 3.8.9 only (source: s-little-scale-lsdj-tuning-tables):
| what | offset | size | notes |
|---|---|---|---|
| GB / GBC / GBA pitch table | $6D3A (27,962) | 216 bytes = 108 × 2 | starts with the bytes 2C 00 9C 00 06 01 |
| Super Game Boy pitch table | $6E12 (28,178) | 216 bytes | immediately after the first, recomputed for the SGB1's ~2.4 % fast clock |
- Open the ROM in a hex editor in overwrite mode (little-scale uses Hex Fiend on OS X). Do not insert — the ROM must stay 1,048,576 bytes.
- Find the table: "starts just after location
$6D30with the bytes2C 00 9C 00 06 01. Select 216 bytes starting with2Cand00" (source: s-little-scale-underclocking-and-retuning). - Paste your 108 little-endian values over it.
- Patch the second block too. KiGB reads only the SGB table "regardless of emulator settings", so a ROM patched in one place will test wrong there and play wrong under a Super Game Boy (source: s-little-scale-lsdj-tuning-tables).
- Save, flash, play.
ROM retuning — patching a tracker's pitch table › LSDj — with lsdj_tune #
abrasive's Perl script does all of the above from the command line and, uniquely, rewrites the note names as well, so the display matches the tuning. Built for LSDJ 3.9.9 (source: s-little-scale-abrasive-lsdj-tune):
lsdj_tune --et 24 --base A5 440 --rom lsdj.gb --out lsdj_et24.gb
lsdj_tune --cstep 78 --base 0 70 --rom lsdj.gb --out lsdj_alpha.gb # Wendy Carlos alpha
lsdj_tune --ratio 1,256/243,9/8,32/27,81/64,4/3,729/512,1024/729,3/2,128/81,27/16,16/9,243/128,2 \
--names D,Eb,E,F,F#,G,G#,Ab,A,Bb,B,C,C# --base 0 73.42 --rom lsdj.gb --out lsdj_pyth.gb
Modes: --et n, --cents, --cstep, --ratio; all 108 notes may also be given explicitly. Its stated limitation is that the base-frequency option "won't take custom note names, and sequences always start on the base note".
Sample looping (perfect loops, sustain loops, long loops) › LSDj: the loop points are a pattern command #
The Game Boy's kit samples loop too, and LSDj is unusual in letting the pattern move the loop while the sample plays (source: s-lsdj-manual).
- The kit instrument's LOOP is three-way:
OFFdoes not loop,ONloops and starts playing from OFFSET,ATKloops the sample but starts playing from the beginning — so ATK keeps the attack and repeats the body, the shape a sustaining instrument needs. OFFSET is the loop start (or, with LOOP off, a plain sample-offset) and LEN the length. Sxyon a kit instrument "changes the loop points. The first digit modulates the offset value; the second digit modulates the loop length. (1–7= increase,9–F= decrease.)" — the manual's own note is that "used creatively, this command can be very useful for creating a wide range of percussive and timbral effects". Walking the loop length down over a few rows turns any sampled tail into a pitched buzz; walking the offset along it granulates (retrigger, wavetable-programming).
The budget behind all of it: 3FA0 bytes per kit at 11,468 Hz, so a loop measured in time is measured in tens of milliseconds, and the sample must be lowpassed at 5,734 Hz and faded at both ends before it ever gets there (source: s-little-scale-lsdj-kits; chip-samples).
Sample offset tricks › LSDj #
The Game Boy has sample memory after all — the kit ROM — and LSDj offsets into it two ways (source: s-lsdj-manual).
Fxxon a kit instrument "modifies the sample position.00–7Fsteps forward,80–FFsteps back". Unlike9xx/Oxxit is relative and it goes backwards, so a column of smallFvalues walks a sample forwards and back — stutter and grain rather than a jump to a fixed point. (The same command means PU2 transpose + finetune on a pulse instrument and a wave-frame step on a wave instrument, so it only reads as an offset in a kit.)- The instrument's OFFSET parameter sets a static start point: with LOOP OFF it "can be used for skipping the initial part of a sound", the classic snare-tail-becomes-a-hi-hat trick that ST3's manual also documents; with LOOP ON it is the loop start. LEN cuts the other end (chip-samples, instrument-design).
Shuffle, swing and FunkTempo › LSDj #
Grooves are the native mechanism: each groove lists how many ticks every phrase (or table) step lasts. Groove 0 defaults to 6/6; 8/5 makes even steps last 8 ticks and odd steps 5 — swing; other lists give triplets and complex rhythms. In the groove screen A+UP/DOWN changes the swing percentage while keeping the total ticks, so the song speed stays constant (6/6 = 50 % → 7/5 = 58 %). Gxx selects a groove in a phrase or a table (SELECT+DOWN on it edits the groove); tables can run their own groove for rhythmic envelopes. The T tempo command is exact only for 6-tick grooves — otherwise use bpm = desired × ticks/step ÷ 6 — and sync modes expect 6-tick grooves (source: s-lsdj-manual).
Grooves also solve arrangement problems: to shorten the gap between a kick and the bass note that follows it, give the row pair its own groove — in defense-mechanism's example the first tick count of groove 10 is how long the kick lasts and the second how long the bass lasts, "No fancy kick transposition needed!" (source: s-intense-tech-10-kicks-part-1).
Defense Mechanism's groove practice (sources: s-intense-tech-06-groove-and-tick-tricks-part-1, s-intense-tech-07-groove-and-tick-tricks-part-2): a tick is the smallest time unit, its length set by the tempo; a G on a line makes that line last the groove's first value and the following lines the next values. Hypnogram's convention — grooves 01–0C set to 1…12 ticks so G03 reads "three ticks per line", 10–1F for custom feels (G10 = 7/5) — keeps commands legible. Swing lives per channel: 7/5 on the wave channel (kick and bass) against 6/6 elsewhere sits "in-between swung and straight"; 8/4 and 9/3 swing harder; 8/5/7/4 mixes two feels in 24 ticks for a human lead; 3/9 (or 3/9/6/6) makes room for note bends or a three-tick kick before a bass note. LSDj 6 restarts a groove on a repeated G, older versions do not. A 3-tick groove doubles phrase resolution at half the phrase length — H gives it back (H71 = hop to line 1 seven times). Triplets: G08 (8 ticks = 24 ÷ 3) for the three notes, then H00 to skip the last 6-tick line so the next phrase lands on the beat; 3/4 time can be a groove alone (a trick from Zef). Tables take grooves too (2 or 3 ticks for arps and duty changes), and Hop + Groove inside a table gives Hypnogram's dramatic "Zenarchy" sound. Mrwimmer's version of the same idea: G01 on a table's first line with groove 01 = 2/2 halves an arpeggio's speed without doubling rows (source: s-chipmusic-tables-and-chords-threads); aphasia's live tip: with a MIDI keyboard, the lowest possible groove and a high tempo minimise quantisation (source: s-chipmusic-lsdj-faq).
Tempo is not BPM (source: s-painperdu-06-grooves). The TEMPO field sets the tick rate; the groove decides how many ticks a step lasts, so the groove is what sets the musical speed and the feel. Picture the song as an hourglass: "tempo says how fast they will fall, but grooves say how many of them will be in each note" — hold TEMPO at 255 and the music still speeds up, slows down and changes feel as the grooves change. Consequences worth keeping:
- A 16-step phrase is a bar only at groove
6; at grooveC(12 ticks) it is half a bar, at groove3two bars. A ternary bar is 12 steps, not 16, so end it with anHhop. - A groove needs only one value if the speed is constant — the list wraps. A longer list is a per-step tempo map:
12 6 12 6 6 6 2 3is two long notes, two short, two long, and so on, and nothing stops you writing1 6 3 4 F Afor experimental work. - Grooves are per channel, so pulse 1 can run at groove
3while the wave channel runs at6— as long as the tick totals match (eight phrases at3= four phrases at6), "at the end of the day they still sing together". - Triplets by arithmetic: double the tempo and the groove together to keep the BPM (groove
C= 12 ticks), then run the triplet channel at groove8— 12 ÷ 3 × 2. - Tables take grooves too, and that is the space saver: "by default tables run at one tick per step", so a
Gin a table halves what a slow arpeggio costs and lets a percussion table pack more commands into the same time. Pain Perdu credits the trick to Joe Toye of Chiptune Belgium; Mrwimmer describes the same thing above.
Three more things pain-perdu does with grooves, from the walkthroughs:
- The groove reaches into the instruments. A wave-synth instrument's SPEED is ticks per wave frame, so it should be set to the groove's tick count: at groove
6/6, SPEED6puts exactly one wave frame on every step — "this is relevant to the groove, so if you're in groove5 5this is going to be5, for groove7 7this is going to be7" (source: s-painperdu-02-wav-channel-walkthrough; wavetable-programming). - The groove is a resolution knob, not only a feel. For a sidechain recovery, halving the groove to
3makes each step a 32nd, so the same twoEcommands recover twice as fast — "it's almost as if you hear the bass being triggered at the same time as the kick, but this is an illusion being made possible by the fast groove" (source: s-painperdu-04-sidechaining). - Two grooves at once, with the hop that keeps them honest. A chord section at groove
C C(12 ticks per step) against another channel at groove2"time together perfectly, you just have to be a bit of math" — six to one — but the fast channel needs anHhop at the end of its phrase or the two do not land together. In the same song the tempo itself is written as a curve, a newTvalue per phrase from100up through142and150to180and back down to80: "each phrase I'll have a new tempo that goes slightly up very organically … this was really painstaking … [but it] really pays off".Taffects the whole song from whichever channel carries it, so it goes on the second tick of a phrase when aGhas taken the first (source: s-painperdu-03-isometric-sav-walkthrough; arrangement).
defense-mechanism's 2024 version of the kick-into-bass groove is two instruments and two grooves: a wave kick and a separate 808 bass, with a groove of 3 9 — "I want this kick to play for three ticks and then the bass for the next nine" — and a second groove 3 9 6 so the following bar's timing works, returning to groove 0 after. It costs two groove slots and buys independent control of both sounds, plus the W command for how fast the bass decays (source: s-defensemech-every-lsdj-kick; the values are spoken over an auto-transcribed video and are (unverified); instrument-design).
Since version 8 the Z command also randomises a preceding G, so a phrase can switch between a straight and a swung groove by chance — Defense Mechanism expected "very interesting rhythmic consequences" (source: s-intense-tech-14-lets-appreciate-version-8); see randomization-and-probability.
Sidechain pump › LSDj #
The table envelope column is a custom amplitude envelope (amplitude digit + duration in ticks, loop with H in the second digit — the manual's tremolo example); a table that starts low and rises over a beat, run with a groove of the beat length, pumps any instrument that uses it. Exy on pulse/noise sets amplitude x with release y per row for hand-drawn ducks (source for the mechanics: s-lsdj-manual).
In a full arrangement it comes out as an envelope on every chord instrument: each arp note triggers a rising envelope so the chords give way on the beat — "kind of your poor man's sidechain compression emulation in LSDj, with just volume" — timed so the kick lands in the dip (source: s-painperdu-03-isometric-sav-walkthrough).
pain-perdu builds the whole effect out of those pieces (source: s-painperdu-04-sidechaining). Half of it is free: kick and bass share the wave channel anyway, so they cannot sound together — what has to be written is the recovery. Put E02 (50 %) and then E03 (100 %) on the steps after the kick and the bass swells back in on the 16th-note grid. Then halve the groove: at groove 3 each step is a 32nd, the same two commands recover twice as fast, and the pump stops announcing itself — "it's almost as if you hear the bass being triggered at the same time as the kick, but this is an illusion being made possible by the fast groove" (shuffle-funktempo). Duck the channels the kick never touches as well: an envelope command rising from 0 at speed A once per beat on the pulse channel "gives a little bit more of a four-to-the-floor groove … and it helps the kick stand out", and it carries the feel through bars with no kick at all — "even if you have no kick playing you still have the feel of the song". The same command on the noise channel gives the house-record hat that pumps instead of hitting. Two kick patches with different kill points and pitch-drop speeds (his verse kills at 4, his chorus at 6 with more low end) turn the same trick into a section contrast.
On the wave channel E is too coarse to pump with — E01/E02/E03 are 25 / 50 / 100 %, and "there's nothing between fifty and a hundred percent … sometimes 2 is too soft for an instrument and 3 is too loud in the context of your mix". Ramp LIMIT instead: 0 on the synth's first wave, F on its last, PLAY LOOP with the loop point at the end so the instrument sustains once it has recovered — "now we can have this going from zero to F and have this kind of naturally do its own sidechaining". SPEED and LENGTH set how fast the duck recovers, and a start value above 0 keeps it from ducking to silence; VOLUME and Q can ride the same ramp for a filter-and-volume pump (source: s-defensemech-wave-channel-ramble). Before LSDj 7's silky wave this was impractical — every frame change clicked (wavetable-programming).
Song initialisation and looping › LSDj #
Playback only stays in sync if every channel has something to play from the top: Infu keeps silent chains — chain 7F holding the empty phrase FE, used as 7E (a short bridge) and 7D (a full-length chain) — in every gap of the song screen, with the same number of phrases as the neighbouring chains, so START works from any row (source: s-infu-getting-started-with-lsdj). Grooves added at the end of a phrase must be taken back (H00, or a G back to the default) so the next phrase starts on beat 1 (source: s-intense-tech-07-groove-and-tick-tricks-part-2).
H is both the loop and the ending: in a phrase H00–H0F hop to the next phrase at the given step (H00 on step C is how you compose in 3/4), H10–HFE hop back within the phrase — first digit how many times, second digit the destination step — and HFF stops the song, or just that channel in live mode (source: s-lsdj-manual). Without an HFF the song screen simply plays its chain lists top-down and comes round again, so the sticky-state rule above applies to LSDj too: a T, M or G set late in the song is still set on the next lap.
Stereo panning › LSDj #
Instrument OUTPUT parameter (L/R/both/none); Oxx command to pan a channel from a phrase or table; B+LEFT/RIGHT in the song screen pans a channel live; Mxy sets or nudges the master volume per side (source: s-lsdj-manual). Classic use: the same chain on PU1 and PU2, one left, one right, slightly detuned (detune).
The hardware: NR51 ($FF25) has one left bit and one right bit per channel — a channel is hard left, hard right, centre (both) or absent, nothing in between — and NR50 scales each side in eight steps (0 = 1/8, 7 = full) without ever muting, which is what Mxy writes. Changing NR51 for a channel whose DAC is on causes a pop, so make panning moves on silent rows; the built-in speaker merges both sides to mono (sources: s-pandocs-audio-registers, s-pandocs-audio-details, s-pandocs-audio-overview).
One table for both pulses: when PU1 and PU2 play the same instrument with its table set to Automate at the same time, channel 1 receives the even-numbered table rows and channel 2 the odd-numbered ones, so alternating O values pan the two channels apart from a single table, instrument and phrase (source: s-intense-tech-09-lets-table-this-discussion).
Clicks and tricks from the forum: on pre-8.8.0 versions an O change clicks, so "fade the instrument off before doing the panning" (herr_prof; source: s-chipmusic-lsdj-faq); the stereo snare trick is the opposite use — a very quick left-to-right flick at the top of the snare table, then centre (Victory Road; source: s-chipmusic-noise-drum-threads); Infu's snare table opens with alternating O rows to make the snare "wide on the speakers" (source: s-infu-getting-started-with-lsdj); "Use O command to create stereo space" (SketchMan3; source: s-chipmusic-lsdj-advanced-tricks).
Random and alternating panning (intense-tech): the O values count OLR = 00, O__ = 01, OL_ = 02, O_R = 03, so OL_ followed by Z02 on later steps chooses among left, right and both — starting from OLR would include the mute — and a value added past the range wraps to the remainder after dividing by 4; since version 6 Z works in tables too, and alternating OLR/O__ in an Automate table gives a random gate (randomization-and-probability; source: s-intense-tech-03-dont-sleep-on-z). defense-mechanism counts stereo placement as one of three mixing levers beside volume and register: alternating left/right on pulse notes or noise hi-hats creates "a sense of space and ambience" even with only left, right or both available (source: s-intense-tech-15-lets-mix-it-up-and-down). sabrepulse's beginner pattern puts the O commands on the empty rows between the lead's notes — OL_ on rows 1, 5, 9 and D, O_R on rows 3, 7, B and F, notes on the even rows — which "gives a better stereo effect" than panning on the note rows and leaves those rows free for other commands such as C (source: s-sabrepulse-getting-started-with-lsdj).
Vibrato and delayed vibrato › LSDj #
Vxy: x = speed, y = depth in semitones — 0 0.125, 1 0.25, 2 0.375, 3 0.5, 4 0.75, 5 1, 6 1.5, 7 2, 8 2.5, 9 3, A 3.5, B 4, C 5, D 6, E 7, F 8; V00 resets. Shape and speed depend on the instrument's PITCH setting: with PITCH = TICK the vibrato is synced to the music (assuming 6 ticks/step) and CMD/RATE slows it; A+LEFT/RIGHT on PITCH chooses the shape (triangle, saw or square, upward or downward). Delayed vibrato: put V a few steps after the note, or in the instrument's table on a later row so every note gets it automatically. The manual also suggests V (and P) on noise snares to liven them up (source: s-lsdj-manual).
Dire Hit's account of the digits: the first is the modulation speed (0 slow … F "so fast it almost becomes audible as a tone"), the second the depth; VFF is FM in all but name — Monodeer's pulse-channel cymbals are a single V command, "if you ever need noise percussion out of a pulse channel" (source: s-chipmusic-tables-and-chords-threads). SketchMan3: "High frequency V effects can give you a more complex raspy sound" (source: s-chipmusic-lsdj-advanced-tricks); a fast V on a table's first tick, cancelled by V00 on the second, sharpens an attack (source: s-intense-tech-09-lets-table-this-discussion).
More from intense-tech: random vibrato is V00 on the note and Z03 on each repeat of it, so every repeat acts as V00…V03 (randomization-and-probability; source: s-intense-tech-03-dont-sleep-on-z). The slowing setting was introduced as FX/SPEED in version 7 (7.7.4) — it lengthens each step of C, P, R and V, the V only when PITCH is TICK — and renamed CMD/RATE in version 8 (sources: s-intense-tech-12-scoping-out-new-features, s-intense-tech-14-lets-appreciate-version-8). Since 9.1.0 the TICK vibrato rates are rhythmic at the default groove — one cycle per V0x 16 steps, V1x 12, V2x 32/3, V3x 8, V4x 6, V5x 16/3 … VFx 1/2 step — and V also works on noise instruments, always tick-based (source: s-intense-tech-19-new-noise-and-910-news).
Pushed far enough, a V on the wave channel stops being vibrato: with the right combination of speed and depth a bass note "kind of self-resonates with itself", a sound defense-mechanism rates highly and uses rarely — "I honestly don't use enough V commands on the wave channel". It belongs to one note, so a different pitch needs the values retuned, and silky wave may have softened it (source: s-defensemech-learning-lab-shorts).
Two wave-channel notes from pain-perdu (source: s-painperdu-02-wav-channel-walkthrough): in the instrument screen, LEFT/RIGHT cycles the vibrato type while A+UP/DOWN inverts the vibrato's phase; and a fast V on a wave instrument — normally a pulse-channel trick, since wave instruments are raspy already — turns a raspy hand-drawn wave into "a kind of flanger filtery modulation effect" with no synth movement at all. It costs CPU, and because the modulation interacts with the note's pitch the value that works on one note will not work on the next, so it belongs on the note rather than in the table. A slow vibrato does the opposite job: it detunes a held pulse note enough to "fight off the really robotic feel" (source: s-painperdu-03-isometric-sav-walkthrough).
Two more places V earns its keep. On the noise channel it has worked since 9.1.0, alongside C and P, and combines with P — a bend and a wobble on the same hit; the pitched (short-loop) noise shapes make that read as a tonal snare rather than as noise (source: s-defensemech-noise-channel-92l). And on a wave instrument imitating an acoustic one, V is most of the imitation: "using a variety of vibrato speeds (Vxx commands) will also help make a flutey tone sound more convincing. It's all about articulation, really. LSDJ is really good for flutey articulation though!" — varied speeds across a phrase, not one setting held (Victory Road, source: s-chipmusic-lsdj-wav-instrument-tutorials; lead-articulation).
Volume slides, fades and effect memory › LSDj #
No slide command: volume is shaped per note by Exy (x = level 0–F; y = 1–7 decrease from fastest to slowest, 9–F increase from slowest to fastest, 0/8 hold), by the instrument ENV/ADSR and by the table volume column (level + ticks, looping when all 16 rows are used). Until 8.8.0 every pulse or noise volume change reset the hardware envelope with a click; since 8.8.0 a software volume makes E, the table column and K click-free, with speeds from 1 (shorter than any hardware speed) to F. Mxy moves the master volume per side (9–B up, D–F down). Global fades and ducks are therefore tables and M, not slides — and the four wave-channel steps are enough for a rhythmic one: because E02 is 50 % and E03 100 %, an 02 followed by an 03 on the next step is an audible pump locked to the 16th note, which is how pain-perdu writes the recovery half of a sidechain. On the pulse and noise channels he instead runs an envelope that starts from zero and rises once per beat, so the pump is there even in bars where the kick is not (sidechain-pump; source: s-painperdu-04-sidechaining). (adsr-envelope, sidechain-pump; sources: s-intense-tech-18-adsr-makes-life-easier, s-intense-tech-09-lets-table-this-discussion, s-lsdj-manual).
Mixing levers beyond E (source: s-intense-tech-15-lets-mix-it-up-and-down; the headroom argument behind them is on levels-and-headroom): when E03 (100 %) is too loud and E02 (50 %) too soft on the wave channel, cap the synth's LIMIT instead — at instrument VOLUME 3, LIMIT 8 gives about 50 %, 9 ≈ 56 %, E ≈ 94 % — and different LIMIT values on the synth's first and last wave, run with W (speed, length), make a wave-channel volume envelope (wavetable-programming). On pulse and noise the version-8 ADSR chains E-like stages and can fade in to a chosen lower maximum, where a rising E climbs to F or the next E; E commands and the table volume column override the ADSR (source: s-intense-tech-14-lets-appreciate-version-8). A transient beats a louder level: instrument volume around 90 with the table's E pulling it down after the first tick lets a snare cut through "without overpowering the other channels" (Pain Perdu's trick; instrument-design).
Before software volume the clicks were the topic of the LSDJ FAQ thread (source: s-chipmusic-lsdj-faq): a table fade-in 01 21 41 61 81 A1 clicks on every step because "to change the volume, the phase of the waveform needs to be restarted" (nitro2k01 — the hardware behaviour Pan Docs describes, adsr-envelope); fixes of the time were chained E commands that continue where the previous one stops, aphasia's stepped fade (a short loud 0F, then a sustain at the wanted level, repeated), or spacing the steps to the groove's ticks so the clicks fall on the beat. Infu's reading of ENV: each box is a level and the speed to the next box's level, 0 holds, lower speeds are shorter — a fade-in starts at 0: 07/88/-- (source: s-infu-getting-started-with-lsdj).
LIMIT is the wave channel's volume fader, and VOLUME is not. The two do different jobs and only one of them is safe to move: VOLUME scales the signal before CUTOFF, Q, PHASE and DIST, so turning it down also destroys the clipping or wrapping that made the sound — "what if you want to keep the same wave shape … I really like this sound, but it's too loud, and this was the bane of my existence in the early versions of LSDj, because you're just stuck — you can't get it to wrap if the volume isn't high". LIMIT (added in synth version 6) constrains the samples after all of that: F allows the full 0–F, 5 allows only 5–A, and whatever exceeds the window is handled by the DIST type. It exists precisely because the hardware's four steps leave the channel "often being too loud at 100% volume but too quiet at 25% or 50%". defense-mechanism's verdict: "LIMIT, I think, is almost more useful than anything else on this entire thing." Because the synth interpolates across its 16 waves, different start and end LIMIT values (say F → 4) are a fade — "a nice gradual fade without having to use the E commands, which only give you 100, 50, 25 or zero" (sources: s-defensemech-learning-lab-shorts, s-intense-tech-02-wave-synth-deep-dive-part-2; wavetable-programming, levels-and-headroom).
The wave channel is the exception (sources: s-chipmusic-lsdj-wav-channel-release, s-defensemech-wave-channel-ramble): E gives four steps only (0 / 25 / 50 / 100 %), and they are a bit shift, so the quiet settings also lose resolution. Three ways around it, in the order they were found — draw the fade into the waves themselves and step frames with F01 from a table (16 steps per synth, 32 across two); pan the channel alone to one side and use M, which has 8 steps and does move it; or, from LSDj 8, ramp LIMIT across the synth's waves, which is the smoothest of the three and doubles as a sidechain-pump.
Wavetable programming (waveform / arp tables) › LSDj #
Two different things are "wavetables" on the Game Boy:
- Instrument tables — six columns (amplitude envelope, transpose, two command/value pairs), one tick per step by default, started by the instrument's TABLE setting or
Axx, looped withH, with probabilistic hops viaB. They do what the SID-Wizard wave/arp table does: pitch drops for drums (transpose column +L/P), noise-then-tone attacks (switch instruments/Eper row), custom envelopes (tremolo example in the manual). With TABLE set to STEP the table advances one row per note trigger — a per-note sequence. - The wave channel's synth: 16 synth sounds × 16 four-bit waves. The synth screen generates them from a SIGNAL (square, saw, triangle, custom), FILTER (low/high/band/all-pass), DIST (CLIP/FOLD/WRAP), PHASE (PINCH/WARP/RESYNC), fading VOLUME, CUTOFF, Q, VSHIFT, LIMIT and PHASE from the first wave to the last. WAVE instruments play them ONCE, LOOP, PINGPONG or MANUAL;
Fxxsteps through frames by hand (F10= next synth sound),Wxychanges synth speed/length. The wave screen edits single waves.
(source: s-lsdj-manual)
LIMIT is not a volume control, and that is the point (source: s-defensemech-learning-lab-shorts): VOLUME scales the signal before the rest of the chain, so turning it down destroys the clipping or wrapping that made the sound — "you can't get it to wrap if the volume isn't high" — while LIMIT constrains the dynamic range afterwards and keeps the shape. Ramped across a synth's 16 waves it is also the fade the E command cannot give (E steps 0 / 25 / 50 / 100 %). There is no LIMIT command for the phrase screen, so different levels mean different synths. VSHIFT finally has a rule from the same clip: it is to DIST what Q is to the filter — with CLIP it merely squashes the wave against the ceiling ("a sound-bad button", "just a way to make it quieter"), but with FOLD or WRAP the shifted part folds or wraps back in and "that's almost like a pulse-width modulation thing happening" (pulse-width-modulation). 10 lifts the wave about one step; FF is silence. In older versions VSHIFT wrapped regardless of the DIST setting.
Sweeps longer than one synth (same source, credited to hypnogram): slice the CUTOFF range across consecutive synths — synth 1 1→2, synth 2 20→30, synth 3 30→40, Q around 5–7 — and play the matching instruments in sequence, each PLAY ONCE at a slow SPEED. The sweep then continues past the sixteen-frame limit, at the cost of a synth per slice.
The instrument side of the synth (source: s-painperdu-02-wav-channel-walkthrough): LENGTH is how many of the 16 waves the cycle uses, REPEAT is how many frames at the end of that cycle repeat afterwards — "if you play with this cleverly you can have really interesting rhythmic wave cycles" — and SPEED is ticks per frame, which belongs to the groove rather than to taste: SPEED 6 under groove 6/6 advances one wave per step, SPEED 5 under groove 5/5, and so on. SPEED 1 "is more clipping than actual modulation". MANUAL is the quiet mode because only one wave is ever read, so no frame change occurs. Two corrections from the same source: hand-drawn waves are not restricted to MANUAL — "one of the most common misconceptions is that the hand-drawn waves in LSDj are only accessible when you set this to MANUAL … [they] are available even when you're in PINGPONG and LOOP and ONCE" — and F offsets that run past a synth's sixteen waves bleed into the next synth's waves, which is a way to make one note evolve out of its own timbre.
Hand-drawn banks and their hazards (source: s-chipmusic-lsdj-wav-channel-release): the synth screen is a generator, the wave screen an editor, and re-entering the synth screen overwrites all 16 of that synth's waves — later versions warn first ("are you sure you want to override hand-drawn waveforms?"), older ones do it silently. F is relative and accumulates, so F05 F05 lands on frame 0A; a wave — a section of one or a whole one — can be copied and pasted between waves in the WAVE screen (SELECT+B, highlight, B, then SELECT+A on the target), which is what makes a 16-wave hand-drawn bank affordable at all (source: s-painperdu-05-shortcuts-and-workflow); F10 steps into the next synth, which is also how two synths are chained into a 32-frame animation. Frame changes clicked on hardware until LSDj 7's silky wave; the standing advice was to set the frame rate so the clicks fall on 16ths, where percussion masks them.
A wave can also hold two notes at once: draw a second waveform at 2× or 3× the fundamental on top of the first and the channel sounds a bass note plus an independently steerable higher one — the ghost-channel (sources: s-chipmusic-lsdj-ghost-channel, s-tylerbarnes-ghost-channel-tutorial). The 2020 answer needs no drawing at all: an allpass filter with a low CUTOFF and a high Q (around 8–9) lifts one overtone into audibility while passing everything else — "the nice thing about the allpass is that no matter how much you boost this Q you really never lose the root note", where lowpass isolates the fifth but throws away the edge. Both give "this overtone emphasis that sounds like almost two notes … the power chord" (source: s-defensemech-ghost-channel-allpass).
The hardware under the wave channel (sources: s-pandocs-audio-registers, s-pandocs-audio-details): wave RAM ($FF30–$FF3F) holds 16 bytes = 32 four-bit samples, played upper nibble first at 32 × the tone frequency (65536 ÷ (2048 − period value) Hz — one octave below a pulse channel at the same value, which is why WAV is the bass channel). There is no envelope, only the NR32 output level 100 / 50 / 25 % (a right shift of the samples) or mute — LSDj's VOLUME setting and E00–E03. Wave RAM can only be rewritten while the channel is inactive (on the DMG only in step with the channel's own reads; on the Color a write lands on the byte being played), so every wave or synth-frame change means stopping and retriggering the channel; a retrigger resets the read index but keeps the last sample in the output buffer, and on monochrome consoles retriggering while a byte is being read corrupts the first bytes of wave RAM. Pan Docs names the two classic uses: "shortening" the wave by repeating a pattern or doubling samples and read rate, and "lengthening" it by reloading wave RAM as soon as it has been read once — "sometimes used for full-on sample playback", which is presumably how LSDj's kits and speech play on this channel (inference).
Drum tables from Intense Tech (sources: s-intense-tech-10-kicks-part-1, s-intense-tech-11-kicks-part-2): the wave kick table is a fast P on the first line (how quickly the pitch falls from the played note) and on the second an L with transpose 80 — the slide stops at the lowest note instead of wrapping to the top, survives tempo changes (DRUM-mode P/L ignore tempo) and leaves the attack tunable by the note (C5–C7) and the P speed. The "Kyoto kick" (popularised by Toriena) puts a noisy, gritty wave in slot 00 and the clean kick in 01–0F, switching with F01 on the second table line — or without any command by setting PLAY LOOP, LENGTH 1, REPEAT 0, SPEED 01, which plays wave 00 for one tick and then jumps to 0F. A kick that becomes a bass note: in LSDj 7 with DRUM pitch, start two octaves up and let the L line carry transpose E8 (−24); in LSDj 6 it needs FAST pitch and instrument TRANSPOSE ON — line 1 transpose 0C with a two-tick P down, line 3 transpose F4 with an L. A wave snare is the same shape, P then L to the note the snare is tuned to, E commands trimming the decay, layered with a noise snare.
The wave synth in depth (sources: s-intense-tech-01-wave-synth-deep-dive-part-1, s-intense-tech-02-wave-synth-deep-dive-part-2, s-infu-getting-started-with-lsdj): a wave is 32 four-bit samples, and the number of cycles inside the frame is the harmonic that sounds, so the synth's CUTOFF reads as harmonic numbers — every multiple of 10 is one overtone (20 the octave, 30 octave + fifth, 40 two octaves). SIGNAL saw = all harmonics, square = odd harmonics (the pulse channels' 50 % sound), triangle = odd harmonics falling off faster (the deep NES-style bass); there is no sine, but Lowp with CUTOFF 10, Q 3 and VOLUME 08 extracts one — the lowest, cleanest bass and kick wave the channel can make. PHASE Normal compresses the wave and pads it with silence, so Square with Phase 00 → 1F is a pulse-width sweep ("SID lead"; Triangle gives a vocal-like lead); Resync repeats the compressed wave to fill the frame (new overtones), Resync2 repeats without compressing (quieter). DIST governs overflow when VOLUME or Q exceed 0–F: Clip squares the wave off, Fold (version 6) mirrors the excess for resonant highs, Wrap throws it to the opposite edge for buzz; VSHIFT follows the DIST type in version 6 (FF with Fold inverts the wave). LIMIT (version 6) clamps the samples afterwards (5 = 5–A) — the fine volume control the hardware's four levels lack, and with different start and end values a volume fade. Infu's rules of thumb: Q does little until CUTOFF moves, VOLUME above 20 triggers DIST, LIMIT above 0F rarely helps, instrument LENGTH skips waves, and W sets SPEED and LENGTH from a phrase. A synth's parameters interpolate from the first to the last of its 16 waves, so a kick and a bass can share one synth: the kick plays the first wave, the bass loops the rest.
LENGTH changes resolution, not the endpoint (source: s-defensemech-wave-channel-ramble). The synth always travels from wave 0 to wave F; LENGTH decides how many of the sixteen are generated and spreads them evenly — "it actually always plays from zero to F, but it will only play as many frames and it will interpolate those … it kind of skips frames in the middle to equalize them". The chart, written out by defense-mechanism himself (so not subject to transcript error):
| LENGTH | waves generated | LENGTH | waves generated | |
|---|---|---|---|---|
0 | 0 | 8 | 0 1 3 5 7 9 B D F | |
1 | 0 F | 9 | 0 1 3 5 7 8 9 B D F | |
2 | 0 7 F | A | 0 1 3 4 6 7 9 B C E F | |
3 | 0 5 A F | B | 0 1 2 4 5 7 8 A B D E F | |
4 | 0 3 7 B F | C | 0 1 2 3 5 6 7 9 A B D E F | |
5 | 0 3 6 9 C F | D | 0 1 2 3 4 6 7 8 9 B C D E F | |
6 | 0 2 5 7 A D F | E | 0 1 2 3 4 5 6 7 9 A B C D E F | |
7 | 0 2 4 6 9 B D F | F | 0 1 2 3 4 5 6 7 8 9 A B C D E F |
Three more from the same source. The filters are not filters: "this is a wavetable synthesizer, it's not a subtractive synthesizer — so the filters that you see here are actually just kind of emulated" — the filtering happens when the sixteen waves are generated, not on the output, which is why CUTOFF behaves like a harmonic selector rather than a tone control. The harmonic ladder runs further than the 20/30/40 rule above: with bandpass and a high Q, CUTOFF 10 is the fundamental, 20 the octave, 30 the fifth above it, 40 two octaves, 50 a major third, 60 another fifth, 70 "an out-of-tune kind of seventh", 80 another octave, 90 "like a major second", A0 "another major third", B0 "a sharp fourth", C0 a fifth, D0 "almost like a sixth … kind of a flat seventh" — above that the synth "probably only generates up to here really" (harmonic-series). And adding an overtone is multiplying the wave: on the oscilloscope, raising CUTOFF from 10 to 20 "kind of replicate[s] your waveform … every time you add an extra overtone you multiply the waveform", which is also what PHASE RESYNC does by another route — the mechanism the ghost-channel exploits, stated from the outside.
LIMIT ramped into a self-sidechain (same source): with LIMIT 0 on the first wave and F on the last, PLAY LOOP and the loop point at the end, the instrument ducks and recovers on every note — "now we can have this going from zero to F and have this kind of naturally do its own sidechaining", SPEED and LENGTH setting the recovery time and a start value above 0 keeping the duck out of silence. "You could do more than LIMIT too — you could do VOLUME here, you could do Q." He notes this only became practical once the wave channel stopped clicking (sidechain-pump).
How the wave channel changed from version 7 to 9.2 (sources: s-intense-tech-12-scoping-out-new-features, s-intense-tech-14-lets-appreciate-version-8, s-intense-tech-19-new-noise-and-910-news, s-intense-tech-21-whats-new-in-lsdj-92): version 7 introduced silky wave — a timer moves the wave-RAM rewrite to "a more opportune time", so the hardware click of every frame change disappears and a synth at SPEED 01 becomes "eminently more audible at its intended frequency"; version 7 also brought a wave-channel oscilloscope, a wave instrument FINETUNE of -F…+F and the R8x super-fast retrig, which brings the old wave-channel pitch wrap back as a tunable effect (retrigger). Version 8 renamed REPEAT to LOOP POS (the position of the loop point; 0 repeats every frame within LENGTH), made R restart the synth from its first frame, made MANUAL the default play mode and allowed cloning a synth from the wave instrument screen with SELECT+(A,B) on the synth number. Version 9.1.0 gave FINETUNE two digits (an old 01 equals a new 10), gave LIMIT two digits so that values above 0F overdrive — with CLIP the samples wrap and new higher harmonics appear — and made wave F commands immediate again: silky wave had delayed them since version 7, so the slight click returns but frame changes land exactly on the tick. Contradiction: Infu's rule that LIMIT above 0F "rarely helps" (source: s-infu-getting-started-with-lsdj) vs Defense Mechanism presenting the overflow of 9.1.0 as a deliberate overdrive worth trying. Version 9.2 fixed waves that had been inverted and displaced by one sample and rebuilt PHASE: PINCH and WARP are the old NORMAL with better interpolation (PINCH also with less DC offset), the new RESYNC is a smoother version of the old RESYNC that sounds close to the old RESYN2, and the new RESYN2 is the old RESYNC "for when you really want to get dirty with aliasing" — which is how the Normal/Resync/Resync2 description above maps onto the manual's PINCH/WARP/RESYNC/RESYN2; the synth screen also swapped the positions of CUTOFF and Q. A new WAVE instrument play mode RESYNC is PINGPONG without silky wave: SPEED 1 gives the low undertone of versions up to 7.3.3, and slower speeds switch frames exactly in time, which is audible on low bass notes.
LIMIT as a volume control (source: s-intense-tech-15-lets-mix-it-up-and-down): where E02 (50 %) is too soft and E03 (100 %) too loud, LIMIT caps the waveform regardless of the instrument VOLUME — 8 gives about 50 % at VOLUME 3, 9 about 56 %, E about 94 % — and different LIMIT values on the synth's first and last wave, run by W (speed and length), make a volume envelope (volume-slides).
Sample-derived wavetables — the wave cruncher (sources: s-intense-tech-05-wave-cruncher-instrument-library, s-intense-tech-08-dotcnts-wave-cruncher): lsdj-wave-cruncher (by DOTCNT) reduces one tonal note to a series of 4-bit waveforms, one reduced cycle per wave, that fill the 16 frames of a synth — it "turns the wave synth itself into a rudimentary sampler". Command line: crunch SAMPLE.WAV A4 (or the frequency in Hz, or auto, which takes 30–60 s and can fail on complex waveforms) with --normalize, and --linear (one cycle from each of 16 equal slices of the sample) or --exp (more frames from the attack, fewer from the decay) instead of the default first 16 cycles; --channel=0|1 picks a side of a stereo file, --output= names the .snt, --analyze only reports the detected pitch. Bells, FM electric pianos and steel drums work; snares and other non-tonal sounds do not. The .snt is written into a synth slot of a save or an .lsdsng with liblsdj's lsdj-wavetable-import savefile.sav synth.snt 0 (a save is patched only in its working-memory song), so the instrument travels with the song, unlike kit samples in the ROM; play it as a WAVE instrument with PLAY ONCE, LENGTH 3, SPEED 3 as a starting point and adjust to the tempo. Ready-made .snt files are collected in the lsdjsynths repository (psgcabal on GitHub).
Articulating a wave instrument — the flute problem, "all the tutorials I find are just about kick drums and snares" (source: s-chipmusic-lsdj-wav-instrument-tutorials). Victory Road's recipe is a table trick, not a waveform trick: start from a sine or triangle "maybe with a couple notches in it for some extra harmonics", make the first frame of the synth quite a bit louder than the rest, set PLAY to MANUAL, and put an F01 on the first tick of the instrument's table. The loud first frame is the attack, and because a table only restarts when the note carries the instrument number, omitting the instrument number slurs — "you can imitate tonguing and slurring in the phrases by removing the instrument number from notes that you want slurred" (lead-articulation). Flutter tonguing: give the third frame a slightly different volume and shape, then alternate frames two and three from a separate table started with A — "F01 to move ahead, FFF to move back" (FFF is −1 in F's relative arithmetic). tyler-barnes adds noise-burst frames for the breath of the attack; an0va argues against imitation altogether and works subtractively: "Start with sine or a thick square so you have a lot of bass — then mess with parameters and chip away at the bass frequencies until you get something you like. It's like ice sculptures then." (He also settles which end of CUTOFF is which: 00 is the low end, FF the high, which is why a high-pass instrument at the default FF seems silent.)
The instrument number is what retriggers the wave cycle (source: s-painperdu-01-instrument-retriggering). A note without an instrument number plays with whatever is already running; the number re-reads the settings and restarts envelope, table and the synth's wave cycle. So a PINGPONG instrument with LENGTH F and a slow SPEED never gets heard in full if every note is triggered — "I cannot actually hear the full range of wave cycles" — but trigger it once every four notes and the whole cycle plays: "if you have something that cycles through waves really slowly you can have rhythmically evolving waves that are really interesting". The practical wrinkle is that kicks usually live on the wave channel too, and a kick is a different instrument, so it retriggers the lead when the lead returns; the fix is to size the cycle to the gap — LENGTH 3 at SPEED 6 completes between 16th-note kicks. The same rule reshapes tables: with TABLE set to AUTOMATE the table advances per instrument value, so an L/R panning table gives L R L R when every note is triggered and L L R R when only every second one is (stereo-panning).
Two more instrument-level moves: F3 on a three-frame bass offsets the wave cycle so the note does not start at its quietest, and different offsets on successive hits "makes a bit of differentiation to something that's really four-to-the-floor"; and a filter sweep can be built into the synth itself — high cutoff on the first wave, low cutoff with high resonance on the last, so the note "cycles through a very abrasive squarey sound" on its own (source: s-painperdu-03-isometric-sav-walkthrough).
Nesting tables with A (source: s-intense-tech-09-lets-table-this-discussion): tables are "arguably the sole most useful feature to shape your sounds" and there is never a spare one — there is nothing beyond table 1F. The volume column is level + hold ticks (36 = volume 3 for six ticks; on the wave channel the level is only 0–3), and a completely filled column loops from the top while a partly filled one holds its last level. A in the command column stacks a second table under Automate — one command in the phrase, one in table 01, A02 in its second column and two more in table 02 gives "a total of four commands at once"; without Automate it simply extends the current table into the named one. A20 or higher stops the table without needing a K, "since no tables beyond 1F exist". And a quirk worth a free stereo widener: two channels playing the same Automate instrument at the same time split the table between them — channel 1 takes the even-numbered rows, channel 2 the odd ones, "easy stereo panning or similar effects using only one table, one instrument, and one phrase".
Transients by waveform switch (source: s-defensemech-every-lsdj-kick): put a harsh wave in the synth's first frame and step off it with an F on the first tick — and copy the frame you want to keep before editing the synth, because the synth screen regenerates the whole bank. The same trick on the pulse channel is offered untested; the wave channel's advantage is simply that it reaches lower (the pulse channels stop at C2).
LSDj Wave Cruncher cheat sheet
Reference
Cheat sheet#
crunch SAMPLE.WAV NOTE|FREQUENCY|auto --flags — e.g. crunch epiano.wav A4, crunch epiano.wav 440, crunch epiano.wav auto (detection takes 30–60 s and can fail on complex waveforms).
| flag | effect |
|---|---|
| (none) | the first 16 wave cycles |
--linear | one cycle from each of 16 equal slices of the whole sample |
--exp | more frames from the attack, fewer from the decay |
--normalize | maximise the level before crunching (recommended) |
--channel=0 / --channel=1 | left or right channel of a stereo file |
--output=name.snt | name the result (e.g. bell-exp.snt) |
--analyze | only report the detected frequency; no output |
Input: a .wav of one tonal note; sounds rich in overtones (bells, FM electric pianos, steel drums) work, noisy ones (snares, whistles) do not. In LSDj set the WAVE instrument to PLAY ONCE, LENGTH 3, SPEED 3 as a start and adjust per tempo and per crunch (source: s-intense-tech-08-dotcnts-wave-cruncher).
Martin Galway's player (the Ocean "macro-language" driver) cheat sheet
Reference
Cheat sheet#
All from the two reverse-engineered files (sources: s-realdmx-galway-rambo-player, s-realdmx-galway-arkanoid-player).
The stream — one byte-code program per voice, no patterns, no order list:
| bytes | Rambo loader | Arkanoid |
|---|---|---|
$00–$58 / $00–$5e + nn | note (C-0 … E-7) with nn = index into a 17-entry duration table (multiples of 4 frames) | note with nn = 1-based index into a 32-entry table rebuilt per tune as multiples of its minimum duration |
note + $60 + nn | note with an immediate duration in frames | note with a raw tick count |
$5f / $bf | rest (table / immediate time) | $5f nn rest |
≥ $c0 | opcode + 2 parameter bytes (3 bytes; CE has 4) | opcode + parameters (1–4 bytes) |
Opcodes
| Rambo loader | Arkanoid | meaning |
|---|---|---|
C0 RET | C0 RTS | return from a call; on an empty stack, stop the voice |
CA addr PLAY | C2 addr JSR | call a sub-stream (8-level stack per voice) |
CE addr,n PLAYT | C6 n,addr JSRT | call with a note transpose ($f4 = −12) |
| — | C4 addr JMP | jump (endless tunes; voices can jump into each other's streams — a delayed echo) |
DA n … DC REPEAT/NEXT | CC n … CE FOR/NEXT | loops, nestable |
CC n TRANS | (in JSRT) | set the transpose |
C2 addr INSTR5 | D4 addr INSTR | copy 5 bytes: control, AD, SR, gate time, "hrtime" |
C4 addr INSTR | D2 n,addr SETNI | copy a whole instrument (29 bytes) |
C6 addr SETFQ | F0 addr SETFI | copy the 14-byte frequency program |
C8 addr SETPM | — | copy the 10-byte pulse program |
D8 addr ARP | (DC $08 addr) | load a 10-byte / 4-byte arpeggio table |
D0 off,val ISET | CA id,val SET, DC id,v1,v2 SET2I | poke the instrument definition |
D6 off,val CISET | D6 id,val SETCI, DE id,v1,v2 SET2CI | poke the running instrument — change the sounding note |
D4 addr EXEC | D8 addr EXCT | execute 6502 code from the song (Rambo's morse-code intro; Arkanoid's filter switches) |
| — | E0 LF3, E2 addr FILTA | filter on voice 3 (resonance $f, low-pass); load a 16-byte filter envelope |
Reading a phrase: p2c9d: REPEAT 8 / $00,$01 / NEXT / REPEAT 4 / $00,$02 / NEXT / RET then PLAYT G4,p2c9d and PLAYT Fx4,p2cb4 (Rambo); sub07: JSRT $1f sub06 / JSRT $1d sub06 / JSRT $1b sub06 / JSRT $1a sub06 / RTS (Arkanoid).
Instrument = 29 bytes ($00–$1c):
| offset | content |
|---|---|
$00–$07 | four signed 16-bit frequency adders |
$08–$0b | their durations in frames/ticks (0 = skip) |
$0c | initial delay |
$0d | flags: $01 reload the stages (loop), $80 reload from the note's own frequency after stage 4, $02 apply adder 4 during the delay (a slide into the note), $08 arpeggio mode (Arkanoid: voice 2 only) |
$0e/$0f | two pulse-width stage lengths |
$10 | pulse delay |
$11 | pulse flags ($80 reset the width and restart, $01 restart the counters) |
$12–$15 | two signed 16-bit pulse adders |
$16/$17 | initial pulse width |
$18 | control byte (the test bit here is a mode flag: release the gate $1b ticks before the next note instead of after the note-on) |
$19/$1a | AD, SR |
$1b | gate time ($ff = never release) |
$1c | "hrtime": frames after gate-off at which the voice's 7 registers are zeroed ($ff = never) — Tognon's "; hard restart" |
A vibrato is three adders: !wo 30, !wo -30, !wo 30, !wo 0 / $03,$06,$03,$00 / delay $16, flags $05 (Rambo fq2b91); $14,$00 / $ec,$ff / $14,$00 / $00,$00 / $03,$06 / $03,$00 / $1e,$05 (Arkanoid ins01). A drum: ISET $00,$b0 ; fq1add / ISET $08,$ff ; fq1time / ISET $1a,$a9 ; sr / ISET $1b,$0a ; release. A pulse: $14,$14,$00,$05, $14,$00,$ec,$ff, $00,$08 = 20 frames +20, 20 frames −20 around $0800. An arpeggio table is a 4-note stack including the octave — $00,$04,$07,$0c (Rambo, doubled to 8 entries), arp37: $0c,$00,$03,$07 (Arkanoid, read backwards). Every note starts by writing $00 and then the five register bytes (Rambo) or $08 (test) and then the registers (Arkanoid).
Arkanoid's sample track (own language, opcodes = 6502 opcodes): 81–86 xx play synthesized drum n, wait xx ticks; 87 xx nothing; 20 lo hi JSR; 40 NEXT; 49 xx FOR; 4C lo hi JMP; 60 RTS.
Matt Gray's player (Driller / Dominator engine) cheat sheet
Reference
Cheat sheet#
Pattern bytes (Driller, 1987; the same in V4.2 with additions):
| byte | meaning |
|---|---|
$01–$60 | note number (V4.2 source uses names C0 … B7 = 1 … 96) |
$00 | gate off for the previous note → release (hard-restart) |
$FA nn | instrument nn |
$FB mm / $FC pp | slide down / up by that amount per frame (pitch-slide-and-portamento) |
$FD kk | Driller: note duration kk. V4.2: $FD ci is the chord-plex command (count nibble c, table nibble i; AGAIN3 CMP #$FD → PLEXSETUP in Gray's source) — a Driller-style duration byte would be read as an arpeggio (sources: s-sidin02-matt-gray-driller, s-sidin14-dominator-player) |
$FF | end of pattern |
V4.2 only: $F9 nn | vibrato delay (label VIBDELAY) |
V4.2 only: $70–$F8 | note duration = byte − $70 (NOTEDUR CMP #$70 / SBC #$70): $70 = 0, $71 = 1 … $EF = 127, $F8 = 136 frames — e.g. $71,D2,D2,$70,F2; the bytes $AF/$DF/$EF/$EE/$97/$E7 seen in the Dominator bars are durations 63/111/127/126/39/119 (source: s-sidin14-dominator-player) |
Example (Driller): $FA,$0C / $FD,$01 / $31,$3D,$49,$3D … = instrument $0C, very short notes a 12-semitone stack apart (source: s-sidin02-matt-gray-driller). Example (Dominator): T1: $FA,$04, $71,D2,D2, $70,F2,D2,F2, $71,G2,G2, $70,G2, $FF (source: s-matt-gray-dominator-source).
Instruments — two 8-byte rows per instrument (Driller instr1/instr2, Dominator VDATA/VDATA2; source: s-sidin02-matt-gray-driller):
| table 1 | table 2 |
|---|---|
0 pulse width as nibbles xxyy → lo xx00, hi 00yy | 0 vibrato step |
| 1 control register (waveform + gate) | 1 vibrato length |
| 2 attack/decay | 2 control register for the first two frames (drum switch) |
| 3 sustain/release | 3 portamento value |
4 pulse inc/dec step; hi byte bounces between $08 and $0E | 4 portamento flag: 00 none, 01 −lo, 02 +lo, 03 −hi, else +hi |
5 arpeggio xxyy: xx notes, table yy | 5 length of the effect-1 cycle |
| 6 control register written at the end of the note, same frame as the next | 6–7 unused |
| 7 effect bits: 1 freq/noise effect, 2 re-set pulse each note, 4 waveform switch (drums) |
- Arpeggio tables are short semitone lists (
$00,$08,$12;$00,$08;$00,$04,$08) and the instrument says how many entries to use, so$30= table 0 with 3 notes,$22= table 2 with 2 (source: s-sidin02-matt-gray-driller). V4.2 adds the PLEX chord tablesP0–P6=$07,$03,$00,$09,$05,$00,$08,$03,$00,$18,$0C,$00,$07,$05,$00,$07,$04,$00,$08,$05,$00— the "note or chord plex" (chord-arpeggio; source: s-matt-gray-dominator-source). - Vibrato: subtract the step for L frames, add it for 2L, subtract for 2L … — a triangle on the frequency value, which is why Gray says "the higher the notes you played, the less vibrato you got, and the lower you went, the deeper it got" (vibrato; sources: s-sidin02-matt-gray-driller, s-c64com-matt-gray-interview).
- Drums: effect bit 4 plays table-2's control register for two frames, then the instrument's own; V4.2 adds a drum table of (control, pitch) frame pairs —
DT: $81,$30, $11,$02, $41,$04, $80,$30, $80,$15 … $FF— and a hi-hat routine that writes$50to the frequency high byte and$81(noise+gate) to the control register (wavetable-programming; sources: s-sidin02-matt-gray-driller, s-matt-gray-dominator-source). - Pulse: a per-instrument step and a bounce between
$08xxand$0Exx, i.e. pulse width 2048–3584 — Gray's "pulse width mod" (pulse-width-modulation; source: s-sidin02-matt-gray-driller). - Gray: "I was always adding-in modifiers and routines to produce better-sounding drums, but I always kept a bank of sounds that could be modified from project to project" (source: s-c64com-matt-gray-interview).
MUSICFILE — the Maniacs of Noise driver cheat sheet
Reference
Cheat sheet#
From the Cybernoid II source (MUSICFILE V01-07-1988), all via s-realdmx-sid-players; the names are Deenen's Dutch/English labels, the semantics read from the code where noted.
- Tune-wide constants at the top of the file:
volume = $0f,vibtotzover = $30,pulserunspeed = $63,dubvoice = $0c(double voice),noisehitone = $fa,pulsearpwait = $01,gitarwait = $0f,spacelength = $00,spacewait = $60,wavearpwait = 2. - Routines (the driver's feature list): Tonearpeggio · Vibrato · Tone glide · pulse handling ("pulsegedoe") · Wavearpeggio · Pulsearpeggio · Tonesweep up · filter handling ("Filterklooi") · Strangefilter · Pulserun · Double voices · Space effect · Drumroutine · noisetik.
- Song → sequences → steps:
snelheid(speed) per song;seqtabelgives three sequences per song (seq0a–ctitle,seq1a–cgame over); a sequence is a list of step-table numbers below$40with prefix bytes — verified in the code:$80–$fd= transpose,toneadd = byte & $1f, added to every note and glide target of the following steps, upward only (0–31 semitones;$84,$01= +4 then step 1,$8c= +12);$40–$5f= repeat the next step& $3fmore times;$60–$7f= an instrument-number offset& $0f;$fe= end;$ff= restart the sequence without resetting the transpose (source: s-realdmx-deenen-test-tunes); 33 step tablesst00–st20hold the notes (orderlist). - Instruments: 8-byte rows with the columns
pulsehi, waveform, attdec, susrel, filcount, fx1, fx2, fx3(instrument-tables, instrument-design):
| name (Deenen's label) | pulsehi | waveform | attdec | susrel | filcount | fx1 | fx2 | fx3 |
|---|---|---|---|---|---|---|---|---|
| leeg (empty) | $00 | $00 | $00 | $00 | $00 | $00 | $00 | $00 |
| bass | $05 | $41 | $08 | $89 | $00 | $53 | $64 | $80 |
| bassdrm | $08 | $11 | $00 | $a8 | $f0 | $00 | $00 | $10 |
| snardrm | $08 | $11 | $00 | $a9 | $f0 | $01 | $00 | $10 |
| arp+filt | $04 | $21 | $00 | $c8 | $01 | $00 | $81 | $85 |
| melo-1 | $0c | $41 | $00 | $b8 | $00 | $52 | $22 | $01 |
| melo-2 | $06 | $41 | $00 | $e8 | $02 | $53 | $74 | $01 |
| $17zooi | $00 | $17 | $00 | $88 | $f0 | $00 | $00 | $80 |
| arp-filt | $04 | $21 | $00 | $88 | $00 | $00 | $81 | $84 |
| $55 | $00 | $55 | $00 | $b8 | $00 | $00 | $00 | $20 |
| bassfilt | $03 | $41 | $07 | $69 | $00 | $00 | $51 | $80 |
| melo-3 | $05 | $41 | $00 | $b8 | $03 | $53 | $83 | $01 |
| tingel | $01 | $41 | $00 | $89 | $f0 | $00 | $00 | $02 |
| omhoogt (upwards) | $06 | $41 | $00 | $c8 | $08 | $00 | $41 | $00 |
| $81lang | $07 | $81 | $08 | $fd | $f0 | $00 | $00 | $00 |
| solo | $05 | $41 | $00 | $b8 | $03 | $c5 | $24 | $01 |
| melo-1 (2nd) | $0c | $41 | $00 | $b8 | $00 | $c6 | $22 | $00 |
| basso | $07 | $41 | $08 | $89 | $00 | $00 | $31 | $00 |
| solo2 | $05 | $41 | $00 | $a7 | $00 | $c5 | $22 | $00 |
- Per-instrument start ("noisetik",
fx3bit 7):starttabel($81,$81,$81,$81, $41,$11,$11,$81, $41,$81,$81,$81) andstartlen($02 … $05, $06) — verified in the code of Deenen's own test tune: while the note's frame counter is belowstartlen, the waveform written is thestarttabelvalue; a value of$7for more forces the frequency high byte tonoisehitone = $faand the waveform to$81. Effects skip the note's first frame, sostartlen = $02is exactly one frame of high noise on the second frame of the note, and$41/$11with$05/$06swap in that waveform at the note's own pitch for four or five frames; for two frames afterwards pitch and waveform are restored explicitly (source: s-realdmx-deenen-test-tunes; hard-restart, wavetable-programming).vibtabwaitholds vibrato delays per instrument ($0c,$18). - Drums:
drumtabel→dwa(waveform per frame, length byte first:$0b; $81,$81,$20,$20,$10,$10,$10,$10,$10,$10,$10,$10) anddto(pitch per frame:$34,$0a,$08,$06,$04,$05,$06,$05,$04,$05,$06,$05) — two frames of noise, then sawtooth and triangle sliding down (wavetable-programming). - Chords:
arp0–arp7= length byte + semitone offsets:$02,$00,$03,$07(minor),$02,$00,$04,$07(major),$02,$00,$05,$08,$02,$00,$05,$09,$02,$00,$03,$08,$02,$00,$04,$09,$02,$00,$03,$06;arp6 = $17+ a 24-step descending run$e9 … $00;wavearp $80,$10,$80,$10alternates noise and triangle (chord-arpeggio). - Filter:
filterbytes→ four 10-byte programsfb0–fb3, e.g.$a0,$fe,$02,$ff,$80, fp0,$02,$22,$42,$62wherefp0 = $10 + volumeis the$D418byte (mode nibble + volume);strafilterandaftrekspeedfor the "strange filter" (filter-programming). - Pulse:
pulsetabel, four 8-byte programs such as$04,$0c,$02,$30, $04,$30,$06,$30(pulse-width-modulation). - The driver shadows the SID registers per voice (
d400 … d403,stod404) and keeps glide, vibrato, arpeggio, pulse-run and filter counters in 3-byte tables — the state a sid-player-routine needs.
Nanoloop cheat sheet
Reference
Facts#
- It predates lsdj, and was the thing to beat. johan-kotlinski tried it "before LSDj existed" and found it "a beat making toy rather than something I would like to make full songs in"; his own milestone for LSDj's adoption is the 3.0.0 file screen, "after which LSDj started to become as popular as Nanoloop" (source: s-chipmusic-kotlinski-interviews).
- The interface is a grid, not a tracker's note column — the screenshot in little-scale's 2009 post shows the familiar 4×4 pattern grid running under KiGB (source: s-little-scale-nanoloop-18-tet).
- What it does that LSDj does not: "Nanoloop can do hard sync and soft pulse, LSDj cannot" (Biere Gratuite). The counter-position in the same thread, from herr_prof: "There is nothing you can do in nanoloop that cant be done in lsdj, except you actually have to know what you are doing" (source: s-chipmusic-tables-and-chords-threads). Both stand.
- ROM internals, version 1.3d (
nl13d.gb, read from a hex-editor screenshot): the ROM is 32,768 bytes and the pitch lookup table is 144 bytes at$730A(29,450) — 72 entries against lsdj's 108. Its stock contents are byte for byte the same 12-TET-from-C2 period series LSDj uses, because both drive the same game-boy-apu registers (source: s-little-scale-nanoloop-18-tet). Patching it is rom-retuning; little-scale's 18-TET Nanoloop is the wiki's first worked example. - Sampled and cut into kits. little-scale released 44 kick sounds recorded from Nanoloop 1.6.3 on a grey DMG (2012, unrestricted), and made a Nanoloop 2.3 kit for lsdj in 2009 — the two programs raiding each other (sources: s-little-scale-chip-sample-packs, s-little-scale-lsdj-kit-releases).
- Sync, at pin level: Nanoloop listens on the link connector's SI (serial in) pin, where lsdj listens on SC (serial clock) — the reason a sync box can support one and not the other. Ground to ground and one wire is the whole connection; 2.x needs a series resistor on SI where 1.x does not. Its clock rate is 12 ppqn, half of MIDI beat clock's 24, so a MIDI→Nanoloop box is a divider — which is why the cheapest one is a single
$14017 decade counter with no microcontroller at all (sources: s-little-scale-arduino-gameboy-sync-boxes, s-little-scale-teensy-usb-midi-sync, s-little-scale-1-dollar-nanoloop-sync; see sync). A commenter puts the rate in context: his Boss DR-110 "uses essentially the same 12ppq sync signal as nanoloop". - Oliver Wittchow sold a Nanoloop MIDI sync cable — "basically a cable with a small area for the chip in the middle", powered from the Game Boy connector, which also syncs lsdj in MIDI sync mode. Premade units had stopped by October 2008 with a kit promised (source: s-little-scale-sync-options-for-game-boys).
- It could not do triplets, and that was worth building hardware for: little-scale's nanoGroover "generate[s] weird timings for Nanoloop like 2:4, 3:4, 5:4 and 6:4. Finally, you can do triplets in Nanoloop!" — at the cost of two Game Boys and two copies of Nanoloop. His nanoSync24 clocks Nanoloop from a Sync24 signal, "so that the C64 is controlling the speed of Nanoloop" (source: s-little-scale-sync-options-for-game-boys).
- Sync: Nanoloop's clock signal is one of the standard Game Boy sync formats, sitting beside LSDj sync, MIDI clock and DIN sync in scannerboy's C64 user-port adapter for defmon (LSDj sync, nanoloop sync, MIDI clock, DIN sync and a 24–2 ppqn analogue clock; 36 EUR, first batch 2015-03-07) — so a Nanoloop cartridge can clock or be clocked by a C64 (sources: s-defmon-wiki-sync-and-stereo, s-chipmusic-defmon-thread). little-scale ran Nanoloop and LSDj off one MIDI clock in 2008 (sync; the posts are listed in
inbox/scout-little-scale-2026-08-31.md, not yet ingested).
Techniques
ROM retuning — patching a tracker's pitch table › Nanoloop #
For 1.3d (nl13d.gb, 32,768 bytes): the pitch table is 144 bytes at $730A (29,450), and its stock contents are the same 12-TET-from-C2 series as LSDj's (source: s-little-scale-nanoloop-18-tet). Same procedure, same formula.
Ninjatracker cheat sheet
Reference
Cheat sheet#
All from s-sidin11-sid-factory-vs-ninjatracker (Ninjatracker V2.x, February 2007).
Track (one per voice, per subtune; orderlist)
| value | meaning |
|---|---|
00 | loop |
01–7F | play pattern 01–7F |
80–BF | transpose downwards |
C0–FF | transpose upwards |
Pattern row: note C1–B7, +++ (key on) or --- (key off) · command 01–7F (instrument if a note is given, effect otherwise) or 81–FF (legato) · note duration · the command's name (display only). Empty fields keep the previous values.
Command = ADSR · wave-table pointer · pulse-table pointer · filter-table pointer. ADSR is not used in legato mode; a pointer of 00 keeps the table already running (instrument-tables).
Wave table (left byte / right byte; wavetable-programming)
| left | right | effect |
|---|---|---|
00–8F | arpeggio: 00–7F relative, 8C–DF absolute note | set waveform (chord-arpeggio) |
90–BF | — | no waveform; delay the arpeggio by 00–2F frames |
C0–DF | depth | vibrato with speed 00–1F |
E0–FE | speed low byte | slide with speed high byte 00–1E (pitch-slide-and-portamento) |
FF | destination | jump — not to be entered directly from a command |
Pulse table (pulse-width-modulation)
| left | right | effect |
|---|---|---|
01–7F | signed speed | modulate the pulse width for that many frames |
80–FE | value | set the pulse width |
FF | destination | jump (can be entered from a command) |
Filter table (filter-programming)
| left | right | effect |
|---|---|---|
01–7F | signed speed | modulate the cutoff for that many frames |
80–FE | cutoff | set passband (left nybble − 8) and the channels to filter (right nybble) |
FF | destination | jump (can be entered from a command) |
OpenMPT cheat sheet
Reference
Cheat sheet#
Effect letters are uppercase + hex in the effect column, lowercase + decimal in the volume column. MOD/XM letters and S3M/IT letters are different alphabets for the same jobs — see effect-command-crosswalk (source: s-openmpt-manual-effect-reference).
IT / MPTM effect column#
| cmd | effect | cmd | effect |
|---|---|---|---|
Axx | speed (ticks per row) | Qxy | retrigger every y ticks, volume change x (see table) |
Bxx | jump to order xx | Rxy | tremolo speed x depth y |
Cxx | break to row xx of the next pattern | S1x | glissando off/on ("quirky") |
Dxy | volume slide down y / up x; DFy/DxF fine; D0F every tick | S2x | MOD finetune (legacy) |
Exx/Fxx | portamento down/up; EFx/FFx fine; EEx/FEx extra fine | S3x S4x S5x | vibrato / tremolo / panbrello waveform 0 sine, 1 saw, 2 square, 3 random |
Gxx | tone portamento (linear: xx/16 semitone per tick) | S6x | extend the row by x ticks |
Hxy / Uxy | vibrato / fine vibrato (shared memory) | S70 S71 S72 | past notes: cut / off / fade |
Ixy | tremor on x off y ticks | S73–S76 | NNA of this note: cut / continue / off / fade |
Jxy | arpeggio +x, +y | S77–S7C | volume / pan / pitch envelope off, on (MPTM S7D/S7E: force pitch / filter) |
Kxy / Lxy | volume slide + vibrato / + tone portamento | S8x | coarse pan 0–F |
Mxx / Nxy | channel volume / slide | S91 | surround (other S9x: filters S9C global / S9D local, play direction S9E/S9F — MPTM) |
Oxx | sample offset × 256 (SAx adds x × 65536) | SB0 / SBx | loop start / loop x times |
Pxy | pan slide right y / left x; PFy/PxF fine | SCx / SDx | note cut / note delay after x ticks (0 = 1) |
Txx | tempo ≥ 20; T0x/T1x slide down/up per tick | SEx | repeat the row x times |
Vxx / Wxy | global volume 00–80 / slide | SFx | select parametered macro |
Xxx | pan 00–FF | Yxy | panbrello |
Zxx / \xx | MIDI macro / smoothed (\ is a hack) | MPTM: :xy | delay x ticks then cut after y; #xx extends the previous B/C/O/T/+; +xx/*xx finetune |
Retrigger x: 1–5 −1, −2, −4, −8, −16 · 6 ×⅔ · 7 ×½ · 9–D +1 … +16 · E ×1.5 · F ×2. Memory: 00 recalls the same command's last value in IT; in S3M most commands share one memory.
Volume column (decimal)#
IT/MPTM: vxx volume, pxx pan 0–64, a0x/b0x fine volume up/down, c0x/d0x slide up/down, e0x/f0x portamento down/up (×4), g0x tone portamento (g01=G01, g02=G04, g03=G08, g04=G10, g05=G20, g06=G40, g07=G60, g08=G80, g09=GFF), h0x vibrato depth, MPTM o0x cue point. XM: vxx, pxx (16 positions), axx/bxx fine, cxx/dxx slide, gxx tone portamento (= 3xx × 16), hxx vibrato depth, uxx vibrato speed only, lxx/rxx pan slide. MOD has no volume column.
Song properties and tempo#
Linear frequency slides (1/16 semitone units; off in MOD/S3M) · Fast Volume Slides (S3M 3.00) · Extended Filter Range (130 Hz–5 kHz → 10 kHz) · IT Old Effects · Compatible Gxx (own portamento memory, envelopes reset) · ProTracker 1/2 mode and Amiga Frequency Limits for MOD · mix levels (Compatible for shared IT/XM/MOD/S3M, identical to Schism's; 1.17RC3 with plugins). Tempo modes: Classic — rows per minute = tempo × 24 ÷ speed, tick = 2.5 s ÷ tempo; Alternative — tempo in ticks per second; Modern (MPTM) — tempo = real BPM, rows per minute = tempo × rows per beat, speed no longer changes the pace; Tempo Swing per beat row, globally or per pattern (source: s-openmpt-manual-song-properties).
Instruments and samples#
Instruments: sample map (drum kits: map every note to C-5), global volume, fade out (32768 ÷ value ticks), pan, pitch/pan separation, filter cutoff/resonance (max cutoff + min resonance = off), volume/pan/cutoff/resonance swing, NNA cut/continue/off/fade with duplicate checks, envelopes in ticks with loop, sustain loop, carry and release node, plugin MIDI channel and pitch-bend range (source: s-openmpt-manual-instruments). Samples: C-5 frequency (IT/S3M) or finetune (MOD 1/8, XM 1/128 semitone), loops off/on/bidi plus sustain loops, auto-vibrato (depth in 1/64 semitone, sweep, rate 256 ÷ rate ticks), draw mode and resize for chip waves, crossfade, trim, time-stretch, OPL editor for S3M/MPTM (opl-fm-instruments) (source: s-openmpt-manual-samples).
Filter and macros#
Z00–Z7F cutoff, Z80–Z8F resonance (defaults); macro messages F0F000xx cutoff, F0F001xx resonance, F0F00200 lowpass, F0F00210 highpass, F0F003xx plugin dry/wet; SFx switches the channel's parametered macro; S9C/S9D global/local filter mode (filter-programming; source: s-openmpt-manual-zxx-macros).
The clipboard text format#
The pattern-clipboard text, pinned precisely by duet's docs (source: s-duet-docs-clipboard):
- Header line: any line whose last three characters are
IT— OpenMPT writesModPlug Tracker IT(two spaces beforeIT); schism-tracker writesPasted Pattern - IT.S3MandMPTheaders read the same way;XM/MODblocks read too, but their effect letters are another alphabet. - One line per row; each channel is
|plus exactly 11 characters in four fields: NOTE(3) —C-5/C#5(sharps only;Db5reads asC#5),...empty,===off,^^^cut,~~~fade; INS(2) — decimal01–99; VOL(3) — a letter and two decimal digits (v64,p32,a/bfine volume,c/dslide,e/fportamento,gtone portamento,hvibrato); FX(3) — the effect letterA–Zand two hex digits. - Rows end in
\r\n; spaces read like dots. A field the mark did not reach is spelled as spaces (a volume-only mark copies| v40) and honoured on paste. OpenMPT and Schism are strict about the widths; duet forgives short cells, ragged rows and lowercase.
Techniques
Filter programming on the SID › Impulse Tracker / OpenMPT (resonant filter) #
The PC-tracker equivalent of the SID filter table is a column of Zxx macros (source: s-openmpt-manual-zxx-macros): by default Z00–Z7F set the cutoff (00 lowest … 7F highest; the top is about 5 kHz, or 10 kHz with Extended Filter Range) and Z80–Z8F the resonance; the underlying messages are F0F000xx cutoff, F0F001xx resonance, F0F00200 lowpass and F0F00210 highpass (mutually exclusive), so a fixed macro can switch filter type. Instruments carry default cutoff, resonance and (MPTM) filter mode; cutoff at maximum with resonance at minimum turns the filter off; the pitch envelope can act as a filter envelope (S7D/S7E force one or the other in MPTM); S9C makes filters stay until switched off (Impulse Tracker behaviour), S9D resets them on every note; MPTM adds cutoff and resonance swing per instrument; the filter never touches plugins (sources: s-openmpt-manual-instruments, s-openmpt-manual-effect-reference). On OPL instruments the cutoff macro scales the modulator — "effectively … a lowpass filter" (opl-fm-instruments; source: s-openmpt-manual-samples). The Amiga's only filter is the LED low-pass toggled by E0x — "connects filter (turns power LED on)" — which OpenMPT calls "muffled" and emulates only with the Amiga resampler (sources: s-protracker-23d-help, s-openmpt-manual-effect-reference).
MIDI output from trackers (Impulse Tracker macros) › OpenMPT #
The macro configuration dialog defines the sixteen parametered and 128 fixed macros; Zxx/\xx in XM, IT and MPTM execute them, and external MIDI messages go to the first plugin in the channel's chain (source: s-openmpt-manual-zxx-macros).
Multisampling and drum-kit instruments › OpenMPT #
The Sample Map lists pattern note → heard note + sample; "for drum sets, simply map all notes to C-5" instead of retuning each sample; XM lacks the note column and allows only 16 samples per instrument; Transpose Samples / Reset Map trades the map for retuned samples so IT portamento between samples behaves (source: s-openmpt-manual-instruments). For chopping one long recording into a map rather than recording separate keys, the sample editor has cue points (MPTM o0x) and slice at cues or grid (source: s-openmpt-manual-samples) — the tidy version of the offset-based approach on sample-offset.
Octave bass › Impulse Tracker / OpenMPT #
Jxy is an arpeggio over three notes — "the note playing, a note x halftones above, and a note y halftones above", an effect the manual itself compares to "old C-64 chords". So there is no single command for a strict 0 12 alternation: JCC gives 0 12 12 and J0C gives 0 0 12. For an exact 8th-note octave, type the two rows (source: s-it-manual). See effect-command-crosswalk for the same effect's number in MOD/XM (0xy).
OPL / AdLib FM instruments in trackers › OpenMPT (S3M / MPTM) #
Create the instrument from the sample tab's New-sample dropdown or Resize; the OPL editor exposes per operator: attack, decay, sustain level, release rate, Sustain Sound (hold the sustain until note-off), volume, tremolo (1 dB), envelope key scaling, key-scale level (1.5/3/6 dB per octave), frequency multiplier 0.5–15, vibrato (7 cents), and one of 8 waveforms — sine, half sine, absolute sine, pulse sine (the four the OPL2 and therefore S3M allow), plus even-period sines, square and derived square on OPL3/MPTM; a feedback amount; additive or FM mode. Pattern volume commands scale the carrier in FM mode (both operators in additive mode); filter cutoff — the instrument's filter settings, a filter envelope, or the Zxx macro F0F000xx — scales the modulator instead. Panning is left / centre / right only; Oxx, SAx, S9x and surround do nothing on OPL notes; in S3M tone portamento is not available for OPL notes (sources: s-openmpt-manual-samples, s-openmpt-manual-effect-reference, s-openmpt-manual-zxx-macros).
Sidechain pump › Impulse Tracker / OpenMPT #
Three levers, in increasing order of tidiness (source: s-it-manual):
Dxyvolume slides typed per row, the crude version (volume-slides).Mxxchannel volume (0–40h) withNxychannel volume slide — one command per channel per beat, no per-note volumes to edit, and it survives copy-paste of the notes. This is the closest thing a tracker has to a sidechain bus: putM20on the beat row andN0xafter it on every channel that should duck. S3M players only supportM/Nas an extension, so a song that needs them should stay.it.Vxxglobal volume withWxyglobal volume slide ducks everything including the kick, so it is a mastering lever rather than a pump — and IT'sVxxaffects notes already playing, unlike ST3's.
Or bake it into the instrument: a volume envelope that starts low and rises, retriggered every beat, pumps without a single command in the pattern (instrument-envelopes; source: s-037-lab). Keep the global volume high while doing any of this — at V05–V08 a volume-column fade jumps instead of sliding (source: s-it-hints).
Paul Hughes's Ocean music driver (Jonathan Dunn's player) cheat sheet
Reference
Cheat sheet#
All from the two sources (source: s-realdmx-ocean-dunn-hughes-driver).
Voice program — bytes $00–$5d notes (C0 = 0 … A7 = 93, sharps CS4), 94 = REST; in manual mode every note/rest is followed by its duration in frames, after LENGTH n (auto mode) each note lasts n. Commands:
| byte | name | arguments | effect |
|---|---|---|---|
$80 | JUMP | addr | go to |
$81 | CALL | addr | call a phrase (5-deep stack shared with LOOP) |
$82 | RET | return, and reset the transpose | |
$83 … $84 | LOOP n … NEXT | repeat | |
$85 | BEND | dir, step, length, offset16 | bend into the next note: the frequency is pre-offset by step × length and climbs to the written pitch |
$86 | PATCH | n | select a 5-byte patch |
$87 | LENGTH | frames | auto-duration mode |
$88 / $89 | VIBON / VIBOFF | delay, rate, depth | triangle vibrato on the 16-bit frequency (cancels an arpeggio) |
$8a / $8b | ARPON / ARPOFF | addr | arpeggio table (suppresses vibrato and bend while active) |
$8c | MANUAL | back to note,duration pairs | |
$8d | PWM | n | select a 5-byte pulse-sweep entry |
$8e / $92 | FILTER / FILTOFF | empty handlers | |
$8f | END | stop the voice | |
$90 | TRANSPOSE | n | signed semitones |
$91 | CT | n, addr | transposed CALL — the harmony device |
$93 | MODE | mask | bit 7 of the mask = set, else clear: gate writes, pulse retrigger per note, "pluck" mode |
$94 | DRUM | n, transpose[, duration] | voice C only |
$95 | PORT | value, sid-offset | write any SID register (volume $18) |
$96 | CODE | addr | JSR into the music data (fades, ramps) |
$97 | EFFECT | note | every note starts at that (absolute or relative) pitch until its release point — a pluck |
Durations: TEMPO = 5 → SQ 5, QV 10, CR 20, MN 40, SB 80; TEMPO2 = 6 → SQ2 6, QV2 12, DQV2 18, CR2 24, DCR2 36, MN2 48, SB2 96 (a 4/4 bar). Example: DITTY2: PATCH,1,PWM,1 / ARPON ARP2 / LENGTH,SQ / CALL MEL1 / CT,-5 MEL1 / CT,-12 MEL1 / CT,-17 MEL1 / D4 / END with MEL1: LOOP,2 / F4,G4,F4,D5 / NEXT / RET. The loader: MANUAL / PATCH,1,PWM,1 / VIBON,0,9,6 / EFFECT,12 / BEND,UP,$10,48 / !wo $10*48 / C2,192 ….
Patch = 5 bytes: gate-on control byte, AD, SR, hold (frames; bit 7 GAP = "N frames before the next note" instead of "N frames after note-on"), gate-off control byte — two waveforms per instrument:
| patch | bytes | sound |
|---|---|---|
| DT88 00 | $51,$00,$C8,3,$40 | triangle + pulse, 3 frames, released as pulse |
| DT88 01 | $01,$00,$88,2,$42 | gate with no waveform for 2 frames, then pulse + sync — heard only in release |
| DT88 02 | $55,$00,$99,3,$40 | triangle + pulse + ring |
| DT88 05 | $81,$00,$A8,3,$10 | 3 frames of noise, then triangle — a click transient |
| DT88 09 | $11,$AA,$79,QV2+SQ2+GAP,$10 | the only patch with an attack — the title pad |
| DT88 13 | $41,$00,$88,4+GAP,$14 | pulse, released as triangle + ring |
| Loader 0 | $43,$00,$7B,96+GAP,$22 | pulse + sync, gate off 96 frames before the end, released as sawtooth + sync — the lead |
| Loader 1 | $41,$00,$AD,3,$40 | the bend bass |
PWM entry (5 bytes): rate, frames up, frames down, initial width (word) — $80,$00,$02 / $0F50; $F0,$04,$04 / $0800; loader $40,48,42 / $0000. Arpeggio table: frames per step, steps, offsets… — ARP1 !by 3,4,0,4,7,9, ARP2 !by 1,3,24,12,0, TARP1 !by 2,3,0,3,7. Drum (7-byte entry: wave ptr, freq ptr, length, SR, pulse-hi; AD forced $00): BASS DRUM $41,$41,$10,$80 / $0E,$06,$0F,$10; SNARE $41,$41,$40,$80,$80,$80,$10,$80,$10,$80,$80,$10,$80 / $11,$0C,$08,$70,$70,$2F,$0C,$2E,$0C,$2D,$BC,$0C,$2B; HI-HAT $11,$11,$80,$80,$80 / $10,$10,$70,$20,$30. Fades are self-modifying data: FADEPOS !by PORT,$0F,$18 with TFADEAWAY DEC FADEPOS+1 in a loop.
ProTracker cheat sheet
Reference
Cheat sheet#
Effects#
| cmd | effect | cmd | effect |
|---|---|---|---|
0xy | arpeggio +x, +y ("noisy and grainy on most samples, but ok on monotone ones"; 047 major, 037 minor) | E0x | LED filter: E00 on, E01 off ("some A500 + A2000") |
1xx / 2xx | portamento up / down per tick (cannot pass B-3 / C-1) | E1x / E2x | fine slide up / down, once ("Great for creating chorus effects") |
3xx | tone portamento to the note (300 continues) | E3x | glissando: portamento by semitones |
4xy | vibrato speed x depth y (400 continues) | E4x / E7x | vibrato / tremolo waveform 0 sine, 1 ramp down, 2 square, 3 random; +4 "Don't retrig WF" |
5xy / 6xy | tone portamento / vibrato continued + volume slide up x down y | E5x | finetune (+7…0 = 7…0, −1…−8 = F…8) |
7xy | tremolo | E60 / E6x | loop start / loop x times |
9xx | sample offset $xx00 ("Handy for speech-samples") | E9x | retrig every x ticks — "Retrig on hi-hats!" |
Axy | volume slide up x / down y per tick ("The slower the song, the more the volume will be changed") | EAx / EBx | fine volume up / down |
Bxx | jump to position xx (hex; also breaks the pattern; "instead of restart as on Noisetracker") | ECx | note cut at tick x (volume only) |
Cxx | volume 00–40 | EDx | note delay to tick x (ED0 still delays "a little" — flanging with a doubled note) |
Dxx | pattern break to line xx (decimal, 00–63) | EEx | pattern delay x notes (effects keep running) |
Fxx | VBlank: speed 01–FF; CIA: 01–1F speed, 20–FF BPM; F00 stops | EFx | invert loop at speed x (short loops of $10/$20/$40/$80 bytes; "Sounds better than funkrepeat"; EF0 off) |
8xx and E8x are "NOT USED" (sources: s-protracker-23d-help, s-protracker-23-readme-and-docs).
Keys#
Two note rows; F1/F2 low/high octave; F6–F10 go to line 0/16/32/48/63 (Shift stores, Alt plays, Ctrl records from there); Shift/Alt/Ctrl+F3–F5 cut/copy/paste sample / track / pattern / commands; Ctrl+0–9 edit skip; Tab next track; right Amiga / right Alt / right Shift play pattern / song / record; Space stop/edit; Del note, Alt+Del command, Shift+Del both; Shift+0–9 store and Alt+0–9 insert a command; Alt+\ copies the command above (= / - ±1); Ctrl+A mute channel, B mark block, C/X/P/J copy/cut/paste/join-paste, H/L transpose block, E/O expand/contract, W polyphonize, Y backwards, K kill to end, U undo, Z restore effects, F filter, G boost all; Alt+D/E/S Disk Op / Edit Op / Sampler, Alt+M metronome, Alt+R resample, Alt+T tuning tone, Alt+Q quit; keypad 0–9 and Enter pick samples $0–$1F; L-Amiga + keys transpose note/octave for sample or all, track or pattern (source: s-protracker-23d-help).
Sample tools#
Sampler screen: waveform/display/range play, ranges, cut/copy/paste, volume box with \ / - ramps and Normalize, tuning tone, Resample by note, loop on/off. Edit Op 3: Mix (offset, modulation), Echo, Boost ("Use this on hi-hats and snares!"), Filter ("noisy basses"), X-Fade for hard loops, Backwards, Upsample/Downsample (octave up/down), Fade Up/Down, Vol, and the Chord maker (major, minor, sus4, major7, minor7, major6, minor6 into a new sample). Edit Op 2: record with quantise and a metronome on sample $1F (source: s-protracker-23d-help).
Tips from the help file#
---01C00 sets a volume without a note; C-301A08 followed by ---01A08 rows "will create a strange arpeggiato effect, like on 'Cream of the earth' by Romeo Knight / RSI"; lock locks the program with a password; Ctrl+Alt+Shift+L-Amiga+Del prepares "the infamous 'backwards play' trick" (source: s-protracker-23d-help).
Rob Hubbard's driver (the Monty on the Run player) cheat sheet
Reference
Cheat sheet#
All values from the two disassemblies (source: s-realdmx-hubbard-player).
Song structure: init (A = song) copies three track pointers; a track is a list of pattern numbers, $ff = restart the track, $fe = stop. A pattern is a stream of notes ended by $ff.
Note entry (1–3 bytes):
| byte | bits | meaning |
|---|---|---|
| 1 | 0–4 | length in ticks, 0–31 |
| 1 | 5 | "no release": do not clear the gate (and do not zero AD/SR) when the length runs out |
| 1 | 6 | extension: a one-byte entry that adds its length to the current note; the registers are re-written with the gate off, so the tail is the release ($7f = +32 ticks, keep ADSR; $5f = +32 ticks, then cut) |
| 1 | 7 | a second byte follows |
| 2 | 7 = 0 | instrument number |
| 2 | 7 = 1 | portamento: bits 1–6 the frequency step per frame, bit 0 the direction (0 = up, 1 = down) — e.g. $90 = +16/frame, $99 = −24/frame, $e8 = +104/frame |
| 3 | note, $00 = C-0 … $5f = B-7 (frequency table $0116 … $fd2e) |
Examples: $83,$00,$37 = 4 ticks, instrument 0, G-4; $bf,$0c,$56,$7f,$7f = a 32-tick note held for 64 more ticks in release; $af,$90,$35 = 16 ticks of pitch bend up. Note-off is the end of the length, and without bit 5 it writes $00 to AD and SR — an instant cut (hard-restart).
Instrument (8 bytes):
| # | byte | values |
|---|---|---|
| 0 | pulse width lo | |
| 1 | pulse width hi | $08–$0e if the pulse sweep is used |
| 2 | control register with gate | $41 pulse, $81 noise, $11 triangle |
| 3 | attack/decay | |
| 4 | sustain/release | $ff for skydive notes that must keep sounding through their extensions |
| 5 | vibrato depth | 0 = off; n = step of a semitone ÷ 2^(n+1); needs a note of 8+ ticks (Commando: 6+) |
| 6 | pulse modulation | bits 0–4 delay in frames between steps, bits 5–7 step ($20, $40 …); the width bounces between $0800 and $0eff; with flag $08 (Commando only) the whole byte is added to the low byte every frame instead |
| 7 | effect flags | $01 drum, $02 skydive, $04 octave arpeggio, $08 pulse-lo modulation (Commando); they combine ($05 = drum + arpeggio) |
Rows from Monty on the Run: $80,$09,$41,$48,$60,$03,$81,$00 (lead: pulse, vibrato 3, slow PWM) · $00,$08,$81,$02,$08,$00,$00,$01 (noise drum) · $00,$09,$41,$3f,$ff,$01,$e7,$02 ("first skydive") · $00,$08,$41,$08,$50,$02,$00,$04 (pulse + octave arpeggio) · $00,$00,$11,$0a,$fa,$00,$00,$05 (triangle drum + arpeggio). From Commando: $52,$01,$41,$09,$9f,$00,$16,$08 (bass, pulse-lo modulation) · $00,$02,$81,$0a,$09,$00,$00,$05 (snare).
The effects
| effect | what the code does |
|---|---|
| vibrato | 8-frame sequence 0,1,2,3,3,2,1,0 × step, added to the note frequency (bends upward only) |
| pulse sweep | add the step every delay frames; reverse at hi byte $0e / $08; modifies the instrument bytes in place |
| portamento | add/subtract the step to the 16-bit frequency every frame for the length of the note |
drum $01 | first tick noise ($80), then each frame the instrument waveform with the gate off while the frequency high byte decrements by 1 — "fast attack/decay and a rapid downwards frequency slide" (wavetable-programming) |
skydive $02 | every 2nd frame decrement the frequency high byte until 0 (Commando's variant increments by 2) |
octave arpeggio $04 | odd frames note + 12, even frames the note — a 25 Hz octave trill (octave-bass) |
Processing order per frame: note fetch → vibrato → pulse → portamento → drum → skydive → arpeggio.
Scream Tracker 3 cheat sheet
Reference
Cheat sheet#
Screens and global keys#
F1 orders and global variables · F2 pattern editor · F3 instrument list · F4 instrument library · F5 info screen (and play) · Shift+F5 play song, F6 play pattern, Shift+F6 from the current order, F7 from the mark (Shift+F7 sets it), F8 stop · Shift+F8 reload samples into the GUS · F9 status, Shift+F9 setup (colours, directories, chord set) · F10 quick help · Ctrl+R load, Ctrl+W/Ctrl+S save as / quick save, Ctrl+N new, Ctrl+P song length, Ctrl+D DOS shell, Ctrl+Q quit (source: s-st3-manual).
The row#
C#4 04 25 H81 = note + octave (0–7), instrument (00–99 decimal), volume (0–64 decimal), effect (A–Z), infobyte (hex). Middle C is C-4; a sample's C4Spd is the frequency it plays at C-4 (8363 = "no finetune"; +/- octave, * reset, / set by note). Patterns: 32 columns × 64 rows, up to 100 patterns, 255 orders. Effect memory: 00 in D E F G H I J K L Q repeats the last infobyte — and in ST3 the memory is largely shared between commands, unlike IT (sources: s-st3-manual, s-openmpt-manual-compatible-playback).
Effects#
| cmd | effect | cmd | effect |
|---|---|---|---|
Axx | speed 1–FF (default 6) | Oxy | sample offset × 256, loop-aware (hi-hat from the tail of a snare) |
Bxx | jump to order xx (hex) | Qxy | retrig every y frames, volume change x: 1–5 −1/−2/−4/−8/−16, 6 ×⅔, 7 ×½, 9–D +1…+16, E ×3/2, F ×2 (Q72 at speed 8: 64, 32, 16, 8) |
Cxx | break to row xx (decimal) | Rxy | tremolo |
D0y / Dx0 | volume slide down / up, (speed−1) × value per row (D04 at speed 8 = −28) | S1x | glissando (semitone portamento) on/off |
DFy / DxF | fine volume down / up, once per row | S2x | ProTracker finetune → C4Spd 7895…8757 Hz (8 = 8363) |
Exx / Fxx | pitch down / up (00–DF) per frame | S3x / S4x | vibrato / tremolo waveform 0 sine, 1 ramp down, 2 square, 3 random |
EFx / FFx | fine slide (once per row) | S8x | pan 0–F (ST 3.2; GUS only) |
EEx / FEx | extra fine slide (four times finer) | SB0 / SBx | loop point / loop x times (never across patterns) |
Gxx | tone portamento | SCx / SDx | note cut / note delay after x frames |
Hxy / Uxy | vibrato / fine vibrato (4× finer, for high notes) | SEx | repeat the row x times (effects still applied) |
Ixy | tremor on x / off y frames | Txx | tempo 20–FF (default 7D = 125 BPM) |
Jxy | arpeggio +x, +y semitones "50 times per second" — J37 C minor | Vxx | global volume 0–40 |
Kxy / Lxy | H00 + Dxy / G00 + Dxy (no fine slides) | not implemented | S0x Amiga filter, SAx old stereo control, SFx funk repeat |
(source: s-st3-manual; OpenMPT adds Mxx, Nxy, Pxy, S5x, S9x, SAx, Wxy, Yxy, Zxx and volume-column pxx to S3M — none are original ST3 commands, source: s-openmpt-manual-effect-reference)
Pattern editor#
Two piano rows, . clears · * / base octave · , toggles the edit mask (whether volume/effect follow a new note) · Alt+1…8 skip value · chord mode Alt+Z…M (preset chords spread over channels, : exits) · Shift+Q…L enter instrument 1–10 with the current note (drum lines) · Alt+N polychannel · Ctrl+1…9 / Ctrl+B rows between bars (3/4: break at row 47) · < > instrument, + - pattern (Shift ×4), { } speed · 1 AdLib note-off, 4/8 play note/row · Ctrl+Backspace undo, Ctrl+Enter store undo · Alt+T/Alt+R pin channels. Blocks: Alt+D quick-select 16/32/64 rows, Alt+B/Alt+E begin/end, Alt+L channel (×2 pattern), Alt+U unmark, Alt+C copy, Alt+P paste/overwrite, Alt+M mix (echoes), Alt+H overwrite keeping volumes, Alt+Y swap, Alt+Z erase (×2), Alt+X erase effects (×2), Alt+Q/Alt+A transpose ±1, Alt+V/Alt+W set volumes, Alt+S set sample, Alt+I/Alt+J volumes × 3/2 or 2/3, Alt+F/Alt+G double/halve, Alt+K slide volumes (source: s-st3-manual).
Instruments and global variables#
Instrument list: Tab subwindow, Alt+D delete, Alt+O/Alt+W save with/without header, Alt+M maximise, Alt+X/Alt+S exchange/swap, Alt+A Amiga/PC sample flip, Alt+V view as text, Enter library; samples ≤ 64000 bytes, 8-bit; A on the type column makes an AdLib instrument (opl-fm-instruments). F1 variables: tempo, speed, global volume, master volume (SB), volume-0 optimisation, Force Amiga limits (octaves 3–5), Mod Edit Mode (red = not MOD-safe), Fast volslides (ST 3.0 behaviour, auto for old files), Ultraclick removal, stereo; channels L1–L8, R1–R8, A1–A9 with default pans (source: s-st3-manual).
Saving MOD#
Three octaves (C-3–B-5), no volume column, finetune approximated from C4Spd, 128 orders, 64 patterns (100 = extended MOD), 31 instruments, no extra-fine slides / fine vibrato / tremor, speeds ≥ 20h, retrig loses its volume slide (source: s-st3-manual).
Techniques
Chord arpeggio (the 0 3 7 trick) › Impulse Tracker / Scream Tracker 3 #
Jxy cycles base, +x, +y once per tick — the IT manual calls it "an effect similar to old C-64 chords" (source: s-it-manual): the Modsquad's chip lead has a chord channel of J47 (major) and J37 (minor) at volume 64 with J00 to stop, and their rules are "chords in one channel — never two — and no percussion inside them" (source: s-tw077-chip-off-the-block). Pinion admits that for "really neato chords" Jxx is "a bit… shitty sounding" in a sample tracker — but on a looped noise sample with a long falling pitch envelope a column of Jxx makes analog-style sweeps (instrument-envelopes; source: s-tw081-it-tip-of-the-week). Trixter's reminder that "a chord isn't a thing, it's any combination of notes" applies: an arp is a chord spread in time (source: s-tw039-chord-theory-debate).
MOD and XM use 0xy for the same command: ProTracker's help calls it "used to simulate chords … noisy and grainy on most samples, but ok on monotone ones" — C-3 00047 C major, 037 C minor — and FT2 plays the note on tick 1, +x on tick 2, +y on tick 3 (sources: s-protracker-23d-help, s-ft2-manual). ST3's manual says the same in its own letters: Jxy changes the pitch "50 times per second … best to use it with clear or tight-looped (chip) instruments. Old users of the Commodore 64 remember this effect which was used to make chords" (J37 = C minor) (source: s-st3-manual). Two quirks players emulate: Fasttracker 2's arpeggio runs backwards (the second parameter's note comes first), and in ProTracker mode arpeggios that leave the Amiga range wrap around an octave (sources: s-openmpt-manual-compatible-playback, s-openmpt-manual-song-properties).
One command-memory trap when porting a part between formats: in S3M the effect memory is mostly global to the column, so a bare J00 recalls the last non-zero parameter of any command in that column, not just the last arpeggio — where MOD's 0xy has no memory at all and IT keeps per-command memory. Only vibrato and tone portamento have their own memory in S3M (source: s-openmpt-manual-effect-reference; effect-command-crosswalk).
Lead articulation (velocity, legato, late vibrato, drop-off) › Scream Tracker 3 / Impulse Tracker #
Necros's worked example (E minor run; ST3 letters, identical in IT/OpenMPT; source: s-tw012-advanced-tracking-tips):
- Velocity in the volume column — ramp a run up to its held peak and back:
E-4 40 · G-4 40 · A-4 50 · B-4 60 · E-5 64 … G-5 60 · F#5 50 · B-4 40 · C-5 40 → 50 → 64 · A-4 50. Multiples of 10 are quick to type; the volume column, notD20, so the effect column stays free. - Legato with tone portamento so the sample is not restarted:
GF0for any jump over three semitones ("practically instant"),G20/G06for a slow slide over a small step, and aGF0on the row after a slow slide to guarantee it lands, "since some players tend to play Gxx/3xx effects too slowly" (pitch-slide-and-portamento). - Late vibrato on the held notes only:
HA1a row or two after the note, thenHA2, never the main event except in hard up-tempo tunes; fade it back or fade the note (vibrato). - Echo track: copy the lead column,
ALT-Jits volumes down to a third at most (22 from 64), shift it 2–3 rows at speed 6 (4–6 at speed 3), pan it the same distance on the other side of the lead (fake-echo, stereo-panning). - Drop-off ("made infamous by Purple Motion and other siner junkies"): slide up into the top note, sustain it with vibrato, and at the very end fall away with an accelerating down-slide and falling volume:
| row | note / vol / cmd | what happens |
|---|---|---|
| 0 | B-4 01 50 | approach note |
| 1 | C-5 01 64 G05 | the big note, sliding up into it |
| 2 | GF0 | make sure it arrives |
| 3 | HA1 | vibrato in |
| 4 | HA2 | deeper |
| 5 | H00 | continue |
| 6 | HA1 | lessen |
| 7 | 50 E04 | slow fall starts |
| 8 | 30 E06 | faster, quieter |
| 9 | 10 E10 | fast fall, nearly silent |
| A | 00 | kill |
Catspaw's version of the same shape mixes volume-column values with K/H/E commands (C#6 02 33 UC3 → K20 → 44 H82 → K01 → 32 H71 → 20 E0E; source: s-tw058-the-finishing-touches; see volume-slides). The cheapest cousin of the drop-off is vegas's release tip of 1996: "Dont use a ^^^ to kill a note in the lead, just drop the volume to 10, 15, or 20 and volume slide the rest away. It leaves a reverb-ish effect thats really good on flutes, piano's and violins" — no pitch fall, just a volume-column 10–20 on the release row and a D0x slide to silence (source: s-tw062-interview-vegas).
Staccato and grace notes (Dan Hartrell's funk sax run, source: s-tw021-tracking-tips): D0F on a note and the row after it for "4 staccato" notes, G90 on each note of a phrase for a "wavey" pipe-or-reed sound, SD1 (note delay) to turn a note into a grace note that slips into the next, and alternating A05/A08 speeds so the run swings (shuffle-funktempo). Greg Heo's definition: a note cut SCx after x ticks is staccato, the absence of it legato (source: s-tw074-intro-to-musical-theory).
OPL / AdLib FM instruments in trackers › Scream Tracker 3 #
Press A in the instrument list's sample-type column, then Space on Parameters to edit the FM registers; FM voices live on channels A1–A9 (Sound Blaster only — a GUS can still play the samples at the same time); 1 in the pattern editor enters the AdLib note-off; rip the FM sounds from Skaven's example S3M to learn ("they can be saved as normal samples") (source: s-st3-manual). The instrument record packs the OPL registers per operator (multiplier, envelope scaling, sustain, vibrato/tremolo flags, level, attack/decay, sustain/release, waveform, feedback and mode) and carries a C2Spd that scales the note frequency sent to the chip; instrument types distinguish melody, bass drum, snare, tom, cymbal and hi-hat (source: s-st3-tech-doc).
Retrigger and resync › Impulse Tracker / Scream Tracker 3 #
Qxy replays the sample every y frames with a volume change x per hit: 0 none · 1–5 = −1, −2, −4, −8, −16 · 6 = ×⅔ · 7 = ×½ · 8 none · 9–D = +1, +2, +4, +8, +16 · E = ×1½ · F = ×2 (source: s-it-manual). Catspaw's frame arithmetic: at speed 6, Q03 hits again exactly halfway through the row, Q02 gives three hits, Q04 a lopsided pair; avoid odd speeds (5, 7, 9) because no retrig can land on the half-row — get the feel with tempo instead. vegas's tip of 1996 is the same arithmetic from the other side: "Use EVEN speed values like 2, 4, or 6, to make your retrigs sound smoother" — Qxy intervals that divide a speed-6 row evenly (source: s-tw062-interview-vegas). Recipes: ride cymbal Q43 (32 → 24), a snare roll Q53 then Q43 on consecutive rows, and the tom "thwump" QC2 from volume 04 rising by 8 per hit (source: s-tw058-the-finishing-touches). Q00 reuses the last value (volume-slides). ST3's manual gives the same table (with 8 marked "?") and the worked examples Q72 at speed 8 = 64, 32, 16, 8 and QC2 at speed 6 = 12, 20, 28 (source: s-st3-manual). ProTracker's E9x retrigs every x ticks — "If you retrig with 1 in speed 6 that note will be trigged 6 times in one note slot. Retrig on hi-hats!" — and FT2 keeps E9x and adds Rxy with the volume table, which OpenMPT calls "very buggy" (a volume command in the same cell skips ticks) (sources: s-protracker-23d-help, s-ft2-manual, s-openmpt-manual-compatible-playback). IT-compatible players refuse to retrigger a channel that has already stopped, so a very short hi-hat sample needs a silent loop at its end (source: s-openmpt-manual-compatible-playback).
Song initialisation and looping › ST3 / Impulse Tracker #
Put a silent dummy pattern first in the order list:
1 | ^^^ .. .. X3C | ^^^ .. .. X40 | ^^^ .. .. T7D | ^^^ .. .. A06 |
2 | ... .. .. C00 | ... .. .. .00 | ... .. .. X44 | ... .. .. X40 |
^^^ cuts anything still ringing from the previous loop, Xxx sets each channel's pan (works in S3M too), T7D/A06 set tempo 125 and speed 6, C00 breaks to the real first pattern after a fraction of a second. If you fade the global volume out at the end, reset it here too (volume-slides). At the end, put C00 on the same row as the final AFF so the pause lasts one slow row and the song restarts; give the Cubic player a row or two of AFF before the break because it stops on C00 immediately.
Jumps and breaks by format (sources: s-protracker-23d-help, s-ft2-manual, s-st3-manual, s-openmpt-manual-effect-reference, s-openmpt-manual-compatible-playback): ProTracker Bxx jumps to a hex position and "also perform[s] a pattern-break" — "you can use this command instead of restart as on Noisetracker"; Dxx breaks to a decimal line; F00 stops the song. FT2 Dxx takes a hex row (D16), and its E60 loop start has a bug: the next pattern begins on the loop row unless the pattern ends with D00. ST3 Bxx is hex, Cxx decimal, SB0/SBx loops never cross patterns. IT/OpenMPT: Bxx + Cxx on one row jump into the named pattern at the named row; a Bxx right of a terminating SBx cancels the loop. Song length in MOD is "one more than the last position" and NoiseTracker's restart byte is unused by ProTracker.
SID Factory II cheat sheet
Reference
Cheat sheet (from the tutorial)#
| what | how |
|---|---|
| load / file selector | F10 |
| play song | F1; toggle tracks Ctrl+1/2/3 |
| instrument table / wave table / pulse table | Alt+i / Alt+w / Alt+p (or Tab around) |
| play the current instrument | Shift+q (Shift+w, Shift+e … for other notes) |
| jump from an instrument's table index to that table row | Ctrl+Enter |
| edit a flag byte bit by bit | Shift+Enter opens a box; Space toggles a bit |
| old / new SID chip | click the field in the top bar (defaults to 8580) |
Instrument bytes: byte 1 = attack/decay, byte 2 = sustain/release, byte 3 = flags — $80 hard restart on, $10 set the test bit at note start; second nibble points to the HR table (default pair 0F 00); last byte = wave table start index. Example rows: 00 c9 00 00 00 00 sawtooth, 04 69 90 00 00 00 "support" with hard restart + test bit, 00 c8 80 00 00 05 snare drum.
Wave table: waveform note per tick; 7f xx loops to row xx; waveform bytes 11 triangle, 21 saw, 41 pulse, 81 noise (+ 51, 61, 31, 71 combinations); the note byte is a semitone offset (0c = octave) or a static frequency-table note 80–df. Pulse table minimal entry 84 00 00 / 7f 00 00.
Techniques
Hard restart › SID Factory II #
Set bit $80 of the instrument's third flag byte; the second nibble points into the HR table, whose default pair 0F 00 is the ADSR used for the last two ticks — "I have never had to change it" (source: s-chordian-sf2-instruments).
Instrument design beats note count › SID Factory II #
Instrument bytes = ADSR pair + flags ($80 hard restart, $10 test bit) + wave-table index; the tutorial's examples are a sawtooth (00 c9), a "support" instrument (04 69, HR + test bit) and the static snare 81 ca / 41 a8 / 41 a4 / 80 ca / 7f 08; ADSR feel: 04 69 bump-then-sustain, 00 a0 instant, 9b 2a slow pad (source: s-chordian-sf2-instruments).
Multispeed (framespeed) › SID Factory's multispeed driver (2007) #
laxity's SID Factory shipped two drivers: v5.0x, "standard music driver with calculated vibrato and no aim at execution speed (multispeed allowed)", and v6.0x, a "fast" driver without calculated vibrato that caps its rastertime spike at about $18 lines. Tognon: "Multispeed in a natural way with a specific player. I can say that this is the first editor I try that has this features (in other, if you add multispeed to a tune, you have to adjust instruments to the new mode)" — ninjatracker V2, released the same day, could not make multispeed tunes at all (source: s-sidin11-sid-factory-vs-ninjatracker).
Octave bass › SID Factory II #
Same shape, and the manual-level warning that goes with it. In the wave table the second byte is a semitone offset, 0c = +1 octave, and the table runs one row per tick until a 7f xx loop row; repeating a row slows the alternation ("Repeating lines in the wave table can often make instruments sound more pleasant"). Two constraints: slide, portamento and vibrato only work while the offset is 00, so the sustained rows must stay at 00 and the octave belongs on the short rows; and offsets that push the note outside the 8-octave frequency table sound "somewhat random". Values 80–df are static notes read straight from the frequency table regardless of the note played — the documented use is "a static hi-hat before a bass note" (source: s-chordian-sf2-instruments).
Pulse width modulation (PWM) › SID Factory II #
A pulse waveform (41) "doesn't say anything at all" until the pulse table sets a width; the minimal table is 84 00 00 / 7f 00 00 (source: s-chordian-sf2-instruments).
Ring modulation and oscillator sync › SID Factory II #
Test bit at note start: flag $10 in the instrument's third byte (Shift+Enter opens a bit editor). It also unlocks the noise generator after a "forbidden" noise combination (source: s-chordian-sf2-instruments).
Wavetable programming (waveform / arp tables) › SID Factory II #
Rows are waveform note, one per tick, until a 7f xx loop row; repeating a row slows the change ("Repeating lines in the wave table can often make instruments sound more pleasant"); the note byte is a semitone offset (0c = octave) — but slides, portamento and vibrato only work while it is 00, so keep offsets on the short attack rows; 80–df are static frequency-table notes that ignore the played note. The tutorial's oldskool snare: 81 ca / 41 a8 / 41 a4 / 80 ca / 7f 08 — one tick of high noise, two of pulse at descending medium pitches ("a 'thunk'"), then gated-off noise looped so the drum goes into release however long the sequence holds it. Keep rows gated on until the loop; toggling the gate row by row gives "a wobbling volume that you can't always trust" (source: s-chordian-sf2-instruments).
SID-Wizard cheat sheet
Reference
Cheat sheet#
Most-used keys#
| key | action |
|---|---|
F1 / F2 / F3 / F4 | play from start / from play-mark / selected patterns / stop-continue (C=+F1..F4 = same with follow-play) |
← | fast-forward 6× |
Shift+F / Shift+G | framespeed up / down |
< > (Shift+,/.) | subtune tempo up/down; [ ] second FunkTempo; C=+T toggle FunkTempo |
C=+, / C=+. | select subtune |
RETURN / Shift+RETURN | note-on / note-off; go to instrument/chord |
Shift+1..9/0 | mute/solo tracks |
C=+1..8, C= +/- | octave |
C=+Z/X/C/V | undo / cut / copy / paste; Shift+C marks end of block |
Shift+Q/W, C=+Q/W | transpose from cursor by semitone / octave |
Shift+V, Shift+P, Shift/C=+R, Shift/C=+S | vibrato, portamento, ring-mod on/off, sync on/off in the note column |
Shift+A/Z, Shift+H/J | auto-advance step, highlight step |
C=+E (orderlist) | find first empty pattern |
Shift+N (instrument) | name instrument; C=+P / C=+F toggle PW / filter reset; = negate table value |
C=+N (chord table) | toggle note-mode / number-mode |
Instrument-column effects#
| value | effect |
|---|---|
$01–$3E | select instrument |
$3F | legato / tied note (pitch only, no retrigger) |
$40–$4F | set waveform (small fx) |
$50–$5F | set sustain level (note volume) |
$60–$6F | set release time |
$70–$7F | set chord (overrides the instrument's default chord) |
Effect-column "small" effects ($xy, y = value)#
| range | effect |
|---|---|
$2x / $3x | attack / decay time of the note |
$4x…$7x | same as the instrument-column effects above |
$8x / $9x | vibrato amplitude / rate |
$Ax | main volume ($D418 low nybble) |
$Bx | filter band nybble |
$Cx | chord (arpeggio) speed |
$Dx | detune current note |
$Ex | control nybble (test / ring / sync) |
$Fx | filter resonance |
Effect-column "big" effects ($xx + value byte)#
| fx | effect | fx | effect |
|---|---|---|---|
$01 | pitch slide up | $0E | set pulse width |
$02 | pitch slide down | $0F | set filter cutoff hi-byte |
$03 | tone portamento (auto-portamento) | $10 | set main single tempo |
$04 | waveform/control register | $11 | set main FunkTempo |
$05 | attack/decay register | $12 | launch main tempo program |
$06 | sustain/release register | $13 | set track's single tempo |
$07 | select chord (overrides default) | $14 | set track's FunkTempo |
$08 | vibrato amplitude & rate | $15 | launch tempo program for track |
$09 | go to WF-ARP table position | $16 | vibrato type (00/10/20/30) |
$0A | go to pulse-width table position | $1C | shift cutoff hi-byte (permanent) |
$0B | go to filter table position | $1D | delay track by $00–$FF frames |
$0C | set chord / arpeggio speed | $1E | delay note (max = tempo − 3 frames) |
$0D | detune current note upwards | $1F | set filter-switch/resonance register ($D417) |
Orderlist values#
$01–$7F pattern · $80–$8F transpose down ($8F = −1) · $90–$9F transpose up ($90 = original) · $A0–$AF main volume · $B0–$EF single track tempo · $F0–$FD separator NOP with section id (shown as --…-D) · $FE end of tune · $FF xx jump to position xx (above $80: jump to subtune). The orderlist must not begin with $FE/$FF.
Chord table#
$00–$7D relative pitch up (semitones) · $80–$FF relative pitch down · $7E return from chord to the arp table · $7F loop the chord infinitely. Note-mode lets you set a root note outside the table and type the chord's notes as notes.
Tempo table#
$00–$7F = tempo (frames) for one pattern row; tempo programs can vary the tempo per row.
Table value schemes#
See instrument-tables for the WF-ARP-Detune, pulse-width and filter tables ($8x..$Fx = set, $00..$7F = add n times, $FE = jump).
Techniques
Chord arpeggio (the 0 3 7 trick) › SID-Wizard #
- Chord table (
C=+F5orC=+K): entries$00–$7D= semitones up,$80–$FF= semitones down,$7F= loop the chord forever,$7E= return from the chord to the instrument's arp table.C=+Ntoggles note-mode, where you set the root note outside the table and type the chord's notes as notes (select editing mode with Space).Shift+K/Lselects a chord from anywhere,+/-inside the table. - Assign it: each instrument has a default chord number; override per note with
$70–$7Fin the instrument column or$07 xxin the effect column. - Speed:
$0C xx(big effect) or$Cx(small effect) sets the chord/arpeggio speed. - Arps in the instrument instead: the Arp column of the WF-ARP-Detune table (
$01–$5Fup,$E0–$FFdown,$81–$DFabsolute pitch,$7Fjump to the chord) — see instrument-tables. Note: an arp entry cancels a running slide or vibrato. - The chord table is not available in the Light, Bare and Demo player types (sid-player-routine).
(source: s-sid-wizard-manual)
The SID-Wizard book's arpeggio instrument: WF-ARP 11 7F (triangle, jump to the default chord), chord table 00 03 07 0C 07 03 ending in 7F (loop) — "it runs quite fast", so set chord speed 02 in the instrument or in the WF column left of the 7F; attack 8, release B. Chords "are essentially arpeggios in SID-Wizard, but they don't depend on instruments"; 7E returns to the wave table's next row; note-mode (default since 1.5, C=+N toggles) lets you type or play chord notes from a MIDI keyboard with the root shown above the table (source: s-witchmaster-creating-chiptunes-with-sid-wizard).
A player author's confirmation of the idiom: in linus-walleij's SID player the arpeggio macro is a table of bytes that "represents the number of halftones to transpose the current note UPWARDS. For example macro 0x00 0x03 0x07 creates a minor chord"; the table "can loop or end", and the arpeggio step is skipped while the instrument's vibrato runs (source: s-walleij-sid-player-routine).
What the player actually does (SW 1.97 player.asm)#
The exact stepping rules, from m64's duet research (WFARPTB, player.asm 2396–2537; source: s-duet-research-sidwizard-deep):
- The arp-speed counter is decremented on every player call that reaches the table; a step happens only on underflow, so a row is held (speed+1) calls and speed 0 steps every call. In a multispeed tune the unit is player calls, not frames — arps speed up with the framespeed. Small-FX
$Cxsets the speed and forces an instant step on the next call. - A WF-column value
$00–$0Fis a one-shot speed override for that row only (held value+1 calls); no waveform is written for such a row. On ordinary rows the waveform is written only on the step entering the row; on chord rows it is re-read and re-masked every step. - On a chord row (arp
$7F) the table does not advance; each step reads the chord table:$7Ereturns — and the next WF-table row executes immediately in the same step;$7Fwraps to the chord's first entry; anything else is a note-relative offset. Chord speed is the arp speed — same counter. - Chord entries are relative to the pattern note, and every chord step stores the row's detune column unconditionally —
$FF, elsewhere "keep previous", becomes a literal +255 detune on a chord row (quirk; keep the detune column at$00on$7Frows). - A pitch-yielding arp step is a plain frequency-table lookup written over the accumulator — this overwrite is the "arp cancels slide/vibrato" rule;
$80(NOP) leaves even the accumulated vibrato displacement untouched.
Detune › SID-Wizard #
- Per instrument: the Detune column of the WF-ARP-Detune table (
$00–$FEdetune upwards per row,$FFkeep) — so a "lead B" instrument can be a detuned copy of "lead A". - Per note:
$Dxsmall effect detunes the current note;$0D xx(big effect) detunes upwards with finer range. - Not available in the Light and Bare players (sid-player-routine).
(source: s-sid-wizard-manual)
What the player actually does (SW 1.97 player.asm)#
From m64's duet research (player.asm 2445–2448, 2539–2541, 3399–3404; source: s-duet-research-sidwizard-deep):
- The detune value is added at the output stage every frame, never into the pitch accumulator — so vibrato, slides and arps cannot destroy it, and it detunes upward only (0..254 frequency LSBs; small-FX
$Dxsets x×8, big-FX$0Dthe raw value). - It is never reset — not by note start, not by player init: a pattern detune stays on the channel until a table row or another FX changes it. The table column's
$FFmeans "keep previous" — except on chord rows, where it is stored unconditionally and becomes a literal +255 (quirk: keep$00in the detune column of$7Fchord rows). - The addition has a path-dependent carry-in (no CLC), giving a deterministic ±1 LSB jitter tied to the table state — part of the SW sound a bit-exact reimplementation must reproduce.
Fake echo / delay › SID-Wizard #
Per-note volume is the instrument-column effect $5x (sustain level = note volume), so an echo note is the same note with a lower $5x, or a separate quieter echo instrument. $1D xx (Extra player) delays a whole track by $00–$FF frames and $1E xx delays a single note by up to tempo−3 frames — (unverified suggestion) a duplicated track with $1D gives a delay finer than one row (source of the commands: s-sid-wizard-manual).
Filter programming on the SID › SID-Wizard #
The instrument's filter-program table:
| entry | meaning |
|---|---|
$8r..$Fr xx | set resonance r and cutoff xx; the high nybble picks the band: 9 low-pass, A band-pass, C high-pass |
$00..$7F xx | add xx to the cutoff, this many times |
$FE xx | jump to table position xx |
Third column: $00–$7F / $FF–$90 keyboard tracking (cutoff follows the note pitch), $8x filter-switch override. Behaviour: filters are switched on automatically for channels using a filtered instrument; if several tracks try to control the filter, the leftmost channel wins; an instrument with an empty first table row is filtered but does not control the filter. C=+F toggles filter reset on instrument selection.
Pattern effects: $0B xx go to filter table position · $0F xx set cutoff hi-byte · $1C xx shift the cutoff hi-byte permanently · $1F xx write the filter-switch/resonance register · $Bx filter band nybble · $Fx resonance. The Extra player adds a filter-switch/resonance effect and keeps program tables from being skipped; Light lacks keyboard tracking and the 11-bit filter; Bare/Demo lack the filter small effects and filter shift (sid-player-routine). The cutoff bar in the top border shows what the filter does. With a table speed above $80 the filter table runs at multispeed rate (source: s-sid-wizard-manual).
More from the SID-Wizard book: the band nibble also allows combinations — $8 filter off, $9 low-pass, $B low+band, $C high-pass, $D low+high, $E band+high, $F all three (then resonance cannot be $F); the cutoff byte spans roughly 30 Hz–10 kHz; keyboard tracking is a signed exponential strength ($00–$7F brighter for higher notes, $FF–$90 weaker); $80–$8F in the third column is a filter-switch override kept for GoatTracker imports ($81 channel 1, $82 channel 2, $84 channel 3 — printed "channel 4" in the book — $88 external input, combinable). "The latest instrument always takes over the control over the common filter" ("like with polyphonic jamming in JCH's editor"); C=+F toggles whether the program restarts on every note (bright FILT. header) or only on instrument selection. The book's bass filter: 9B 45 (low-pass, resonance B, cutoff $45 — "quite dark") followed by 40 05, which opens the cutoff by $05 sixty-four times (source: s-witchmaster-creating-chiptunes-with-sid-wizard). The 1.6 charts print the same band list but skip $A (band-pass alone), which the beginners' tutorial confirms as "A (band pass)"; the tutorial's first filter row is 9F 30 — low-pass, resonance F, cutoff $30 — and it repeats the rule that an instrument with a blank first row is "filtered, but not to control the filter" (sources: s-sid-wizard-charts-and-tables, s-chipmusic-c64-music-for-dummies).
What the player actually does (SW 1.97 player.asm)#
The mechanism behind "the leftmost channel wins", from m64's duet research (flprog/STRTSND, player.asm 2175–2328, 1931–2009; source: s-duet-research-sidwizard-deep):
- There is one filter program per SID, and only the current controller track executes it. At init the controller is a
$0F"nobody" sentinel — no filter program runs until an instrument takes over. - Arbitration happens at note start, by the FIRST byte of the starting instrument's filter table:
$00→ passive (the channel's routing bit is switched on, controller untouched);$FF→ unfiltered (own routing bit off; if this track was the controller, the program parks on the$FFrow); anything else → take over: this track becomes controller and the table starts from its pointer next tick. Leftmost priority is emergent: channels are processed 3→2→1, so on simultaneous starts channel 1 writes last and wins. An instrument with filter-reset disabled (ctrl bit 7) and no re-typed instrument number skips arbitration entirely — including its routing-bit update. - The table position is per SID but interpreted against whatever instrument currently sits on the controller track — switch instruments there without a reset and the offset points into the wrong table (a real quirk, reproduced by DUET).
- The sweep works on the true 11-bit cutoff ((hi<<3)|low3), the "fine filter sweep" of the Normal/Extra players; the sweep counter is not reset by a take-over.
- Column 3's
$80–$8Foverride replaces the entire$D417routing nibble (all three channel bits plus external-in) and zeroes the keyboard-track value. - Write-out each frame:
$D416= kb-track curve value (indexed by the controller track's pitch) + cutoff-hi + the permanent$1Cshift, carries chained;$D415gets the raw low 3 bits, un-tracked. Big-FX$0B(filter-table jump) skips the controller check — it moves the shared position from any track (quirk).
Hard restart › SID-Wizard #
Instrument main settings (F7):
| setting | meaning |
|---|---|
ADHR | the ADSR loaded "1-2 frames before a new note is triggered"; common values 0F00 and F800 |
| HardRestart timer | 0..2 frames before the note |
| HardRestart type | normal, or staccato / aggregated: the test bit is also reset at hard restart, "adds 1-2 frames of gap between consequent notes" |
| Frame-1 waveform | waveform/control byte for the note's first frame (enable with RETURN, on by default); Hermit: its purpose "is the same as in Goattracker, to test / reset the oscillators with waveform $09 (test-bit set) before the sound starts and get a short 'sexy' start of the sound" |
In SID-Wizard 1.0 the beginners' tutorial had every instrument set HRTY to 2 (a square symbol appears next to the number) "so that the gate bit is reset between each note, which is important because otherwise notes will not sound if they come after another note rather than a note off" — later versions do this by default (source: s-chipmusic-c64-music-for-dummies). The Medium player drops the HR type and frame-1 setting; the Demo player has no hard-restart/frame-1 settings (sid-player-routine) (sources: s-sid-wizard-manual, s-witchmaster-creating-chiptunes-with-sid-wizard).
What the player actually does (SW 1.97 player.asm)#
The exact schedule behind the HR timer, from m64's duet research (player.asm 1517–1592, 1726–1728, 1820–2054; source: s-duet-research-sidwizard-deep):
- A row is fetched at tick 0 but its note starts at tick 2 — uniformly 2 frames later. That lookahead is what makes hard restart possible: the control byte's bit 1 fires the HR phase at tick 0, bit 0 at tick 1 (both bits = both ticks), so "HR timer 0..2" is literally which of the two pre-note frames get the treatment.
- An HR phase sets the ghost ADSR to the instrument's HR values (ADHR), masks the gate off, and clears the gate bit in the waveform ghost. The staccato type (ctrl bit 2) additionally writes waveform
$18(test bit + triangle) and skips the rest of the channel's processing that tick — the audible 1–2 frame gap. - During HR ticks the Normal player pauses vibrato, filter and pulse tables but keeps the WF table running (even for HR-timer-0 instruments); the Extra player pauses nothing. Because tick 2 must exist, the Normal player needs tempo ≥ 3 for notes; only Extra's fast-speed binding folds the ticks for tempo 1–2.
- Hard restart is suppressed when the incoming row is legato (
$3F), tone portamento ($03), or follows a$78portamento flag — glides never restart. - The 1st-frame waveform mechanism at tick 2: the player writes the frequency hi byte only (the low byte still holds the previous note) plus the frame-1 waveform — default
$09, whose test bit freezes the oscillator so the stale low byte is inaudible; the WF table's row 0 then executes on the next call, releasing the test bit and setting the true 16-bit pitch in the same write-out. ADSR order at note start: SR is written first, then AD.
Instrument design beats note count › SID-Wizard #
An instrument (F7 panel, up to 36 per tune in 1.8, Shift+N to name) = adsr-envelope + hard-restart settings + vibrato settings + default chord + octave shift + the three instrument-tables (wave/arp/detune, pulse, filter). Instruments are saved separately as .swi files, travel between tunes through the clipboard (C=+C … load … C=+V), and the distribution includes 324 example instruments. C=+X/C/V cut/copy/paste whole instruments; C=+P/C=+F decide whether pulse/filter tables restart on every note or only on instrument change (sources: s-sid-wizard-manual, s-witchmaster-creating-chiptunes-with-sid-wizard). The examples are the usual starting point in practice — "A lot of excellent example instruments are included in the Zip file" — and a tweaked one gave a Lemon64 poster a TR-808-like bass drum with a long decay, though he posted its WF-ARP table only as an image, so the values are lost (source: s-lemon64-sid-wizard-instrument-recommendations).
Three worked recipes from the SID-Wizard book (source: s-witchmaster-creating-chiptunes-with-sid-wizard):
| instrument | WF-ARP table | pulse table | ADSR / vibrato / filter |
|---|---|---|---|
| Bazz ("a standard SID bass") | 41 (pulse, gate on); octave transpose −3 | 82 (width $200), then 40 20 (add $20 sixty-four times — watch the pulse bar); keyboard tracking 10 on both rows | ADSR 089A; vibrato 3720, delayed up-down; filter 9B 45 (low-pass, resonance B, cutoff $45) then 40 05 (opens the cutoff by $05 sixty-four times) |
| Snare | 81 CE (noise at F-7) · 41 AD · 41 AC (pulse at G#4, G-4) · 80 C4 · 80 C5 (noise, gate off) | 88 ($800) | decay D, sustain E, release 9 — "the release parameter makes the biggest difference" |
| Arpeggio | 11 7F (triangle, jump to the default chord); chord 00 03 07 0C 07 03 + 7F loop | — | chord speed 02 (instrument or WF column); attack 8, release B "for a smooth attack and longer release" |
Because the snare uses only absolute pitches "all notes will sound the same". The 037-lab-style pitch drop for kicks and the "tiny downward pitch envelope" for bass go in the Arp column of the wave table ($01–$5F up on the first rows, then $00); hi-hat = a short noise row with a fast decay (wavetable-programming); lead = pulse with a slow pulse-width-modulation sweep and delayed vibrato.
A beginner's set from the 2012 chipmusic.org tutorial for SID-Wizard 1.0 (source: s-chipmusic-c64-music-for-dummies):
| instrument | ADSR | WF-ARP table | pulse table | notes |
|---|---|---|---|---|
| saw lead | 00F0 | 21 .. | — | "no dynamics", but a sound; 11 .. for triangle |
| octave flick | 00F0 | 21 0C · 21 .. | — | starts an octave up and "quickly flicks back down" — one table row is 1/50 s (1/60 on NTSC) |
| pulse kick | 0800 | 41 30 · 41 20 · 41 10 · 41 0C · 41 .. | 88 .. (square; 80 10 for "a very thin sound") | play it in octave 1; a pulse instrument is silent until the pulse table sets a width |
| hi-hat | 0400 closed, 0800 open | 81 .. (noise; a pitch in the arp digits makes it "slightly tonal") | — | "a short blast of white noise" |
Multispeed (framespeed) › SID-Wizard #
Shift+F/Shift+Gincrease / decrease the framespeed (SDI layout:?sets speed calls 1..8).- Instrument tables can follow the higher rate selectively: a WF-Arp table speed above
$40runs the pulse table at multispeed, above$80the filter table too. - Exported tunes expose the multispeed call at LoadAddress + 6, which the host program must call the extra times per frame (sid-format, sid-player-routine).
- The Bare player does not support multispeed.
(source: s-sid-wizard-manual)
Design note from the book: in SID-Wizard (as in X-SID) only the tables (waveform / pulse / filter) run at the multiplied rate; tempo, vibrato and slides are handled once per frame — "you can't set tune-tempo in a finer scale, but on the other hand in multispeed the tempo / hard restart / vibrato / slide settings can stay the same". GoatTracker calls the whole player. "The 2x speed (100Hz) can be quite enough for some nice effects. (E.g. Rubicon's title music by Jeroen Tel is 2x, and has drums that are not possible in 1x single-speed at 50Hz)" (source: s-witchmaster-creating-chiptunes-with-sid-wizard).
What the player actually does (SW 1.97 player.asm)#
The exact split between the main call and the extra calls, from m64's duet research (MULPLY/MULCNTP, player.asm 1240–1327; source: s-duet-research-sidwizard-deep):
- The framespeed−1 extra calls are spaced evenly across the 312 PAL rasterlines by the exporter. Row fetch, orderlist, hard restart, note start, tempo, vibrato and slides happen only in the main call; the extra calls run tables and re-write the registers.
- Per channel each extra call enters the chain by the instrument's table-speed byte: the WF-arp table always runs at the multiplied rate; bit 6 (
$40) adds the pulse table, bit 7 ($80) the filter table (which falls through pulse and WF). The filter/volume registers (COMMONREGS) are rewritten every subframe. - Table counters therefore tick per player call: an arp speed or sweep length means calls, not video frames — the same instrument runs its tables N× faster in an N× tune (the design the book describes as "only the tables run at the multiplied rate").
- A channel is skipped by the extra calls on its note's first frame (the note-start marker), so the frame-1 waveform trick survives multispeed: the WF table's row 0 lands on the next frame's first call.
Octave bass › SID-Wizard #
25 % pulse = pulse width $400 (set with $8x..$Fx in the pulse table or $0E); triangle is a plain waveform entry in the wave table. A short downward pitch envelope in the wave table's Arp column makes the octave hits punchier (instrument-design; source for the table mechanics: s-sid-wizard-manual).
Pitch slides and tone portamento › SID-Wizard #
| command | effect |
|---|---|
$01 xx | pitch slide up |
$02 xx | pitch slide down |
$03 xx | tone portamento (auto-portamento to the new note) |
Shift+P | portamento flag directly in the note column |
$3F in the instrument column | legato / tied note: sets the pitch only, no envelope retrigger |
Slides are calculated: a slide of N semitones takes about the same time at any pitch. Practical ranges from s-037-lab: $30–$60 is the everyday portamento zone (a semitone in ~140–40 ms), $08–$20 a slow dramatic slide, $80 and up a one-frame snap; every +$18 doubles the speed. The Light and Bare players lack calculated slides / note-column portamento; an arp table entry cancels a slide; in the Extra player vibrato survives a pitch slide (source: s-sid-wizard-manual).
The book's pattern tutorial: 03 25 on a G#5 for a slow portamento, 02 20 slide down near the end, then a note-off; "when using slow portamento … you may have to adjust the note to play a bit earlier so it doesn't sound as if the note starts late" — they move it from row $10 to $0C (source: s-witchmaster-creating-chiptunes-with-sid-wizard).
What the player actually does (SW 1.97 player.asm)#
From m64's duet research (player.asm 2085–2171, 3094–3099, 1803–1816; source: s-duet-research-sidwizard-deep):
- A slide's per-frame step is
freq16(speed/2 + note − 107)through the exponential table — the "calculated" slide: equal semitones per second at any pitch. Slides$01/$02never self-terminate (no clamp; the 16-bit frequency can wrap) — they end only when something rewrites the slide state: a note start,$03/$08/$16, a$6xnote-FX or legato. - Tone portamento
$03steps FREQMOD+1 per frame (a carry quirk — plain slides step exactly FREQMOD, so$03 00still creeps 1 LSB/frame), detects overshoot by borrow and snaps to the exact target, then stays pinned re-asserting the target each frame. The note on a$03row sets the target pitch but skips the sound init, and hard-restart is suppressed for it. - The note-column portamento flag (
$78,Shift+P) uses a fixed speed of 110 (≈ note frequency / 20 per frame) with no parameter; the next real note then converts into a glide without retrigger — hard restart and note start are both suppressed. - Legato (
$3F) is implemented as a maximum-speed portamento: slide speed is forced to the ceiling so the pitch snaps within a frame or two, while envelope, tables and vibrato state are left completely untouched.
Pulse width modulation (PWM) › SID-Wizard #
The SID pulse width is a 12-bit value (low byte + high nybble), so 50 % = $800, 25 % = $400, 12.5 % = $200. The instrument's pulse-width table (Shift+P) programs it frame by frame:
| entry | meaning |
|---|---|
$8x..$Fx xx | set the pulse width to xxx |
$00..$7F xx | add xx to the pulse width, this many times (one step per frame) |
$FE xx | jump to table position xx |
A sweep is therefore: set a start value, add a small positive step for n frames, add a negative step (= negates a value) for n frames, jump back. The third column is a keyboard-tracking curve ($00 off; $01 upward = more pitch dependence, $FF downward = less), so the width can follow the note. C=+P toggles whether the table restarts when the instrument is selected; $0E xx sets the pulse width from the pattern; $0A xx jumps to a table position. The current width is shown as a bar in the top border. With a table speed above $40 the pulse table runs at multispeed rate for smoother sweeps (source: s-sid-wizard-manual).
Details from the SID-Wizard book: $000 and $FFF give "a constant DC output (silence)", $800 a square wave; the first nibble of a set-row must be $8–$F but does not affect the width (true for the immediate output — but the player keeps seven bits of it in its ghost register, and a later sweep runs from the full value; see "What the player actually does" below). Keyboard tracking is "a signed value in exponential scale" — $00–$7F widens the pulse for higher notes, $FF–$80 does the same more weakly. C=+P toggles the header: bright PULSE = the program restarts on every note, dark = only when an instrument is (re)selected. The book's bass recipe: 82 (width $200) then 40 20 (add $20 sixty-four times) with keyboard tracking 10 on both rows — "look at the pulse width bar … while you try the instrument" (instrument-design; source: s-witchmaster-creating-chiptunes-with-sid-wizard).
The beginners' tutorial for SID-Wizard 1.0 puts it in two numbers: 80 10 is "a very thin pulse width", 88 .. the square wave, and past it the pulse gets "thinner again"; a pulse instrument with an empty pulse table is silent ("there is no default pulse width in this tracker"); a sweep row is 01–7F (frames) followed by the speed and direction — FF "a slow downward sweep", 81 "a very fast downward sweep" — and the purple KT column makes "the pulse width follow the pitch of the note being played" (source: s-chipmusic-c64-music-for-dummies).
What the player actually does (SW 1.97 player.asm)#
From m64's duet research (SETPWID, player.asm 2332–2394; source: s-duet-research-sidwizard-deep):
- A set row stores seven bits into the pulse-hi ghost (
cmd & $7F), not just the nibble: the SID ignores bits 4–7 of$D403, so$9xand$8xsound identical now, but a following sweep runs from the full 7-bit ghost value and wraps at a different point. - A sweep row
[N, xx]makes N signed 16-bit additions over N+1 ticks (the last tick advances the row without adding). The ghost can run through the whole 16-bit space; the SID sees bits 0–11. The sweep counter is reset on row advance but not at note start — leftover residue can shorten an instrument's first sweep row. - Keyboard tracking is applied at the output stage only, every tick: the player adds the first difference
EXPTABH[kb+pitch] − EXPTABH[kb+pitch−1]to the written hi byte, never to the ghost. 6502 borrow semantics leak through: a flat region of the curve yields a −1 artifact, an index wrap a +1. - The pattern gate does not touch the pulse program — it keeps stepping and writing through the release phase; gate-off merely redirects the position to the instrument's PW gate-off pointer.
- A
$FEjump landing on a set row executes it the same tick (set+jump in one tick); landing on a sweep row starts it the next tick. Big-FX$0A(table jump) also zeroes the sweep counter; big-FX$0E vvwrites only PW bits 8–11 (vv & $0F), keeping the low 8 bits.
Ring modulation and oscillator sync › SID-Wizard #
- In the note column:
Shift+R/C=+Rswitch ring modulation on/off,Shift+S/C=+Sswitch sync on/off — shown as small symbols after the note. - As effects:
$Exsets the control nybble (test / ring / sync / gate) as a small effect;$04 xxwrites the whole waveform/control register. - In the instrument's wave table any
$10–$FDentry is a full waveform/control byte, so ring/sync/test can be switched per frame (wavetable-programming): control nibble1gate +4ring =5, e.g.$15for a gated ring-modulated triangle; the 1.6 charts and the beginners' tutorial spell the nybble out —1gate,2sync,4ring,8test;3= sync + gate,5= ring + gate,7= both with gate, and "you need to keep the gate bit turned on" (sources: s-sid-wizard-charts-and-tables, s-chipmusic-c64-music-for-dummies). - The Bare and Demo players drop the waveform/ring/sync small effects (sid-player-routine).
(sources: s-sid-wizard-manual, s-witchmaster-creating-chiptunes-with-sid-wizard)
What the player actually does (SW 1.97 player.asm)#
From m64's duet research (player.asm 3101–3108; source: s-duet-research-sidwizard-deep):
- The note-column flags flip single bits in the channel's waveform ghost:
$79/$7Aset/clear the sync bit,$7B/$7Cthe ring bit — and they persist only until a WF-table waveform row replaces the whole byte or the next note starts. An instrument whose wave table keeps writing waveform values will silently erase a pattern's ring/sync flag on its next table step; the flags survive only over table rows that hold ($00–$0Frepeats,$FFend). - Small-FX
$Exreplaces the ghost's entire low nibble (gate/sync/ring/test at once),$4xthe high nibble; big-FX$04the whole byte, raw.
Shuffle, swing and FunkTempo › SID-Wizard #
Tempo is frames per row. Besides a single tempo there is FunkTempo — "two tempos are alternated every pattern step so with funktempo activated the first tempo is for even rows in the pattern and the second tempo is for odd rows" (source: s-witchmaster-creating-chiptunes-with-sid-wizard):
| control | effect |
|---|---|
< > (Shift+,/.) | subtune tempo up/down; [ ] (Shift+:/;) second FunkTempo; C=+T toggle subtune FunkTempo |
$10 xx / $11 xx | set main single tempo / main FunkTempo |
$13 xx / $14 xx | set this track's single tempo / FunkTempo |
$12 xx / $15 xx | launch a tempo program for the tune / for this track |
orderlist $B0–$EF | single track tempo |
Tempo programs (C=+F7/C=+F8 table, Shift+T/Y to select) hold one tempo value $00–$7F per pattern row, so any repeating groove — not just two-value swing — can be written. Different tracks may run at different tempos. The Light player has no tempo programs; the Extra player allows "fast tempo" 0..2 (source: s-sid-wizard-manual).
The book adds the BPM arithmetic: at 4 lines per beat, BPM ≈ 3007.47 / (tempo × 4) on PAL, and a funktempo counts as the mean of its two values (0604 → 5). Tempo programs (C=+F7) take values up to $7F and roll over automatically; a tempo program selected from a pattern effect maps its rows onto the rows of that pattern (source: s-witchmaster-creating-chiptunes-with-sid-wizard).
The 1.6 charts print the arithmetic as lookup tables for tempos $01–$14 against 1–32 lines per beat, which is how you pick a tempo/row-height pair for a target BPM: on PAL, tempo 06 at 4 lines, tempo 08 at 3 lines and tempo 04 at 6 lines all give 125.31 BPM, tempo 05 at 5 lines gives 120.30, and the same tempo 06 at 5 lines on NTSC gives 119.65 (source: s-sid-wizard-charts-and-tables). The charts also name two effects that shift timing without touching tempo at all — $1D delays the whole track by a number of frames (20 ms each) and $1E delays a single note — a per-track or per-note nudge where FunkTempo would move every row (same source; compare defMON's per-channel speed column below).
Inside the tempo machinery (SW 1.97 player.asm)#
From m64's duet research (player.asm 1341–1384, 3586–3696, packdepack.inc; sources: s-duet-research-sidwizard, s-duet-research-sidwizard-deep):
- The runtime tempo table starts with the main tempo/funktempo pair (loaded from the subtune's funktempo bytes at init), then one pair per track, then the tempo programs. A plain byte = tempo for one row then advance; a byte with bit 7 = tempo (&
$7F) then loop — so a single tempo is just a one-byte looping program, and funktempo is a nibble pair written as two entries (hi plain, lo |$80) alternating for ever. A row lasts tempo &$7Fframes; the Normal player needs tempo ≥ 3. - Every subtune owns a funktempo pair at the module's tail; an untouched subtune carries
$86/$83— bit 7 on the left byte means single tempo, so that reads "tempo 6, with 3 parked for the dayC=+Ttoggles funktempo on". - Tempo programs are a saved thing with tight caps: the file stores only the programs (an empty tune saves zero tempo bytes); at most 62 programs, 32 bytes per program, and a total table of 119/113/107/101 bytes for the 1–4-SID formats. In the editor bit 7 is never typable (the loop marker is set by the packer),
INSinserts a$00row andDELcannot remove a terminator. - The tempo-program effects
$12/$15treat operand00as a no-op ("NO TEMPOPROGRAM 0") — program numbering starts at 1.
Sound effects and game audio › SID-Wizard #
The exported tune is an API with an effects entry point. Call LoadAddress + 12 with X = note, Y = instrument, A = length; SFX plays on channel 3 (sources: s-witchmaster-creating-chiptunes-with-sid-wizard, s-sid-wizard-manual). That is the same instrument-plus-pitch triple the 1980s drivers used, exposed as three registers — so any of the tune's 36 instruments can be a sound effect, and designing effects becomes ordinary instrument-design and wavetable-programming.
Vibrato and delayed vibrato › SID-Wizard #
- Per instrument: four hex digits — amplitude, frequency (speed), and a two-digit delay (or increment speed); the four vibrato types are delayed up-down, delayed downwards, delayed upwards and incremental "violin style" (source: s-witchmaster-creating-chiptunes-with-sid-wizard; note the traced 1.97 player arithmetic runs
$20/$30the other way round — see "What the player actually does" below). Vibrato is "calculated", i.e. its depth is pitch-independent. The book's bass uses3720with delayed up-down. - In the note column:
Shift+Vputs a vibrato flag on the note (amplitude1..F), shown as a tiny graph symbol. - Effects:
$08 xyset amplitude and rate;$8xamplitude only;$9xrate only;$16 xxselect vibrato type (00/10/20/30). - Caveats: an arp entry in the instrument's table cancels vibrato; a pitch slide cancels it too except in the Extra player; the Light player has no calculated vibrato; Bare and Demo drop the vibrato-rate/frequency effects (sid-player-routine).
(source: s-sid-wizard-manual)
What the player actually does (SW 1.97 player.asm)#
The "calculated" arithmetic, from m64's duet research (VIBSLIDE/SETVIB0, player.asm 2085–2171, 2890–2941; source: s-duet-research-sidwizard-deep):
- Vibrato is a triangle added directly to the 16-bit frequency accumulator: period = 2×rate frames, per-frame step
FREQMOD = freq16(4×amplitude + note − 107)looked up through the exponential table — which is why the depth is a constant musical interval at any pitch. - The four types differ only in phase seed and the role of instrument byte 6: type
$00"increasing" has no delay — byte 6 is a per-frame amplitude increment, and the ramp is unbounded (it never clamps); type$10"normal" waits byte 6+1 frames then oscillates symmetrically; type$20seeds at the full rate and, as traced, oscillates above the note; type$30seeds at zero and oscillates below. The source comments name$20"down-oriented" and$30"up-oriented" — the opposite of the traced arithmetic (open question in the research; the traced behaviour is what DUET implements). - Note-column
$6xand small-FX$8xset the amplitude only — the rate stays the instrument's, the phase resets, and the delay counter is not reloaded; they also cancel a running slide/portamento by restoring the instrument's vibrato type.$9xsets the rate only, touching nothing else; big-FX$16the type only. - "Arp cancels vibrato" is an overwrite, not a flag: a pitch-yielding WF-table step writes a fresh table lookup over the accumulator, discarding the displacement; on hold/end ticks the displacement survives and keeps accumulating. On ticks 0/1 before a new note the vibrato stage is skipped altogether (Normal player).
Wavetable programming (waveform / arp tables) › SID-Wizard #
The Waveform-Arpeggio-Detune table (Shift+W in the instrument panel; at least one row is required), three columns per row, one row per frame:
| column | values |
|---|---|
| WF | $00–$0F repeat only the arp/detune columns for 1–16 frames (no waveform change) · $10–$FD waveform/control byte written to the SID (waveform bits + test/ring/sync/gate) · $FE xx jump to row xx (≥ $40 jumps to itself = hold) · $FF END (shown, not typed) |
| Arp | $00 original pitch · $01–$5F semitones up · $E0–$FF semitones down · $81–$DF absolute pitch ($81 = C-1, $8D = C-2, $99 = C-3, $A5 = C-4, $B1 = C-5, $BD = C-6, $C9 = C-7, $D5 = C-8) · $80 NOP · $7F jump to the chord (chord speed override in the WF column) |
| Detune | $00–$FE detune up · $FF keep |
Waveform nibble: 1 triangle, 2 saw, 4 pulse, 8 noise (add to combine, noise excluded; pulse needs a pulse-table row); control nibble: 1 gate, 2 sync, 4 ring, 8 test. Shift+SPACE marks a row to be executed on note-off — "more control on the release phase … reverb-like effects by changing the waveform". Related instrument settings: Frame-1 waveform (the byte for the note's first frame, normally $09 = test + gate), WF-Arp table execution speed (run the table slower than 1 row/frame; >$40 also runs the pulse table at multispeed, >$80 the filter table), = negates a value. $09 xx in the pattern jumps to a table row; $04 xx writes the waveform/control register directly (above $F0 jumps to a table position); $4x sets the waveform as a small effect. An arp entry cancels slides and vibrato. In the Extra player program tables are never skipped even at fast tempos (sources: s-sid-wizard-manual, s-witchmaster-creating-chiptunes-with-sid-wizard).
The book's snare (all absolute pitches, so every key sounds the same): 81 CE (noise at F-7), 41 AD, 41 AC (two frames of pulse at G#4 and G-4 — "a tone to the snare"), 80 C4, 80 C5 (noise with the gate off, so the release starts even while the key is held); pulse table 88; ADSR decay D, sustain E, release 9 (source: s-witchmaster-creating-chiptunes-with-sid-wizard).
sid-wizard-vessel cheat sheet
Reference
Cheat sheet#
| key / action | function |
|---|---|
| menu → SYNC MODE | arm sync playback (1 = NMI sync ON, 0 = normal Vessel MIDI, unsynced) |
| MIDI START (from the gear) | synced playback starts, follow play on; tempo must be 06 |
| cursor UP/DOWN | move the playback position in the orderlist — the running pattern finishes first; position −1 = song start |
F3 | hold (loop) the current pattern — oscilloscope turns green |
F1 | continue — release the loop, advance to the cursor's orderlist position — oscilloscope purple |
SHIFT+1/2/3 | mute/unmute channels (standard SID-Wizard) |
| MIDI STOP | exits sync mode; re-enter to re-arm so all devices restart together |
(source: s-sid-wizard-vessel-readme)
siddump cheat sheet
Reference
Cheat sheet#
| what | how |
|---|---|
| dump a tune to a text file | siddump tune.sid -tX > out.txt — X = the tune's length in seconds; or simply siddump.exe tune.sid > dump |
| reading the output | one row per frame: 50 rows = 1 s on PAL, 60 on NTSC; frame number ≈ 50 × seconds |
| columns, per channel | Freq (the 16-bit frequency value) · Note/Abs (note name and an absolute note byte; a note in parentheses is the nearest note) · WF (control byte: 11 triangle + gate, 81 noise + gate, 41 pulse + gate, 40 pulse with the gate off …) · ADSR (08F8 = attack 0, decay 8, sustain F, release 8) · Pul (pulse width); a filter column follows the three channels |
| unchanged values | printed as .... / .. |
| viewer | anything monospaced — Notepad, not WordPad (the columns break) |
| multispeed tunes | needs 1.05 or later; may still fail on complex interrupt code |
The Abs byte is $80 plus the semitone index counted from C-0 (AD = A-3, C7 = B-5, A8 = E-3, A5 = C#3, 96 = A#1 in Klose's dump) — the same numbering as goattracker's absolute wavetable notes (81–DF = C#0–B-7), so a dumped drum can be typed straight into a GoatTracker wavetable (derived by comparing the two documents; worked example on wavetable-programming).
SIDId cheat sheet
Reference
Cheat sheet#
| wiki page | SIDId names |
|---|---|
| soundmonitor | Soundmonitor, (MusicMaster_1), (MusicMaster_2), (MusicMaster_TMM), (Huelsbeck_Digi_V1/V2); Chris_Huelsbeck for his later players |
| rockmonitor | (Digitronix) (under Soundmonitor); Rockmonitor itself is a Soundmonitor signature |
| tfmx | TFMX (1988), TFMX/MasterComposer (1990), TFMX/TimeComposer (1990) |
| matt-gray-player | Matt_Gray, (Andrew_Rodger) — a 1990 modification |
| musicfile | MoN/Deenen with (MoN/Cyb2), (MoN/TTWII), (MoN/JTS), (MoN/RWE), (MoN/Bantam), (MoN/Deenen_Digi); MoN/FutureComposer = future-composer |
| johannes-bjerregaard | Bjerregaard, MoN/Bjerregaard, (Audiomaster_V1) |
| rob-hubbard | Rob_Hubbard, (Rob_Hubbard_Digi), Paradroid/HubbardEd, Jason_Page/RobTracker, Companion (the 1984 type-in his earliest SIDs used) |
| hubbard-player | Rob_Hubbard — the driver itself; see the row above |
| galway-player | Martin_Galway, Martin_Galway_Digi — the Rambo loader and Arkanoid players |
| ocean-music-driver | Paul_Hughes, MusDriver/Paul_Hughes ("Music Driver", pauliehughes.com); no Jonathan_Dunn entry |
| whittaker-player / david-whittaker | David_Whittaker |
| fred-gray | Fred_Gray |
| jeroen-kimmel | Jeroen_Kimmel |
| bjerregaard-player | Bjerregaard, MoN/Bjerregaard, (Bjerregaard); (Audiomaster_V1) is based on his Stormlord player |
| FAME (Adam Bulka) | FAME — "1988 F.A.M.E. (Fallacious Antrophoid Music Entertainment)" |
| Audial Arts (François Prijt) | Audial_Arts — "Zong Player"; (Audial_Arts_Digi), Audial_Arts/Cody, Audial_Arts/Cody_Digi |
| martin-galway | Martin_Galway, Martin_Galway_Digi |
| chordian (JCH) | JCH_OldPlayer, JCH_NewPlayer V1–V20, JCH_Protracker, JCH_DigiPlayer |
| laxity | Vibrants/Laxity, Laxity_NewPlayer_V21, SidFactory/Laxity, SidFactory_II/Laxity (sid-factory-ii) |
Soundmonitor cheat sheet
Reference
Cheat sheet#
| key | action |
|---|---|
X / SYS 4096 | leave / restart the editor |
SHIFT+I, Y | initialise: all steps → $BE00, defaults |
Z | sound page; F1/F3 select sound number; type the 24 bytes top-down; RETURN leaves |
RETURN on a bar address | open the bar's note display; RETURN back |
N / P | play from FIRST STEP with SID init / play on-off at CURRENT STEP |
F3 / F5 | set FIRST STEP / LAST STEP at the cursor |
TR column | transpose in semitones, 00–7F up, FF–80 down (0C = octave, FC = −4) |
ST column | added to every sound number in the bar |
RETURN under ARP/S | base-settings page: bytes 0–1 CIA timer lo/hi (hi "35–50"), 2 coarse tempo 0–4 (smaller = faster), 3 bar length ($20, $30 for 6/8, $40 double), 4 fade-out (FF none, 10 fast … 30 slow), 5 volume 00–0F; next lines = arpeggios of 8 semitone steps, e.g. minor 0c 07 03 00 0c 07 03 00 |
| arpeggio per note | set option bit 3 (digit 4) on the note; the byte after the last note selects it: 08 first, 10 second, 18 third, 20 fourth … |
O (+SHIFT) · CLR · K · , . / | keyboard octave · sound · key-transpose · voice for live play |
F7 | play on the keyboard (CTRL = C, 1 = C#, …; border red); F7/RETURN back |
R, Q, F7 | record: pick the track, quantize (1 = 16ths, 2 = 8ths, 3 = quarters, 0 = none), record — bar addresses must be filled in first |
£ | invert option bits and show the digit |
SHIFT+= | copy the FIRST…LAST STEP block to the cursor |
L … SHIFT+S | copy a sound, a bar or an ARP/S line |
SHIFT+INS/DEL / DEL | insert / delete a step |
SHIFT+@ | clear the bar under the cursor; on ARP/S: write default settings and two arpeggios |
T, SHIFT+S, SHIFT+L, $ | file type (Soundnumber / Complete Song with routine / Steps only), save, load, directory |
SYS 49152 | starts a "Complete Song" file from BASIC |
Sound registers (source: s-64er-soundmonitor-article): 0 waveform+gate at key-on (11 tri, 21 saw, 41 pulse, 81 noise; +2 sync, +4 ring, +8 test) · 1 AD · 2 SR · 3 portamento target · 4 pulse width · 5/6/7 pulse-EG up time / down time / step (> 30 "gets dirty") · 8 waveform at key-off (10/20/40/80) · 9 pulse-EG restart (1x) and portamento mode (x1 up, x2 down, x4 once) · 10/11 portamento speed lo/hi · 12/13/14 vibrato depth / speed (00 fast … 7F slow, bit 7 = start direction) / delay · 15 fine detune · 16 filter type nibble (FF = leave the filter alone, avoids clicks) · 17 resonance + voice mask · 18 cutoff · 19/20 filter-EG up/down time · 21/22 filter-EG step lo/hi · 23 filter-EG mode + trigger voice.
Recipes from the article: bass 41,09,99,00,20,10,10,10,40,10,00,00,00,00,00,00,FF,… · lead 41,08,7C,00,60,10,10,10,40,10,00,00,10,07,1A,00,FF,… · flute 11,09,99,00,00,00,00,00,10,00,00,00,10,06,10,00,FF,… · bass drum 11,09,09,01,00,00,00,00,10,01,FF,00,… (a triangle pulled down once) · snare 81,09,09,01,00,00,00,00,80,01,10,30,… · "Rambo theme sound" 41,08,7D,00,00,20,10,10,40,10,00,00,10,08,1D,00,FF,… · ring-mod effect 15,08,7A,10,00,00,00,00,14,01,20,23,… (instrument-design).
Generic / PC trackers cheat sheet
Techniques
Chip samples — tiny looped waveforms › Trackers with real chips #
On the C64 and Game Boy the "sample" is the instrument definition itself — see instrument-tables and wavetable-programming; the closest PC-tracker equivalent to pulse-width-modulation is switching between pulse chips of different widths (s-037-lab).
The C64 has a sample channel of sorts too — the digi, or volume-register sample: the 6581 "produces a DC output with its intensity being regulated by the global volume register", so writing 4-bit sample values to it fast enough gives "a crude, virtual fourth 4-bit PCM channel"; furnace offers this as the system Commodore 64 (SID 6581) with software PCM and notes that the 8580 "fixed this problem, making such PCM nearly inaudible" (source: s-furnace-c64-docs). commodore-64.eu calls it the "sample bug" and names Ghostbusters and Arkanoid as games that used it (source: s-commodore-64-eu-sid-chip; secondary). SID musicians also use looped samples the way PC chiptunes do: in Gallefoss's Electronic Transfer "the bass tone is a sample loop (like how chip modules do it)" (4mat, source: s-chipmusic-sid-music-hints-n-tips). Background on sid.
How the composers used it:
- bob-yannes confirms the mechanism from the design side — the volume register's DC step — and that "Game programs often used this method to synthesize speech or play 'sampled' sounds" (source: s-sidmusic-yannes-interview).
- martin-galway: "I saw some utilities from the USA and picked them apart" — first the "flatulence stuff that shipped in Arkanoid", later real drum samples; "Things were better once I got to Game Over" (source: s-sidmusic-galway-interviews); in 2001: "my samples sounded like farts and burps" (source: s-remix64-galway-interview).
- rob-hubbard: the "Go!" in BMX Kidz is his own voice; PowerPlay Hockey and Kings of the Beach "both had samples" (source: s-sidmusic-hubbard-interviews).
- jeroen-tel on Turbo Outrun: "Having samples (and my own voice) inside a tune, that was awesome"; for Agony the Amiga samples were cut down to a low rate (source: s-sidmusic-jeroen-tel-interviews).
Detune › PC trackers #
Vivid's flange/chorus: the same sample on two channels, the second delayed by a sample offset (9xx) or note delay (EDx), with a fine pitch slide (E1x/E2x in ProTracker) on one of them to control the beating — "works pretty fine on brass leads" (source: s-tw059-tracking-hints). Zinc's stereo doubling with two slightly different samples, or the same sample slightly offset, panned apart, is the same idea across the stereo field (source: s-tw075-it-percussion-tips). A permanent detune is a different tuning on the duplicated sample, and the unit depends on the format (sources: s-protracker-23d-help, s-st3-manual, s-st3-tech-doc, s-ft2-manual, s-openmpt-manual-samples): ProTracker finetune −8…+7 shifts A from 412.0 Hz to 457.0 Hz in steps of roughly 1/8 semitone (0 = 436.4, +1 = 439.0, +2 = 441.6 …), also settable per note with E5x; ST3 replaces it with C4Spd, the frequency at C-4 (8363 = none; S2x maps the MOD values to 7895–8757 Hz; +/- on the field halve or double it, / sets it by note); FT2 widened finetune to a signed byte, 1/128 semitone (audible in steps of 8), plus a relative tone; IT/OpenMPT set the C-5 frequency directly. Fine pitch slides (E1x/E2x) are "Great for creating chorus effects" (ProTracker), and MPTM has +xx for a per-note finetune.
StereoMan's IT flanging: the same sample on two channels at exactly the same pan, one with a fine pitch slide (EE1, or volume-column u11… then u00); put the pair at X00/XFF instead for a three-dimensional sound (source: s-it-hints).
Fake echo / delay › Any tracker #
Copy the melody column, paste it 3 or 6 rows lower into a free channel (or into the gaps of the same channel), lower its volume, and optionally use a duller instrument.
Fake echo / delay › Sample trackers #
The "standard techno echo" of the 1990s PC scene: copy a column to another channel with an offset of 2 or 3 rows and lower its volume (GBlues, source: s-tw055-panning-debate); pan the echo to the other side of the source, or spread several echoes across the stereo field (Vivid, source: s-tw059-tracking-hints). Alternatives when channels are short: impulse-tracker's retrigger Qxy with a volume decrease, or a looped reverb tail shaped by a volume envelope so the "echo" lives inside the instrument (instrument-envelopes; source: s-tw081-it-tip-of-the-week). Necros's numbers for a lead echo (source: s-tw012-advanced-tracking-tips): copy the track, ALT-J its volume to at least a third lower — 22 from 64; "I hate leads where people copy the track, move it down, and forget to drop the volume" — and offset it two or three rows at speed 6, four or six at speed 3 so the delay sits on the beat; pan it the same distance on the other side of the lead, or hard on the lead's own side (stereo-panning, lead-articulation).
The manuals' own echo tools (sources: s-st3-manual, s-protracker-23d-help, s-ft2-manual): ST3's block mix — "set the skip level to 2 and write the melody. Then copy the melody to an adjacent channel, lower its volume with ALT-J, insert it one row, and mix it with the original melody"; Alt-I/Alt-J multiply volumes by 3/2 or 2/3 "for creating echoes". ProTracker: ED0 delays a note "a little anyway. You can play the same note on two channels, delay one, and get a nice flanging effect", the Edit Op Echo function bakes an echo into a sample ("If you want more room to echo in, just turn up the length of the sample"), and Ctrl+J join-pastes a block over existing notes. FT2's sample editor extension has an Echo command too.
Airon (1998) calls this channel echo "a primitive version" of a reverb's early reflections; the real thing has to be baked into the sample offline — see reverb-and-compression (source: s-tw118-reverb-and-compression).
Instrument design beats note count › Sample trackers #
- Drums: make chip drums by cutting both ends off real drum samples until they are tiny (source: s-tw077-chip-off-the-block); tune percussion by setting the sample's C-5 speed and always playing one note; kick in the centre; volume swing on hi-hats; keep sample volumes relative and balance with the global volume (Zinc, source: s-tw075-it-percussion-tips).
- Sample prep: centre (
ALT-H) and amplify (ALT-M) in IT (source: s-tw081-it-tip-of-the-week); filter out what a sound doesn't need — "why should a bassdrum have high frequencies?" — and add reverb offline, then pan the echoes (Vivid, source: s-tw059-tracking-hints); tune melodic samples with a guitar tuner on the line-out (source: s-tw077-general-tracking-tips); offline reverb and compression — threshold/ratio/attack per sound, gated-reverb and preverb recipes — are on reverb-and-compression (source: s-tw118-reverb-and-compression), the recording chain on recording-samples (source: s-tw066-sound-recording). - Instruments, not just samples: NNAs for sustain in one channel (new-note-actions), envelopes for reverb tails, sirens and analog sweeps (instrument-envelopes); several cheap instruments per sample.
- Realistic instruments come from sampling a real synth (Behemoth's Korg X5) — the opposite aesthetic to chip-samples, same craft (source: s-tw076-realism-in-mods).
- Where the samples came from (1995–96), per the traxweekly interviews: CDs and a friend's synth (basehead; source: s-tw001-interview-basehead); own CDs and videotapes through Goldwave 2.1 or CoolEdit (maelcum; source: s-tw009-interview-maelcum); a full own-synth chain — Korg Poly-61, Roland JX-8P, Yamaha DX7, Yamaha FX-500, an SM57 and a small mixer — for 99 % of one group's samples (the-zapper; source: s-tw027-interview-zapper); a whole song from a Casio CZ-101 (skaven; source: s-tw109-interview-skaven); the #trax wish list of December 1996 — Roland XP-50, Korg Prophecy, Korg Trinity, K2500, Nord Lead (source: s-tw080-trax-mass-interview). The ripping ethic of the same interviews: fine if you lack equipment, lazy if you have it, always credit (zinc; source: s-tw032-interview-zinc); "technique is technique, all that matters is the vibe" (jugi; source: s-tw010-interview-jugi) — see sample-ripping.
- Why the PC scene chose samples at all, from two later interviews: Mental Floss, after buying a Yamaha CS1x, "just had to go back to tracking. Synths are nice, but you just have a bigger sound stock by using samples, and more control" — and names what samples still lacked in 1998, "A) A sampler with filters B) An effects box" (source: s-tw119-interview-mental-floss). The flip side is that the instrument is the sample: for tracked techno, "with good samples, you can make stuff that sounds like real vinyl" (Injekted), and the main problem with scene techno is "lots of bad samples" (Subhuman) (source: s-tw054-interview-injekted-and-subhuman).
- Palettes and sample sets in the interviews (1995–96): a fixed palette as a writing method — perisoft's three standby samples, "FC SINER FROM PANIC", a "FILTER SYNTH" and the lead from Insideout, gave him ten songs in two weeks (source: s-tw011-interview-perisoft; compare chip-samples); new samples as the creativity trigger — beaner: "without new samples, i have absolutely NO creativity" (source: s-tw011-interview-beaner) — against big-jim's warning that spending the time on samples and rushing the tracking "gets boring half way through" (Foreign Skys; source: s-tw013-interview-big-jim); sample sets travelled with a style — lord-pegasus used "like 50% bh samples" and was told he tracked like basehead (source: s-tw018-interview-lord-pegasus), and maelcum claimed the "rezonant bassy sounds floating around nowadays" as his own, uncredited (source: s-tw019-interview-quarex); u4ia's criterion for a vocal sample is a voice that "alters much like an analog synth does. The sound progresses instead of sounding the same all the time" (Annie Lennox, "diva" voices), and his advice is "distort your samples and be happy" (source: s-tw067-interview-u4ia).
- Drum sampling (the sincere part of a satirical series, source: s-tw087-music-theory-a-modern-approach): sample drum machines in a pawn shop or real drums; study commercial drum loops closely — their main pulse is often a tambourine, so sample one; sample kick-plus-snare combinations in one file (playing them separately with NNA continue in impulse-tracker "loses the subharmonics and resounding frequencies as the two waveforms interact"); prefer a splash to a crash; render a pattern to a sample, drown it in reverb (Sound Forge, Cool Edit, GoldWave), then record to tape and resample for "analog noise".
Three tool-level recipes from the manuals: ProTracker's Chord maker mixes major, minor, sus4, 6th and 7th chords of one sample into a new chord sample (the way a 4-channel MOD gets a full chord on one channel), and its Boost/Filter/Echo shape drum samples ("Boost … Use this on hi-hats and snares!"; Filter "on noisy basses") (source: s-protracker-23d-help); FT2 builds instruments from envelopes, auto-vibrato and key splits (instrument-envelopes, multisampling; source: s-ft2-manual); S3M and OpenMPT's MPTM add two-operator FM patches — opl-fm-instruments (sources: s-st3-manual, s-openmpt-manual-samples).
New Note Actions (NNA) › Other trackers #
XM has no NNAs — the FT2 manual defines an instrument as envelopes, auto-vibrato, samples, key split and MIDI, nothing more, and the Schism FAQ's "Tell the Milky Tracker guys to add NNAs ;)" makes the same point about FT2-style trackers (sources: s-ft2-manual, s-schism-tracker-wiki). openmpt implements IT's in full — Note Cut (default), Continue ("mostly useful with short one-shot samples such as percussion"; looped samples continue "indefinitely until you trigger one of the 'Past Note' effects S70, S71 or S72"), Note Off, Note Fade (equals Continue when Fade Out is 0) — plus Duplicate Note Checks by note, sample, instrument or plugin with their own action, and calls NNAs "a great way to save pattern channels that would otherwise be used just fading out playing notes" (source: s-openmpt-manual-instruments). Chip trackers have nothing comparable — the chip has no spare voices, which is why channel-interleaving exists.
Octave bass › Any tracker #
Type the pattern by hand (C-2 C-3 C-2 C-3 …) or, where the tracker has an arpeggio command, run a two-note arp 0 12 at 8th/16th rate (chord-arpeggio).
OPL / AdLib FM instruments in trackers › Before the trackers: EdLib and a C64 composer's AdLib player #
The scene did not only reach OPL through trackers. JCH's route is documented in detail and is worth reading as design notes for FM sequencing (sources: s-chordian-my-computer-chronicles, s-chordian-player-editor-notes).
- The player (November 1991) carried the C64 habits straight over: arpeggio tables in the C64 style, his own vibrato and modulation control — "it immediately distanced the player from almost anything that used AdLib on the PC" — and a timer interrupt instead of raster sync, since the PC has no raster to hang a player on (multispeed, sid-player-routine).
- "Register bypassing", his own invention and the one idea here that any OPL player still needs: cache every OPL register write and skip the ones whose value has not changed. The chip is addressed through a slow port pair, so the win is real, and it is the FM equivalent of the ghost-register tricks the SID drivers use (instrument-tables).
- EdLib, the DOS editor grown out of a "Multi-Editor" prototype, used "the same sequence editing principle as on the C64", folding out only the selected one of nine channels — nine being exactly the OPL2's melodic voice count. First version September 1993, public December 1994.
- The paper trail dates the design before the code: AdLib editor ideas are dated 1991-08-10 and February 1992, while the PC player's own notes start in December 1991 and its header format in March 1992 (source: s-chordian-player-editor-notes).
- Converting SID tunes to FM is not free. He kept a candidate list of C64 tunes to move to AdLib/Sound Blaster; "only laxity's The Alibi and Star Dream were eventually transferred among these" (source: s-chordian-player-editor-notes). His paid AdLib work came through the PC version of Hugo and the 1992 Harald Hårdtand, where drax composed on the C64 and JCH converted (source: s-chordian-my-computer-chronicles).
Pitch slides and tone portamento › Generic trackers #
Tone portamento is usually 3xx (slide the running note towards the new note at speed xx); pitch slides up/down 1xx/2xx. In S3M/IT the letters are Gxx to the note, Exx down, Fxx up, Lxy portamento + volume slide; ProTracker has fine slides E1x/E2x, which Vivid uses to steer a two-channel flange (sources: s-tw074-intro-to-musical-theory, s-tw077-chip-off-the-block, s-tw059-tracking-hints). In impulse-tracker tone portamento is Gxx, where xx/16 is the semitone step per tick — 037-lab converts its slide values to Gxx assuming speed 6 and tempo = BPM (source: s-037-lab).
Legato leads with Gxx (necros, source: s-tw012-advanced-tracking-tips): tone portamento "switches from note to note without re-starting the sample", which suits leads whose sample evolves over time. GF0 is practically instant — use it for every jump of more than three semitones so the lead is not "pitch bended too slowly"; smaller values (G20, G06) for one- or two-step moves; and put a GF0 on the row after a slow slide "to make sure that it makes it all the way up to the next note, since some players tend to play Gxx/3xx effects too slowly". Dan Hartrell's sax run uses G90 on every note for a "wavey" pipe-and-reed sound (source: s-tw021-tracking-tips). The whole recipe — velocity, legato, late vibrato, echo, drop-off — is on lead-articulation.
Units and limits per format (sources: s-protracker-23d-help, s-ft2-manual, s-st3-manual, s-st3-tech-doc, s-openmpt-manual-effect-reference, s-openmpt-manual-song-properties): ProTracker 1xx/2xx add to the Amiga period every tick ("called as many times as the speed of the song") and cannot pass B-3 (period 113) or C-1 (856); 3xx slides to the note (300 continues), E1x/E2x slide once ("Great for creating chorus effects"), E3x glissando snaps portamento to semitones. FT2 keeps the numbers, adds X1x/X2x extra-fine (speed ÷ 4), the volume-column Mx, and a linear frequency table that makes "all pitch bends run in constant speed, independent of the current frequency" (Amiga table = period slides). ST3's Exx/Fxx use periods four times finer than the Amiga's (hence EEx/FEx "four times more accurate"), with Gxx portamento and S1x glissando. IT/OpenMPT: with linear slides one unit = 1/16 semitone (extra-fine 1/64), otherwise a period (3,546,895 ÷ Hz; 3,579,364 in XM) — so a slide value means a different interval at every pitch; "Compatible Gxx" keeps tone-portamento memory separate from Exx/Fxx as FT2 does. Quirks: regular slides are not supposed to move at speed 1 (fine slides are); FT2 wraps a note slid too low "around at some point" into a very high note; IT plays nothing for a tone portamento with no previous note; ST3 continues a slide from the last arpeggiated note (source: s-openmpt-manual-compatible-playback).
Pulse width modulation (PWM) › Sample-based trackers #
Fake it by switching between pulse samples of different widths every row or two (source: s-037-lab); (unverified) or use single-cycle pulse samples with an instrument that cycles them.
Randomization and probability (MayBe, RandomiZe) › Other trackers #
(unverified) SID-Wizard has no probability or swing commands; fake variation with alternating patterns in the orderlist.
Retrigger and resync › Other trackers #
(unverified) SID-Wizard has no retrig command — use a wave table that re-gates (wavetable-programming).
Reverb and compression (offline, in the sample editor) › Inside the tracker #
The channel echo of the 1990s scene is, in Airon's words, "a primitive version" of reverb — its early reflections (source: s-tw118-reverb-and-compression); see fake-echo for the copies-on-extra-channels method, instrument-envelopes for looping a reverb tail under a volume envelope, and stereo-panning for spreading the echoes of a reverb-treated sample.
Shuffle, swing and FunkTempo › PC trackers #
Necros in 1995 (source: s-tw012-advanced-tracking-tips): the Amiga funk "floating tempo" alternates speeds row by row — A08 on the even rows, A05 on the odd — so the off-beat rows arrive late; the resulting average speed is 1 ÷ ((1/8 + 1/5) ÷ 2), "a bit slower than A06", and the swing amount is coarse. His refinement: alternate fine tempos instead, T60/T90 or T70/T9A, the first about two thirds of the second for a medium swing (his "Realization 2"); experiment from there. Dan Hartrell swings a sax run with A05/A08 (source: s-tw021-tracking-tips).
Alternating Axx speed commands row by row (e.g. speed 7 / speed 5) is the classic method in ST3/IT — every format's speed command can do it (Fxx below 20 in MOD/XM, Axx in S3M/IT), and IT/MPTM also extend single rows by ticks with S6x (XM: the X6x hack) (source: s-openmpt-manual-effect-reference). openmpt's MPTM format replaces the trick with Tempo Swing: in Modern tempo mode a slider per row of the beat lengthens or shortens that row, globally or per pattern; the rows always add up to the tempo, the swing survives tempo changes, plugins get a steady clock and no tempo commands litter the patterns (source: s-openmpt-manual-song-properties). ProTracker's speed is either VBlank ticks or CIA BPM, and FT2's "BPM is correct at speed 06" (sources: s-protracker-23d-help, s-ft2-manual).
Stereo panning › PC trackers #
- A pan position is a balance, not a switch. In FastTracker 2's
P0–PFscaleP3is about 80 % left and 20 % right; onlyP0/PFare one-sided, andP0 + PFon two channels is mono (trixter, source: s-tw055-panning-debate). GBlues's proposal of a second "reflection" channel at 25 % volume on the opposite side is therefore redundant as physics — but it survives as a stereo fake-echo flavour, and his pseudo-stereo drum trick (one loop on two opposite channels at 50 %, accent a side with a volume slide) still works. - Impulse Tracker: pan in the volume column (
0–64) or withXxx(00–FF; volume-column value =Xxx÷ 4,X80= centre — Airon's chart, source: s-tw106-a-little-panning); the`volume-column entry changes pan while keeping vibrato; panning default per instrument, panning swing for subtle per-note variation, panning envelopes for beat loops (instrument-envelopes). Zinc's rules: kick in the middle; make things wide by doubling channels equidistant from the target with slightly different samples, a small offset/delay, or two consecutive notes; extremes at00/64; "track as if your speakers are side by side" and let listeners lower the separation (default 128) (source: s-tw075-it-percussion-tips). - Panbrello
Yxyfilled down a bass channel with a fast rate and shallow depth (YF7) reads as width rather than movement (Pinion, source: s-tw081-it-tip-of-the-week); Pulse's single-row templateC-4 01 X30 | C-5 01 XC0is the cheapest stereo doubling (same source). - Vivid: place the echoes of a reverb-treated sample at different pan positions so it sounds "a bit more realistic" (source: s-tw059-tracking-hints).
- Necros's ST3-era placement (source: s-tw012-advanced-tracking-tips): prefer channel panning to instrument panning (instrument pans suit drums only; a melodic sample plays lead, echo and chord roles in different places); never double a part on both sides "for stereo" — it wastes channels and muddies non-GUS mixes. Drums near the centre and slightly apart — kick and snare
S87, hi-hats and tambourinesS8A, crashes middle; the lead atS86–S8Awith its echo mirrored at the same distance (S86→S8A/S8B) or hard on the lead's side (S81); layered chords spread out, a single chord pad centred, one pan per note of a multi-channel chord;S8xon every row makes a hi-hat travel round the head. Stereo width from one sample: the same chord at the same note on a left and a right channel withO01on one of them, panned well apart (S82/S8Dor the extremes) — sample-offset as a delay line. - Two 128-step scales: in ST3
S8xis the 16-step GUS hardware pan (S80left,S88middle,S8Fright; played correctly only by ST3 3.2+ on a GUS), andXxxa 128-step software pan for DMP/IPlay —X00left,X40middle,X80right,XA4DMP's SBPro surround — which ST3 saves but does not play (source: s-tw012-advanced-tracking-tips). IT'sXxxruns00–FFwithX80= centre (source: s-tw106-a-little-panning): the same letter, two ranges — anX40from a 1995 S3M is centre, in an IT file it is quarter-left. The hardware side of the same story: on a cheap Sound Blaster Pro clone ST3 gave claim "either mono or stereo with swapping (which drove me crazy)", which is why some 1995 users moved to FT2 (source: s-tw015-interview-claim). - Stereo samples instead of panning (Zinc, source: s-tw094-stereo-samples-in-impulse-tracker): a panned mono sample stays mono — "shallow and fake" at pan 32 — while a stereo sample gives each ear a different signal. In IT load the stereo file twice, once as LEFT and once as RIGHT (IT asks), set the two samples' default pans hard left and right, and play identical note columns on two adjacent channels; twice the size and channels, so reserve it for kicks, bass and short hits and keep strings mono-panned.
- Zinc's magazine-derived mix rule: bass in the centre, drums near but "not always dead center", lighter parts such as strings and guitars wider; check the mix in mono (source: s-tw096-studio-tracking-tips). Over MIDI the equivalent is controller
0A—00left,40centre,7Fright (midi-in-trackers; source: s-tw098-impulse-tracker-midi).
- Per format (sources: s-openmpt-manual-effect-reference, s-ft2-manual, s-st3-manual, s-protracker-23d-help): the Amiga has a fixed L-R-R-L layout and ProTracker's
8xx/E8xare "NOT USED" (MOD players ignore panning); FT2 pans per instrument —8xx00–FF orPxin the volume column, reset by the next instrument number, withPxy/Rx/Lxslides, and the GUS knows only 16 positions; ST3'sS8x(0–F) is new in 3.2 and "only works on a GUS", with default pans per channel on F1; IT/OpenMPT pan per channel withXxx00–FF (pxx0–64 in the volume column),Pxyslides,Yxypanbrello andS91surround. FT2 used a square-root pan law that emphasises the centre — OpenMPT's "Compatible (FT2 Pan Law)" (source: s-openmpt-manual-song-properties). Changing NR51-style hard pans on a chip and instrument-based pans in XM are the two places a pan command silently resets.
Vibrato and delayed vibrato › Generic trackers #
Most trackers have a vibrato command, often 4xy (x = speed, y = depth): place it a few rows after the note starts, or use an instrument envelope with a delay (source: s-037-lab). In impulse-tracker / S3M the command is Hxy (4xy in protracker) and Kxy combines it with a volume slide; the Modsquad's chip lead uses H81/HA4 and puts an HFF vibrato on percussion instead of an arpeggio (sources: s-tw074-intro-to-musical-theory, s-tw077-chip-off-the-block).
Necros's rule for leads (source: s-tw012-advanced-tracking-tips): "Realistic vibrato, in a medium-tempo lead, starts out very soft and gradually fades in" — HA1 a row or two into a held note, then HA2, speeds 1–2 so the vibrato "doesn't become the main focus"; only "very up-tempo hard-hitting tunes" tolerate wild vibrato; and on a long sustain either bring it back to zero or fade the note, because "nothing sounds worse than a heavily oscillating note which just refuses to die" (lead-articulation). Over MIDI the modulation wheel (controller 01) usually sets vibrato depth only, the synth decides the rate (midi-in-trackers; source: s-tw098-impulse-tracker-midi).
Numbers from the manuals (sources: s-protracker-23d-help, s-ft2-manual, s-st3-manual, s-openmpt-manual-effect-reference, s-openmpt-manual-samples): ProTracker 4xy (400 continues; ProTracker 1.1A doubled the depth scale "to be compatible with NT2.0"), waveform E4x 0 sine, 1 ramp down, 2 square, 3 random, +4 = do not retrigger the waveform on a new note; FT2 the same plus a volume-column Vx and Sx (speed only); ST3 Hxy with Uxy four times finer "if a note is played very high", waveform S3x; IT/OpenMPT the same letters. Every LFO waveform is 64 points long and the speed is points per tick, so speed 2 completes a cycle in 32 ticks; "random" is unsupported by ProTracker and FastTracker. Sample-level auto-vibrato exists in XM (per instrument) and IT/MPTM (per sample): waveform, depth in 1/64 semitones, a sweep-in (IT: depth × 256 ÷ sweep ticks; XM: sweep ticks) and a rate of 256 ÷ rate ticks per cycle — it adds to pattern vibrato and cannot be changed from the pattern. FT2's ramp-down tremolo is a known bug ("even influenced by vibrato") (source: s-openmpt-manual-compatible-playback).