1 Reply
      Latest reply on Oct 9, 2019 7:32 PM by Zachary Girouard
      fsoc Level 1 Level 1 (0 points)

        I'm trying to convert a CMSampleBuffer to a AVAudioPCMBuffer instance to be able to perform audio processing in realtime. I wrote an optional initialiser for my extension to pass a CMSampleBuffer reference. Unfortunately I simply don't know how to write to the AVAudioPCMBuffer's data. Here is my code so far:

         

        import AVKit
        
        extension AVAudioPCMBuffer {
            static func create(from sampleBuffer: CMSampleBuffer) -> AVAudioPCMBuffer? {
                
                guard let description: CMFormatDescription = CMSampleBufferGetFormatDescription(sampleBuffer),
                    let sampleRate: Float64 = description.audioStreamBasicDescription?.mSampleRate,
                    let numberOfChannels: Int = description.audioChannelLayout?.numberOfChannels
                    else { return nil }
                
                guard let blockBuffer: CMBlockBuffer = CMSampleBufferGetDataBuffer(sampleBuffer) else {
                    return nil
                }
        
                let length: Int = CMBlockBufferGetDataLength(blockBuffer)
                
                let audioFormat = AVAudioFormat(commonFormat: .pcmFormatFloat32, sampleRate: sampleRate, channels: AVAudioChannelCount(numberOfChannels), interleaved: false)
                let buffer = AVAudioPCMBuffer(pcmFormat: audioFormat!, frameCapacity: AVAudioFrameCount(length))!
                buffer.frameLength = buffer.frameCapacity
                
                for channelIndex in 0...numberOfChannels - 1 {
                    guard let channel: UnsafeMutablePointer<Float> = buffer.floatChannelData?[channelIndex] else { return nil }
                    
                    for pointerIndex in 0...length - 1 {
                        let pointer: UnsafeMutablePointer<Float> = channel.advanced(by: pointerIndex)
                        pointer.pointee = 100
                    }
                }
                
                return buffer
            }
        }
        

         

        Does anyone knows how to convert a CMSampleBuffer to AVAudioPCMBuffer and back again? I assume there is no other way if I want to interact with AVAudioEngine, am I right?