gpt4 book ai didi

ios - iOS Audio Calling APP使用Circular Buffer的原因是什么?

转载 作者:可可西里 更新时间:2023-11-01 05:01:38 25 4
gpt4 key购买 nike

我的问题几乎不言自明。对不起,如果它看起来太愚蠢了。

我正在编写一个 iOS VoIP 拨号器并检查了一些开源代码(iOS 音频调用应用程序)。几乎所有这些都使用循环缓冲区来存储记录和接收的 PCM 音频数据。所以我想知道为什么我们需要在这种情况下使用循环缓冲区。使用这种音频缓冲区的确切原因是什么。

提前致谢。

最佳答案

使用循环缓冲区可以让您从源头异步处理输入和输出数据。音频渲染过程发生在高优先级线程上。它从您的应用程序(播放)请求音频样本,并以回调的形式在计时器上提供音频(录制/处理)。

一个典型的场景是音频回调每 0.023 秒触发一次以请求(和/或提供)1024 个音频样本。此线程与系统硬件同步,因此您的回调必须在 0.023 秒结束之前返回。如果您不这样做,硬件将不会等待您,它只会跳过那个周期,您将听到爆音或静音,或者错过您尝试录制的音频。

循环缓冲区的作用是在线程之间传递数据。在将样本异步移入和移出音频线程的音频应用程序中。一个线程在缓冲区的“头部”生成样本,另一个线程从“尾部”消耗它们。

这是一个示例,从麦克风中检索音频样本并将它们写入磁盘。您的应用已订阅每 0.023 秒触发一次的回调,提供 1024 个要记录的样本。天真的方法是简单地将音频从该回调中写入磁盘。

void myCallback(float *samples,int sampleCount, SampleSaver *saver){
SampleSaverSaveSamples(saver,samples,sampleCount);
}

这行得通!!大多数时候...

问题是无法保证写入磁盘会在 0.023 秒之前完成,因此时不时地,您的录音中会出现弹出消息,因为 SampleSaver 花费的时间太长,而硬件只是跳过下一个回调。

正确的做法是使用循环缓冲区。我个人使用 TPCircularBuffer因为它很棒。它的工作方式(外部)是你在一个线程上向缓冲区询问一个指针以将数据写入(头部),然后在另一个线程上你向缓冲区询问一个指针以从(尾部)读取数据。以下是使用 TPCircularBuffer 完成的方法(跳过设置并使用简化的回调)。

//this is on the high priority thread that can't wait for anything like a slow write to disk
void myCallback(float *samples,int sampleCount, TPCircularBuffer *buffer){
int32_t availableBytes = 0;
float *head = TPCircularBufferHead(buffer, &availableBytes);
memcpy(head,samples,sampleCount * sizeof(float));//copies samples to head
TPCircularBufferProduce(buffer,sampleCount * sizeof(float)); //moves buffer head "forward in the circle"

}

此操作非常快速,不会对敏感的音频线程造成额外压力。然后,您可以创建自己的计时器(一个单独的线程)以将示例写入磁盘。

//this is on some background thread that can take it's sweet time
void myLeisurelySavingCallback(TPCircularBuffer *buffer, SampleSaver *saver){
int32_t available;
float *tail = TPCircularBufferTail(buffer, &available);
int samplesInBuffer = available / sizeof(float); //mono
SampleSaverSaveSamples(saver, tail, samplesInBuffer);
TPCircularBufferConsume(buffer, samplesInBuffer * sizeof(float)); // moves tail forward
}

好了,你不仅可以避免音频故障,而且如果你初始化一个足够大的缓冲区,你可以将你的写入磁盘回调设置为仅每隔一两秒触发一次(在循环缓冲区建立一个好一点的音频)这在你的系统上比每 0.023 秒写入磁盘要容易得多!

使用缓冲区的主要原因是样本可以异步处理。它们也是在没有锁的情况下在线程之间传递消息的好方法。 Here是一篇很好的文章,解释了用于实现循环缓冲区的简洁内存技巧。

关于ios - iOS Audio Calling APP使用Circular Buffer的原因是什么?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/30691684/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com