[英]AKMetronome countdown, how to publish to main thread from background thread to start recorder?
我一直在研究如何使用 AudioKit 庫實現節拍器倒計時,但遇到了與線程和我的實現相關的問題。
我的實現使用 AudioKit AKMetronome
,這是一種處理metronome.start
的方法。start 和metronome.callback
.callback 處理程序在完成給定數量的小節后開始recording
。
init () {
metronome.callback = handler
}
func record () {
self.metronome.start()
}
處理程序及時計算節拍器 position,如果完成所需的小節數(倒計時),錄音機將啟動。
不幸的是,在 AKMetronome 的.callback handler
中AKMetronome
.record
的AKNodeRecorder
會導致警告消息:
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.
因此,在metronome.callback
.callback 處理程序中開始錄制的調用通過 GCD API 傳遞給主線程:
DispatchQueue.main.sync {
do {
try self.recorder.record()
} catch {
print("[ERROR] Oops! Failed to record...")
}
}
我已經使用.sync
阻塞方法盡可能立即解決計算問題,因為時間在音頻應用程序中至關重要(理想情況下,調用應該在實時線程中執行); 我是否理解 GCP API main thread
提供最高優先級,但我不確定這是否是對時間敏感的應用程序的最佳選擇?
如果可能,希望從其他用戶那里獲得一些反饋或指導,謝謝!
好的,所以實際問題與節拍器或倒計時無關? 你真正想知道的是:從后台線程使用sync
會讓我更快地進入主線程嗎?
如果是這樣:基本上沒有。 這不是sync
的用途或意義。 async
/ sync
差異對速度絕對沒有影響。 如果您使用async
進入主線程,您將在它空閑時立即啟動,因此您說sync
什么也得不到。
此外,如果您已經在async
后台線程中到達回調,那么任何可以造成的損害都已經造成; 你的時間現在是不准確的,除非你的口袋里碰巧有一台時間機器,否則你絕對無能為力。
跟進@matt 關於回調內部調用的建議,我采用的方法基於Timer
的.scheduledTimer
進行了更改。
func record () {
metronome.restart()
Timer.scheduledTimer(withTimeInterval: self.barLength, repeats: false) { _ in
self.startRecording()
print("Timer fired!")
}
}
該record
是一個啟動AKMetronome
的handler
,選擇使用.restart
以便每次請求的時間都從一開始就開始。
屬性.barLength
保存計算the desired countdown
長度的值。 調用的.startRecording
方法是處理 AKRecorder .record
調用的處理程序。
未來的讀者,請記住Timer
並不意味着根據( NSTimer 的准確性)是准確的,但不幸的是,這是我測試過的最好的方法,我發現到目前為止。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.