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.
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.
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.
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.
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.
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?
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
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.