MP3 to MIDI Not Working? Every Message and What It Leaves Behind

Six ways a conversion can fail or come back empty, the exact wording the page uses for each, and what is still loaded afterwards. The messages are the easy part.

Short answer: a failed conversion does not clear anything. I converted an 8-note file, then selected an 85 MiB file and had it turned away - and the page then converted the old file again and handed back the old .mid, byte for byte, while the file input was holding the rejected one. A file the browser cannot decode behaves the same way: the message goes red and the result card hides, but the previous note list and .mid are still sitting there to download. Clear is the only control that drops them. And when a conversion succeeds but finds zero notes, Download still writes a 33-byte .mid file, while Copy note list does nothing at all and says nothing about it.

Everything below was measured on this page's own converter while it ran in a real browser: real files pushed into the file input, the real buttons clicked, and the page's own status text, buttons, result card and output files read back afterwards. Nothing here is inferred from the way the code looks.

Every message the page can show

The status line under the buttons has three visual states - neutral grey, green for success, and red for a problem. These are the messages, quoted exactly as the page renders them. Where the page breaks a message across lines, I have kept its line breaks.

What happenedWhat the page saysColour
File is over the size limit That file is 85.0 MB. This page turns files away above 80 MB, because the browser has to hold the whole decoded track in memory. red
The browser refuses to decode the file Could not decode this file.
Your browser refused it, which usually means the format is not one it can decode (WMA is a common case).
Detail: Unable to decode audio data
red
It decoded, but no steady pitch was found Decoded 2.0 s of audio, but no steady pitch was found.
This detector tracks one pitch at a time, so dense mixes, chords and percussion usually come back empty. Try a clearer single-line recording, or lower the sensitivity.
red
Copy note list, but the browser refused the clipboard Copy failed - your browser blocked clipboard access. red
The page cannot reach the microphone API at all This browser does not expose microphone recording to the page. red
A file was read from disk and is waiting Ready: ok.wav. Press Convert to MIDI. grey
Clear was pressed Cleared. Choose a file to begin. grey
A conversion finished with notes in it Converted 8 note(s) from 4.0 s of audio in 0.1 s.
Range C4 - C5. Download the .mid below.
green

Two things are worth noticing in that list. The first is that "Ready" is grey, not green - it is not a promise that the file will convert, and the next section shows why. The second is that the last line of the decode message is not written by the page. The page writes Detail: and then prints whatever error the browser's decoder produced. In Chrome 153 that string is Unable to decode audio data; a different browser will word it differently.

Nothing is cleared by a failure

This is the part that is worth knowing before you go looking for a bug. The page keeps four separate pieces of state: the file's bytes, the detected notes, the .mid it built, and what is drawn on screen. A failure only touches the last of those.

I ran one file through the whole sequence - success, then a rejected file, then an undecodable file, then a different file with no conversion, then a conversion that found nothing, then Clear - and read the page's state after each step. The note list and the .mid are the same objects throughout:

StepStatusResult cardNotes Download givesCopy gives
Converted an 8-note filegreenshown8 105 bytes9 lines
Then selected an 85 MiB file (rejected)redshown8 105 bytes, identicalidentical to above
Then selected a file the browser cannot decoderedhidden 8105 bytes, identical9 lines
Then selected a silent file, without convertinggreyhidden 8105 bytes, identical9 lines
Then converted that silent file (0 notes)redshown0 33 bytesnothing
Then pressed Cleargreyhidden0 no file at allnothing

Read the second and third rows again. After the 85 MiB file was turned away, the .mid that Download produced was byte-for-byte identical to the one from the run before it, and the copied note list was character-for-character identical. After the undecodable file failed, the same was still true - the result card had been hidden, but the outputs behind it had not moved. And after selecting a completely different file, they still had not moved.

The "Notes" column is the giveaway. Even in the rows where the result card is hidden, the numbers inside it are still the previous run's numbers; hiding the card does not rewrite them.

The practical consequence, measured. I converted a file called ok.wav and downloaded ok.mid, 105 bytes. Then I selected a different file, silence.wav, without converting it, and pressed Download again: I got a 105-byte file called silence.mid - the previous conversion's notes, carrying the new file's name. After notaudio.wav failed to decode, the download was called notaudio.mid and still held those same 105 bytes. The file name comes from whatever you selected last; the contents come from the last conversion that succeeded. Check the note count in the status line before you trust a download.

The size rejection: one action, two completely different end states

Selecting an oversized file is the same gesture every time, but what is left behind depends entirely on what was on the page before it. I ran it both ways.

Nothing loaded beforeA finished result on screen
Status messageidentical - the red "turns files away above 80 MB" line
Convert buttondisabledstill enabled
Result cardhiddenstill showing the old result
File info lineNo file chosen yet. still ok.wav - 125.0 KB

