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?