![](/img/trans.png)
[英]AudioKit: Can I disable an AKMicrophone without calling AudioKit.stop()?
[英]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()
內部)后,我不能再對頻率和幅度進行采樣了? 我應該如何重新開始整個事情?
如果我每次重新啟動變量mic
, tracker
和silence
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 做了:
(stop)MicTracker
您知道您已經為AKMicrophone
、 AKFrequencyTracker
和AKBooster
創建了實例,將其從 memory 中釋放出來
func stopMonitoring() {
...
self.mic = nil
self.tracker = nil
self.silence = nil
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.