Crash in AVAudioEngine.start() even though it's wrapped in do/catch
Asked Answered
E

2

17

I have the following code to (re)start AVAudioEngine wired up to AVAudioEngineConfigurationChangeNotification:

   do {
       try self.engine.start()
   } catch {
       DDLogError("could not start sound engine")
       self.soundEnabled = false
       return
   }

self.engine is defined as

private let engine = AVAudioEngine()

However, I frequently receive crash reports via Crashlytics saying

Fatal Exception: com.apple.coreaudio.avfaudio error 561015905

on the line containing the try self.engine.start().

561015905 is AVAudioSessionErrorCodeCannotStartPlaying and from what I understand, this should be a NSError error code, not an exception, which should be caught by my blank catch in the code above. Still, the app just seems to crash at that point. What am I missing?

I know there are situations where the app wakes up in the background where this error can occur and I would be fine with that, as long as I can somehow catch it happening, as I thought I could with do/catch.

Edbert answered 14/12, 2015 at 13:16 Comment(4)
I get a similar error. Did you figure out why this was happening?Caracara
No. I've opened a bug report with Apple but haven't received a response yet. Meanwhile I stopped using AVAudioEngine.Edbert
@Edbert any updates on this? Did you find a better work around than sleep()? And did you hear from Apple at all? This is still a problem in iOS 11 by the looks of it.Sumptuous
As I already said, we've stopped using AVAudioEngine because of this bug. Apple has since asked us to reproduce the bug with newer iOS versions (and automated message sent to open reports when new SDK versions are released) but since the issue is no longer of interest to us, we didn't do so. Meaning if you still care, you should probably open your own bug report. Sorry I couldn't be of more help, good luck tackling this. If you ever do, I'd love to hear back!Edbert
G
6

Xcode Version 9.2 (9C40b) + Swift 4 : I know this question is a little old, however, I was having the same crashing issues with audioEngine.start() even though in a do/try/catch and also receiving the following from Crashalytics:

Fatal Exception: com.apple.coreaudio.avfaudio error 561015905

S1LENT WARRIOR's sleep(1) "hack" worked in some cases, but not all (specifically with AVAudioEngineConfigurationChangeNotification selector).

Finally, I used Obj-C exception handling to really catch the error so no crash occurs, from this very useful post by freytag (big thanks!):

Catching NSException in Swift

Now, after implementing the ObjC .h and .m files and the bridging header, I do:

do {
    try ObjC.catchException {
        try! self.audioEngine.start()
    }
}
catch {
    print("An error occurred: \(error)")
}

You can test this by screwing up the engine initialization (eg don't .attach or .connect anything) and no crash... only:

2018-01-06 10:01:48.890801+0700 XXXXXX[16389:3367770] [avae] AVAEInternal.h:70:_AVAE_Check: required condition is false: [AVAudioEngineGraph.mm:1209:Initialize: (inputNode != nullptr || outputNode != nullptr)] An error occurred: Error Domain=com.apple.coreaudio.avfaudio Code=0 "(null)"

Make sure you check the audioEngine is running before using it, something like:

func play(soundName: String) {
    if !audioEngine.isRunning {
        return
    }
    // play sound
 }

OK, so you get no sound but it is a "graceful fail".

Seems ridiculous that in Swift you can't properly catch an exception, and ok if you're going to make some exceptions not catchable then at least provide a method to test first, something like audioEngine.areYouConfiguredProperly(). Oh hang on there is this method (in Obj-C) [AVAudioEngine startAndReturnError:] but someone decided to wrap it with the startEngine() function and do away with all useful functionality... doh.

Gove answered 6/1, 2018 at 3:10 Comment(0)
C
5

I encountered the same error when handling AVAudioSessionInterruption notification.
In my case, the error was arising when i tried to start AVAudioEngine after the interruption ended.
After detailed testing and debugging for a while, i noticed the app wasn't crashing if i introduce a debugger breakpoint before audioEngine.prepare() or audioEngine.start().
So i added sleep(1) before audioEngine.start() and my app stopped crashing!

I know its not a very elegant solution but still hope this may help someone else!

Conjectural answered 8/10, 2016 at 20:6 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.