Optimization B, superseding v0.4.6's per-bus skip. Instead of iterating each active bus's whole POLYPHONY pool per sample (calling render() on idle slots, which merely early-out), fillBlock now builds compact lists of the voices that are actually sounding — once per block — and the per-sample mix loop touches only those. Correctness for mid-block starts: the sequencer can trigger a note part way through a block, so the allocators queue the chosen voice into this block's list (queueSeq/queueSmp), keeping note timing sample-accurate. A per-voice generation stamp dedups the append so a voice that finishes and is re-allocated within one block is never rendered twice (which would double its amplitude). Live/bus-audition voices are snapshotted at block start (a manual press mid-block sounds at the next block, ≤2 ms later — imperceptible, and the pre-existing ~30 ms output buffer dwarfs it). On-device (moto g84, 98% battery, real busy track, ~13 voices, 2.0 ms budget), avg render callback: baseline 2.00 ms (xruns +250..+515) → A 1.44 ms (+0) → B ~1.00 ms (+0) B removes ~51 inactive-slot render() calls per sample; ART's virtual dispatch makes each ~90 ns, so this is a real ~30% gain over A (not the ~1% first estimated from the sample track — measurement corrected it). Fast-tapping audition during playback stays ~1.0-1.3 ms, xruns +0, voices drain cleanly (no stuck notes, no double-render). Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Sizzletracker (Android)
A retro, grid-based music tracker for Android — monospace UI, pixel icons, demoscene-style pattern editing — playable equally with touch, keyboard, gamepad, and MIDI (USB or Bluetooth).
Features at a glance
- Tracker tab — 4-track pattern grid (note / velocity-hex / MIDI-channel per track), beat & bar coloring, tap-to-focus + drag-to-edit with haptics and scale-aware note entry; plus an 8-lane arrangement piano-roll (up to 256 bars) with A/B loop regions.
- Mix tab — 4 channels, each with an instrument + 4 FX slots, MIDI channel, volume, mute/solo.
- Toolbox tab — 16 slots for instruments (NES synth, sampler, SF2/XI) and effects (arp, transposer, LFO, tape delay, reverb, filters, 10-band EQ, bitcrusher). Every device has an auto-generated editor and text presets.
- Setup tab —
.sngproject save/load, color themes (with import/export), gamepad bindings, and searchable/collapsible MIDI bindings. - Master recording — render the master bus (with FX tail) to a WAV file.
- Background playback with a media notification (Play/Pause/Stop).
- Two-thread design — Compose UI on the main thread, a sample-accurate sound engine on its own high-priority thread.
There is also a standalone tools/samplepack-builder.html — an offline page for
assembling Sampler preset bundles (drop audio onto 16 note-labelled pads, then
download an importable .zip).
Build & run
Open the project in Android Studio (2024.1+) and Run on an API 26+ device or emulator.
From the CLI (the Gradle wrapper is committed, so a fresh clone needs no setup):
./gradlew assembleDebug
Where to start reading
See docs/DEVELOPER_HANDOVER.md — a from-scratch tour written for a developer new to Android: architecture, the file map, the "one action / one song / two threads" model, how to add an instrument or input, and an honest implemented-vs-TODO list.
Fastest orientation in code:
model/Project.kt → input/InputAction.kt → ui/AppViewModel.kt →
audio/AudioEngine.kt.
Project format
Songs use a human-readable .sng text format (see io/ProjectIo.kt), aligned in
spirit with the desktop
Sizzletracker; a byte-exact
compatibility shim is a listed TODO in the handover doc.
License
Sizzletracker is free software: you can redistribute it and/or modify it under
the terms of the GNU General Public License v3.0 or later
(GPL-3.0-or-later). See the LICENSE file for the full text; every
source file carries an SPDX GPL-3.0-or-later header.
Copyright © 2026 Reactorcoremeltdown