Currently, I'm getting an EXC_BAD_ACCESS error on the audio thread, and I'm trying to deduce what is going wrong.
When converting .wav file data from Data to an AVAudioPCMBuffer, do I need to strip the RIFF header first?
import AVFoundation
public class Player : NSObject {
  let engine = AVAudioEngine()
  public override init() {
    super.init()
    do {
      let _ = engine.mainMixerNode
      try engine.start()
    } catch {
      print("Player error: \(error)")
    }
  }
  @objc public func play(_ data: Data) {
    let format = AVAudioFormat(commonFormat: .pcmFormatInt16, sampleRate: 48000, channels: 2, interleaved: true)!
    let buffer = data.toPCMBuffer(format: format)!
    let player = AVAudioPlayerNode()
    engine.attach(player)
    engine.connect(player, to: engine.mainMixerNode, format: nil)
    player.scheduleBuffer(buffer, at: nil, completionCallbackType: .dataPlayedBack) {
      callbackType in
      // Nothing in here.
    }
    player.play()
  }
}
Here's the toPCMBuffer extension:
// Taken from: https://stackoverflow.com/a/52731480/2228559
extension Data {
  func toPCMBuffer(format: AVAudioFormat) -> AVAudioPCMBuffer? {
    let streamDesc = format.streamDescription.pointee
    let frameCapacity = UInt32(count) / streamDesc.mBytesPerFrame
    guard let buffer = AVAudioPCMBuffer(pcmFormat: format, frameCapacity: frameCapacity) else { return nil }
    buffer.frameLength = buffer.frameCapacity
    let audioBuffer = buffer.audioBufferList.pointee.mBuffers
    withUnsafeBytes { addr in
      audioBuffer.mData?.copyMemory(from: addr, byteCount: Int(audioBuffer.mDataByteSize))
    }
    return buffer
  }
}
Note: I cannot use AVAudioFile because the .wav file data is loaded over-the-wire.