Reputation: 411
I want to know how to convert MIDI ticks to actual playback seconds.
For example, if the MIDI PPQ (Pulses per quarter note) is 1120, how would I convert it into real world playback seconds?
Upvotes: 21
Views: 45155
Reputation: 202
if ppq = 1120,
1120 ticks @60bpm == 1 second.
1120 ticks @120bpm == 0.5 seconds
we can see that this becomes a ratio at 60bpm,
1120:1
given 9999 ticks, we can use this conversion:
9999/1120 = 8.9277 seconds @ 60 bpm
we can also see that there is a ratio between 60bpm:120bpm as a 1:0.5 ratio, since 60/120 = 0.5
60/bpm is the multiplier.
Putting this together, if I have a 30bpm song at 1120 ppq, and I want to calculate out how many seconds 9000 ticks is , I first calculate it at 60bpm at then multiply with the multiplier:
`(ticks/ppq )*(60/bpm)`
which gives us:
(9000/1120)*60/30 = 16.071 seconds
in typescript, this would look like:
export function ticksToSecs(ticks: number, ppq: number = 96, tempo: number = 33) {
return (ticks/ppq)*(60/bpm)
}
for going from seconds to ticks, I found this works (tested against 60, 120 and 200 bpm)
I made a converter going seconds to ticks starting with the above answer from Aaronaught in 2010 of
60000/(tempo* ppq)
However, it was not updating based on tempo in my testing , so I put in tempo*1000 for the top, and divided by 1000 to get seconds since his was in milliseconds.
I also added in tempo so it would change the overall ticks
That gave me this:
export function secondsToTicks(secondsIn: string, ticksPerQuarterNote: number = 96, tempo: number = 33) {
const seconds = parseFloat(secondsIn)
const secondsPerTick = tempo*1000 / (tempo * ticksPerQuarterNote)/1000
console.log("seconds:" ,seconds,"ticks:", seconds / secondsPerTick * 1.0,"seconds per tick:", secondsPerTick)
return seconds / secondsPerTick * 1.0
}
I then saw that tempo
and 1000
could be simplified out of the equation, which gave me this:
export function secondsToTicks(secondsIn: string, ticksPerQuarterNote: number = 96, tempo: number = 33) {
const seconds = parseFloat(secondsIn)
const secondsPerTick = 1/ticksPerQuarterNote
console.log("seconds:" ,seconds,"ticks:", seconds / secondsPerTick * 1.0,"seconds per tick:", secondsPerTick)
return seconds* ticksPerQuarterNote
}
which can be simplified further by removing secondsPerTick since it is no longer used and console.log which gives us a seconds to tick- multiply seconds by ticks per quarterNote to get the ticks
export function secondsToTicks(secondsIn: string, ticksPerQuarterNote: number = 96, tempo: number = 33) {
const seconds = parseFloat(secondsIn)
return seconds* ticksPerQuarterNote
}
and that is how to convert from seconds to ticks and ticks to seconds.
Upvotes: 0
Reputation: 5796
You need two pieces of information:
Ticks can be converted to playback seconds as follows:
ticks_per_quarter = <PPQ from the header>
µs_per_quarter = <Tempo in latest Set Tempo event>
µs_per_tick = µs_per_quarter / ticks_per_quarter
seconds_per_tick = µs_per_tick / 1.000.000
seconds = ticks * seconds_per_tick
Note that PPQ is also called "division" or "ticks per quarter note" in the document linked above.
Note that Tempo is commonly represented in BPM (a frequency) but raw MIDI represents it in µs per quarter (a period).
Upvotes: 20
Reputation: 122624
The formula is 60000 / (BPM * PPQ)
(milliseconds).
Where BPM is the tempo of the track (Beats Per Minute).
(i.e. a 120 BPM track would have a MIDI time of (60000 / (120 * 192))
or 2.604 ms for 1 tick.
If you don't know the BPM then you'll have to determine that first. MIDI times are entirely dependent on the track tempo.
Upvotes: 30