Buttons
- ▲▼◀►
- D-pad - move the cursor on every screen. Auto-repeats while held.
- A
- Edit modifier. In PATTERN: A + Up/Down cycle the cell value, A + Left/Right nudge the cell's per-cell octave (-2..+2). A+B (either order) DELETES the cursor cell - works on note OR inst sub-row. A+R pastes the row clipboard. In SONG: A + Up/Down cycle the song cell's pattern number. In LAB: held alone or with L/R to nudge a parameter value. In PERFORM: capo glitch (see Glitch section).
- B
- In PATTERN: on the inst sub-row opens the INSTRUMENT LAB for that inst; on the note sub-row B alone is a no-op (delete is the dedicated A+B combo now, so a stray B can't wipe a note you were auditioning). In SONG: B alone clears the cell. In PERFORM: live-arp modifier (B + dir picks UP/DOWN/TRI/RANDOM).
- X
- In EDIT: tap toggles FOCUS between the top tracker and the bottom song arranger. In PERFORM: tap still toggles focus; hold = stutter (32nd-note retrigger of the current step).
- Y
- In PATTERN: Y + Left/Right step the edit pattern. Y+B (either order) pastes the last entered value -- last note on the note sub-row, last instrument on the inst sub-row. In PERFORM: Harmony modifier - momentary transpose that sums with the A capo (see Glitch section).
- L
- Toggle PERFORM mode (D-pad and face buttons become live glitch triggers).
- R
- Copy cursor's voice row to the row clipboard. A+R = paste.
- SELECT
- In SONG focus: open SETTINGS overlay. In PATTERN focus: open COPY FROM modal. A+SELECT: open RANDOMIZE modal. Inside the lab: open COPY FROM patch modal. In PERFORM: flashes a "EXIT PERFORM (L) FIRST" hint -- settings are EDIT-mode only.
- START
- Play / pause the transport. Hold ~0.4s to restart from song position 0.
Screens & navigation
- TOP
- Text-mode pattern editor (tracker) + live oscilloscope at the right edge. Overlays here: INSTRUMENT LAB, modals.
- BOTTOM
- Song arranger by default. Overlays: SETTINGS, PHRASE editor.
- FOCUS
- One screen owns the cursor at a time. The focused mode label glows bright; the unfocused side dims to grey. Toggle with X.
Help-row indicators
- MIDI
- Yellow tag on the top help row means the mDS slot-2 MIDI cart was detected; the song clock is locked to it.
- scope hue
- Right-edge waveform colors itself by the dominant voice: cyan samples, magenta pulse, white noise.
Pattern editor (top)
- ◀►
- Move between the 16 step columns.
- ▲▼
- Walk through all 18 cursor slots (9 voices × note / inst rows).
- A+▲▼
- Cycle the cell value. Note: REST → 1..12 → X (loop) → S (sustain) → REST. Inst: 0..31.
- A+◀►
- Step the edit pattern (0..95). Cross-pattern paste lands on the cursor's CURRENT pattern.
- A+B
- DELETE the cursor cell (any sub-row). Bidirectional edge - A first or B first both fire.
- Y+B
- Paste the last entered value - note on the note sub-row, instrument on the inst sub-row. Bidirectional edge.
- B
- Inst row: open the INSTRUMENT LAB for that inst. Note row: no-op.
- X (cell)
- LOOP marker - silences the row from that step on and wraps the pattern to step 0.
- S (cell)
- SUSTAIN - hold whatever the voice was already playing; envelope continues, no retrigger.
Voice rows
- P1 P2
- Pulse (DS PSG square channels). Per-patch duty.
- F1 F2
- FM (2-op, DS-10 style). Pre-rendered wavetable looped on a PCM channel. Used to be P3 / P4 PSG voices.
- N
- Noise (PSG noise channels). Variant picks LFSR clock multiplier.
- S1 S2 S3 S4
- PCM samples (DS PCM channels). Each patch source is PCM slot or SAM phrase.
Per-cell octave color
- +2
- Bright magenta - two octaves up.
- +1
- Dim magenta - one octave up.
- 0
- Yellow on every 4th step (beat), white off-beat.
- -1
- Dim cyan - one octave down.
- -2
- Bright cyan - two octaves down.
Song arranger (bottom)
- ◀►▲▼
- Move within the 16-cell page; top / bottom wraps to the next page (6 pages, 96 cells total).
- A+▲▼
- Change the pattern number at the cell (0..95).
- B
- Clear the cell back to empty.
- empty / LOOP
- Empty cells wrap to slot 0. LOOP marker (X) also wraps to 0.
- play mode
- PLAY_SONG vs PLAY_PATTERN. Y starts the song from slot 0 (SONG focus) or loops the edit pattern (PATTERN focus). X-toggle while playing swaps modes live.
Instrument lab
- open
- B on a PATTERN inst-row cell, or Y on the cursor cell. Takes over the top screen.
- ▲▼
- Move between visible parameter rows.
- ◀►
- Change the value at the cursor row.
- A+◀►
- Flip through patches in the same bank without leaving the lab. Wraps 0..31.
- A
- On the PHRASE row of a SAM-source sample patch: open the phrase editor.
- SELECT
- Open COPY FROM modal: header swaps to COPY src -> dst, D-pad walks the source inst (same bank, wraps 0..31), A overwrites the current patch with the picked one (phrase too, on SAMPLE bank), B or SELECT cancels.
- B
- Close the lab.
Banks
- PULSE
- 32 patches. Shared by P1 + P2. Variant = duty cycle.
- FM
- 32 patches. Shared by F1 + F2. 2-op carrier+modulator; variant = mod ratio, sweep field = feedback, penv_* fields drive the modulator ADSR.
- NOISE
- 32 patches. Used by N. Variant = LFSR rate multiplier.
- SAMPLE
- 32 patches. Shared by S1..S4. Variant = PCM slot OR SAM phrase preset.
See the Patch codes section below for every parameter and its range.
SAM speech voice
- enable
- In a sample patch, set SOURCE = SAM. PCM-only rows hide; SAM-only rows reveal.
- PHRASE
- Up to 31 chars. Press A on this row in the lab to open the editor.
- keys
- Phrase editor. D-pad: Up/Down cycle the letter at the cursor (A..Z + space + .?!,'); Left/Right move the cursor. L = insert space, R = backspace. A = ok, B = cancel.
- input
- English vs phonemic. Plain English ("HELLO") goes through SAM's reciter. Prefix with / for SAM's phonemic alphabet ("/HEH4LOW") and skip the reciter.
- pitch
- Cell-note pitch. Cells 1..12 shift playback rate (chipmunk-style), NOT SAM's pitch param. This is what lets the render cache hit across cells.
- cache
- 4 LRU slots keyed on (patch, sam_*, phrase, trim). Pattern loops with the same SAM voice never re-render after the first trigger - no timing drift.
- pre-warm
- Cache pre-warm. Editing any SAM knob (SOURCE / SPEED / PITCH / THROAT / MOUTH / TRIM) or committing a new PHRASE runs the render synchronously while you're still in the lab, so the next trigger after closing is an instant cache hit rather than a 30 ms cold-render block.
- catch-up
- Step catch-up. If a render does block the main loop past a step boundary, the missed step's notes still fire in order via a 16-slot catch-up queue -- so SAM patches never silently drop notes even at fast BPMs.
Settings overlay
- open
- SELECT in SONG focus.
- X (in overlay)
- Swap focused pane between SLOTS (left) and ACTIONS (right).
- ▲▼
- Walk the focused pane's cursor.
- A
- Execute the selected action on the selected slot.
- B / SELECT
- Close the overlay.
Actions
- NEW
- Wipe the live project back to defaults. Saved slots are untouched. Overlay auto-closes back to the song screen so the blank arranger is the confirmation. Resets Y harmony overrides back to factory; keeps the global FM TUNE setting.
- SAVE
- Write the project to the focused slot's file on the SD card. Always prompts "SAVE- SLOT NN? A=yes B=no" so a wrong-cursor overwrite needs a deliberate second press. On success the overlay auto-closes back to the song screen; on failure ("SAVE FAILED") it stays open so the error is readable + retryable.
- LOAD
- Read the focused slot into the live project. Always prompts "LOAD SLOT NN? A=yes B=no" so an accidental A doesn't blow away unsaved work. Empty slots bail with "slot empty" before the prompt. On success the tracker flips to SONG focus and the overlay auto-closes; on failure ("LOAD FAILED") it stays open.
- BPM
- Hold A + Left/Right to set tempo (20..300).
- MIDI
- Tri-state MIDI mode toggle: OFF / SYNCIN / SYNCOUT. A + Left/Right cycles. SYNCIN slaves the DS clock to the mDS slot-2 MIDI cart; SYNCOUT drives a downstream slave from the DS.
- OFFSET
- Sync offset in ms (0..127). A + Left/Right nudges. Compensates the DS's near-zero-latency audio against a DAW softsynth's output buffer (typically 3-10 ms).
- RATE
- MIDI sync rate: 0.5x / 1x / 2x. A + Left/Right cycles.
- FMTUNE
- Global FM fine-tune in cents (-100..+100). A + Left/Right nudges. Calibration knob for the perceptual "FM sounds slightly off vs PSG" offset - not stored per project, lives like BPM. Applies to both F1 and F2.
- Y harmony
- Per-project Y / Y+U / Y+D / Y+L / Y+R overrides - five rows, each a signed semitone value (-36..+36). A + Left/Right nudges by 1 semitone. Defaults: +12 / +24 / -12 / -5 / +7 (the values main.c used to hardcode). Tailor harmony per groove; persists in the save file.
- CLOSE
- Same as B.
Randomize modal
Open with A+SELECT in PATTERN focus + EDIT. Notes only; insts never touched.
- ▲▼
- Cycle MODE: sparse / dense / euclid / mutate.
- ◀►
- Adjust DENSITY by 5% (clamped 0..100).
- SELECT (in modal)
- Toggle SCOPE between row (cursor voice) and pat (all 9 voices).
- A
- Roll + apply. Modal stays open so you can mash for new variations.
- B
- Close (last roll stays).
Modes
- sparse
- Clear row, then drop a uniform 1..12 note at each step with the density % chance.
- dense
- Every step gets a fresh uniform 1..12 note (density ignored).
- euclid
- N = round(density × 16 / 100), clamped 1..16. N notes Bresenham-spaced. Pitch = first existing non-rest in the row (else 1).
- mutate
- Walk existing notes; with density % chance, swap each to a DIFFERENT random 1..12. RESTs / X / S untouched.
Copy & paste
Row clipboard (per-voice)
- R
- Copy the cursor's voice row (16 notes + insts) to the clipboard. Status flashes row P2 (p05) -> CLIP.
- A+R
- Paste the clipboard onto the cursor's voice row, in whatever pattern is currently being edited. Cross-pattern paste works.
Pattern-wide (COPY FROM)
- SELECT
- Opens the COPY FROM modal in PATTERN focus.
- ▲▼
- Walk the source pattern index.
- A
- Copy the source pattern's notes + insts onto the current edit pattern.
- B / SELECT
- Cancel.
Glitch performance FX
Enter with L. Hold a button while playing. All glitches are momentary - released drops the FX immediately.
Plain D-pad (no modifier):
- ◀
- Loop 8 - beat-quantized 8-step block repeat (half-bar pin).
- ►
- Loop 4 - 4-step block repeat (one-beat pin).
- ▲
- Loop 2 - 2-step block repeat (half-beat pin).
- ▼
- Half-time - each natural step plays for two song ticks.
- X
- Hold = stutter (32nd-note retrigger of the current step). Tap = focus toggle (still works in PERFORM so the visible playhead can follow).
- START
- Tap = play/pause. Hold = restart from song position 0. (Transport, not a glitch.)
Hold A + D-pad - pitch glitch:
- A+▲
- Momentary capo +12 semitones (octave up).
- A+▼
- Momentary capo -12 semitones (octave down).
- A+◀
- Tape slur DOWN - pitch slurs to a halt while held.
- A+►
- Tape slur UP - pitch bends up while held.
Hold B + D-pad - live arpeggios (fire on any patch):
- B+▲
- Arp up - octave staircase climbing.
- B+▼
- Arp down - octave staircase descending.
- B+◀
- Arp bounce (triangle).
- B+►
- Arp random.
Y Harmony - layered pitch shifts. Y's contribution sums with the A capo, so A+DOWN + Y+RIGHT = -12 + 7 = -5 (fourth down). The total caps at ±36 semitones.
Each Y combo's semitone value is per-project configurable from SETTINGS (rows Y, Y+U, Y+D, Y+L, Y+R). Factory defaults shown below.
- Y
- Held alone: default +12 semitones (octave up).
- Y+▲
- Default +24 semitones (two octaves up).
- Y+▼
- Default -12 semitones (octave down).
- Y+◀
- Default -5 semitones (fifth down).
- Y+►
- Default +7 semitones (fifth up).
FX-muted voices (see bottom-screen FX band) skip Y harmony, capo, tape slur, live arp, and stutter retrigger - they keep playing their pattern straight while the rest of the mix shifts around them.
External MIDI sync
- cart
- mDS slot-2 MIDI cart -- custom RP2040 in the GBA Slot-2. Writes magic STDS at 0x0A000000; DS confirms via the DETECT CART action in SETTINGS.
- detection
- Opt-in. Boot does NOT auto-probe -- raw slot-2 reads at boot wedge R4i and some emulator combos before first frame. Once you press DETECT CART in settings, the probe uses gbacartOpen() + 18-cycle SRAM wait timing to safely poll Slot-2; on a match the sync is active for the rest of the session.
- sync_state
- 256-byte struct the Pico mirrors: tick_counter (24-PPQ), bpm_q8, flags (clock / transport), song_pos_16ths, micros.
- poll rate
- Every synth_tick (512 Hz). target_step = tick_counter / 6.
- transport
- DAW START (0xFA) snaps the song clock to the cart's target step and begins playing. STOP (0xFC) pauses.
- local override
- Y still works while the cart says stop, so you can rehearse offline.
Patch parameter codes
| Code | Range | Banks | Meaning |
|---|---|---|---|
| VOLUME | 0-127 | all | Patch volume base. The ADSR is normalised separately; this is the final scalar. |
| VARIANT | 0-? | all | PULSE: duty cycle 0..7. NOISE: LFSR rate (chunky..hiss). SAMPLE: PCM slot index 0..31 (or phrase preset when SOURCE=SAM). |
| ATTACK | 0-127 | all | 0 = instant (snap to peak). Higher = longer attack time, up to ~4 s. |
| DECAY | 0-127 | all | Fall rate from peak down to SUSTAIN. |
| SUSTAIN | 0-127 | all | Held-note level (% of peak; decoupled from VOLUME). |
| RELEASE | 0-127 | all | Tail rate after note-off. 0 = cut immediately. |
| OCTAVE | -1..+3 | pulse, sample | Coarse pitch shift (semitone x12). |
| PAN | 0-2 | all | L / C / R. |
| DETUNE | -64..+63 | pulse, sample | Fine pitch offset in cents. |
| PORTA RATE | 0-127 | pulse | Pitch glide rate between consecutive notes. PCM samples freeze their playback rate at note-on, so PCM ignores this. |
| VIB RATE | 0-127 | pulse | Vibrato speed. |
| VIB DEPTH | 0-127 | pulse | Vibrato amount (cents). |
| TRM RATE | 0-127 | all | Tremolo speed. |
| TRM DEPTH | 0-127 | all | Tremolo amount (volume dip). |
| TRM SHAPE | SIN / SQR | all | Sine wobble or square gate (chop). |
| PENV AMT | -128..+127 | pulse | Pitch envelope amount - one-shot pitch bend at note-on, decays. |
| PENV DECAY | 0-127 | pulse | How fast the pitch envelope decays toward 0. |
| SWEEP | -64..+63 | pulse | Hardware-style sweep (deeper, slower-fading than PENV). 0 = off. |
| ARP RATE | 0-127 | all | Arpeggiator speed. 0 = off. |
| ARP LEN | 1-7 | all | How many notes / steps the arp collects. |
| ARP DIR | UP..TRI | all | UP / DOWN / RANDOM / AHEAD / BEHIND / TRI (triangle bounce). AHEAD + BEHIND scan upcoming / earlier real notes in the same voice row. |
| LENGTH | 0-127 | all | Note-on duration gate (each unit ~8 ms). 0 = no gate, note rings until the next step. |
| PCM BASE | 0-127 | sample | MIDI note the sample is "tuned to" (used only when PCM PITCHED is on). |
| PCM PITCH | 0 / 1 | sample | 0 = fixed-rate drum mode; 1 = cell note shifts playback rate. |
| SOURCE | PCM / SAM | sample | PCM slot or SAM-rendered speech phrase. |
| PHRASE | text | sample (SAM) | Up to 31 chars. English or SAM-phonemic (prefix with /). |
| SAM SPEED | 1-255 | sample (SAM) | SAM's SetSpeed param. Default 72. Min 1 -- speed=0 underflows SAM's u8 speedcounter into an infinite loop. |
| SAM PITCH | 16-255 | sample (SAM) | SAM's pitch period. Default 64. Lower = higher voice. Min 16 -- below that, a stressed phoneme can walk pitches past array bounds. |
| SAM THROAT | 0-255 | sample (SAM) | F2 formant. Default 128. |
| SAM MOUTH | 0-255 | sample (SAM) | F1 formant. Default 128. |
| SAM TRIM | 0-100 | sample (SAM) | Chop N ms off the front of the rendered phrase. Dials out leading silence / buildup to shave perceived onset delay. Re-applies the 2 ms parabolic fade at the trim point so trimmed playback still ramps from 0 (no click). |
Screen labels & markers
- mode tag
- EDIT / PERF / view. Top-left mode tag. EDIT = focused for editing; PERF = glitch mode active (red); view = focus on the other screen.
- p<NN>
- Currently displayed pattern (0..95).
- p>p
- p<NN>><MM> - edit pattern > playing pattern. Shown when the edit cursor is on a different pattern from the one sounding (SONG mode).
- s<NN>
- Current step within the pattern (1..16).
- X cell
- LOOP marker - silences the row from this step and wraps to step 0.
- S cell
- SUSTAIN marker - hold the previous note; envelope continues, no retrigger.
- transport
- PLAY / STOP. Green when playing.
- MIDI tag
- Yellow MIDI on the help row - external MIDI clock cart is locked; song clock is driven by it instead of internal BPM.
- voices
- P1 P2 / F1 F2 / N / S1..S4. The nine voice rows. P1 P2 Pulse, F1 F2 FM, N Noise, S1..S4 PCM sample. Bright = cursor on this row; brighter = voice currently sounding.
- VU bar
- One sprite per voice on the top tracker, next to each row's cells. Height tracks the live envelope level. (The bottom-screen mirror was removed - the tracker VU is enough.)
- MUT band
- Top of the bottom screen. 9 tappable buttons: MUT P1 P2 F1 F2 N S1 S2 S3 S4. Tap a voice to silence it (pattern triggers skip; tail finishes naturally). Yellow border above + below each name greys out together with the dimmed name when toggled.
- FX band
- Below the song cells on the bottom screen. 9 tappable buttons: FX P1 P2 F1 F2 N S1 S2 S3 S4. Tap a voice to FX-mute it (voice plays its pattern normally but skips PERFORM effects: Y harmony, capo, tape slur, live arp, stutter retrigger). Borders flip cyan while PERFORM is active, dim grey in EDIT mode.
- FM pads
- Two X-Y touch pads (F1, F2) on the bottom screen. Drag X = modulator ratio, Y = modulator depth, on the matching FM voice. Held = drives the sound live; releases ramp ~100 ms back to the patch defaults.
- octave
- Per-cell octave color. magenta for +1 / +2 (UP), cyan for -1 / -2 (DOWN). Intensity matches magnitude.
- scope
- Right-edge 96 x 128 px live oscilloscope. Hue: cyan (sample), magenta (pulse), white (noise).