diff --git a/Sources/IO/IOAudioResampler.swift b/Sources/IO/IOAudioResampler.swift index 8727b8085..5c7bf2316 100644 --- a/Sources/IO/IOAudioResampler.swift +++ b/Sources/IO/IOAudioResampler.swift @@ -77,10 +77,6 @@ struct IOAudioResamplerSettings { final class IOAudioResampler { private static func makeAudioFormat(_ inSourceFormat: inout AudioStreamBasicDescription) -> AVAudioFormat? { if inSourceFormat.mFormatID == kAudioFormatLinearPCM && kLinearPCMFormatFlagIsBigEndian == (inSourceFormat.mFormatFlags & kLinearPCMFormatFlagIsBigEndian) { - // ReplayKit audioApp. - guard inSourceFormat.mBitsPerChannel == 16 else { - return nil - } let interleaved = !((inSourceFormat.mFormatFlags & kLinearPCMFormatFlagIsNonInterleaved) == kLinearPCMFormatFlagIsNonInterleaved) if let channelLayout = Self.makeChannelLayout(inSourceFormat.mChannelsPerFrame) { return .init( @@ -168,8 +164,17 @@ final class IOAudioResampler { func append(_ sampleBuffer: CMSampleBuffer) { inSourceFormat = sampleBuffer.formatDescription?.audioStreamBasicDescription + guard let inSourceFormat else { + return + } if sampleTime == kIOAudioResampler_sampleTime { - sampleTime = sampleBuffer.presentationTimeStamp.value + let targetSampleTime: CMTimeValue + if sampleBuffer.presentationTimeStamp.timescale == Int32(inSourceFormat.mSampleRate) { + targetSampleTime = sampleBuffer.presentationTimeStamp.value + } else { + targetSampleTime = Int64(Double(sampleBuffer.presentationTimeStamp.value) * inSourceFormat.mSampleRate / Double(sampleBuffer.presentationTimeStamp.timescale)) + } + sampleTime = AVAudioFramePosition(targetSampleTime) if let outputFormat { anchor = .init(hostTime: AVAudioTime.hostTime(forSeconds: sampleBuffer.presentationTimeStamp.seconds), sampleTime: sampleTime, atRate: outputFormat.sampleRate) } diff --git a/Sources/IO/IOAudioRingBuffer.swift b/Sources/IO/IOAudioRingBuffer.swift index f7cc60c94..b554aedcd 100644 --- a/Sources/IO/IOAudioRingBuffer.swift +++ b/Sources/IO/IOAudioRingBuffer.swift @@ -40,8 +40,14 @@ final class IOAudioRingBuffer { guard CMSampleBufferDataIsReady(sampleBuffer) else { return } + let targetSampleTime: CMTimeValue + if sampleBuffer.presentationTimeStamp.timescale == Int32(inputBuffer.format.sampleRate) { + targetSampleTime = sampleBuffer.presentationTimeStamp.value + } else { + targetSampleTime = Int64(Double(sampleBuffer.presentationTimeStamp.value) * inputBuffer.format.sampleRate / Double(sampleBuffer.presentationTimeStamp.timescale)) + } if sampleTime == 0 { - sampleTime = sampleBuffer.presentationTimeStamp.value + sampleTime = targetSampleTime } if inputBuffer.frameLength < sampleBuffer.numSamples { if let buffer = AVAudioPCMBuffer(pcmFormat: inputFormat, frameCapacity: AVAudioFrameCount(sampleBuffer.numSamples)) { @@ -67,7 +73,7 @@ final class IOAudioRingBuffer { } } } - skip = max(Int(sampleBuffer.presentationTimeStamp.value - sampleTime), 0) + skip = max(Int(targetSampleTime - sampleTime), 0) sampleTime += Int64(skip) append(inputBuffer) }