2016-01-12 4 views
6

Chciałbym załadować pliki audio w formacie mp3 i wav jako tablice zmiennych lub podwójnych, podobnie do funkcji io.wavfile.read w scipy. Mogę to zrobić z danymi mikrofonu lub odtwarzaniem dźwięku, zapisując strumień audio do bufora. Jednak nie jestem pewien, jak załadować wszystkie dane pliku audio naraz.Jak wygenerować tablicę obiektów pływających z pliku audio w Swift

- Aktualizacja

Dla każdego, kto pracuje z danymi sygnału audio w przyszłości, tutaj jest to funkcja, która załatwia sprawę. Opiera się na odpowiedzi Rytmicznego Fistmana.

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

Zapraszamy do obejrzenia ' EZAudio': https://github.com/syedhali/EZAudio – dfri

+0

To miła biblioteka, dzięki. Mam problem z uruchomieniem go w Swift, zaktualizuję moje pytanie. – Alizaybak

Odpowiedz

7

AVAudioFile wbudowana w iOS (i OS X), jest bardzo wygodny i zrobi konwersji formatu dla Ciebie:

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

Niestety, dla deblu nie wydaje się być wystarczająco do zastąpienia .PCMFormatFloat32 z .PCMFormatFloat64, ponieważ AVAudioPCMBuffer nie ma metody float64ChannelData.

aktualizacja bo nie wiem szybkiego studnię

Można uniknąć kopiowania tablicę poprzez współpracę z UnsafeBufferPointer, który jest doskonale dobry typ kolekcja:

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