Swift

2016-01-12 30 views
6

'daki bir ses dosyasından nasıl bir dizi float üretebilirim Scipy'deki io.wavfile.read işlevine benzer şekilde, mp3 ve wav ses dosyalarını float veya double dizileri olarak yüklemek istiyorum. Bunu mikrofon verileriyle yapabilir veya ses akışını bir arabelleğe yazarak ses çalabilirim. Ancak, bir ses dosyasının tüm verilerini bir kerede nasıl yükleyeceğimi bilmiyorum. Swift

- Güncelleme

gelecekte ses sinyali verileri ile çalışan herkes için, burada hile yapan bir fonksiyondur. Ritmik Fistman'ın cevabına dayanıyor.

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

'göz at EZAudio': https://github.com/syedhali/EZAudio – dfri

+0

Güzel bir kütüphane, teşekkürler. Swift'de çalışmam için sorun yaşıyorum, sorumu güncelleyeceğim. – Alizaybak

cevap

7

AVAudioFile iOS'un yerleşik (ve OS X) için, çok uygundur ve ayrıca sizin için format dönüşümleri yapacak:

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

Ne yazık ki, yeterli görünmüyor çiftler ,ile .PCMFormatFloat32 yerine float64ChannelData yöntemi yoktur.

güncelleme ben hızlı kuyu bilmiyorum çünkü

Sen gayet iyi toplama türüdür UnsafeBufferPointer, birlikte çalışarak dizi kopyalama önleyebilirsiniz

:

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