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.
Related
I keep getting this pesky error on init sometimes. It occurs for a while and sometimes it goes away. I am not sure what is the problem. Please help. Details below
Terminating app due to uncaught exception 'com.apple.coreaudio.avfaudio', reason: 'required condition is false: IsFormatSampleRateAndChannelCountValid(format)'
The stack trace points to this piece of init() code.
init() {
guard let AK52_input = AK52_engine.input else {
fatalError()
}
do {
AK52_recorder = try NodeRecorder(node: AK52_input)
} catch let err {
fatalError("\(err)")
}
let silencer = Fader(AK52_input, gain: 0)
self.AK52_silencer = silencer
AK52_mixer.addInput(silencer)
AK52_mixer.addInput(AK52_player)
AK52_engine.output = AK52_mixer <----- error pops from here
}
And this code is identical to the one in the AudioCookbook. Infact, I see the same error when I run AudioCookbook too.
Please help.
thanks,
-Vittal
AudioKit 4.9.3
iOS 11+
I am working on a project where the user is recording on the device using the microphone and it continues to record, even if the app is in the background. This works fine but when receiving a phone call I get an AudioKit error. I assume it has something to do with the phone taking over the mic or something. here is the error:
[avae] AVAEInternal.h:109
[AVAudioEngineGraph.mm:1544:Start: (err = PerformCommand(*ioNode,
kAUStartIO, NULL, 0)): error 561017449
AudioKit+StartStop.swift:restartEngineAfterRouteChange(_:):198:error
restarting engine after route change
basically everything that i have recording up until that point is lost.
here is my set up AudioKit code:
func configureAudioKit() {
AKSettings.audioInputEnabled = true
AKSettings.defaultToSpeaker = true
do {
try try audioSession.setCategory((AVAudioSession.Category.playAndRecord), options: AVAudioSession.CategoryOptions.mixWithOthers)
try audioSession.setActive(true)
audioSession.requestRecordPermission({ allowed in
DispatchQueue.main.async {
if allowed {
print("Audio recording session allowed")
self.configureAudioKitSession()
} else {
print("Audio recoding session not allowed")
}
}
})
} catch let error{
print("Audio recoding session not allowed: \(error.localizedDescription)")
}
}
func configureAudioKitSession() {
isMicPresent = AVAudioSession.sharedInstance().isInputAvailable
if !isMicPresent {
return
}
print("mic present and configuring audio session")
mic = AKMicrophone()
do{
let _ = try AKNodeRecorder(node: mic)
let recorderGain = AKBooster(mic, gain: 0)
AudioKit.output = recorderGain
//try AudioKit.start()
}
catch let error{
print("configure audioKit error: ", error)
}
}
and when tapping on the record button code:
do {
audioRecorder = try AVAudioRecorder(url: actualRecordingPath, settings: audioSettings)
audioRecorder?.record()
//print("Recording: \(isRecording)")
do{
try AudioKit.start()
}
catch let error{
print("Cannot start AudioKit", error.localizedDescription)
}
}
Current audio Settings:
private let audioSettings = [
AVFormatIDKey : Int(kAudioFormatMPEG4AAC),
AVSampleRateKey : 44100,
AVNumberOfChannelsKey : 2,
AVEncoderAudioQualityKey : AVAudioQuality.medium.rawValue
]
What can I do to ensure that I can get a proper recording, even when receiving a phone call? The error happens as soon as you receive the call - whether you choose to answer it or decline.
Any thoughts?
I've done work in this area, I'm afraid you cannot access the microphone(s) while a call or a VOIP call is in progress.
This is a basic privacy measure that is enforced by iOS for self-evident reasons.
AudioKit handles only the basic route change handling for an audio playback app. We've found that when an app becomes sufficiently complex, the framework can't effectively predestine the appropriate course of action when interruptions occur. So, I would suggest turning off AudioKit's route change handling and respond to the notifications yourself.
Also, I would putting AudioKit activation code in a button.
I am using EZaudio to play mp3 files and it works on iOS 12 and below but on physical Device (iPhone X) running iOS 13 app crashed and console print error
Error : Failed to fill complex buffer in float converter
I am using Audiokit and PandoraPlayer framework
what may cause this error and how to fix this ?
I'm using this code to configure avaudiosession and it works fine on iOS 12 and below
private func configureAudio() {
do {
try AVAudioSession.sharedInstance().setCategory(.playback, mode: .default)
try AVAudioSession.sharedInstance().setActive(true)
updateCommandCenter()
} catch {
print(error)
}
AKSettings.playbackWhileMuted = true;
AKSettings.enableRouteChangeHandling = true
}
I think EZAudioFloatConverter and microphone may cause this problem but I am not using microphone in my app
This worked for me: In AudioKit I changed in file EZOutput.m constant : Float64 const EZOutputDefaultSampleRate = 48000.0f. By default this constant is 44100.0f
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.
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...