Yesterday I asked a question about How to read the bytes that store the time signature data, but now what I'm having trouble with is time signatures displayed in frames per second. for example, I have a MIDI file with the header 4d54 6864 0000 0006 0001 0008 0180
which has it's time signature in frames per second. Following the instructions in the answer linked above, I tried to separate the bytes to find the SMPTE format and the frames per second, but thus far I've had no luck. If this MIDI file turns out to be indeed in metrical timing (eg. ticks per quarter note) than an example of how to parse a time code in frames per second would be greatly appreciated.

- 546
- 2
- 19
1 Answers
The 0x0180
in your example is ticks per quarter note. (High bit unset indicates this format, as opposed to SMPTE).
To turn that into absolute timing, you'll need to look for Set Tempo (0x51) meta events.
Those typically (always?) are in the first MTrk chunk, and will look something like this:
0xff 0x51 0x03 0x11 0x22 0x33
...indicating a tempo of 0x112233
microseconds per quarter-note.
Given ticks-per-quarter-note from MThd and microseconds-per-quarter-note from MTrk, you can calculate the absolute timing of a tick. Mind that this should change, if another Set Tempo event appears.
The spec says this about SMPTE timing:
If bit 15 of is a one, delta-times in a file correspond to subdivisions of a second, in a way consistent with SMPTE and MIDI time code. Bits 14 thru 8 contain one of the four values -24, -25, -29, or -30, corresponding to the four standard SMPTE and MIDI time code formats (-29 corresponds to 30 drop frame), and represents the number of frames per second. These negative numbers are stored in two's complement form. The second byte (stored positive) is the resolution within a frame: typical values may be 4 (MIDI time code resolution), 8, 10, 80 (bit resolution), or 100. This system allows exact specification of time-code-based tracks, but also allows millisecond-based tracks by specifying 25 frames/sec and a resolution of 40 units per frame. If the events in a file are stored with bit resolution of thirty-frame time code, the division word would be E250 hex.
...basically, the high byte is frames-per-second and low byte is ticks-per-frame.

- 358
- 1
- 5
-
Yes, but what about if MThd is noted in absolute timing? how to do convert that into ticks per beat? From what I understand, you're explanation only applies to type 2 MIDIs, as type 0 would have tempo data at the beginning of the track and type 1 would have the first MTrk as a global tempo track. – 3ddavies Dec 30 '19 at 22:17
-
Updated answer with SMPTE. In Type 2, you'd probably find a Set Tempo on each track, I'm not sure. Files I've dealt with have all been Type 1 with ticks-per-qnote in the MThd. – aksommerville Dec 30 '19 at 22:29
-
Ok so if I have `03c0` that appears to be in frames per second as the decimal value is 960, but the first bit is a zero. – 3ddavies Dec 30 '19 at 22:34
-
`03c0` is still ticks-per-qnote. `0000`-`7fff` are ticks-per-qnote, and `8000`-`ffff` are SMPTE. – aksommerville Dec 30 '19 at 22:40
-
So if `03c0` is in ticks-per-qnote then how many ticks per qnote is it bc the decimal value is 960 (sorry I'm v confused) – 3ddavies Dec 30 '19 at 22:48
-
960. Then take the microseconds-per-qnote from Set Tempo to find the duration of one tick, eg: `millisecondsPerTick = microsecondsPerQnote / (ticksPerQnote * 1000)` – aksommerville Dec 30 '19 at 22:53
-
Ahh that makes sense.. the only other thing is where do I find Set Tempo? I'm assuming that's at the beginning of the track for type 0 and in the Global Tempo track for type 1? – 3ddavies Dec 30 '19 at 22:57
-
Common sense says there should be a Set Tempo at time zero in the first track, but I think they can appear anywhere. Don't assume that it's the first event, though. You should read all the time-zero events for every track before starting playback. – aksommerville Dec 30 '19 at 22:59
-
Once I've read all time zero events how do I know which is Set Tempo? Is there some sort of identifier? – 3ddavies Dec 30 '19 at 23:00
-
Yes: `0xff` introduces a Meta Event, followed by `0x51` meaning Set Tempo, then its length `0x03`, then the 3-byte payload. – aksommerville Dec 30 '19 at 23:01