Tempo Convert Tempo, Preserve Duration

The Convert Tempo, Preserve Duration tool re-targets a MIDI file (or a part of it) from one musical tempo to another without changing how long it takes to play back in real time. A 90 BPM vocal recording dropped into a 180 BPM project will line up bar-for-bar with the project grid and sound exactly the same speed it always did.

💡 Find it in: Tools → Tempo Tools → Convert Tempo, Preserve Duration…, or right-click a track / channel / selection and pick the same entry from the context menu.

Convert Tempo, Preserve Duration dialog

The dialog: detected source tempo, target tempo, the scope picker, the three tempo-map modes and the live preview above the Convert button.


Why this exists

Two existing operations almost solve the problem but neither is enough on its own:

Combining the two by hand is fiddly and easy to get wrong. Convert Tempo, Preserve Duration does both in one atomic, undoable operation and shows the projected duration delta before you commit.


The math - one formula, one example

scale = target_bpm / source_bpm new_tick = round(old_tick * scale) new_duration = round(old_duration * scale) tempo_meta := target_bpm

Worked example, 90 BPM → 180 BPM (scale = 2.0):

QuantityBeforeAfter
Note start tick480960
Note length (ticks)240480
Tempo meta90 BPM180 BPM
Real-time start0.333 s0.333 s
Real-time length0.167 s0.167 s

Real playback duration is preserved; the file now lives in the host project's 180 BPM grid. Because every tick is rounded to a whole number, a round trip 90 → 180 → 90 can land up to one tick per event away from where it started. That is inaudible, but if you need the result exactly on the grid afterwards, quantize the converted events.


The dialog - field by field

FieldWhat it does
Source BPM (detected) Filled in from the file's earliest tempo event. Override it for material whose real tempo differs from what the file claims - the conversion always works from the number in this box.
Target BPM Where you want to end up. It starts at the detected tempo, so the dialog opens on "nothing to do" until you change it.
Apply to Whole project, Selected tracks, Selected channels or Selected events. The entry point decides which tracks, channels or events those are, and a coloured line under the picker names them ("Pre-filled tracks: 2", "Pre-filled with 128 selected event(s)."). To convert one track, open the dialog from that track - see Entry points.
Tempo map handling Replace with single fixed tempo at tick 0 (default), Scale existing tempo map (preserve curves), or Scale events only (leave tempo map untouched). The default does what most people mean by "convert tempo": rewrite the tempo to the target BPM and scale every event tick by target/source so the real-time playback length stays identical. See the modes section for the other two.
Preview box The dark box above the buttons recomputes after every change - without touching the file - and reports the scale factor, how many events would be affected, and the playback duration before and after. When the chosen mode rewrites the tempo map it also reports how many tempo events go and how many arrive. A warning line appears below it when there is something to warn about.
Convert The only button that changes anything. Everything above it is a projection; Cancel leaves the file untouched.

Tempo handling modes

ModeBehaviourUse when
Replace with single fixed tempo at tick 0
(default - "just convert the BPM")
All TempoChange events are removed and a single tempo at target_bpm is inserted at tick 0. Event ticks scale by target/source so note lengths grow / shrink to match. The piece sounds exactly the same speed as before but now lives at the new BPM. The common case: re-target a clip from one tempo to another. 90 BPM vocal → 180 BPM project, etc.
Scale existing tempo map (preserve curves) The tempo events move with the music and their BPM values are scaled along, so a written-in tempo curve keeps its shape at the new musical-tick rate. Pieces with a written-in ritardando / accelerando that you want to retime without flattening the tempo changes.
Scale events only (leave tempo map untouched) The tempo map is left exactly as it was. Only the event ticks in scope are rescaled, so the material really does take longer or shorter in real time. You want a half-time / double-time correction inside a project that already runs at the correct musical tempo - and it is the mode every partial scope uses.

Partial scopes use Scale events only. The tempo map belongs to the whole file, not to a track or a channel, so changing it from a partial scope would retime everything outside the scope. As soon as Apply to is anything other than Whole project, the dialog therefore selects Scale events only and greys the other two modes out, with that reason printed under them. Set the scope back to Whole project and all three are available again, with your previous choice restored.


Entry points

All four open the same dialog; only the scope it starts on differs. Tempo numbers and the tempo-map mode are yours to change before you press Convert - which tracks, channels or events are in scope is decided by the entry point you used, so pick the one that matches what you want to convert.


Safety guarantees


Warnings the dialog raises

