快速将float数组写入wav音频文件

zo_*_*chu 5 audio core-audio audiotoolbox ios swift

我现在有这个流程:我使用AudioEngine记录音频,将其发送到音频处理库并获取音频缓冲区,然后我很想将其写入到wav文件中,但是我完全困惑如何在其中执行该操作迅速。

我已经尝试了另一个stackoverflow答案中的此代码段,但是它写入了一个空的且损坏的文件。(将pcm加载到AVAudioPCMBuffer中

//get data from library

var len : CLong = 0
let res: UnsafePointer<Double> = getData(CLong(), &len )
let bufferPointer: UnsafeBufferPointer = UnsafeBufferPointer(start: res, count: len)

//tranform it to Data

let arrayDouble = Array(bufferPointer)
let arrayFloats = arrayDouble.map{Float($0)}
let data = try Data(buffer: bufferPointer)

//attempt to write in file
    do {
        let format = AVAudioFormat(commonFormat: .pcmFormatFloat32, sampleRate: 16000, channels: 2, interleaved: false)

        var buffer = AVAudioPCMBuffer(pcmFormat: format, frameCapacity: AVAudioFrameCount(data.count))
        buffer.floatChannelData!.pointee.withMemoryRebound(to: UInt8.self, capacity: data.count) {
            let stream = OutputStream(toBuffer: $0, capacity: data.count)
            stream.open()
            _ = data.withUnsafeBytes {
                stream.write($0, maxLength: data.count)
            }
            stream.close()
        }
        //settings are from AudioEngine.inputNode!.inputFormat(forBus: 0).settings

        var audioFile = try AVAudioFile(forWriting: url, settings: settings)
        try audioFile.write(from: buffer)

    } catch let error as NSError {
        print("ERROR HERE", error.localizedDescription)
    }
Run Code Online (Sandbox Code Playgroud)

所以,我想我对floatChannelData的转换是错误的,或者是所有错误。任何建议或指针在哪里可以读到的都很棒!

zo_*_*chu 5

在一位出色的同事的帮助下,我们设法使它开始工作。显然,填充后的AudioPCMBuffer也需要通知其新大小。我也使用完全错误的格式。

这是代码:

let SAMPLE_RATE =  Float64(16000.0)

let outputFormatSettings = [
    AVFormatIDKey:kAudioFormatLinearPCM,
    AVLinearPCMBitDepthKey:32,
    AVLinearPCMIsFloatKey: true,
    //  AVLinearPCMIsBigEndianKey: false,
    AVSampleRateKey: SAMPLE_RATE,
    AVNumberOfChannelsKey: 1
    ] as [String : Any]

let audioFile = try? AVAudioFile(forWriting: url, settings: outputFormatSettings, commonFormat: AVAudioCommonFormat.pcmFormatFloat32, interleaved: true)

let bufferFormat = AVAudioFormat(settings: outputFormatSettings)

let outputBuffer = AVAudioPCMBuffer(pcmFormat: bufferFormat, frameCapacity: AVAudioFrameCount(buff.count))

// i had my samples in doubles, so convert then write

for i in 0..<buff.count {
    outputBuffer.floatChannelData!.pointee[i] = Float( buff[i] )
}
outputBuffer.frameLength = AVAudioFrameCount( buff.count )

do{
    try audioFile?.write(from: outputBuffer)

} catch let error as NSError {
    print("error:", error.localizedDescription)
}
Run Code Online (Sandbox Code Playgroud)