Fatal error: AudioKit: Could not start engine. When calling AudioKit.start() - ios

I'm using AudioKit 4.0.4 with iOS 11.2
I'm using a code that is almost the same as the MicrophoneAnalysis sample project.
class FrequencyProcessor {
var node: AKNode {
return mic
}
private let mic: AKMicrophone
private let tracker: AKFrequencyTracker
private let silence: AKBooster
init() {
AKSettings.audioInputEnabled = true
mic = AKMicrophone()
tracker = AKFrequencyTracker(mic)
silence = AKBooster(tracker, gain: 0)
AudioKit.output = silence
}
func startRecording() {
AudioKit.start()
}
}
The code works perfectly in a simulator but I always get this crash when I run it on a device:
Fatal error: AudioKit: Could not start engine. error: Error Domain=com.apple.coreaudio.avfaudio Code=-10875 "(null)" UserInfo={failed call=err = AUGraphParser::InitializeActiveNodesInOutputChain(ThisGraph, kOutputChainOptimizedTraversal, *GetOutputNode(), isOutputChainActive)}.
This happens when I call startRecording.
Any idea what may be causing this issue?
(I have set the "NSMicrophoneUsageDescription" in Info.plist)
edit: The audio recording session happens in a modal view which embeds an AVPlayerLayer. If I remove this AVPlayerLayer I no longer have a crash.
How can I fix this issue?
edit2: I created a sample project here: https://github.com/ydemartino/MicrophoneAnalysisTest.git

It seems AudioKit doesn't want to work with AVKit: https://github.com/AudioKit/AudioKit/issues/1224
As a workaround, this is what I did:
let item = videoPlayer.player.currentItem
videoPlayer.player.replaceCurrentItem(with: nil)
startAudioKit()
videoPlayer.player.replaceCurrentItem(with: item)
Not elegant, but at least, it's no longer crashing my app...

Related

AKManager Audiokit crash: HALB_IOBufferManager_Client::GetIOBuffer: the stream index is out of range

I am running XCode 12.4 and iOS 13.7. The following, straightforward class
import AudioKit
import UIKit
class SoundManager {
private var sampler: AKAppleSampler
private var booster: AKBooster
private var reverb: AKReverb
private let mixer: AKMixer
required init() {
sampler = AKAppleSampler()
booster = AKBooster(sampler, gain: 3.0)
reverb = AKReverb(booster)
mixer = AKMixer()
}
func setup() {
reverb.loadFactoryPreset(.largeRoom)
mixer.connect(input: reverb)
AKManager.output = mixer
try? AKManager.start()
}
}
when called
let soundManager = SoundManager()
soundManager.setup()
crashes with
HALB_IOBufferManager_Client::GetIOBuffer: the stream index is out of
range AQME.h:254:IOProcFailure: AQDefaultDevice (1): output stream 0:
null buffer AQMEIO_HAL.cpp:1774:IOProc: EXCEPTION thrown (-50): error
!= 0
This is something that is crashing on iOS 13.7 simulator but in some 14.x versions doesn't produce a problem. Any idea?
Looks like this problem occurs on iOS 12 & 13 on the simulator but works fine when running on device. Source

Implementing microphone analysis with Audiokit v5

