Swift 3:使用AVCaptureAudioDataOutput分析音频输入

时间:2017-01-24 02:09:43

标签: ios swift3 avcapturesession audiobuffer

我正在尝试使用AVCaptureAudioDataOutput来分析音频输入,如here所述。这不是我自己能想到的东西,所以我复制了这个例子,但我遇到了困难。

Swift 3中的Xcode促使我做了一些改动。我在分配samples的行时收到编译错误。 Xcode说,“无法为类型'UnsafeMutablePointer< _>调用初始化程序。使用类型'(UnsafeMutableRawPointer?)'“

的参数列表

以下是我修改过的代码:

func captureOutput(_ captureOutput: AVCaptureOutput!,
                    didOutputSampleBuffer sampleBuffer: CMSampleBuffer!,
                   from connection: AVCaptureConnection!){
    var buffer: CMBlockBuffer? = nil
    var audioBufferList = AudioBufferList(mNumberBuffers: 1,
                                          mBuffers: AudioBuffer(mNumberChannels: 1, mDataByteSize: 0, mData: nil))
    CMSampleBufferGetAudioBufferListWithRetainedBlockBuffer(
        sampleBuffer,
        nil,
        &audioBufferList,
        MemoryLayout<AudioBufferList>.size,     // changed for Swift 3
        nil,
        nil,
        UInt32(kCMSampleBufferFlag_AudioBufferList_Assure16ByteAlignment),
        &buffer
    )
    let abl = UnsafeMutableAudioBufferListPointer(&audioBufferList)
    var sum:Int64 = 0
    var count:Int = 0
    var bufs:Int = 0
    for buf in abl {
        let samples = UnsafeMutableBufferPointer<Int16>(start: UnsafeMutablePointer(buf.mData),  // Error here
                                                        count: Int(buf.mDataByteSize)/sizeof(Int16))
        for sample in samples {
            let s = Int64(sample)
            sum = (sum + s*s)
            count += 1
        }
        bufs += 1
    }
    print( "found \(count) samples in \(bufs) buffers, sum is \(sum)" )
}

有谁能告诉我如何修复此代码?

1 个答案:

答案 0 :(得分:1)

答案是我需要将buf.mData包裹在OpaquePointer中。即,在UnsafeMutableBufferPointer<Int16>(OpaquePointer(buff.mData))的呼叫中,更改

start: UnsafeMutablePointer(buff.mData)

start: UnsafeMutablePointer(OpaquePointer(buff.mData))

以下是为Swift 3更新的完整代码:

    func captureOutput(_ captureOutput: AVCaptureOutput!,
                   didOutputSampleBuffer sampleBuffer: CMSampleBuffer!,
                   from connection: AVCaptureConnection!){
    var buffer: CMBlockBuffer? = nil
    var audioBufferList = AudioBufferList(mNumberBuffers: 1,
                                          mBuffers: AudioBuffer(mNumberChannels: 1, mDataByteSize: 0, mData: nil))
    CMSampleBufferGetAudioBufferListWithRetainedBlockBuffer(
        sampleBuffer,
        nil,
        &audioBufferList,
        MemoryLayout<AudioBufferList>.size,
        nil,
        nil,
        UInt32(kCMSampleBufferFlag_AudioBufferList_Assure16ByteAlignment),
        &buffer
    )
    let abl = UnsafeMutableAudioBufferListPointer(&audioBufferList)
    var sum:Int64 = 0
    var count:Int = 0
    var bufs:Int = 0
    for buff in abl {
        let samples = UnsafeMutableBufferPointer<Int16>(start: UnsafeMutablePointer(OpaquePointer(buff.mData)),
                                                        count: Int(buff.mDataByteSize)/MemoryLayout<Int16>.size)
        for sample in samples {
            let s = Int64(sample)
            sum = (sum + s*s)
            count += 1
        }
        bufs += 1
    }
    print( "found \(count) samples in \(bufs) buffers, RMS is \(sqrt(Float(sum)/Float(count)))" )
}

这满足了编译器,它似乎生成了合理的数字。