Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
392 views
in Technique[技术] by (71.8m points)

swift - Processing CMSampleBuffer fails after some time

I am attempting to capture audio from the device microphone and process it as a Float array. I have set up an AVCaptureSession and have implemented captureOutput(_:didOutput:from:) and it appears to work for a while but after a number of samples have been processed, the number of channels suddenly becomes zero. Why is this?

The output is:

numSamples: 512, mNumberBuffers: 1, mNumberChannels: 2
signals count: 2, signals[0] count: 1536
...
numSamples: 512, mNumberBuffers: 1, mNumberChannels: 2
signals count: 2, signals[0] count: 1536
numSamples: 512, mNumberBuffers: 1, mNumberChannels: 0

My code is:

class Capture: NSObject, AVCaptureAudioDataOutputSampleBufferDelegate {
    var captureSession: AVCaptureSession
    
    override init() {
        self.captureSession = AVCaptureSession()
        super.init()
        beginCapture()
    }
    
    func beginCapture() {
        guard let device = AVCaptureDevice.default(for: .audio) else { return }
        guard let input = try? AVCaptureDeviceInput(device: device) else { return }
        guard captureSession.canAddInput(input) else { return }
        
        captureSession.addInput(input)
        
        let output = AVCaptureAudioDataOutput()
        let queue = DispatchQueue(label: "myqueue")
        output.setSampleBufferDelegate(self, queue: queue)
        guard captureSession.canAddOutput(output) else { return }
        captureSession.addOutput(output)
        captureSession.commitConfiguration()
        
        captureSession.startRunning()
    }
    
    func captureOutput(_ output: AVCaptureOutput, didOutput sampleBuffer: CMSampleBuffer, from connection: AVCaptureConnection) {
        var audioBufferList = AudioBufferList(mNumberBuffers: 1, mBuffers: AudioBuffer(mNumberChannels: 0, mDataByteSize: 0, mData: nil))
        var blockBuffer: CMBlockBuffer? = nil
        
        CMSampleBufferGetAudioBufferListWithRetainedBlockBuffer(sampleBuffer,
            bufferListSizeNeededOut: nil,
            bufferListOut: &audioBufferList,
            bufferListSize: MemoryLayout<AudioBufferList>.stride,
            blockBufferAllocator: nil,
            blockBufferMemoryAllocator: nil,
            flags: kCMSampleBufferFlag_AudioBufferList_Assure16ByteAlignment,
            blockBufferOut: &blockBuffer)
        
        var monoSamples = [UInt8]()
        let a = audioBufferList.mBuffers
        let ptr = a.mData?.assumingMemoryBound(to: UInt8.self)
        monoSamples.append(contentsOf: UnsafeBufferPointer(start: ptr, count: Int(a.mDataByteSize)))
        
        let n = Int(a.mNumberChannels)
        
        let signals: [[Float]] = (0..<n).map { i in
            let a = stride(from: i, to: monoSamples.count, by: n)
            let b = a.map { ii in Float(monoSamples[ii]) }
            return b
        }
        
        print("numSamples: (sampleBuffer.numSamples), mNumberBuffers: (audioBufferList.mNumberBuffers), mNumberChannels: (audioBufferList.mBuffers.mNumberChannels)")
        
        print("signals count: (signals.count), signals[0] count: (signals[0].count)")
    }
}
question from:https://stackoverflow.com/questions/65902471/processing-cmsamplebuffer-fails-after-some-time

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Answer

0 votes
by (71.8m points)
Waitting for answers

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...