I’m not surprised that happens especially on Windows. In the docs for hiResTimerCallback()
it says
On some platforms the dedicated timer thread may be shared with
other HighResolutionTimer’s so aim to complete any work in this
callback as fast as possible.
This is referring to Windows in which to get the most accurate timing for the callbacks we need to use a Multimedia Timer, this ultimately means sharing a thread. So I suspect they are called sequentially in the order that they register with the Multimedia Timer, which I think will likely be determined by the order startTimer is called.
I should add as well that any work in a HighResolutionTimer
might well be in direct competition with the audio thread as it will often have the same level of priority!
Therefore I suggest you can do one of the following
-
Avoid HighResolutionTimer altogether, maybe spin up your own Threads, or consider if you really need something so “HighResolution”
-
Move your busy work onto another thread and only use the HighResolutionTimer as a trigger to do the work?
For example you could use a ThreadPool. However, if you do that you have to ask yourself, do you really need a HighResolutionTimer? or would a normal Timer suffice using the same technique?
class MyTimer final : public juce:: HighResolutionTimer
{
public:
~MyTimer() { stopTimer(); }
void hiResTimerCallback() final
{
threadPool.addJob ([]
{
// busy work
});
}
private:
juce::ThreadPool threadPool { juce::ThreadPoolOptions{}
.withDesiredThreadPriority (juce::Thread::Priority::highest)
};
};