1

I have the following Swift playground code that plays an audio file using AVAudioPlayerNode.

import AVFoundation
import Foundation

NSSetUncaughtExceptionHandler { exception in
    print("Exception thrown: \(exception)")
}

var filePath = "/Users/fractor/Desktop/TestFile.mp3"
let file : AVAudioFile
do {
    file = try AVAudioFile(forReading: URL(fileURLWithPath: filePath))
} catch let error {
    print(error.localizedDescription)
    throw error
}

let audioEngine = AVAudioEngine()
let playerNode = AVAudioPlayerNode()
audioEngine.attach(playerNode)
audioEngine.connect(playerNode, to: audioEngine.outputNode, format: file.processingFormat);

do {
    try audioEngine.start()
} catch let error {
    print(error.localizedDescription)
    throw error
}

playerNode.scheduleFile(file, at: nil){}
playerNode.play();

This works fine on my mac mini when using the inbuilt speaker or when connected to a UE WONDERBOOM bluetooth speaker. However it crashes when connected to a UE BOOM 2 bluetooth speaker.

Using AVAudioPlayer works fine with all speakers I have tried including the UE BOOM 2.

The exception message is "player started when engine not running" however inserting print commands shows that the engine is running prior to playerNode.play() being called.

Here's (part of) the stack trace.

Stack trace

What does EXC_BAD_INSTRUCTION indicate in this case?

To remove the possibility of erroneous behaviour being introduced due to using a Swift playground, I have also created a Swift macOS Cocoa app. Here is the code:

class ViewController: NSViewController {

    let filePath = "/Users/fractor/Desktop/TestFile.mp3"
    var file : AVAudioFile?
    var audioEngine = AVAudioEngine()
    var playerNode = AVAudioPlayerNode()

    override func viewDidLoad() {
        super.viewDidLoad()

        do {
            file = try AVAudioFile(forReading: URL(fileURLWithPath: filePath))
        } catch let error {
            print(error.localizedDescription)
            return
        }

        audioEngine.attach(playerNode)
        audioEngine.connect(playerNode, to: audioEngine.outputNode, format: file!.processingFormat);

        do {
            try audioEngine.start()
        } catch let error {
            print(error.localizedDescription)
            return
        }

        playerNode.scheduleFile(file!, at: nil){}

        print("audioEngine.isRunning = \(audioEngine.isRunning)");
        playerNode.play();
        print("playerNode.isPlaying = \(playerNode.isPlaying)");
    }
}

This fails to play when connected to the UE BOOM 2 speaker with the following errors:

2019-07-23 13:32:50.784444+0100 AVAudioPlayerNodeSwiftTest[1757:29297] [AudioHAL_Client] HALC_ProxyIOContext.cpp:958:IOWorkLoop:  HALC_ProxyIOContext::IOWorkLoop: the server failed to start, Error: 0xE00002D6
2019-07-23 13:32:51.696089+0100 AVAudioPlayerNodeSwiftTest[1757:29249] Failed to set (contentViewController) user defined inspected property on (NSWindow): player started when engine not running
2019-07-23 13:32:53.815222+0100 AVAudioPlayerNodeSwiftTest[1757:29448] [AudioHAL_Client] HALC_ProxyIOContext.cpp:958:IOWorkLoop:  HALC_ProxyIOContext::IOWorkLoop: the server failed to start, Error: 0xE00002D6

Again this works fine with the WONDERBOOM speaker and the inbuilt speaker.

I manage to get an exception trace if I call play on a background thread using the following code:

DispatchQueue.global(qos: .background).async {
    print("audioEngine.isRunning = \(self.audioEngine.isRunning)");
    self.playerNode.play();
    print("playerNode.isPlaying = \(self.playerNode.isPlaying)");
}

The full output being:

