簡體   English   中英

AKMetronome 倒計時,如何從后台線程發布到主線程以啟動記錄器?

[英]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 handlerAKMetronome .recordAKNodeRecorder會導致警告消息:

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是一個啟動AKMetronomehandler ,選擇使用.restart以便每次請求的時間都從一開始就開始。

屬性.barLength保存計算the desired countdown長度的值。 調用的.startRecording方法是處理 AKRecorder .record調用的處理程序。

未來的讀者,請記住Timer並不意味着根據( NSTimer 的准確性)是准確的,但不幸的是,這是我測試過的最好的方法,我發現到目前為止。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM