MP3 to MIDI File Size: What Each Event Costs in Bytes

A converted file is small for two reasons, and neither is compression. The number in front of every event uses a variable-length encoding, and a status byte that repeats is dropped. Both rules are in the public file-format specification.

Short answer

  • Timing is variable width. A delta-time is a variable-length quantity: seven bits per byte, bit 7 set on every byte except the last. Values 0 to 127 take one byte.
  • Four bytes is the ceiling. The largest value allowed is 0FFFFFFF, 268,435,455.
  • A repeated status byte is dropped. Running status omits it when the previous event carries the same status.
  • A chunk length counts data only. The header chunk declares six and occupies fourteen bytes.

Delta-time is written as a variable-length quantity

Every event in a track is preceded by a delta-time, the time before it in the unit the header chose. The number is not fixed width. It is a variable-length quantity: seven bits per byte, most significant first, bit 7 set on every byte except the last. Zero to 127 fits in one byte, and the encoding gains a byte at each power of two: 16,383 in two bytes, 2,097,151 in three, 268,435,455 in four, the last written FF FF FF 7F. Zero still costs a byte, because omitting zero delta-times would need two bytes for any other value, and most are not zero.

How far one delta-time can reach

The ceiling is fixed, but what it means depends on the header: the unit is a fraction of a beat in metrical mode, a fraction of a second in time-code mode. The specification's own illustration puts the maximum at four days of ninety-sixths of a beat at 500 beats per minute.

Running status leaves out the repeated status byte

Running status is the second encoding. A channel message may omit its status byte when the preceding event is a channel message with the same status, so a run on one channel and one message type spells the status out once. A delta-time does not break the run: running status occurs across delta-times. A system message does break it, since a system-exclusive or meta event cancels the status in effect.

What the omission is worth

Running status saves one byte per repeated message. Seven channel voice messages are defined, and five carry two data bytes: three bytes with the status byte, two without. The other two, program change and channel pressure, carry one data byte: two bytes with the status byte, one without. A run of notes on one channel is written at two thirds of the size it would otherwise take.

What a chunk length does not count

The file is built from chunks. Each opens with a four-character type and a 32-bit length that counts only the data after it; the eight bytes of type and length are not included. The specification's example is a declared length of six occupying fourteen bytes on disk, which is exactly the header chunk: four characters for MThd, four bytes of length, six bytes of header data. A track chunk adds eight more ahead of its first event, and a track must hold at least one, so the smallest well-formed file is fourteen plus eight plus four, twenty-six bytes.

Where the bytes go, and what that does not tell you

An event costs one or two bytes of delta-time plus two or three of message, so a note somewhere between three and five bytes and its release the same again. That cost follows the number of events, not the length of the audio. A file that looks small beside its recording was not compressed, and a long silence is cheap: one delta-time covers the whole gap. Size alone is not evidence that a transcription is right.

Related