SituationWhat you'll see
Source and target BPM are the sameA warning line under the preview: "Source and target BPM are identical - nothing to convert." Convert then closes the dialog without changing anything.
The scope holds no eventsThe preview reads 0 events affected. That is the sign you opened the dialog from the wrong place - close it and start from the track, channel or selection you mean.
Several tempo events + Replace modeThe preview adds a Tempo events line showing how many are removed and how many are inserted, so you can see the tempo curve being collapsed to one value before you commit.
No file openThe preview shows the reason instead of numbers, and converting does nothing.

Letting the AI do it

The same conversion is available to MidiPilot as the convert_tempo_preserve_duration tool, with the same four scopes - the whole file, given tracks, given channels, or your current selection - and the same tempo-map modes. It follows the dry-run rule: the agent first reports what the conversion would change, waits for your confirmation, and only then runs it for real, as one undoable step. Ask for it in plain words ("this was recorded at 90 BPM, fit it to the project's 180") and check the summary before you say yes.


Thin Tempo Map

The second tool in Tempo Tools answers a different question: not "which tempo is this at", but "how many tempo events does it take to say so". A tempo ramp drawn in a DAW is exported as a long chain of tiny tempo steps - one every few ticks, thousands of them over a song. Every one of them has to be read whenever the editor works out where a note sits in time, and anything else that plays the file back reads them too. Thin Tempo Map keeps the events that carry the timing and drops the rest.

💡 Find it in: Tools → Tempo Tools → Thin Tempo Map…, by right-clicking the measure ruler above the piano roll, or as the repair button on the Tempo map finding in the playability check.

The Tools menu with Tempo Tools open, showing Convert Tempo, Preserve Duration and Thin Tempo Map

Thin Tempo Map lives next to Convert Tempo under Tools - Tempo Tools; the tempo ruler offers both on right-click too.

The Thin Tempo Map dialog on a file with 12,871 tempo events: the allowed timing shift at 2.0 ms and the preview reporting that 31 events would be kept

The dialog on a real DAW export: 12,871 tempo events, and at the default 2 ms the preview keeps just 31 of them - the music moves by two milliseconds at most.

What "keeping the timing" means

The tempo map is what turns a tick position into a point in time. Thinning replaces it with a shorter map that has to stay inside a corridor around the original: you choose how many milliseconds any point of the piece may end up away from where it was, and the tool keeps exactly the events it needs to honour that - checked at every original tempo event and at the end of the file, so the error cannot creep up over the length of the song. The default corridor is 2 ms, far below anything you can hear. Notes, lyrics and markers are never touched; only tempo events are removed, and every event that survives keeps the tempo value it already had, so no number in the file is ever a computed average.

The first tempo event of the file always survives - it is the anchor everything else is measured from. At the other end of the dial, a corridor of 0 ms still has work to do: a run of tempo events that all say the same thing can be collapsed without moving anything at all, so setting the box to zero removes exactly the events whose removal changes no timing whatsoever.

The shift is counted from the file as you opened it

The millisecond figure is a budget for the whole document, not a fresh allowance for each run. The tool remembers the tempo map it was first asked about in this session and always measures against that one, so "the music moves at most 2 ms" stays true however often you run it:

When the tempo map is changed by something else - a tempo event added or edited, a tempo conversion - the remembered map no longer describes the document, so the tool starts counting from the map as it stands now. Saving and reopening the file does the same, because the saved file is the original from that point on.

The dialog

The dialog opens with a sentence naming how many tempo events the file carries right now - the number the preview is worth comparing against - and one setting underneath it.

ElementWhat it does
Allowed timing shiftThe corridor, in milliseconds, adjusted in half-millisecond steps. Smaller keeps more tempo events and moves the music less; larger keeps fewer.
Preview lineRewrites itself as you turn the dial: how many of the events would be kept, how many removed, the largest timing shift anywhere in the piece and the shift at the end of the file. Nothing has changed at this point. When the setting keeps everything it says so instead - every tempo event is carrying part of the timing.
ThinApplies it as a single undoable step named after the before and after counts, so one Ctrl+Z brings the full map back. The status bar then repeats what happened.

Two extra lines appear under the preview when they apply: one whenever the map has already been thinned in this session, naming how far from the file as opened it already sits and reminding you that the figures count from there; and one in bold when the piece is already further away than the setting asks for.

Letting the AI do it

MidiPilot has the same tool as thin_tempo_map, with the corridor as its only real setting. It follows the dry-run rule: the agent reports how many events it would remove and how far the timing would move, waits for your confirmation, and only then applies it as one undoable step. The figures it quotes are the same cumulative ones the dialog shows, counted from the file as opened. "This file drags, can you clean up the tempo map" is enough to start it.