Search code examples
iosswiftavfoundationavaudioplayeravaudioengine

AVAudioEngine throws exception when connecting AVAudioPlayerNode to output


All I want to do (for now) is play a sound file using AVAudioEngine and AVAudioPlayerNode. Here's my code:

//Init engine and player
let audioEngine = AVAudioEngine()
let audioPlayerNode = AVAudioPlayerNode()

//Hook them up
audioEngine.attach(audioPlayerNode)
audioEngine.connect(audioPlayerNode, to: audioEngine.outputNode, format: nil) // < error

While executing the last line, an exception is thrown. Nothing is printed to the console and the execution continues, but when I set an exceptional breakpoint I get the following with LLDB:

(lldb) po [$arg1 reason]
error: Execution was interrupted, reason: EXC_BAD_ACCESS (code=1, address=0xffffd593).
The process has been returned to the state before expression evaluation.

What can't be accessed here? I haven't even loaded a file yet... Thanks for any hints.

Environment

  • Xcode 8.2.1
  • iPhone 5 running on iOS 10.3.2 (14F89)

Edit

Here is some more contextual information. The code above is part of an iOS game built with SpriteKit and GameplayKit. It is located in a subclass of GKStateMachine, within a method called playSound. This method is invoked in course of a touch event originating from my subclassed SKScene called GameScene. Upon touchesBegan, the call is delegated to all entities with a TouchComponent that have a method with the same signature (touchesBegan). These components will fire a touchDown event to their delegate, which is in turn my subclass of GKStateMachine called GameStateMachine. If the touch event is correct w.r.t. the game rules, the score property of my GameStateMachine is incremented. Within the score setter, the final method playSound is called if the score increases. Here's a sequence diagram of what I just described:

Sequence Diagram showing how "playSound" is invoked


Solution

  • Apparently, the exception thrown is normal. It occurs under any condition and in any environment I have tested, but does not interfere with normal functionality.

    The reason why no sound was played is that the AVAudioEngine and AVAudioPlayerNode objects were released as soon as the function returned, because they had no strong pointers keeping them alive. I have fixed the issue by keeping those two objects as properties.