func processAudioData(_ pData: UnsafeMutablePointer<AudioBufferList>, nbSample len: Int32, withFormat fmt: UnsafePointer<AudioStreamBasicDescription>!, timeinfo pts: CMTime, of trackId: Int32) -> CMSampleBuffer? {
        
	var formatDescription: CMFormatDescription!
	var status = CMAudioFormatDescriptionCreate(allocator: kCFAllocatorDefault,
                                                    asbd: fmt,
                                                    layoutSize: 0,
                                                    layout: nil,
                                                    magicCookieSize: 0,
                                                    magicCookie: nil,
                                                    extensions: nil,
                                                    formatDescriptionOut: &formatDescription)
        
	if status != noErr {
		print("CMAudioFormatDescriptionCreate Error!!!!!")
		return nil
	}
        
	var timing: CMSampleTimingInfo = CMSampleTimingInfo(
            duration: CMTime(value: 1, timescale: Int32(48000)),
            presentationTimeStamp: pts,
            decodeTimeStamp: CMTime.invalid
	)
         
	var sampleBuffer: CMSampleBuffer?
	status = CMSampleBufferCreate(allocator: kCFAllocatorDefault,
                                      dataBuffer: nil,
                                      dataReady: false,
                                      makeDataReadyCallback: nil,
                                      refcon: nil,
                                      formatDescription: formatDescription,
                                      sampleCount: Int(len),
                                      sampleTimingEntryCount: 1,
                                      sampleTimingArray: &timing,
                                      sampleSizeEntryCount: 0,
                                      sampleSizeArray: nil,
                                      sampleBufferOut: &sampleBuffer)
        
        
	if status != noErr {
		print("CMSampleBufferCreate Error!!!!!")
		return nil
	}
        
	status = CMSampleBufferSetDataBufferFromAudioBufferList(sampleBuffer!,
                                                                blockBufferAllocator: kCFAllocatorDefault,
                                                                blockBufferMemoryAllocator: kCFAllocatorDefault,
                                                                flags: 0,
                                                                bufferList: pData)
        
	if status != noErr {
		print("CMSampleBufferSetDataBufferFromAudioBufferList Error!!!!!")
        return nil
	}
        
	guard let samplebuffer = sampleBuffer else {
		print("remote sampleBuffer nil!!!!!")
		return nil
     }
        
	return samplebuffer
}

 

[사용방법]

var streamDesc = AudioStreamBasicDescription()
        
let bytesPerSample: UInt32 = UInt32(MemoryLayout<Int16>.size)  // 2
streamDesc.mFormatID = kAudioFormatLinearPCM
        
streamDesc.mFormatFlags = kLinearPCMFormatFlagIsSignedInteger | kAudioFormatFlagIsPacked  //kLinearPCMFormatFlagIsPacked
        
streamDesc.mBytesPerPacket = bytesPerSample// 2
streamDesc.mFramesPerPacket = 1
streamDesc.mBytesPerFrame = bytesPerSample //2
streamDesc.mChannelsPerFrame = 1 // 1
streamDesc.mBitsPerChannel = 8 * bytesPerSample
streamDesc.mSampleRate = 48000 //44100

let ump = UnsafeMutablePointer<AudioBufferList>.allocate(capacity: 1)
ump.pointee = pcmBuffer.audioBufferList.pointee
                
if let sampleBuffer = self.audioMixer.processAudioData(ump, 
                                                       nbSample: Int32(ump.pointee.mBuffers.mDataByteSize / 2), 
                                                       withFormat: &(streamDesc), 
                                                       timeinfo: CMClockGetTime(CMClockGetHostTimeClock()), 
                                                       of: 0) {
    			..... 생략 .....
}

+ Recent posts