Detect MIDI Files bpm

Luis Marques's icon

Hi all,

I'm developing a path to detect bpm from MIDI files, is it possible to detect MIDI files bpm whithout [mxj midifile]?

Thanks

Luis Marques

broc's icon

Strictly speaking, tempo (bpm) is not a property of MIDI files but specified by one or more 'tempo change' events that may appear anywhere in the sequence. The idea is that the player should react on such events while running. Usually there is only one tempo event, but detecting it requires scanning the file on the byte level.

The MIDI file format is documented here

Luis Marques's icon

Thanks for the link :)
I'm already using the [detonate] object to extract all the MIDI events to a [coll]. Do you think I can use this time events extracted to determine the MIDI file bpm?

Luis Marques

Roman Thilenius's icon

detonate can only play notes, but there are about 100 other things in a midi file.

tempo is a meta event, which is elsewhere in the file and like broc said that can
only be found using [filein] and
- comparing the results of bytewise readout (using metro and a counter) against the list "FF 51",
- when you find one, see if the next byte matches "03",
- if yes, read the next three bytes, they are the tempo meta event in BPM.

i think playing a short sequence with detonate and measuring the time using timer is
less difficult and works fine unless you need to batch process.

-110

Roman Thilenius's icon

oh, of course, you can also do it in discrete time right from your coll.

a list of some 30 to 40 delta times of note-on events on the same
channel should immediatley give you something which can be used
to get the BPM using elementary school maths.

-110

dhjdhjdhj's icon

Each MIDI event in a MIDI file is preceded by a delta time in ticks indicating when the event should be "played" relative to the last event that was played. However, the meaning of those ticks cannot be calculated in the absence of tempo information. I believe that in the absence of a tempo event in the file, the tempo starts at 120bpm

If you think about it, suppose you had 4 quarter notes displayed in a music notation score. Without any information to define the tempo, there is simply no way for you to know at what speed you should play those notes.

Roman Thilenius's icon

right, so forget my second posting. i am confused because i use my own music format, which is based on ms. :)

should we now tell him about the possibilty of tempo tracks as an alternative to meta events? or is that too much.

dhjdhjdhj's icon

As you observed earlier, tempo is just a meta event. There's nothing special about a tempo track. If you have a format 0 MIDI file, you don't have separate tracks into which to insert tempo events anyway.

If you're using a format 1 MIDI file, you would typically dedicate a single track to tempo meta events (each preceded by a delta time by the way) unless you want each track to have its own tempo.

Roman Thilenius's icon

i thought that on tempo tracks there can be what we call a tempo change?

well i´ll be giving him my realtime solution tomorrow.

dhjdhjdhj's icon

The implementation of what you are calling a tempo change is just the settempo metaevent that we have been discussing.

The tempo meta event defines a new tempo that should be set at the point it's triggered.

This is a realtime solution.

Roman Thilenius's icon

oh that can be anywhere, i see (it now in your above post)

dhjdhjdhj's icon

Yes, the issue of using a separate track for tempo events is simply one of organization. It's easier to view/edit the entire tempo map if you don't have to process all the other tracks to find tempo events, for example.

Luis Marques's icon

What a great discussion :)

I don't need to get the BPM in real-time, in fact, the [detonate] object can give me the delta time which is stored in the [coll], and I later translate that to beats:bars:units, so it's all offline. I thought if I have the delta time, I could do some math and try to get the BPM, just by using the delta time. The main problem I found is, the MIDI Files events aren't in the exact time (like 0, 250, 500... and so on, they are mostly like 0, 247, 495), which difficult the calculation using delta times... Later I found the [mxj midifile] but I think there is a way to do this :) without using the [mxj midifile].
Do you guys think this is possible?

Luis Marques

dhjdhjdhj's icon

Sigh --- no, it is not possible and it has nothing to do with real-time.

In the absence of an explicit tempo metaevent, there is NO TEMPO information. You can do math all the way to the moon and back, you still won't get tempo information. Those deltas are not delta TIME values, they are delta TICK values. Depending on the resolution, there will be N ticks per beat but beats by themselves say nothing about TIME and so those ticks cannot be converted to time until you define the tempo.

You can convert to bar:beat:tick but that does NOT give you BPM

Luis Marques's icon

What about if we consider first a fake tempo like 120bpm, and try later to predict the real tempo?

Luis Marques

dhjdhjdhj's icon

You still won't be able to predict "real" tempo. With careful analysis (it's non-trivial, e.g, did you double the tempo or are there now 1/8 notes rather than 1/4 notes?) you can detect relative tempo changes but they will be relative to your initial 120bpm.

I don't know how to say this any clearer ---- THERE IS NO REAL TEMPO INFORMATION in the delta tick information that is available.

Luis Marques's icon