I've been looking into how to implement a Metronome countdown with the AudioKit lib but ran into an issue related to threads and my implementation.
My implementation uses the AudioKit AKMetronome, a method to handle the metronome.start and the metronome.callback handler to start recording after a given number of bars are completed.
init () {
metronome.callback = handler
}
func record () {
self.metronome.start()
}
The handler computes the metronome position in time and if the desired number of bars completes (countdown), the recorder starts.
Unfortunately, running the .record of AKNodeRecorder in the .callback handler of AKMetronome causes the warning message:
Publishing changes from background threads is not allowed; make sure to publish values from the main thread (via operators like receive(on:)) on model updates.
For that reason, the call to start recording in the metronome.callback handler is passed to the main thread through the GCD API:
DispatchQueue.main.sync {
do {
try self.recorder.record()
} catch {
print("[ERROR] Oops! Failed to record...")
}
}
I've used the .sync blocking method to resolve the computation immediately as possible since timing is critical in audio applications (the call should be executed in a real-time thread, ideally). Is my understanding that the GCP API main thread provides the highest priority, but I'm not certain if that's the best option for a time-sensitive application?