midi-json-parser
midi-json-parser copied to clipboard
Determine the total length of a midi file
I've created a function to convert the delta to miliseconds:
const microsecondsPerQuarter = (
midi.tracks[0].find(({ setTempo }) => setTempo).setTempo
).microsecondsPerQuarter;
const deltaToMs = (delta, bpm = 110) =>
(60_000_000 / (bpm * microsecondsPerQuarter)) * delta;
I'm not sure if this is even correct, but it seems to work for now. https://github.com/chrisguttandin/midi-json-parser/issues/305 Says something about divisions but I'm not sure how to use that.
From here, how can I determine the total miliseconds of the midi track in order for a perfect loop?
Assuming you only have one setTempo event for the entire track you could do it like this.
seconds = delta * microsecondsPerQuarter / division / 1000000
Hi thanks for your reply!
Where does delta come from exactly?
My data looks like this:
{
"division": 384,
"format": 1,
"tracks": [
[
{
"timeSignature": {
"denominator": 4,
"metronome": 24,
"numerator": 4,
"thirtyseconds": 8
},
"delta": 0
},
{
"setTempo": {
"microsecondsPerQuarter": 545454
},
"delta": 0
},
{
"endOfTrack": true,
"delta": 0
}
],
[
{
"trackName": "Electric Piano",
"delta": 0
},
{
"programChange": {
"programNumber": 0
},
"channel": 0,
"delta": 0
},
{
"noteOn": {
"noteNumber": 59,
"velocity": 50
},
"channel": 0,
"delta": 0
},
{
"noteOff": {
"noteNumber": 59,
"velocity": 0
},
"channel": 0,
"delta": 96
},
...
{
"endOfTrack": true,
"delta": 0
}
]
]
}
It's the delta of the event. Let's say you want to figure out the time of the noteOff event in your example. Then it would be:
seconds = 96 * 545454 / 384 / 1000000
In other words the first node stops after about 0.136 seconds.
Ah yep I managed to calculate that. But I'm curious to get the entire duration for a perfect loop. For example, if the last note is not at the end of the bar, then there would be some space after of silence
I guess there is no way to derive that information from the file. If you know that your file contains the events for 16 beats you could just use microsecondsPerQuarter * 16 as the length of the loop. But if the last note ends at beat 15 then this will be the end of the MIDI file.
If I can know how many beats my file contains, then that'd be perfect. But I cannot find how to get that information.
Importing the file into Ableton live, it detects the full length correctly. I used this website to write the midi: https://onlinesequencer.net/ And Ableton was able to get the correct lenght of my midi track.
I think the information must be in the file somewhere.
What's the time difference between your last event in the MIDI file and the expected duration that Ableton detects?
I created a midi using onlinesequencer.net.
I marked with a red line where I'd expect the loop to occur, and this is also where Ableton puts the loop (at the end of bar 2):

Maybe Ableton just rounds to the next full bar. You can use the denominator of the timeSignature event to determine how many beats a bar has.
Hmm I'm still trying to figure out how to use the denominator to calculate this.
I'm not pretending that I understood the ins and outs of the timeSignature event. I guess it takes years to understand it completely. :-)
Anyway, as far as I understand a denominator of 4 says a bar has 4 beats. And the microsecondsPerQuarter says a beat is 545454 ticks. When we convert this to seconds using the formula from above we end up with about 136ms.
Given that a bar has 4 beats a bar is about 544ms long. So if we want to end up with a full bar we need to make sure the length is a multiple of 544ms or 2181816 ticks (= 545454 * 4 ticks).
By looking at the image from above I guess the accumulated delta of your last noteOff event is about 3409088 ticks (something close to 545454 * 6.25 ticks).
If you now pick the next multiple of 4 you end up with 8.
Does that make sense?
Thanks so much for this reply! I'm trying it out now. I'm just a little confused why you chose to include the noteOff 96 ticks in the equasion, I guess because it's the last note off in the track?
I'll let you know how I go