agree with @murray. also i would guess that using a timer in itself is just fine unless your timing requirements are really strong. (you didn’t really say who is receiving the OSC.) but as pointed out, this isn’t really a problem with timer resolution per se.
in Qt, you want to create a timer with Qt::PreciseTimer property, and move it to a dedicated QThread.
your QML stuff is going to be one bottleneck, so timing-wise the main thread really must be isolated from the “realtime” stuff (no locks on shared resources, &c). use atomics to write parameters from QML, or look into things like boost::lockfree::spsc_queue to get data from UI to the “realtime” thread.
the OSC tx side could itself be another bottleneck depending on how much data you’re sending on each tick.
in any case, the Tx should happen with stored outputs from previous tick every time the timer thread raises a Tx event (which in this case could be something as simple as an atomic bool.)
after tx’ing last frame’s data, start working on new frame. none of this should happen in Qts main thread. whether its more effective to have two threads:
or just
depends on stuff like parallelizability (?) and size of working memory.
i would probably consider just doing the timing and calculation stuff in a separate process, not using Qt at all. for that. the simplest answer is to just use std::this_thread::sleep_for(std::chrono::nanoseconds(...)) on a dedicated timer thread. i would only get more complicated than this if it is shown to be necessary in a stripped down test case with appropriate threading architecture. (the next level of complication would be to manage the timer thread’s priority, which is not a capability of the c++ standard library.)
my knee-jerk reaction is that using an audio timer for this feels like overkill, especially because your sink is a network endpoint and you’re not going to get sub-millisecond accuracy there anyways. (of course the balance of that consideration changes if you are already running a low-level audio process.)