Question

I want to know how I can receive MIDI tempo (bpm) from host running on my computer (it is simple Ableton Live or Logic Pro) using CoreMidi ?

Does MIDI standards support this feature ? If yes, then please show me Objective C code example. I'm using petegoodliffe-PGMidi to send MIDI. But in this case I want to receive tempo from host.

Thanks.

Was it helpful?

Solution

Believe it or not, there isn't some MIDI message that says "the current tempo is 120BPM". This kind of message wouldn't be very useful anyway, as in most cases, the reason for knowing the current tempo is to synchronize devices, yes? What you have to do is calculate the current tempo based on the timing of the MIDI clock messages.

MIDI clock sync messages are system realtime messages consisting of a single byte, 0xFA (or 1111 1000 in binary). They are sent from the MIDI clock source 24 times per quarter note.

If your BPM is 120, then you will see 2,880 of these messages per minute, or 48 per second. That means that each clock message will be 20.8333 milliseconds apart.

1000 / ((BPM * 24) / 60) = MS_BETWEEN_MESSAGES

To calculate BPM from MIDI clock, you need to know the time in between each clock message. Once you know that, this formula works backwards too. Let's say we know that our messages are about 17.86 ms apart:

(1000 / 17.86 / 24) * 60 = 139.978 BPM

Now, there is a big catch here, and that is realistically, you aren't going to know the exact time between those messages. The amount you will be off varies from system to system, and program to program, but it will be off. Even in a perfect world, there is time for that one byte to be sent over the wire. What I have done in the past is take the average time of the last several messages. This results in a much more stable BPM measurement, but is not without consequence. When the BPM changes rapidly, our measurement of it will lag behind. How you handle this depends on your needs.

All you have to do now is configure Ableton Live to send MIDI clock messages. To do this, go into Preferences, MIDI, and just turn on Sync for the desired MIDI interface.

OTHER TIPS

- (void) midiRead:(const MIDIPacketList *)pktlist{

    MIDIPacket  *packet = MIDIPacketListInit((MIDIPacketList*)pktlist);
    int statusByte = packet->data[0];
    int status = statusByte >= 0xf0 ? statusByte : statusByte >> 4 << 4;

    switch (status) {
        case 0xb0: //cc
            NSLog(@"CC working!");
            break;
        case 0x90: // Note on, etc...
            NSLog(@"Note on/off working!");
            break;
        case 0xf8: // Clock tick
            NSLog(@"clock working!");
            break;
    }

I have a fork of PGMidi with BPM and Quantize calculation. its here: https://github.com/yderidde/PGMidi/blob/master/Sources/PGMidi/PGMidiSession.mm#L186

This said, I'm sure it can be optimized for better and more accurate results and in fact if someone have suggestions to make this even better please let me know !

It is time to have an open source solution for all these basic features that anyone need when creating a coremidi app.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top