Basically I need to create a 4 channel buffer, and output and read data to and from a file. I'm using PCM with a .CAF file since I'm not sure any other format that supports 4 channel audio (if that one even does?) I can create the buffer OK, but when it gets saved, the .CAF file is filled with zeroes, and when I read it back in, it prints all zeroes. I need a low sample rate since this is actually medical data. I What am I missing??
import AVFoundation
func createBuffer(_ outBuffer:AVAudioPCMBuffer) {
let outputBuffer = UnsafeMutableAudioBufferListPointer(outBuffer.mutableAudioBufferList)
var counter:Float = 1
outBuffer.frameLength = outBuffer.frameCapacity
for buffer in outputBuffer {
guard let data = buffer.mData?.assumingMemoryBound(to: Float32.self) else { continue }
for i in 0..<outBuffer.frameCapacity {
data.advanced(by: Int(i)).pointee = counter
counter += 1
}
}
}
func testExample() {
let format2 = AVAudioFormat(
commonFormat: .pcmFormatFloat32,
sampleRate: 220,
interleaved: false,
channelLayout: AVAudioChannelLayout(layoutTag: kAudioChannelLayoutTag_Quadraphonic)!)
let bufferSize:UInt32 = 10
guard let outBuffer = AVAudioPCMBuffer(pcmFormat: format2, frameCapacity: bufferSize) else { print("outBuffer bad"); return }
createBuffer(outBuffer)
// Save matrix to .CAF file
let fm = FileManager.default
let doc = try! fm.url(for:.documentDirectory, in: .userDomainMask, appropriateFor: nil, create: true)
let fileURL = doc.appendingPathComponent("myfile.caf", isDirectory:false)
try? fm.removeItem(at: fileURL) // just in case
do {
let outFile = try AVAudioFile(forWriting: fileURL, settings: outBuffer.format.settings)
try outFile.write(from:outBuffer)
} catch {
print(error)
}
// Read, Convert .CAF file to MLMultiArray
guard let infile = try? AVAudioFile(forReading: fileURL),
let inBuffer = AVAudioPCMBuffer(pcmFormat: infile.processingFormat, frameCapacity: UInt32(infile.length)) else { return }
let test = UnsafeBufferPointer<UnsafeMutablePointer<Float>>(start:inBuffer.floatChannelData, count:Int(inBuffer.format.channelCount))
for buffer in test {
let floats = UnsafeBufferPointer<Float>(start:buffer, count:Int(inBuffer.frameCapacity))
for (index, value) in floats.enumerated() {
print("value \(index): \(value)")
}
}
}
testExample()