MIDI file without tempo or time signature information?

My audio plugin generates temporary .mid files for drag & drop to the DAW timeline.

I want it to be as transparent as possible in regards to tempo and time signature, so I only add note on/off events to the sequence that I write to the .mid file.

But for some reason, when you drag the .mid file into Logic, it asks if you want to import the tempo information, and if you answer “Yes” it will set the tempo to 120 bpm.

I also opened the generated file in MidiYodi, and there it says that the file is in 4/4 and 120 bpm.

I can’t find any “global” tempo or time signature settings in the Juce API.
Is this something that Juce adds behind the scenes, or is it part of the standard that MIDI files without explicit tempo or time signature info should be interpreted as 120bpm 4/4?

I took a closer look at the .mid file in midicsv, and it appears that the file doesn’t contain any tempo or time signature information at all:

0, 0, Header, 1, 1, 960
1, 0, Start_track
1, 960, Note_on_c, 0, 60, 80
1, 1080, Note_off_c, 0, 60, 80
1, 1200, Note_on_c, 0, 60, 80
1, 1320, Note_off_c, 0, 60, 80
1, 2880, Note_on_c, 0, 60, 80
1, 3000, Note_off_c, 0, 60, 80
1, 3000, End_track
0, 0, End_of_file

So I’m guessing that Logic et al simply decides to set some defaults if nothing is stated explicitly in the file? If this is the case, that’s a pretty lousy implementation on their end, I think…

I guess I could read the host tempo and write a tempo event in the beginning of the sequence, but what if the tempo of the song is non-constant? I’d rather not include any tempo information at all.

This is required behavior according to the SMF spec, which sez:

All MIDI Files should specify tempo and time signature. If they don’t, the time signature is assumed to be 4/4, and the tempo 120 beats per minute.

(Standard MIDI File 1.0 spec, p. 5)

2 Likes

Ah, thank you so much for that information!

So I guess we should add tempo and time signature events at the beginning of the midi file, then…

It feels less than ideal since we can only get this information at the current playhead position, and the file can be dragged to anywhere in the timeline of the host. So if there are frequent tempo and/or time signature changes in the song, it could potentially cause problems in those situations.

But since that’s how the MIDI standard is specified, it’s probably best to just follow it. :slight_smile:

Thanks again!

3 Likes

Hi, did you find a way of writing tempo information? I can’t see any obvious calls. thx

Yes! I added a MidiMsg::tempoMetaEvent in the beginning of the MidiMessageSequence. The thing about that event is that you have to state the tempo in microseconds per quarter note. So my code looks like this:

sequence.addEvent(MidiMessage::tempoMetaEvent(static_cast<int>(6.0e7 / bpm));

Simliarily, you use the MidiMessage::timeSignatureEvent to set the time signature, for example timeSignatureEvent(3, 4).

2 Likes