MIDI clock
Table of Contents
:ID: 24E1468A-279A-4B44-8AB8-A8A1C5D8D42D
See also MIDI messages
# Clock Message
- 24 messages = 1 quarter note.
- When 24 clock messages are received, the receiving MIDI device knows that 1 quarter note has passed.
- To generate a MIDI clock signal, calculate the pulse rate based on the BPM and send a simple message at that rate.
# Formula
# Pulse per ms rate
1 minute = 60 seconds = 60,000 ms
60,000 ms / ppq * bpm
Example using 120 BPM:
ppq = 24.0 bpm = 120.0 ppms = 60_000 / (ppq * bpm) "One pulse every #{ppms} ms"
One pulse every 20.833333333333332 ms
# Message Contents
# Status
0xF8
There is no channel number.
# Data
No data is required for this message, just the status byte
# Sequencing
# MIDI Start
# MIDI Stop
# MIDI Continue
# Sending MIDI Clock from Mixxx
# Existing Limitation
Mixxx only supports a 20ms resolution timer. This will work for BPMs under 100 so it’s not practical. See ControllerScriptInterfaceLegacy::beginTimer. It uses QObject startTimer which only supports using MS. This need microsecond precision.
🚨*See Arduino below*
# Possible solution
See https://stackoverflow.com/a/21856299.
This would require adding a high resolution timer. Maybe an API like
engine.beginHighResTimer
.
- Other references
- https://github.com/99x/timercpp/blob/master/timercpp.h
- This is not thread safe.
- Maybe it could be adapted to use
std::chrono::microseconds
- See also https://en.cppreference.com/w/cpp/thread/sleep_for
- https://blat-blatnik.github.io/computerBear/making-accurate-sleep-function/
- The naive approach of using
std::this_thread::sleep_for
is grossly inaccurate. This nice post explains why and some alternative approaches.
- The naive approach of using
- https://github.com/99x/timercpp/blob/master/timercpp.h
# RtMidi
https://www.music.mcgill.ca/~gary/rtmidi/
C++ Library for sending/receiving MIDI messages.
# Needs jack2 development files
In order to develop stuff depending on RtMidi and compiling for JACK, you’ll need the jackd2 development files:
sudo apt-get install libjack-jackd2-dev
# Arduino
The Mixxx midi clock thing ain’t gonna work unless I use an external device to generate the midi clock signal based on beat data from a controller mapping script running in Mixxx’s JS engine. Some data that would be helpful:
- beat_active: On every beat_active send the BPM and beat_distance to compute the clock PPQ and when the clock should start. The BPM value from Mixxx’s engine is up to several decimal places, but probably only need accuracy rounded to the nearest hundredth. The BPM value can be sent with two separate midi messages (due 0-127 limitation). One message containing the whole number part and one with the fractional part.
- beat_distance: With the BPM accurate to two decimal places, might be able to predict where the next beat will happen and therefore when to start the clock.
- bpm: See beat_active.
- sync_leader: I use Mixxx in external mixer mode. Properties like play_latched probably won’t work and I’ll need to explicitly set a sync_leader and only get BPM data from it.
See also https://www.youtube.com/watch?v=hSNHhLqYp_o who appears to have accomplished this.