See also MIDI messages
- 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.
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"
0xF8
There is no channel number.
No data is required for this message, just the status byte
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*
See https://stackoverflow.com/a/21856299.
This would require adding a high resolution timer. Maybe an API like
engine.beginHighResTimer
.
- 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://www.music.mcgill.ca/~gary/rtmidi/
C++ Library for sending/receiving MIDI messages.
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
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:
- [[https://manual.mixxx.org/2.3/en/chapters/appendix/mixxx_controls#control-\[ChannelN\]-beat_active][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.
- [[https://manual.mixxx.org/2.3/en/chapters/appendix/mixxx_controls#control-\[ChannelN\]-beat_distance][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.
- [[https://manual.mixxx.org/2.4/en/chapters/appendix/mixxx_controls#control-\[ChannelN\]-sync_leader][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.
https://www.pjrc.com/teensy/td_libs_TimerOne.html