user967493 user967493 - 3 months ago 58
Swift Question

Convert audio into raw PCM data of type [Double]

I'm trying to convert a recorded audio file into raw PCM data of type [Double]. I found a way to load and convert audio to PCM data of the type [Float32] like this:

// load audio from path
let file = try! AVAudioFile(forReading: self.soundFileURL)
// declare format
let format = AVAudioFormat(commonFormat: .PCMFormatFloat32, sampleRate: file.fileFormat.sampleRate, channels: 1, interleaved: false)
// initialize audiobuffer with the length of the audio file
let buf = AVAudioPCMBuffer(PCMFormat: format, frameCapacity: UInt32(file.length))
// write to file
try! file.readIntoBuffer(buf)
// copy to array
let floatArray = Array(UnsafeBufferPointer(start: buf.floatChannelData[0], count:Int(buf.frameLength)))


The problem is, I need the data as [Double] and AVAudioPCMBuffer() only knows the
.PCMFormatFloat32
. Does anybody know a workaround?
Thank you.

Answer

But AVAudioFormat does know .PCMFormatFloat64:

let format = AVAudioFormat(commonFormat: .PCMFormatFloat64, sampleRate: file.fileFormat.sampleRate, channels: 1, interleaved: false)

Maybe you mean AVAudioPCMBuffer doesn't have a float64ChannelData convenience property?

That's fine, you can use AVAudioPCMBuffer's superclass, AVAudioBuffer has everying you need to be able to get at the raw Double/Float64 samples:

let abl = buf.audioBufferList.memory
let doubles = UnsafePointer<Double>(abl.mBuffers.mData)
doubles[0] // etc...

In full:

let file = try! AVAudioFile(forReading: self.soundFileURL)
let format = AVAudioFormat(commonFormat: .PCMFormatFloat64, sampleRate: file.fileFormat.sampleRate, channels: 1, interleaved: false)

let buf = AVAudioPCMBuffer(PCMFormat: format, frameCapacity: UInt32(file.length))
try! file.readIntoBuffer(buf)
let abl = buf.audioBufferList.memory
let doubles = UnsafePointer<Float64>(abl.mBuffers.mData)