I need to run my app which uses AudioKit as one of its libraries in Xcode 12 so I can prepare it for the upcoming iOS 14 release, since Xcode 12 contains all the changes to classes that need to be adopted by me.
However the current stable release of 4.10.1 does not compile in Xcode 12. I then tried to install the latest v5-develop version 5.0.b1 and that compiles successfully, however the API went through significant changes -> AudioKit.output for example is deprecated. I was unable to find any documentation regarding these changes. I reckon that is because it is still in beta.
I previously used this code I have taken from their microphone analysis example:
func setup(completion: #escaping TaskHandler) {
// Setup the microphone
AKSettings.audioInputEnabled = true
mic = AKMicrophone()
tracker = AKFrequencyTracker(mic)
silence = AKBooster(tracker, gain: 0)
// Start the audio engine
AudioKit.output = silence
do {
try AudioKit.start()
completion(true, nil)
} catch {
completion(false, ErrorMessage.microphoneFailedToStart)
AKLog("AudioKit did not start!")
}
}
and then I access the amplitude and frequency like this:
timer?.setEventHandler(handler: {
let currentAmp = self.tracker.amplitude
let currentFreq = self.tracker.frequency
// ... some processing here
}
In the new version I dug around in Xcode and found and tried to get AKMicrophoneTrackerEngine to work and I got it to compile and run:
let engine = AKMicrophoneTrackerEngine()
func setup(completion: #escaping TaskHandler) {
engine.start()
completion(true, nil)
}
// ..later in code
timer?.setEventHandler(handler: {
let currentAmp = self.engine.amplitude
let currentFreq = self.engine.frequency
// ... some processing here
}
However the frequency (and possibly amplitude) are slightly off. Playing a 1000Hz test tone using 4.10.1 produced exactly 1000 as an output but my new approach produces a value around 918.
Can anyone guide me to a piece of documentation or advise me how to implement the same functionality using the new API?
Thank you.
https://github.com/AudioKit/AudioKit/issues/2267 the issue should be fixed by updating to AudioKit 4.11.1 pod 'AudioKit' , '~> 4.11.1' . This version successfully compiles in Xcode 12. You also need to replace all AudioKit instances with AKManager for example: AudioKit.output = ... with AKManager.output = ...

AudioKit: Red Mic Icon Always Appears When App In Background

I’m having difficulty finding a way to get rid of the red “mic in use” icon at the top of the iPhone when my app goes to background (while not recording). Thus it gives the appearance that the app is always recording even when in the background.
Here’s how I’m initializing the mic in my AudioKitManager class:
// FYI: need to set to playAndRecord here otherwise crashes with “required condition is false: IsFormatSampleRateAndChannelCountValid(format)”
do {
try AVAudioSession.sharedInstance().setCategory(.playAndRecord, mode: .default, options: .allowBluetoothA2DP)
try AVAudioSession.sharedInstance().setActive(true)
} catch {
print(error)
}
mic = AKMicrophone()
let inputBooster = AKBooster(mic)
// boost helps with pitch tracking on some iPads
inputBooster.gain = 5
tracker = AKFrequencyTracker(inputBooster)
tracker.stop() // turned off until it's needed - startPitchTracking() called
micMixer = AKMixer(tracker)
micBooster = AKBooster(micMixer)
micBooster.gain = 0.0
micBooster >>> mixer
print("Setting AudioKit.output = mixer")
AudioKit.output = mixer
AKSettings.playbackWhileMuted = true
AKSettings.defaultToSpeaker = true
AKSettings.sampleRate = 44100
do {
print("Attempting to start AudioKit")
try AudioKit.start()
} catch {
AKLog("AudioKit did not start!")
}
Things I’ve tried:
“Stopping” and “starting” the mic when the recording vc appears/disappears. e.g. mic.stop() - Red icon still shows even when mic stopped.
Setting the AVAudioSessionCatagory to and from playAndRecord and .play as recording vc appears/disappears. Really thought this would work!… but the Red Icon of Terror still stares back at me and into my soul.
Calling: AKSettings.audioInputEnabled = false. - Red icon still indicated mic input is enabled.
Only initializing the mic when needed. (Tried this a while ago: seem to remember it was a total no-go)
Dressing as David Bowie and singing “Starman” loudly into mic before app goes to background. Probably should have been the first thing to try, but still to no avail.
Various combinations of above
Any help much appreciated! Thx!
Kudos to AudioKit - it’s an amazing framework! :^)
AudioKit: 4.5.4
iOS: 12.1
Xcode: 10.1
Aha. The solution is to call audioKit.stop() when the app goes to background. Then audioKit.start() before it's used again!! Goodbye red mic icon. Goodbye.
I'd overlooked this previously because I'd been experiencing a lot of issues whenever stopping and starting audio kit. However (as I mentioned in this post Continuous Sine Wave From AKMIDISampler when AKMicrophone is Present ) the main problem was fixed by reloading the samples into all samplers AFTER Audio Kit is started again.
Wheew.

AudioKit 4.1 - How to properly stop AKSampler from playing audio?

I have 2 AKSamplers that are connected to an AKMixer but when I call the stop function for each AKSampler, the audio does not stop playing it only stops when I call the stop of the AKMixer. How do I stop playing an AKSampler which is connected to an AXMixer?
Sample Code:
func stop() {
let sampler1 = AKSampler()
let sampler2 = AKSampler()
let mixer = AKMixer(sampler1, sampler2)
AudioKit.output = mixer
do {
try sampler1.loadWav("Support Objects/audio")
try sampler2.loadWav("Support Objects/audio")
} catch {
return
}
do {
try AudioKit.start()
} catch let error as NSError{
print(error.debugDescription)
}
sampler1.play(noteNumber: //some midi number)
sampler2.play(noteNumber: //some midi number)
sampler1.stop() // does not stop sampler1 from playing
}
A preferred method to stop notes with AKSampler is to stop the specific AKSampler note that was previously started.
For example:
sampler1.play(noteNumber: yourMIDINoteNumber)
...
sampler1.stop(noteNumber: yourMIDINoteNumber)
Should successfully stop the AKSampler.

Crash when setting AudioKit output node on iPhone 5s

I get a consistent crash whenever I set AudioKit output to a mixer node. The crash happens on an iPhone 5s running iOS 10.3.3, but NOT on an iPhone 7 running iOS 11.3.
The code I'm running (setting up a recording view):
mic = AKMicrophone()
mic.stop()
fft = AKFFTTap.init(mic)
micMixer = AKMixer(mic)
micBooster = AKBooster(micMixer)
micBooster.gain = 0
do {
recorder = try AKNodeRecorder(node: micMixer)
if let file = recorder.audioFile {
player = try AKAudioPlayer(file: file)
player.looping = false
player.completionHandler = playingEnded
}
mainMixer = AKMixer(player, micBooster)
AudioKit.output = mainMixer //THIS IS WHERE IT CRASHES!
}
catch {
//debug prints here don't get printed
throw error
}
The catch block is never called, an error is not thrown.
Crash details in logs:
ERROR: [0x1b12c0b40] >avae> AVAudioIONodeImpl.mm:466: EnableBus_block_invoke: error -10849
*** Terminating app due to uncaught exception 'com.apple.coreaudio.avfaudio', reason: 'error -10849'
Any help or information would be appreciated!
You can’t create a player with a file that is being recorded.
I'm not sure this is the cause, but I was starting the AudioKit engine in another piece of code before that I missed. When I moved the AudioKit.start() call after the AudioKit.output = .... call, it doesn't crash.

Resources