- MidiFile.set_loop(): one call writes LOOP_START/END, RPR LOOP
START/END (Reaper) and LoopBegin/End markers - every engine finds
its dialect; reader now parses markers and the smoke test asserts
the round-trip
- tools/make_tune.py: declarative JSON spec -> fully arranged MIDI
with style presets (dos_adventure, n64_ambient, chiptune_racing);
the agent-friendly front door, no Python required
- tunes/specs/: demo tune 04 'Tea Break at the Terminal' (Am/112,
loop bars 4-20) generated entirely from JSON
- AGENTS.md: spec schema, score grammar, verification loop, looping
conventions for game BGM
- MIT LICENSE; history audited clean of credentials
Replaces the April wreckage (fifteen 70-byte 'working' MIDIs, archived)
with a proper pipeline:
- lib/midikit.py: stdlib-only SMF format-1 writer + reader/verifier
- lib/songkit.py: composition helpers (bar-grid score DSL with a 4/4
bar linter, OPL arps, driving bass, vibrato, drum patterns)
- tunes/: three original tunes - DOS adventure theme (Dm/132),
N64 ambient (G/72), chiptune racing (Em/152) - all with LOOP_START/
LOOP_END markers for game engines
- tools/build_all.sh + tools/check_wav.py: generate, verify, render
via timidity+FluidR3, fail on clipping/dead air
- tests/smoke_test.py: round-trip verified against mido
All three tunes render clean: no clipping, no dead air, durations
match, chromaticism audited against the chord chart.