IOS AudioUnit播放裂纹问题(swift)

Muh*_*zan 1 core-audio playback audiounit ios swift

我正在尝试在 IOS 中播放来自 Android 设备的 UDP 字节。我正在使用 TPCircularBuffer 来播放字节。我的代码如下:

let success = initCircularBuffer(&circularBuffer, 1024)
        if success {
            print("Circular buffer init was successful")
        } else {
            print("Circular buffer init not successful")
        }



func udpReceive() {
        receivingQueue.async {
            repeat {
                do {
                    let datagram = try self.tcpClient?.receive()
                    let byteData = datagram?["data"] as? Data
                    let dataLength = datagram?["length"] as? Int
                    self.dataLength = dataLength!

                    let _ = TPCircularBufferProduceBytes(&self.circularBuffer, byteData!.bytes, UInt32(dataLength! * MemoryLayout<UInt8>.stride * 2))

                } catch {
                    fatalError(error.localizedDescription)
                }
            } while true
        }


    }

    func consumeBuffer() -> UnsafeMutableRawPointer? {
        self.availableBytes = 0
        let tail = TPCircularBufferTail(&self.circularBuffer, &self.availableBytes)
        return tail
    }
Run Code Online (Sandbox Code Playgroud)

我们以 16K 采样率进行录制,并通过 UDP 从 Android 端发送到 IOS,然后使用 AudioUnit 来播放字节,但问题是声音中出现噼啪声和削波声。

播放回调代码:

func performPlayback(
        _ ioActionFlags: UnsafeMutablePointer<AudioUnitRenderActionFlags>,
        inTimeStamp: UnsafePointer<AudioTimeStamp>,
        inBufNumber: UInt32,
        inNumberFrames: UInt32,
        ioData: UnsafeMutablePointer<AudioBufferList>
    ) -> OSStatus {

        var buffer = ioData[0].mBuffers             

        let bufferTail = consumeBuffer()

        memcpy(buffer.mData, bufferTail, min(self.dataLength, Int(availableBytes)))
        buffer.mDataByteSize = UInt32(min(self.dataLength, Int(availableBytes)))


        TPCircularBufferConsume(&self.circularBuffer, UInt32(min(self.dataLength, Int(availableBytes))))

        return noErr
    }
Run Code Online (Sandbox Code Playgroud)

UDP 每个样本向我们发送 1280 字节。我们认为问题是缓冲区大小设置不正确。谁能指导我如何设置适当的缓冲区大小。这确实会有很大的帮助。我知道 @Gruntcakes 作为 voip 工程师的工作/sf/answers/3999559301/。我还研究了 @hotpaw2 的工作,并查看/sf/answers/4098209181/以检查是否存在一些线程问题。任何形式的帮助将不胜感激。

hot*_*aw2 5

音频单元回调应仅返回请求的帧数(样本),如 inNumberFrames 参数所示。您的代码似乎将一些不同数量的样本复制到 AudioBufferList 中,这是行不通的,因为 iOS 音频单元只会将请求数量的帧发送到音频输出。

您可以在音频会话配置中建议首选缓冲持续时间,但这只是一个建议。iOS 可以忽略此建议,并使用与设备的音频硬件、系统活动和当前电源状态更好匹配的 inNumberFrames。

不要忘记预先填充循环缓冲区,以考虑网络 (UDP) 传输时间中的最大预期抖动。也许测量网络数据包到数据包的延迟抖动,并计算其统计数据、最小值、最大值、std.dev。ETC。

如果您的 UDP 缓冲区大小不是 2 的幂,或者包含不符合 iOS 硬件采样率的样本,那么您还必须在安全缓冲开销中考虑小数缓冲区和重采样抖动。