For anyone else looking to do the same thing (creating a valid audio file without touching disk), once the data buffers are extracted using AVAssetReader, it's easiest to put them into a CAF file.
Refer to Apple's CAF specification: https://developer.apple.com/library/content/documentation/MusicAudio/Reference/CAFSpec/CAF_spec/CAF_spec.html#//apple_ref/doc/uid/TP40001862-CH210-TPXREF101
The AudioToolbox framework has a CAFFile.h header with all of the relevant structs. So it's just a matter of reading the spec, populating the structs, then sticking them into Data objects something like this:
return Data(bytes: &fileHeader, count: MemoryLayout<CAFFileHeader>.size) +
Data(bytes: &audioDescriptionChunkHeader, count: MemoryLayout<CAFChunkHeader>.size) +
Data(bytes: &audioDescriptionChunkData, count: MemoryLayout<CAFAudioDescription>.size) +
Data(bytes: &audioDataChunkHeader, count: MemoryLayout<CAFChunkHeader>.size) +
Data(bytes: &audioDataChunkData.mEditCount, count: MemoryLayout<UInt32>.size) +
data
Things to keep in mind:
when initializing the structs, everything needs to be bigEndian, including the "strings" (represented in CAFFile.h as UInt32), ex:
var audioDescriptionChunkHeader = CAFChunkHeader(
mChunkType: kCAF_StreamDescriptionChunkID.bigEndian,
mChunkSize: Int64(MemoryLayout.size).bigEndian
)
and mBitsPerChannel is just the bitDepth, no need to divide it by the number of channels