Skip to content

synthio: stop MidiTrack treating every 0xF. byte as End of Track - #11658

Open
tyeth wants to merge 1 commit into
mainfrom
synthio-miditrack-meta-events
Open

tyeth wants to merge 1 commit into
mainfrom
synthio-miditrack-meta-events

Conversation

@tyeth

@tyeth tyeth commented Oct 23, 2026 •

Copy link
Copy Markdown
Member

First of five stacked PRs fixing synthio.MidiTrack's MIDI parsing. Each later one targets the previous branch; review in order.

MidiTrack read any byte with a high nibble of 15 as an "End of Track" event and stopped there. A MIDI track conventionally opens with a Set Tempo meta event, which begins 0xFF, so for most real files the track ended before a single note played and the sample was silent.

Meta and System Exclusive events both carry an explicit length, so skip exactly that many bytes instead of guessing, and end the track only on an actual End of Track meta event. Also report error_location as the offset where the error was found rather than the end of the track it was abandoned at.

Effect

Decoding the first 30 seconds of a stock Bach Toccata (public-domain MIDI from mfiles.co.uk, format 1, 256 ticks/beat):

track before after
2 2 note events 479
3 0 423

Verification

The before and after decoders were mirrored in Python and cross-checked against the adafruit_midi_parser library as an independent oracle on hand-built files covering each case; the new decoder reproduces its note timeline exactly where the old one returned nothing.

Builds clean for circuitplayground_bluefruit (arm) and adafruit_funhouse (xtensa). pre-commit formatting passes and no new MP_ERROR_TEXT strings are added, so the translations check is unaffected.

Playback through this decoder is confirmed on hardware (Adafruit FunHouse), though via audiopwmio from #11663 rather than a stock board.

Size

About +272 bytes of flash on nrf52840.

🤖 Generated with Claude Code

The decoder read any byte with a high nibble of 15 as an "End of Track"
event and stopped there. A MIDI track conventionally opens with a Set
Tempo meta event, which begins 0xFF, so for most real files the track
ended before a single note was played and the sample was silent.

Meta and System Exclusive events both carry an explicit length, so skip
exactly that many bytes instead of guessing, and end the track only on an
actual End of Track meta event. Decoding the first 30 seconds of a stock
Bach Toccata now yields 479 and 423 note events on its two note tracks,
where it previously yielded 2 and none.

Also report error_location as the offset where the error was found rather
than the end of the track it was abandoned at.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
@tyeth
tyeth added this pull request to stack #11668 October 23, 2026 22:57
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant