Developer guide

Convert MIDI to JSON for JavaScript

Export MIDI Viewer JSON v1, understand ticks, seconds and channel numbering, and run a JavaScript example against the downloaded notes.

Last updated September 6, 2026

Use MIDI to JSON to turn a Standard MIDI file into structured notes and timing data. The output is MIDI Viewer JSON v1, not a universal interchange format for every music library.

Export a known sample

  1. Download the original changing-tempo MIDI.
  2. Choose it in MIDI to JSON and review the preview.
  3. Download midi-data.json. The full export contains both notes; larger files show at most 200 notes in the preview but include all supported notes in the download.

Read the fields correctly

  • schemaVersion: 1.
  • header: format, ppq, initialBpm and durationSeconds.
  • tempoChanges: ticks, seconds, bpm and source (file or default).
  • timeSignatures: ticks, seconds, numerator and denominator for file events.
  • tracks: index, optional name, channels, optional summarized program, instrument and notes.
  • Each note: channel, pitch, velocity, startTicks, endTicks, startSeconds and durationSeconds.

JSON channels are 0–15; the Analyzer displays 1–16. Pitch is the MIDI note number and velocity is a MIDI integer, not a 0–1 value. Seconds account for the tempo map. In the example, the first note lasts 0.5 seconds and the second starts at 0.5 seconds and lasts 1 second.

Run a small JavaScript reader

Save this as inspect-midi.mjs, then run it with Node.js and the downloaded JSON path:

// Run with Node.js: node inspect-midi.mjs midi-data.json
import { readFile } from 'node:fs/promises';
const file = process.argv[2];
if (!file) throw new Error('Pass the downloaded JSON path.');
const midi = JSON.parse(await readFile(file, 'utf8'));
if (midi.schemaVersion !== 1 || !Array.isArray(midi.tracks)) {
  throw new Error('Expected MIDI Viewer JSON v1.');
}
const notes = midi.tracks.flatMap(track => track.notes);
console.log('Notes:', notes.length);
console.log('Initial BPM:', midi.header.initialBpm);
console.log('First note:', notes[0]);

The sample prints 2 notes and an initial BPM of 120. Do not schedule every quarter note at that initial BPM if the tempo changes; use each note’s startSeconds and durationSeconds.

Know what the export omits

Controllers, audible sustain interpretation, SysEx, raw events and complete program-change history are not included. Track program describes the last detected program on its lowest-numbered channel. This is not a lossless round-trip format: keep the original MIDI.

Tone.js, Unity and rhythm-game chart formats need explicit field mapping. No compatibility is implied by the .json extension. For a human-readable timing view, use Tempo Finder.