GoatTracker v2.72 readme (summary)

author Lasse Öörni (Cadaver)
date 2.72 (undated in the file; version history in the file)
created 2026-08-30 · updated 2026-08-31

The manual of goattracker 2 by lasse-oorni — "a tracker-like C64 music editor running on Win32 or Linux platforms" with reSID emulation (Dag Lem; distortion model by Antti Lankila) or HardSID hardware, distributed under the GPL. It assumes familiarity with trackers, hex and the sid and points to the C64 Programmer's Reference Guide for the chip. Sections: warnings and v1 compatibility, command-line options, keys per editing mode, song data (orderlist, patterns, instruments, the four tables), playback details tick by tick, tips, multispeed tips, utilities, packer/relocator and playroutine options, file formats, version history.

Key claims#

  • Model: 32 subtunes; single-channel patterns of up to 128 rows, 208 patterns; up to 63 instruments; a pattern row is note+octave · instrument ($01–$3F, $00 no change) · command $0–$F · databyte. Highest note G#7 (A-7…B-7 only via transpose). Special notes: ... rest, --- key off, +++ key on; the real gate bit is the key mask AND the wavetable's gate bit, so +++ cannot re-open a gate the wavetable cleared.
  • Orderlist per channel: pattern numbers, TRANSPOSE (+0..14, -1..15, reset only at song start), REPEAT R1–R16 (R0 = 16), then a RST endmark with restart position; max 254 entries. TRANSPOSE must precede REPEAT and the entry before RST must be a pattern, otherwise the editor halts playback (orderlist).
  • Pattern commands: 1XY/2XY portamento up/down and 3XY tone portamento (300 = tie note) all take a speedtable index; 4XY vibrato (speedtable); 5XY/6XY set AD/SR registers; 7XY waveform register; 8XY/9XY/AXY set wave/pulse/filter table pointer ($00 stops); BXY filter control (X resonance, Y channel bitmask; B00 = filter off); CXY cutoff; DXY master volume (or timing mark if X ≠ 0); EXY funktempo (speedtable); FXY tempo ($03–$7F all channels, $83–$FF this channel, $00/$01 recall funktempo). There is no "00 = repeat last value". One-shot commands 5F leave a running 14 or instrument vibrato intact; command 0 stops it.
  • Instrument = 9 parameters: AD, SR, wave/pulse/filter table start positions, vibrato speedtable index, vibrato delay ($00 = off), HR/Gate timer (ticks before the next note at which note fetch, gate-off and hard restart happen; at most tempo−1; bit $80 disables hard restart, $40 disables gate-off) and 1stFrame Wave ("usually $09 (gate + testbit)"; $00 leave waveform and gate unchanged, $FE leave waveform + gate off, $FF leave + gate on). All-zero ADSR gives "just a very short click". Examples: 09/00 full volume then automatic fade; 00/8A instant to sustain 8, release A; CC/AF slow swell. Instrument legato: timer bit $40 + 1stFrame $00 = no restart, no gate-off, gate untouched, but tables and ADSR re-initialised.
  • Hard restart in the editor: the ADSR value written during the gate-off ticks is global (-A option or SHIFT+F7), default 0F00; "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." Attack F selects an alternative playroutine that writes the waveform before ADSR — more reliable triggering for releases 0 and 1, but it can change decay/release character. Since v2.68 the SID write order was tweaked for badline stability, so notes with attack 0 & release 1 may ADSR-bug — again try attack F (hard-restart).
  • Tables (shared; instruments and commands point into them; never jump onto a FF jump row):
    • Wavetable left byte: 00 leave 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 0E with the right byte as parameter (not 0, 8, E), FF jump (right byte = row, 00 stop). Right byte: 00–5F relative semitones up, 60–7F down, 80 keep frequency, 81–DF absolute C#0B-7. Delay or "no change" in an instrument's first wavetable row is unsupported (missing notes). Waveform bits: 01 gate, 02 sync, 04 ring, 08 test ("silences sound and resets the oscillator"), 10 triangle, 20 saw, 40 pulse, 80 noise; everything but noise can be combined, differently on 6581 and 8580. Sync/ring source: channel 3 modulates 1, 1 modulates 2, 2 modulates 3.
    • Pulsetable: 01–7F modulation step (left = time, right = signed speed), 8X xx set width $Xxx, FF jump. Filtertable: 00 xx set cutoff, 01–7F modulation step, 80–F0 set passband ($90 lowpass, $A0 bandpass, $C0 highpass) with right byte = resonance/channel mask, FF jump; a set-parameters row followed by a set-cutoff row executes in one frame. Speedtable (no jumps): vibrato XX YY = time until direction change / pitch added per tick; portamento = 16-bit pitch step; funktempo = two tempos; high bit in XX = realtime note-independent calculation with YY as divisor (v2.62). SHIFT+RETURN converts old-style parameters into speedtable entries; SHIFT+H precalculates "hifi" note-independent speeds; SHIFT+L converts limit-based pulse/filter steps to time-based ones.
  • Playback tick schedule (tempo 6, gate-off timer 2): tick 0 initialises new notes (inaudible), advances the orderlist, runs pulse (unless the orderlist advanced), wave and one-shot commands; tick 1 the note becomes audible; tick 4 fetches the next note and performs gate-off and hard restart "2 ticks before first frame"; pulse is skipped on that tick. Filtertable runs every tick; the wavetable is never skipped, "so arpeggios/drumsounds should always play OK". Pulse skipping (-O0) and realtime-command skipping on tick 0 (-R0) can be disabled at a rastertime cost.
  • Multispeed: multiply tempos and gate-off timers (2 → 4 at 2×), multiply vibrato speed and divide depth, divide portamento and pulse/filter speeds; attack 0 can make the first wavetable row nearly silent — raise the attack or prepend E9 00 rows.
  • Warnings: save .SNG (F11) — packed PRG/BIN/SID cannot be reloaded; "the reSID emulation is in some cases quite far from the output of a real SID. Especially if filters are in use" — test on a C64 or HardSID, "every SID tends to sound different"; ADSR bugs after packing with unbuffered writes: make note-init take more cycles (nonzero pulse start position, 1stFrame $09$0B), use buffered writes, or attack F.
  • Packer (F9): PRG/BIN/SID with start and zeropage addresses; removes unused patterns, instruments, table entries, duplicate table parts and unneeded player code; a pattern packs to ≤ 256 bytes (0–4 bytes per row), so >64-row patterns may fail. Calls: LDA #subtune / JSR start to init, JSR start+3 per frame; options: buffered SID writes, sound-effect engine (start+6, priority by address), volume routine, author info + timing marks (DXY with $10–$FF copied to start+$3F), zeropage ghost registers (copy loop LDX #$18 … DEX BPL; with the attack-F player copy wave, frequency, pulse, ADSR last), disable optimisations "if you encounter … ADSR bugs caused by unpredictable timing variation" (sid-player-routine).
  • Utilities: INS2SND2 (instrument → sound-effect source/binary), SNGSPLI2 (split patterns), MOD2SNG (4-channel MOD → SNG minus one channel), BETACONV.
  • Keys: F1–F3 play (from start / position / one pattern), F4 stop, F5 pattern, F6 song, F7 instrument/table, F8 songname, F9 pack, F10 load, F11 save, F12 help, SHIFT+F8 toggles 6581/8580, SHIFT+F5/F6 speed multiplier; Protracker (two-row) or DMC (one-row) note entry; SHIFT+Q/A/W/S transpose, SHIFT+O/P shrink/expand, SHIFT+J/K join/split patterns; table editor SHIFT+N negate, SHIFT+O optimise, SHIFT+R absolute↔relative note.

Practical takeaways#

The readme is the best single description of the tick-level mechanics behind hard restart and of a table system where instruments are just pointers. Its wavetable examples are ready-made recipes (flute, koto, snare, hi-hat-then-pulse, looping arpeggios, waveform alternation with vibrato underneath) and its tips answer the everyday questions: how to stop an unused pulse program, how to get tempo 2, how to keep vibrato depth constant across octaves.

Notable quotes#

"Wavetable is never skipped, so arpeggios/drumsounds should always play OK."

"Using filters has always been complicated because every SID tends to sound different."

Pages touched#

goattracker · lasse-oorni · hard-restart · adsr-envelope · sid · wavetable-programming · pulse-width-modulation · filter-programming · instrument-tables · chord-arpeggio · vibrato · pitch-slide-and-portamento · multispeed · sid-player-routine · shuffle-funktempo · orderlist · instrument-design · ring-modulation-and-sync · vice · sid-wizard · sidechain-pump · song-init-and-looping · semitone-math · chord-inversions · melody-writing · diatonic-chords

source file wiki/summaries/s-goattracker-readme.md · graph