Audio → MIDI

Audio to MIDI Converter

How accurate is the tempo a converter writes to the MIDI

The short answer: this converter does not detect tempo at all — it writes exactly the BPM you type into the Tempo field, accurate to within 0.001 BPM of what you entered, and that BPM does not move a single note. We measured the converter’s own MIDI writer: the same phrase plays back at the same time whether you typed 100, 120, 140 or 173 BPM. So “tempo accuracy” is really your accuracy in setting the field — the tool neither guesses the tempo nor lets it drift the notes.

1. There is no tempo detection

Look at what the converter actually does. The pitch analysis (dsp.js) measures frequency and loudness frame by frame and produces note timings in seconds. The file writer (midi.js) then writes the tempo you supplied as a single meta event:

usPerBeat = Math.round(60000000 / bpm)   // microseconds per quarter note
// note tick = round(note.start * TPQ * bpm / 60)

That is the whole story. Nowhere is the audio’s beat interval measured, estimated, or tapped. The BPM is a number you type, and it goes into the file unchanged. If your song is 140 BPM and you leave the field at the default 120, the MIDI is marked 120 — not because detection was wrong, but because there was no detection. This is the opposite of a “tempo detection accuracy” question: the converter is a pitch-and-timing tool with a manual tempo stamp.

If you need the tempo read off the audio rather than typed in, the BPM finder measures it from the file, shows the key, and can export the notes as a .mid.

2. Measurement 1: the written tempo equals your input

We built a short note list at fixed times and wrote it at four different BPM values through the converter’s own buildMidi(), then read the tempo meta event back out of each file:

Four BPM inputs written and read back from the converter's own MIDI output.
BPM typedusPerBeat writtenBPM read backError
100600000100.0000
120500000120.0000
140428571140.000140.00014
173346821172.99990.0001

The only deviation from your input is the rounding of usPerBeat to whole microseconds — at 140 BPM that is 0.00014 BPM, at 173 BPM it is 0.0001 BPM. In practice the written tempo is your tempo to within a thousandth of a BPM. There is no systematic error, no beat-tracking drift, no smoothing. The converter is a faithful scribe, not an estimator.

3. Measurement 2: the BPM does not move the notes

The more useful question is whether a wrong BPM shifts the notes out of time. It does not. Note positions are written in ticks as round(start * TPQ * bpm / 60), while the tempo map says one quarter = 60000000 / bpm microseconds. The two scale with BPM in opposite directions, so they cancel. We placed one note at exactly 0.500 seconds and wrote it at four tempos:

One note at start 0.500 s, written at four BPM values, then played back.
BPM typedNote tickPlayback time
1004000.500 s
1204800.500 s
1405600.500 s
1736920.500 s

Four different BPM values, four different tick numbers (400, 480, 560, 692) — and the note lands at 0.500 s every time. Because the ticks and the tempo map are derived from the same BPM, the absolute timing you hear is locked to the original audio regardless of what you typed. A wrong BPM will not desync your melody from the recording.

4. What a wrong BPM actually breaks

Since the notes stay put, a wrong tempo only damages the metadata and anything built on the grid:

So the only time the BPM value truly matters is when it feeds a grid you are going to use. Set it to the song’s real tempo (tap it, or read it from your DAW) before converting if you plan to quantize; otherwise leave it and fix the grid later in the DAW.

5. How to check and fix on your own file

  1. Read the tempo field, not the detection. The BPM in the exported .mid is exactly what you typed. There is nothing to “correct” — only something to set right next time.
  2. Confirm the notes are in time. The .csv the converter also writes has a start_sec column. Those times are absolute and BPM-independent, so your notes are already aligned to the audio.
  3. Fix the grid in the DAW. If the bar lines are wrong, just retype the tempo in your DAW — the notes will not move. No re-conversion needed.
  4. Re-convert only if you want to quantize. Turn on snap with the correct BPM and the notes will align to the right grid on export. How to clean up a converted MIDI covers the simpler, non-destructive passes too.

Questions people actually ask

Does the converter detect the tempo automatically?

No. It writes the BPM you type into the Tempo field, verbatim, with no beat analysis of the audio. If you leave it at the default, the file is marked with that default — the converter never guesses what the song’s actual tempo is.

If I set the wrong BPM, will the notes be out of time?

No. We measured a note at 0.500 s playing back at exactly 0.500 s whether the BPM was 100, 120, 140 or 173. The note ticks and the tempo map scale together, so absolute timing is preserved no matter what you type. Only the bar/beat grid is wrong.

How accurate is the written tempo?

To within 0.001 BPM of what you entered. The only error is rounding the microseconds-per-beat to a whole number; at 140 BPM that is 0.00014 BPM. There is no systematic drift.

Should I bother setting the BPM correctly?

Only if you intend to use the grid — quantizing in the converter, or aligning to bars in your DAW. If you just want the notes in time with the audio, the BPM is irrelevant and you can leave it. Set it right before converting if you plan to snap notes to the beat.

Why are my bar lines in the wrong place?

Because the tempo map says the song is whatever BPM you typed, and your DAW draws bars from that. The note positions are still correct; only the grid is mislabeled. Retype the tempo in the DAW to fix the bars without touching the notes.

Drop a file in and read the CSV — the Audio to MIDI Converter runs entirely in your browser, so the note timing in start_sec is yours to check against the audio in seconds, independent of any BPM. Once the notes are right, How to clean up a converted MIDI before you use it walks the passes that turn a raw export into a usable part.

Related guides