How can I generate an array of floats from an audio file in Swift

I would like to download mp3 and wav audio files as arrays of floats or doubles, similar to the io.wavfile.read function in scipy. I can do this with mic data or audio playback by writing an audio stream to a buffer. However, I am not sure how to download all the data of the audio files at once.

- Update

For those who work with audio data in the future, here is a feature that does the trick. This is based on the response of the Rhythmic Fistman.

func loadAudioSignal(audioURL: NSURL) -> (signal: [Float], rate: Double, frameCount: Int) { let file = try! AVAudioFile(forReading: audioURL) let format = AVAudioFormat(commonFormat: .PCMFormatFloat32, sampleRate: file.fileFormat.sampleRate, channels: file.fileFormat.channelCount, interleaved: false) let buf = AVAudioPCMBuffer(PCMFormat: format, frameCapacity: UInt32(file.length)) try! file.readIntoBuffer(buf) // You probably want better error handling let floatArray = Array(UnsafeBufferPointer(start: buf.floatChannelData[0], count:Int(buf.frameLength))) return (signal: floatArray, rate: file.fileFormat.sampleRate, frameCount: Int(file.length)) } 
+6
source share
1 answer

AVAudioFile built into iOS (and OS X) is very convenient and will also do format conversions for you:

 import AVFoundation // ... let url = NSBundle.mainBundle().URLForResource("your audio file", withExtension: "wav") let file = try! AVAudioFile(forReading: url!) let format = AVAudioFormat(commonFormat: .PCMFormatFloat32, sampleRate: file.fileFormat.sampleRate, channels: 1, interleaved: false) let buf = AVAudioPCMBuffer(PCMFormat: format, frameCapacity: 1024) try! file.readIntoBuffer(buf) // this makes a copy, you might not want that let floatArray = Array(UnsafeBufferPointer(start: buf.floatChannelData[0], count:Int(buf.frameLength))) print("floatArray \(floatArray)\n") 

Unfortunately, for doubles, it seems not enough to replace .PCMFormatFloat32 with .PCMFormatFloat64 , because AVAudioPCMBuffer does not have a float64ChannelData method.

because i don't know fast

You can avoid copying the array by working with UnsafeBufferPointer , which is an absolutely good collection type:

 let floatArray = UnsafeBufferPointer(start: buf.floatChannelData[0], count:Int(buf.frameLength)) 
+8
source

All Articles