7

We are experiencing an exception in our project:

2019-08-08 10:18:28.703708-0600 AppName[99385:5069475] *** Terminating app due to uncaught exception 'com.apple.coreaudio.avfaudio', reason: 'required condition is false: !destNodeMixerConns.empty() && !isDestNodeConnectedToIONode'
*** First throw call stack:
(
    0   CoreFoundation                      0x000000010ee2e8db __exceptionPreprocess + 331
    1   libobjc.A.dylib                     0x000000010e21bac5 objc_exception_throw + 48
    2   CoreFoundation                      0x000000010ee2e662 +[NSException raise:format:arguments:] + 98
    3   AVFAudio                            0x0000000111b94dbc _Z19AVAE_RaiseExceptionP8NSStringz + 156
    4   AVFAudio                            0x0000000111bf3937 _Z11_AVAE_CheckPKciS0_S0_b + 295
    5   AVFAudio                            0x0000000111b8cb8f _ZN18AVAudioEngineGraph8_ConnectEP19AVAudioNodeImplBaseS1_jjP13AVAudioFormat + 1031
    6   AVFAudio                            0x0000000111bfb598 _ZN17AVAudioEngineImpl7ConnectEP11AVAudioNodeS1_mmP13AVAudioFormat + 194
    7   AVFAudio                            0x0000000111bfb5ff -[AVAudioEngine connect:to:format:] + 83
    8   AppName                             0x000000010a424c10 $s8AudioKitAAC6outputAA6AKNodeCSgvWZTf4dd_n + 2576
    9   AppName                             0x000000010a4230fd $s8AudioKitAAC6outputAA6AKNodeCSgvsZ + 93
    10  AppName                             0x000000010a2ba3a3 $s6AppName7MaestroC17setUpTrackPlayers7fileURLy10Foundation0H0V_tF + 1235

Examining the common gotchas video I see a similar exception being thrown, required condition is false: !nodeMixerConns.empty() && !hasDirectConnToIONode, which is caused by allowing the variables to go out of scope rather than be retained in the class.

So this occurs when we create an AKPlayer, which is retained in a class, then we create an AKTimePitch with this player which is also retained in that class, and finally assign that to AudioKit.output which triggers the exception. After that we were storing the class that holds onto the player and time pitch in an array, so I tried to move this up after it's created in hopes that was the issue, but I see the same exception.

Interestingly, this code works fine initially when we load up the first song but crashes when we hit the next button to load up the next song.

final class Maestro : NSObject {
    static let shared = Maestro()

    var audioPlayers = [TrackPlayer]()

    func setUpTrackPlayers(fileURL: URL) {
        let playerOne = TrackPlayer(url: fileURL)
        audioPlayers.append(playerOne)

        AudioKit.output = playerOne.handleMixerChain() //boom

        do {
            try AudioKit.start()
        } catch {
            print("Maestro AudioKit.start error: \(error)")
        }
    }

    func next() {
        for player in audioPlayers {
            player.stop()
        }
        audioPlayers.removeAll()

        setUpTrackPlayers(fileURL: newSong.getFileUrl())
    }
}

final class TrackPlayer {
    let player : AKPlayer
    lazy var timePitch = AKTimePitch()

    init(url: URL) {
        player = AKPlayer(url: url)!
    }

    func handleMixerChain(pitch: Double = 0.0, tempo: Double = 1.0) -> AKTimePitch {
        timePitch = AKTimePitch(player)
        timePitch.pitch = pitch
        timePitch.rate = tempo
        return timePitch
    }
}

Any ideas? If you need any more info let me know. May be good to note we are updating from AudioKit 4.5.5 where we didn't experience this crash.

Jordan H
  • 45,794
  • 29
  • 162
  • 306
  • Its been a while that no one has responded to this issue. I wonder if you either figured it out or if you could provide a sample project link on Github that exhibits this bug. Thanks. – Aurelius Prochazka Aug 27 '19 at 23:19
  • @AureliusProchazka I've created a sample project here: https://github.com/jordanhbuiltbyhq/SamplePlayer To reproduce, `pod install` then run app and tap the Next button. Thanks!! – Jordan H Aug 29 '19 at 19:37
  • Sorry I didn't notice this before but it looks like you're trying to start AudioKit even though its already started. Could that be the issue? – Aurelius Prochazka Sep 22 '19 at 18:13

1 Answers1

7

I've opened the project and it seems like you're being a bit too relaxed about your set up / tear down of the signal chain. You're setting up AudioKit's output using local variables, never tearing down this signal chain, and then coming back resetting the AudioKit output and telling AudioKit to start without ever calling AudioKit.stop().

Aurelius Prochazka
  • 4,100
  • 1
  • 9
  • 34