AudioKit:调用后无法重启 AudioKit 频率采样 '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
,内存就会增长,因为它们并没有真正被释放。
这是相同代码思路的第二个版本:
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)
}
}
然后我可以按顺序调用 'second code test':
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
回到信号链中。因此,要重新启动,您需要执行以下操作:
- initMicTracker
- 开始监控
因为您的 stopMonitoring 做了:
- AudioKit.disconnectAllInputs(),即
(stop)MicTracker
您知道您已经为 AKMicrophone
、AKFrequencyTracker
和 AKBooster
创建了实例,将其从内存中释放出来
func stopMonitoring() {
...
self.mic = nil
self.tracker = nil
self.silence = nil
}
我正在使用 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
,内存就会增长,因为它们并没有真正被释放。
这是相同代码思路的第二个版本:
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)
}
}
然后我可以按顺序调用 'second code test':
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
回到信号链中。因此,要重新启动,您需要执行以下操作:
- initMicTracker
- 开始监控
因为您的 stopMonitoring 做了:
- AudioKit.disconnectAllInputs(),即
(stop)MicTracker
您知道您已经为 AKMicrophone
、AKFrequencyTracker
和 AKBooster
创建了实例,将其从内存中释放出来
func stopMonitoring() {
...
self.mic = nil
self.tracker = nil
self.silence = nil
}