audioEngine.isRunning = true
2019-07-24 12:25:38.710647+0100 AVAudioPlayerNodeSwiftTest[1852:21353] [AudioHAL_Client] HALC_ProxyIOContext.cpp:958:IOWorkLoop:  HALC_ProxyIOContext::IOWorkLoop: the server failed to start, Error: 0xE00002D6
2019-07-24 12:25:40.717683+0100 AVAudioPlayerNodeSwiftTest[1852:21340] [General] An uncaught exception was raised
2019-07-24 12:25:40.717738+0100 AVAudioPlayerNodeSwiftTest[1852:21340] [General] player started when engine not running
2019-07-24 12:25:40.717865+0100 AVAudioPlayerNodeSwiftTest[1852:21340] [General] (
    0   CoreFoundation                      0x00007fff2d017cfd __exceptionPreprocess + 256
    1   libobjc.A.dylib                     0x00007fff576bea17 objc_exception_throw + 48
    2   CoreFoundation                      0x00007fff2d032a1a +[NSException raise:format:arguments:] + 98
    3   AVFAudio                            0x00007fff291f2304 _Z19AVAE_RaiseExceptionP8NSStringz + 156
    4   AVFAudio                            0x00007fff29247d8c _ZN21AVAudioPlayerNodeImpl9StartImplEP11AVAudioTime + 1282
    5   AVFAudio                            0x00007fff29246b48 -[AVAudioPlayerNode play] + 75
    6   AVAudioPlayerNodeSwiftTest          0x0000000100002924 $s26AVAudioPlayerNodeSwiftTest14ViewControllerC11viewDidLoadyyFyycfU0_ + 644
    7   AVAudioPlayerNodeSwiftTest          0x0000000100002b8d $s26AVAudioPlayerNodeSwiftTest14ViewControllerC11viewDidLoadyyFyycfU0_TA + 13
    8   AVAudioPlayerNodeSwiftTest          0x00000001000025dd $sIeg_IeyB_TR + 45
    9   libdispatch.dylib                   0x000000010034fe7c _dispatch_call_block_and_release + 12
    10  libdispatch.dylib                   0x0000000100350f1b _dispatch_client_callout + 8
    11  libdispatch.dylib                   0x0000000100363a06 _dispatch_root_queue_drain + 816
    12  libdispatch.dylib                   0x00000001003642da _dispatch_worker_thread2 + 125
    13  libsystem_pthread.dylib             0x00000001003ca0b7 _pthread_wqthread + 583
    14  libsystem_pthread.dylib             0x00000001003c9e01 start_wqthread + 13
)
2019-07-24 12:25:40.718570+0100 AVAudioPlayerNodeSwiftTest[1852:21340] *** Terminating app due to uncaught exception 'com.apple.coreaudio.avfaudio', reason: 'player started when engine not running'
*** First throw call stack:
(
    0   CoreFoundation                      0x00007fff2d017cfd __exceptionPreprocess + 256
    1   libobjc.A.dylib                     0x00007fff576bea17 objc_exception_throw + 48
    2   CoreFoundation                      0x00007fff2d032a1a +[NSException raise:format:arguments:] + 98
    3   AVFAudio                            0x00007fff291f2304 _Z19AVAE_RaiseExceptionP8NSStringz + 156
    4   AVFAudio                            0x00007fff29247d8c _ZN21AVAudioPlayerNodeImpl9StartImplEP11AVAudioTime + 1282
    5   AVFAudio                            0x00007fff29246b48 -[AVAudioPlayerNode play] + 75
    6   AVAudioPlayerNodeSwiftTest          0x0000000100002924 $s26AVAudioPlayerNodeSwiftTest14ViewControllerC11viewDidLoadyyFyycfU0_ + 644
    7   AVAudioPlayerNodeSwiftTest          0x0000000100002b8d $s26AVAudioPlayerNodeSwiftTest14ViewControllerC11viewDidLoadyyFyycfU0_TA + 13
    8   AVAudioPlayerNodeSwiftTest          0x00000001000025dd $sIeg_IeyB_TR + 45
    9   libdispatch.dylib                   0x000000010034fe7c _dispatch_call_block_and_release + 12
    10  libdispatch.dylib                   0x0000000100350f1b _dispatch_client_callout + 8
    11  libdispatch.dylib                   0x0000000100363a06 _dispatch_root_queue_drain + 816
    12  libdispatch.dylib                   0x00000001003642da _dispatch_worker_thread2 + 125
    13  libsystem_pthread.dylib             0x00000001003ca0b7 _pthread_wqthread + 583
    14  libsystem_pthread.dylib             0x00000001003c9e01 start_wqthread + 13
)
libc++abi.dylib: terminating with uncaught exception of type NSException

Again, no problem if using the WONDERBOOM or built in speaker.

People are also having a problem here: https://forums.developer.apple.com/thread/118459

AudioKit also crashes: AudioKit macOS HelloWorld crashes with UE BOOM 2 speaker

AVAudioPlayer is not sufficient for the application I am developing. What is the problem? Presumably since it throws an exception, it is a bug in Apple code?

fractor
  • 1,534
  • 2
  • 15
  • 30
  • @matt It is real code in a swift playground so does not require methods. It plays the audio fine except when the UE Boom 2 speaker is connected. Not production code, sure, but it is executing code. – fractor Jul 18 '19 at 12:17
  • I have a xamarin.mac app where the problem first manifested. Please assume (I believe it to be a safe assumption) that this problem is not due to the code executing in a playground. – fractor Jul 18 '19 at 12:21
  • People seem to be having a similar problem here https://forums.developer.apple.com/thread/118459 – fractor Jul 18 '19 at 12:31
  • According to the documentation `AVAudioEngine.start()` calls `prepare`. https://developer.apple.com/documentation/avfoundation/avaudioengine/1387024-start – fractor Jul 18 '19 at 12:37
  • I've updated the question to include a Swift macOS Cocoa app. This also crashes under the same circumstances. – fractor Jul 23 '19 at 12:41

0 Answers0