2016-01-12 7 views
6

Vorrei caricare file audio mp3 e wav come array di float o double, simile alla funzione io.wavfile.read in scipy. Posso farlo con i dati del microfono o riprodurre l'audio scrivendo il flusso audio su un buffer. Tuttavia, non sono sicuro di come caricare tutti i dati di un file audio contemporaneamente.Come posso generare una serie di float da un file audio in Swift

- Aggiornamento

per chiunque lavori con dati del segnale audio in futuro, ecco una funzione che fa il trucco. Si basa sulla risposta di Rhysthmic 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)) 
    } 
+0

Dai un'occhiata alla ' EZAudio': https://github.com/syedhali/EZAudio – dfri

+0

Questa è una bella libreria, grazie. Sto riscontrando problemi nel farmi funzionare per me in Swift, aggiornerò la mia domanda. – Alizaybak

risposta

7

AVAudioFile built-in per iOS (e OS X), è molto comodo e anche fare conversioni di formato per voi:

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") 

Purtroppo, per i doppi non sembra essere abbastanza per sostituire .PCMFormatFloat32 con .PCMFormatFloat64 perché AVAudioPCMBuffer non dispone di un metodo float64ChannelData.

aggiornamento perché non so bene rapida

È possibile evitare di copiare la matrice lavorando con la UnsafeBufferPointer, che è un buon perfettamente tipo di raccolta:

let floatArray = UnsafeBufferPointer(start: buf.floatChannelData[0], count:Int(buf.frameLength)) 
Problemi correlati