首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >AudioKit:调用'AudioKit.stop()‘后不能重新启动频率的AudioKit采样

AudioKit:调用'AudioKit.stop()‘后不能重新启动频率的AudioKit采样
EN

Stack Overflow用户
提问于 2020-06-05 22:12:02
回答 1查看 133关注 0票数 0

我使用的是AudioKit 4.10。我使用这个简单的代码从麦克风中采样频率和振幅:

代码语言:javascript
复制
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)
    }

}

按照下面的代码调用,我遇到了这种情况:

代码语言:javascript
复制
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时,内存就会增加,因为它们并没有真正被释放。这是同一代码概念的第二个版本:

代码语言:javascript
复制
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)
    }

}

然后我就可以这样把它叫做‘第二个代码测试’,以便:

代码语言:javascript
复制
override func viewDidAppear() {
    super.viewDidAppear()
    print("viewDidAppear!!!")
    tuner = Tuner(delegate: self)
    tuner?.startMonitoring()
}

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

回答 1

Stack Overflow用户

回答已采纳

发布于 2020-06-06 12:17:57

您需要确保AKFrequencyTracker是信号链的一部分,因为这是AVAudioEngine引擎的要求。

也就是说,如果你这样做了:

代码语言:javascript
复制
do {
    AudioKit.disconnectAllInputs()
    try AudioKit.stop()
    try AudioKit.shutdown()
} catch {
   // error handler
}

AudioKit.output = nil

您必须调用initMicTracker才能使AKFrequencyTracker回到信号链中。因此,要重新启动,请执行以下操作:

  • initMicTracker
  • startMonitoring

因为你的stopMonitoring:

  • AudioKit.disconnectAllInputs(),,意思是(stop)MicTracker

您知道,您已经为AKMicrophoneAKFrequencyTrackerAKBooster创建了实例,将其从内存中释放出来。

代码语言:javascript
复制
func stopMonitoring() {
    ...

    self.mic = nil
    self.tracker = nil
    self.silence = nil
}
票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/62224826

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档