MP3 to MIDI System Messages: The Three Codes That Carry No Channel
The MIDI protocol divides at the top into channel messages and system messages, and the division is visible in the status byte: every channel message names a channel, and no system message does. Three system codes carry an instruction, and a MIDI file has no event type for any of them.
The three codes, answered
- The split is in the status byte. Channel messages name a channel in the low nibble; system messages carry no channel field, so nothing addressed to a whole system is a note or a program change.
- Eight rows, three instructions. F0 and F7 are the two ends of System Exclusive, F1, F4 and F5 are Undefined, and only F2, F3 and F6 carry an instruction.
- The only position field counts in sixteenth notes. Song Position Pointer is a 14-bit register of MIDI beats, and one beat is six MIDI clocks. Timing Clock runs 24 per quarter note, so one beat is a sixteenth note.
- A file cannot store them directly. The file format has no Song Position Pointer event; the route the specification provides is the F7 escape.
Where the protocol divides
Channel messages apply to a specific channel and the channel number is included in the status byte; system messages are not channel specific and no channel number is indicated in their status bytes. Every message a converter writes is on the first side of that line: notes, velocity, program changes and controller writes.
Eight rows, three instructions
The System Common block runs from F0 to F7. F0 starts System Exclusive and F7 ends it; F1, F4 and F5 are listed with the single word Undefined. That leaves three codes carrying an instruction: F2 Song Position Pointer, F3 Song Select and F6 Tune Request. Song Select takes one data byte, so a port can be told to play one of 128 sequences. Tune Request takes none: the specification says only that upon receiving one, all analog synthesisers should tune their oscillators.
The only position field counts in sixteenth notes
Song Position Pointer is an internal 14-bit register holding the number of MIDI beats since the start of the song, low seven bits first and high seven second. One beat is six MIDI clocks, and Timing Clock is sent 24 times per quarter note, so six clocks is a quarter of a quarter note: a sixteenth note.
The resolution is therefore fixed by the message, not by the file: a file at 96 pulses per quarter note and a file at 480 are addressed by the same grid. Fourteen bits give 16,384 positions: 4,096 quarter notes, or 1,024 bars of four-four.
A file cannot store them as themselves
The file format defines three kinds of event: MIDI events, sysex events and meta events. None of the three is a Song Position Pointer, a Song Select or a Tune Request. The route the specification provides is the second form of sysex event, which uses F7 and does not imply that an F0 is sent, and its stated purpose is to carry things which would not otherwise be legal, including system real time messages, song pointer or select, and MIDI Time Code.
That escape reuses two bytes with two readings: F7 is End of Exclusive on the wire and an escape inside a file, and FF is Reset on the wire and begins every meta event inside a file.
What this means for a converted file
A converter's output is channel messages plus meta events, so it contains no position field and no song number. If you split a transcription in two and want the second file to start at bar 17, the mechanism the protocol offers is a register counting sixteenth notes from the start of the song.