Skip to the answer

ORIGINAL LEAD-IN EXPERIMENT / OCTOBER 4, 2026

MP3 to MIDI starts late?
Move it. Don't stretch it.

If the phrase is late by a constant amount, shift all notes together; do not change BPM to fix the start. In our controlled test, adding two seconds of silence moved the first exported event from 0.196875 s to 2.195833 s. Moving that MIDI to zero preserved its note spacing and lengths. If the mismatch grows as the phrase plays, investigate tempo instead.

Same phrase. A different starting point.

We generated a four-tone phrase at MIDI pitches 60, 64, 67 and 72. The baseline tones start at 0.2, 0.75, 1.3 and 1.85 seconds; each lasts 0.35 seconds. The second input contains the same phrase with exactly 44,100 zero-valued samples inserted before it: 44,100 / 22,050 = 2 seconds. This is deliberate source silence, not a measurement of MP3 encoder delay.

Both mono inputs were encoded as 128 kbps MP3 and decoded with native FFmpeg at 22,050 Hz. Basic Pitch 1.0.1 ran on the Node CPU backend, followed by this site's unchanged extraction thresholds and note writer. The baseline is 2.5 seconds long and the lead-in version is 4.5 seconds long. Nominal tone starts and lengths are rounded to the nearest whole sample in the generator. No user recording was involved.

BASELINE EXPORT0.196875 sFirst detected note · 189 ticks
5 exported events · 138 bytes
ADDED TWO-SECOND LEAD-IN2.195833 sFirst detected note · 2,108 ticks
5 exported events · 138 bytes
SHIFTED MIDI CONTROL0 sFirst detected note · 0 ticks
5 exported events · 137 bytes
Parsed note timelines: baseline begins at 0.196875 seconds, added lead-in at 2.195833 seconds, and uniformly shifted MIDI at zero
Baseline → 0.196875 s

First exported event. Four source tones produced five events.

Lead-in → 2.195833 s

The source contains two extra seconds of silence.

Shifted → 0 s

Subtract 2,108 ticks from every event's start. Keep durations unchanged.

Every bar uses the parsed start and duration from our files. The displayed 2.195833 s is rounded; the raw value is 2.1958333333333333 s. Open full-size timeline.

The measured first-event difference is 2.1958333333333333 − 0.196875 = 1.9989583333333334 seconds. It is close to the defined two-second edit, not exactly equal. That difference is a result for these generated files, not a universal correction to apply to your recording. The detector does not promise exact source onsets.

Both runs returned five events from four tones: pitch 60 was split into two adjacent events. Their later boundaries and velocities also differ between runs. Adding silence did not produce a bit-identical transcription merely moved by two seconds. A start correction does not repair a split note or certify the pitch transcription.

What the zero-start edit actually changed

We parsed the lead-in MIDI and subtracted its earliest note position, 2,108 ticks, from every note's start. We did not transcribe the audio again, change a tempo event, quantize the notes, or shorten a note. The shifted file below is a separate experimental artifact; the homepage converter does not silently make this edit for you.

Actual parsed starts and lengths. Relative spacing is preserved in ticks.
Exported eventOriginal startShifted startDuration, unchanged
60 · first event2,108 ticks0 ticks279 ticks
60 · split fragment2,386 ticks278 ticks89 ticks
642,643 ticks535 ticks346 ticks
673,167 ticks1,059 ticks357 ticks
723,702 ticks1,594 ticks336 ticks

The interval from the first event to pitch 72 is 3,702 − 2,108 = 1,594 ticks before the edit and 1,594 − 0 = 1,594 ticks afterwards. The script checks every relative start, every duration, every pitch and every velocity after serialization. All those checks passed. Both files have zero tempo events and a resolution of 480 ticks per quarter note.

Use one offset for the entire selection.

new start = old start − chosen offset
new gap = (later start − offset) − (earlier start − offset) = old gap

Here the offset came from the earliest parsed event in our file. For your own take, choose the intended musical anchor, not an arbitrary number from this example.

Zero is not always the right musical target. Moving the earliest note to zero removes the intentional opening gap as well as the added lead-in. If the phrase contains a pickup or should begin after the bar line, preserve that placement. To compare our two unedited controls, keep their known two-second source difference separate from the zero-start rewrite.

Fix the right kind of mismatch

  1. Keep the original audio beside the MIDI. Find an early note that both files clearly contain, then compare a later one. Do not use a spurious split fragment as the alignment anchor.
  2. If both positions need approximately the same correction, select the whole MIDI phrase and move it together. Preserve gaps and note lengths; leave tempo unchanged for this step.
  3. If the first note lines up but later notes progressively drift, check the tempo or time mapping instead. See the separate ticks-versus-seconds experiment before changing BPM.
  4. If only individual boundaries are wrong, edit those boundaries. The duplicated pitch 60 in our controls needs a separate split-note review, not another global shift.
A uniform time subtraction preserves gaps; a tempo scale multiplies gaps and durations
Algebraic distinction, not a DAW screenshot or a real-time latency measurement. Open the diagram.

This is an editing workflow, not a claim that we imported the controls into Ableton, FL Studio or another DAW. A note position is also different from latency while playing an instrument live. Use the actual source and imported events to decide which problem you have.

Open the files. Check the claim.

Run the reproduction script in this project's installed dependency environment, passing the project directory as its first argument. It expects the installed model and this build's src/app.js for the source hash; downloading the script alone is not a complete project setup. It needs Basic Pitch, TensorFlow.js, the MIDI libraries and native FFmpeg. The script generates its own audio and uses the local model; it does not send recordings to an external service. Its result describes this CPU path, not an untested device or browser decoder.

Seconds shown here are parsed-file values. The installed MIDI library uses its default timing interpretation when a file has no tempo map; that is not a detected source BPM. The invariant edit is expressed in ticks to avoid claiming a new tempo estimate. The library's note representation documents how note ticks relate to seconds; our installed version and actual bytes are recorded in the raw report.

Late-start questions, answered

Why does my MP3-to-MIDI result start late?

A retained silent lead-in is one possible cause. Our two-second source edit moved the first event by 1.9989583333333334 seconds on the tested offline path. It does not prove your delay has that cause. Compare the first and later matching notes against your own source.

Should I change the BPM to remove silence?

Not for a uniform starting offset. A uniform shift preserves the note spacing; changing the timing scale changes spacing too. Our separate tempo experiment shows why those operations should not be confused.

Does this prove MP3 encoding adds two seconds?

No. We deliberately inserted those samples before encoding. A real user discussion about MP3 starts in DAWs concerns a different issue. We did not repeat those DAW tests or adopt their delay figures.

Can I make the first note start at zero?

Yes, when zero is the intended anchor. Our downloadable rewrite sets the earliest start to zero and preserves pitches, velocities, note lengths and relative starts in ticks. It does not correct the split first tone, remove false notes or establish the musical downbeat.