A MIDI file is a score. It says C4 starts here, lasts this long, and was struck this hard, and it says nothing whatsoever about what a C4 should sound like. That is why the same file sounds different in every program that opens it, and why converting one to audio is a synthesis job rather than a format change.
What the parser reads
The file is decoded in this tab. Nothing is uploaded.
Notes. Note-on and note-off events are paired per channel and pitch, including the note-on-at-zero-velocity form that sequencers write to keep running status alive. A note re-struck before it is released is handled as two notes, not one.
Tempo. Tempo events are gathered from every track, not just the first, and applied as a map of constant-rate segments. A file that starts at 120 and drops to 60 halfway through converts correctly on both sides of the change.
Programs. Program change events set which General MIDI instrument each channel is playing. The instrument selector reads them when it is set to “From the file”.
SMPTE timing. A file whose division field is negative is timed in real seconds rather than in musical ticks. Tempo events do not apply to it, and the parser does not pretend they do.
Instruments
General MIDI defines 128 programs in sixteen families of eight — pianos, chromatic percussion, organs, guitars, basses, strings, ensembles, brass, reeds, pipes, synth leads, synth pads, and so on. Family is about as much instrument detail as an oscillator can honour, so each family maps to a waveform and an envelope.
Pianos and plucked instruments decay to nothing whether or not the note is still held, because that is what a struck string does. Organs, strings, and pads hold a sustain level for as long as the note lasts. Brass and reeds sit between the two.
The waveforms are band-limited. A raw sawtooth at 2 kHz on a 44.1 kHz render produces harmonics above Nyquist that fold back down as tones unrelated to the music, and no amount of filtering afterwards removes them, so the sawtooth and square use polynomial band-limited steps and the triangle and the harmonic voices are built additively with everything above Nyquist left out.
Setting the instrument to anything other than “From the file” plays every melodic part on the same voice, which is useful for hearing the arrangement rather than the orchestration.
Drums
Channel 10 is percussion by convention, and its note numbers are drum sounds rather than pitches. The kit follows the General MIDI map closely enough that a drum part reads as a drum part:
- Kicks and toms get a sine whose frequency falls as it decays. That falling pitch is most of what makes a kick read as a kick rather than as a short low note.
- Snares and rims mix noise with a body tone around 190 Hz.
- Hats are noise with a short decay — 45 ms closed, 280 ms open.
- Cymbals are noise with a long one, up to a second for a crash.
The noise is a hash of its own position rather than a running random generator, so the same file renders identically every time and a preview matches the download exactly.
Level and polyphony
Forty voices summed together are far louder than one, and a streaming render cannot measure the file before it writes it. The tool counts the largest number of notes sounding at once while it parses, then divides the level by the square root of that number. A busy orchestral file and a solo piano piece arrive at a comparable place, and the level control moves both from there.
The output is hard-clamped at full scale as a last resort, but with the default level it should not reach it.
Practical uses
Auditioning an export. A MIDI file coming out of a notation program or a DAW is easier to check as audio than in another editor.
Making a reference track. Render the MIDI, then use it as a timing guide against a recorded performance.
Getting a file into something that will not take MIDI. Video editors, messaging apps, and most web players take WAV and do not take .mid.
For the other direction — a recorded melody turned into a MIDI file — use the audio to MIDI converter.