In the second column the rejection message is the only thing that changed. The file input was holding oversize.wav, 89,128,960 bytes of it, while the line underneath it still read ok.wav - 125.0 KB. So I pressed Convert again, and the page reported Converted 8 note(s) from 4.0 s of audio in 0.1 s - it had re-run the old file. Download gave 105 bytes, byte-identical to before.

Nothing is broken here in the sense of lost work: you did not lose your previous conversion, which is the friendlier of the two possible behaviours. But the page is now showing you two different answers to "which file am I working on" at the same time, and the one that matters - the one Convert will use - is the one that is not named in the file info line. If you want to be sure you are starting clean, press Clear.

The size limit itself is a byte count, not a duration, and what it means in minutes depends entirely on your format - the same 80 MiB is 7.9 minutes of stereo WAV and about 1.5 hours of 128 kbps MP3.

"Ready" only means the bytes are in memory

The page does not validate the format when you choose a file. It checks the size, reads the bytes with FileReader, and reports ready. I took a 312-byte ASCII text file, renamed it to notaudio.wav, and loaded it:

file info line : notaudio.wav - 0.3 KB
status         : Ready: notaudio.wav. Press Convert to MIDI.
Convert button : enabled

Then I pressed Convert and got the red decode message with Detail: Unable to decode audio data. Pressing Convert again produced the identical message, so this is not a transient failure that a retry will fix - the file is simply not audio the browser can read. The format check is the browser's decoder, and it runs at conversion time, not at selection time.

This is also why the page cannot give you a list of supported formats in advance. It has no list of its own; the list is whatever your browser happens to decode, which is why WAV, MP3, OGG, M4A, FLAC and WebM or Opus work in current browsers while WMA generally does not.

Zero notes: a file you can download, and a button that does nothing

Running out of notes is not treated as a failure - the result card opens anyway. I converted a 2-second file of pure silence:

ReadoutValue
Notes found0
Duration2.0 s
Pitch range-
Analysis time0.0 s
Piano rollblank white, 0 of 135,000 pixels drawn on

Now the two output buttons, pressed in that same state.

Download .mid still writes a file. It came out at 33 bytes, and it is a structurally valid MIDI file - format 0, one track, 480 ticks per quarter note - whose entire content is a tempo event of 500,000 microseconds (120 BPM) and an end-of-track marker:

4d 54 68 64 00 00 00 06 00 00 00 01 01 e0
4d 54 72 6b 00 00 00 0b
00 ff 51 03 07 a1 20        tempo, 500000 us
00 ff 2f 00                 end of track

No note events at all. I parsed it with two independent parsers and they agree: 2 messages on the track, a set_tempo and an end_of_track, total playback length 0.0000 seconds. It will open in a DAW and look like an empty region, which is at least honest, but it is a file that says nothing about why the conversion came back empty.

Copy note list does nothing whatsoever. I checked both ends of it. No clipboard write happened at all, and the message on screen did not change - it was still the red "no steady pitch was found" line before and after the click. The copy handler returns immediately when the note list is empty, before it reaches the code that would report anything. So the button is not broken; it is silent in exactly the state where you would most want it to tell you something.

If you get zero notes and want to know what happened, do not reach for Copy - it will not answer. Use the four readouts instead. The note count and the pitch range together tell you whether the detector heard nothing at all or heard the wrong thing, and the checks that separate those two cases are all numeric.

What actually resets the page

Only Clear does. Measured on the live page, one click of Clear:

Two things Clear does not do, both of which are visible in the table above: it leaves the numbers inside the hidden result card untouched, and it does not erase the canvas - the old piano roll is still in the pixels, just not on screen. It also does not reset the four controls, so whatever you typed into Tempo, Confidence, Transpose and Shortest note is still in place for your next run. The canvas behaviour is measured in detail here.

Choosing a different file is not a reset either. It hides the result card, but the stored note list and .mid survive, which is the whole reason the table above has three identical 105-byte rows in it.

How I measured this

  1. Ran the real page. Files were pushed into the converter's file input over the browser's debugging protocol, and Convert, Copy note list, Download .mid and Clear were clicked for real - 30 state readings across three passes, plus a fourth pass that recorded the file name of every download. The oversize test used an 85 MiB file, and the silent test a 2-second all-zero WAV.
  2. Read the state back, not the appearance. After each step I captured the status text and its CSS class, whether Convert was disabled, whether the result card was displayed, the file info line, the actual File object sitting in the input along with its byte size, the four readouts, and the canvas contents.
  3. Captured the page's own outputs. URL.createObjectURL was wrapped so the exact bytes of the .mid the page writes could be read, and navigator.clipboard.writeText was hooked so the exact text it copies could be read. The byte comparisons above are of those captured bytes, not of files that were saved to disk.
  4. Parsed the 33-byte file twice. Once with a parser written for this test, once with an independent third-party MIDI library. Both report the same two events.

Honest boundaries