User Rating 0.0 ★★★★★
Total Usage 0 times
Drop .mid / .midi file here or click to browse Max 50 MB
Is this tool helpful?

Your feedback helps us improve.

★ ★ ★ ★ ★

About

Standard MIDI Files (SMF) store musical performance data in a compact binary format defined by the MIDI Manufacturers Association. The format encodes delta times as variable-length quantities (VLQ), packs channel messages into status bytes with running status optimization, and nests everything inside MThd and MTrk chunks. Misinterpreting a single byte offset corrupts the entire event stream. This tool performs real binary parsing of .mid files into human-readable JSON, preserving every meta event, control change, and timing value. The reverse operation reconstructs valid MIDI binaries from JSON with correct chunk lengths and VLQ encoding. Note: this parser handles SMF Format 0, 1, and 2 files, but Format 2 (independent sequences) is rare and some DAWs may not load it correctly.

midi json converter music midi-parser midi-encoder file-converter binary-parser

Formulas

MIDI files encode timing deltas using Variable-Length Quantity (VLQ) encoding. Each byte uses 7 data bits and 1 continuation bit.

VLQ(value) → bytes where bi[7] = 1 if more bytes follow, bi[6..0] = data bits

Tempo conversion from microseconds per quarter note to BPM:

BPM = 60,000,000Ξs/QN

Chunk structure follows the pattern: 4-byte type identifier (MThd or MTrk) followed by a 4-byte big-endian unsigned integer for chunk data length, then the raw chunk data.

Chunk = type4B + length4B + datalengthB

Where type = chunk identifier, length = size of data in bytes (big-endian 32-bit unsigned), data = chunk payload. Pitch bend value is a 14-bit number assembled from two 7-bit data bytes:

pitchBend = LSB + (MSB × 128)

Reference Data

MIDI Event TypeStatus ByteData BytesDescription
Note Off0x8n2Release note on channel n
Note On0x9n2Press note (velocity 0 = note off)
Poly Aftertouch0xAn2Per-note pressure change
Control Change0xBn2Controller number + value (0 - 127)
Program Change0xCn1Instrument/patch selection
Channel Aftertouch0xDn1Channel-wide pressure
Pitch Bend0xEn214-bit value, center = 8192
SysEx Start0xF0VariableSystem Exclusive message begin
SysEx End0xF7VariableSystem Exclusive continuation/end
Meta: Sequence Number0xFF 0x002Track sequence identifier
Meta: Text Event0xFF 0x01VariableArbitrary text annotation
Meta: Copyright0xFF 0x02VariableCopyright notice string
Meta: Track Name0xFF 0x03VariableName of the track
Meta: Instrument0xFF 0x04VariableInstrument name for track
Meta: Lyric0xFF 0x05VariableLyric text synchronized to events
Meta: Marker0xFF 0x06VariableRehearsal marker or section label
Meta: Cue Point0xFF 0x07VariableCue for external synchronization
Meta: Channel Prefix0xFF 0x201Associate channel with following meta events
Meta: End of Track0xFF 0x2F0Mandatory track terminator
Meta: Set Tempo0xFF 0x513Microseconds per quarter note
Meta: SMPTE Offset0xFF 0x545Starting SMPTE time code
Meta: Time Signature0xFF 0x584Numerator, denominator power, clocks, 32nds
Meta: Key Signature0xFF 0x592Sharps/flats count + major/minor flag
Meta: Sequencer Specific0xFF 0x7FVariableProprietary sequencer data

Frequently Asked Questions

Format 0 stores all channels in a single track, making it the simplest but hardest to edit per-instrument. Format 1 uses multiple simultaneous tracks (one per channel typically), which is the most common format exported by DAWs. Format 2 contains independent single-track patterns (rarely used). This converter handles all three formats. The format type is stored in the first two bytes of the MThd chunk data.
VLQ encodes an unsigned integer using 7 bits per byte. The most significant bit (bit 7) is a continuation flag: 1 means more bytes follow, 0 means this is the final byte. A delta time of 127 fits in one byte (0x7F). A value of 128 requires two bytes (0x81 0x00). The maximum VLQ value in MIDI is 0x0FFFFFFF (4 bytes). This encoding is critical to preserve - incorrect VLQ reconstruction produces corrupted MIDI files that DAWs will reject.
SysEx messages (status 0xF0) are preserved as byte arrays in the JSON output. The converter stores the raw payload bytes (excluding the 0xF0 start and 0xF7 end markers) as an array of integers. When converting back to MIDI, these bytes are re-wrapped with the correct markers and VLQ length prefix. Multi-packet SysEx (using 0xF7 continuation) is also handled.
The converter preserves all event data faithfully, but running status optimization may differ. The original file might use running status (omitting repeated status bytes) while the reconstructed version writes explicit status bytes for every event, or vice versa. Both are valid per the SMF specification. If timing sounds different, check that the ticksPerBeat value in the header was preserved correctly. Some DAWs also interpret pitch bend center differently (8192 vs 0).
Yes. The header's division field is parsed as a signed 16-bit value. If bit 15 is set (1), the upper byte represents negative SMPTE frames per second (−24, −25, −29, or −30) and the lower byte is ticks per frame. This is stored in JSON as a timeDivision object with framesPerSecond and ticksPerFrame properties instead of a simple ticksPerBeat integer.
The converter processes files up to 50 MB in the browser. Files larger than 100 KB are parsed inside a Web Worker to prevent UI freezing. Typical MIDI files range from 5 to 500 KB. Files exceeding 50 MB likely contain embedded audio (not standard MIDI) and should be checked for corruption.