Hello,
As a pet project, I'm trying to implement an app that sends different midi clocks to different devices at the same time (to control multiple external sequencers).
Being midi clock signals, the thread where this would run should have ideally a real-time behaviour. With a maximum bpm of 300 per quarter, and 24 midi clock messages per quarter, I need to send a message every 60 / (300 * 24) = 0.00833333333 sec. (to have an acceptable jitter it means the thread loop should run every ~ 0.08ms)
To receive midi messages, it's suggested to use: "the AudioStream data callback in AAudio). Since AMidiOutputPort_receive() is non-blocking, there is very little performance impact." Even with a buffer of 64, for 44.1k sampling, seems that the audio callback would run every 64/44.100 = 0.00145124716 sec, that would give a quite significant jitter for a clock.
To send midi messages, it's said: "Since the timing of the outgoing MIDI data is well understood and controlled by the app itself, the data transmission can be done in the MIDI app's main thread. However, for performance reasons (as in a sequencer) the generation and transmission of MIDI can be done in a separate thread.
Apps can send MIDI data whenever required. Note that
AMidi blocks when writing data."
I don't see using a background thread fulfilling those strict timing requirements, and as far as I understand:
- I cannot set SCHED_FIFO or SCHED_RR,
- I can set the niceness of a thread to -19 using that convoluted trick with JNI but not with pthread_setschedprio (why is that, any differences?)
- I can set the affinity of the processor as done on the megadrone sample of oboe library, function setThreadAffinity, although there is no guarantee i can get an exclusive core.
So my question are:
- how to get the best thread configuration for sending and receiving midi clock signals with the lowest jitter possible?
- do I need multiple threads for different couples of (device, midiport) given that the calls are blocking?
- would the use of the timestamp in AMidiInputPort_sendWithTimestamp be able to mitigate those problems? is there any example how to use correctly the timestamp and any guarantee its mechanism is not implementation dependant?
Thanks,