FIXED-OUTPUT EXPERIMENT / OCTOBER 8, 2026
MP3 to MIDI.
Length is a filter.
Minimum note length removed fragments, not just unwanted pitches. In our fixed-output WAV/MP3 test, 20 frames still left eight higher-layer events in each stronger-partial control. At 30 frames they disappeared; at 40 frames both controls produced no notes. These are offline CPU results, not browser settings advice.
Short fragments and higher layers
did not disappear together.
| Generated input | 0 | 5 | 10 | 20 | 30 | 40 |
|---|---|---|---|---|---|---|
| Fundamental WAV | 30 | 9 | 7 | 4 | 4 | 1 |
| Fundamental MP3 | 28 | 8 | 6 | 4 | 4 | 1 |
| Stronger-partial WAV | 43 | 13 | 13 | 12 | 4 | 0 |
| Stronger-partial MP3 | 44 | 14 | 13 | 12 | 4 | 0 |
Fundamental WAV
Frames: 0 / 5 / 10 / 20 / 30 / 40.
Events: 30 / 9 / 7 / 4 / 4 / 1.
Fundamental MP3
Frames: 0 / 5 / 10 / 20 / 30 / 40.
Events: 28 / 8 / 6 / 4 / 4 / 1.
Stronger-partial WAV
Frames: 0 / 5 / 10 / 20 / 30 / 40.
Events: 43 / 13 / 13 / 12 / 4 / 0.
Stronger-partial MP3
Frames: 0 / 5 / 10 / 20 / 30 / 40.
Events: 44 / 14 / 13 / 12 / 4 / 0.
At the homepage's unchanged extraction value of 5 frames, the fundamental WAV contained three short fragments and the MP3 contained four. Here a short fragment means an extracted event with duration at most 10 frames, measured before MIDI writing. At 10 frames that count became zero, but seven WAV events and six MP3 events remained. Eliminating short fragments did not automatically make one event per source tone.
The stronger-partial controls behaved differently. Their higher-layer counts were eight at 5, 10 and 20 frames, even after the short-fragment count reached zero. At 20 frames their slot pitch sets were [48,60,67], [52,64,71], [55,67,74] and [60,72,79]. A duration criterion cannot identify whether a surviving high pitch belongs to the musical part you want.
At 30 frames, all four controls exported four events, with only the reference pitch in each slot. That is a result for these generated tones, not a recommended value for other recordings. At 40 frames, the fundamental controls kept only a pitch-48 event in the first slot; the other three reference slots were empty. Both stronger-partial controls had no events at all. Increasing the threshold further was not an improvement by itself.
Freeze inference.
Vary extraction, not the recording.
We reused the generated harmonic controls, not user media: four source pitches, 48, 52, 55 and 60, starting at 0.2, 0.75, 1.3 and 1.85 seconds. Each source tone lasts 0.35 seconds in a 2.5-second mono file. The fundamental-only waveform uses coefficients [1,0,0]; the stronger-partial waveform uses [0.2,1,0.3] at frequencies [f,2f,3f] before source RMS scaling. WAV and encoded MP3 were separate inputs, not assumed equivalent decoded buffers.
Native FFmpeg decoded each file to mono float32 audio at 22,050 Hz. The installed Basic Pitch model ran on the Node CPU backend. For each input we retained its complete frames, onsets and contours in a compressed JSON capture. Every threshold received a fresh deep copy of that same capture; its content hash was checked before extraction, and the retained original was checked afterwards. We did not rerun inference for each setting or pick different model outputs until the results agreed.
A desktop reconnection interrupted the first measurement process after its two fundamental captures were saved. The continuation reused those exact captures and completed the two stronger-partial captures. The downloadable files retain their capture timestamps and hashes. The continuation did not replace the saved model output with a new fundamental inference.
Onset and frame thresholds stayed at 0.25. Inferred onsets, residual-energy extraction and energy tolerance stayed at the installed defaults. Only minNoteLen changed across 0, 5, 10, 20, 30, 40. We used the homepage's existing time conversion and MIDI writer conventions, including its 0.03-second minimum export duration and velocity clamp. Every nonempty result was written to disk and parsed back; no-note results have no MIDI file.
Frames are not an exact exported duration label.
The installed extraction code rejects durationFrames <= minNoteLen. Its nominal step is 256 / 22050 seconds, from the library's hop and sample-rate constants. Time conversion also applies a window-offset correction every 172 frames, and MIDI writing quantizes time to ticks. Use the report's actual parsed seconds and ticks, not a rounded millisecond name for a threshold.
The filter is part of note extraction, not simply a delete-short-notes pass over an existing MIDI. Rejected onset candidates affect which frame energy remains available to later extraction. In the fundamental WAV, 20 frames produced lengths [33,33,34,35]; at 40 frames the remaining event was 41 frames long. It was not present with that duration in the earlier four-event list. Retaining fewer events therefore does not guarantee that every retained event is an unchanged subset of the previous export.
We assigned each parsed event to the nearest source-tone centre using argmin(abs((startSeconds + durationSeconds/2) - (sourceStart + 0.175))). Higher-layer counts mean the event's MIDI pitch exceeds that slot's known reference pitch. This classification is specific to these synthetic controls; it is not an instruction to remove high notes from a real chord, or a percentage accuracy claim.
Use the evidence.
Keep the limits.
The observed angle comes from Tuneonmusic's shortest-note control and extra-note explanation. Note Foundry also exposes a minimum-length control; MP3MIDITool advises repairing splits and omissions. These reference pages motivated our test. We did not run their converters, and their controls are not assumed to use the same units or implementation.
Our independent evidence is the fixed-output sweep, retained model captures, exported MIDI and parsed per-slot comparisons. It establishes only what this installed extraction implementation did on these four inputs. It does not establish browser-backend equivalence, phone performance, DAW import behavior, vocal accuracy, or a best threshold for a complete song.
- Inspect short repeated fragments separately from sustained higher layers. They responded differently in this experiment.
- After changing a duration filter, check both retained pitches and missing source notes. A smaller event count is not a quality score.
- Keep your original MIDI before cleanup. This site's converter remains unchanged; the values here are experimental extraction parameters, not new homepage controls.
Inputs, captures, real exports.
- Fundamental WAVMinimum frames / MIDI: 0 · 5 · 10 · 20 · 30 · 40
Fixed model capture - Fundamental MP3Minimum frames / MIDI: 0 · 5 · 10 · 20 · 30 · 40
Fixed model capture - Stronger-partial WAVMinimum frames / MIDI: 0 · 5 · 10 · 20 · 30
40: no notes, no MIDI.
Fixed model capture - Stronger-partial MP3Minimum frames / MIDI: 0 · 5 · 10 · 20 · 30
40: no notes, no MIDI.
Fixed model capture - Full measurement reportHashes, settings, pre-export frame events, parsed seconds and ticks, pitches and source-slot assignments.
- Exact experiment sourceRun from the site project with its installed dependencies:
node scripts/measure-minimum-note-length.cjs . --replay. Replay uses the saved captures without rerunning inference.
The published script is an exact copy of the project script. If you download it separately, install the pinned project dependencies, retain the prior harmonic controls and place it in the project's scripts directory; pass the site root as its argument. The captures are gzip-compressed JSON, not opaque claimed results. No external conversion service or user recording was used.