代码之家  ›  专栏  ›  技术社区  ›  Mohammed Atif

使用cmsamplebuffer生成float32数组(float32 pcm数据)

  •  0
  • Mohammed Atif  · 技术社区  · 6 年前

    我从照相机中得到的回拨,用于音频,数据格式为 CMSampleBuffer 但我无法将此数据转换为pcm数据。

    我遵循了苹果提供的文档 copyPCMData , UnsafeMutablePointer , AudioBufferList 但我得到的只是 0.0 最后。

    这是我的代码:

    private let pcmBufferPointer = UnsafeMutablePointer<AudioBufferList>.allocate(capacity: 1024)
    
    init(....){
        //...
        let unsafeRawPointer = UnsafeMutableRawPointer.allocate(byteCount: 4, alignment: 0)
        let audioBuffer = AudioBuffer(mNumberChannels: 1, mDataByteSize: 4, mData: unsafeRawPointer)
        let audioBufferList = AudioBufferList(mNumberBuffers: 0, mBuffers: audioBuffer)
        self.pcmBufferPointer.initialize(repeating: audioBufferList, count: 1024)
    }
    
    
    //CMSampleBuffer obtained from AVCaptureAudioDataOutputSampleBufferDelegate
    private func audioFrom(sampleBuffer: CMSampleBuffer) -> Void {
        let status = CMSampleBufferCopyPCMDataIntoAudioBufferList(sampleBuffer, 0, 1024, pcmBufferPointer)
        if status == 0 {
            Logger.log(key: "Audio Sample Buffer Status", message: "Buffer copied to pointer")
            let dataValue = pcmBufferPointer[0].mBuffers.mData!.load(as: Float32.self) //Tried with Int, Int16, Int32, Int64 and Float too
            Logger.log(key: "PCM Data Value", message: "Data value : \(dataValue)") //prints 0.0
        }else{
            Logger.log(key: "Audio Sample", message: "Buffer allocation failed with status \(status)")
        }
    }
    
    1 回复  |  直到 6 年前
        1
  •  0
  •   Mohammed Atif    6 年前

    终于成功了。

    必须添加额外的步骤来转换 AudioBufferList 指针指向 AudioList 指针

    if status == 0 {
        let inputDataPtr = UnsafeMutableAudioBufferListPointer(pcmBufferPointer)
        let mBuffers : AudioBuffer = inputDataPtr[0]
        if let bufferPointer = UnsafeMutableRawPointer(mBuffers.mData){
            let dataPointer = bufferPointer.assumingMemoryBound(to: Int16.self)
            let dataArray = Array(UnsafeBufferPointer.init(start: dataPointer, count: 1024))
            pcmArray.append(contentsOf: dataArray)
        }else{
            Logger.log(key: "Audio Sample", message: "Failed to generate audio sample")
        }
    }else{
        Logger.log(key: "Audio Sample", message: "Buffer allocation failed with status \(status)")
    }
    

    以上代码仅适用于单通道pcm数据。对于2通道数据,请参考以下要点- https://gist.github.com/hotpaw2/ba815fc23b5d642705f2b1dedfaf0107