簡體   English   中英

AudioKit:調用“AudioKit.stop()”后無法重新啟動 AudioKit 采樣頻率

[英]AudioKit: can't restart AudioKit sampling of frequency after calling 'AudioKit.stop()'

我正在使用 AudioKit 4.10。 我使用這個簡單的代碼來采樣麥克風的頻率和幅度:

import AudioKit

protocol MicAnalyzerDelegate {
    /**
     * The MicAnalyzer calls this delegate function.
     */
    func micAnalyzerInfos(infos: (frequency : Double, amplitude : Double)?)
}

class MicAnalyzer: NSObject {

    // MARK: - Properties
    private static var micAnalyzer: MicAnalyzer = MicAnalyzer()
    var delegate: MicAnalyzerDelegate?

    fileprivate var mic: AKMicrophone!
    fileprivate var tracker: AKFrequencyTracker!
    fileprivate var silence: AKBooster!
    fileprivate var timer: Timer?

    // MARK: - Initializations
    private override init() {
        super.init()
        AKSettings.audioInputEnabled = true
        self.initMicTracker()
    }

    private func initMicTracker(){
        /* Add the built-in microphone. */
        mic = AKMicrophone()
        /* Add a traker */
        tracker = AKFrequencyTracker(mic)
        silence = AKBooster(tracker, gain: 0)
    }

    // MARK: - Accessors
    class func shared() -> MicAnalyzer {
        return micAnalyzer
    }

    func startMonitoring() {
        /* Start the microphone and analyzer. */
        AudioKit.output = silence
        do {
            try AudioKit.start()
        } catch {
            AKLog("AudioKit did not start!")
        }

        /* Initialize and schedule a new run loop timer. */
        timer = Timer.scheduledTimer(timeInterval: 0.1,
                                     target: self,
                                     selector: #selector(MicAnalyzer.tick),
                                     userInfo: nil,
                                     repeats: true)
    }

    // Stopped as described here: https://github.com/AudioKit/AudioKit/issues/1716
    func stopMonitoring() {
        do {
            AudioKit.disconnectAllInputs()
            try AudioKit.stop()
            try AudioKit.shutdown()
        } catch {
            print("AudioKit did not stop")
        }
        AudioKit.output = nil

        // Interrupts polling on tick infos
        timer?.invalidate()
        timer = nil
    }

    var infos: (frequency : Double, amplitude : Double)? {
        if(!tracker.isStopped){
            let frequency = tracker.frequency
            let amplitude = tracker.amplitude

            return (frequency: frequency, amplitude: amplitude)
        } else {
            return nil
        }
    }


    /* Call the delegate. */
    @objc func tick() {
        self.delegate?.micAnalyzerInfos(infos: infos)
    }

}

按順序調用以下代碼我有這種情況:

MicAnalyzer.shared().startMonitoring() // --> Everything works good
MicAnalyzer.shared().stopMonitoring()  // --> I think it is stopped correctly
MicAnalyzer.shared().startMonitoring() // --> From now on the delegate is called but I get always 0 as frequency and amplitude

為什么在調用AudioKit.start() (在MicAnalyzer.shared().startMonitoring()內部)后,我不能再對頻率和幅度進行采樣了? 我應該如何重新開始整個事情?


如果我每次重新啟動變量mictrackersilence memory 增長,因為它們沒有真正被釋放。 這是相同代碼理念的第二個版本:

import AudioKit

protocol MicAnalyzerDelegate : class {
    /**
     * The tuner calls this delegate function 
     */
    func micAnalyzerInfos(infos: (frequency : Double, amplitude : Double)?)
}

// https://audiokit.io/examples/MicrophoneAnalysis/
class MicAnalyzer: NSObject {

    // MARK: - Properties
    private weak var delegate: MicAnalyzerDelegate?

    fileprivate var mic: AKMicrophone!
    fileprivate var tracker: AKFrequencyTracker!
    fileprivate var silence: AKBooster!
    fileprivate var timer: Timer?

    // MARK: - Initializations
    init(delegate: MicAnalyzerDelegate) {
        print("Init called!!!")
        self.delegate = delegate
        super.init()
    }

    deinit {
        print("Deinit called!!!")
    }

    // MARK: - Accessors
    func startMonitoring() {
        AKSettings.audioInputEnabled = true
        /* Add the built-in microphone. */
        mic = AKMicrophone()
        /* Add a traker */
        tracker = AKFrequencyTracker(mic)
        silence = AKBooster(tracker, gain: 0)

        /* Start the microphone and analyzer. */
        AudioKit.output = silence
        do {
            try AudioKit.start()
        } catch {
            AKLog("AudioKit did not start!")
        }

        /* Initialize and schedule a new run loop timer. */
        timer = Timer.scheduledTimer(timeInterval: 1,
                                     target: self,
                                     selector: #selector(MicAnalyzer.tick),
                                     userInfo: nil,
                                     repeats: true)
    }

    func stopMonitoring() {
        do {
            AudioKit.disconnectAllInputs()
            try AudioKit.stop()
            try AudioKit.shutdown()
        } catch {
            print("AudioKit did not stop")
        }
        AudioKit.output = nil

        // Interrupts polling on tick infos
        timer?.invalidate()
        timer = nil

        silence.stop()
        silence = nil
        tracker.stop()
        tracker = nil
        mic.stop()
        mic = nil
    }

    var infos: (frequency : Double, amplitude : Double)? {
        if(!tracker.isStopped){
            let frequency = tracker.frequency
            let amplitude = tracker.amplitude

            return (frequency: frequency, amplitude: amplitude)
        } else {
            return nil
        }
    }

    /* Call the delegate. */
    @objc func tick() {
        print(infos?.frequency ?? "0.0")
        //self.delegate.micAnalyzerInfos(infos: infos)
    }

}

然后我可以這樣調用“第二個代碼測試”:

override func viewDidAppear() {
    super.viewDidAppear()
    print("viewDidAppear!!!")
    tuner = Tuner(delegate: self)
    tuner?.startMonitoring()
}

override func viewDidDisappear() {
    super.viewDidDisappear()
    print("viewDidDisappear!!!")
    tuner?.stopMonitoring()
    tuner = nil
}

您需要確保 AKFrequencyTracker 是信號鏈的一部分,因為這是 AVAudioEngine 引擎的要求。

這意味着如果你這樣做:

do {
    AudioKit.disconnectAllInputs()
    try AudioKit.stop()
    try AudioKit.shutdown()
} catch {
   // error handler
}

AudioKit.output = nil

您必須調用initMicTracker才能讓AKFrequencyTracker回到信號鏈中。 所以,要重新啟動你會這樣做:

  • 初始化麥克風跟蹤器
  • 開始監控

因為您的 stopMonitoring 做了:

  • AudioKit.disconnectAllInputs(),表示(stop)MicTracker

您知道您已經為AKMicrophoneAKFrequencyTrackerAKBooster創建了實例,將其從 memory 中釋放出來

func stopMonitoring() {
    ...

    self.mic = nil
    self.tracker = nil
    self.silence = nil
}

暫無
暫無

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

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