gpt4 book ai didi

c++ - ALSA 捕获丢失的帧

转载 作者:行者123 更新时间:2023-12-02 10:37:41 27 4
gpt4 key购买 nike

我继承了一段代码,它使用 ALSA 来捕获 8KHz、8 位、1 channel 的音频输入。代码看起来相当简单,它将 channel 设置为 1,速率设置为 8000,周期大小设置为 8000。该程序的目标是一次收集 30+ 分钟 block 中的音频数据。

主循环看起来像

int retval;
snd_pcm_uframes_t numFrames = 8000;

while (!exit)
{
// Gather data
while( (unsigned int)(retval = snd_pcm_readi ( handle, buffer, numFrames ) ) != numFrames )
{
if( retval == -EPIPE )
{
cerr << "overrun " << endl;
snd_pcm_prepare( handle );
}
else if ( reval < 0 )
{
cerr << "Error : " << snd_strerror( retval ) << endl;
break;
}
}

// buffer processing logic here
}

我们一直有行为问题(每秒没有获得完整的 8K 样本,而且时间很奇怪),所以我在 snd_pcm_readi 循环周围添加了 gettimeofday 时间戳,以查看时间是如何使用的,我得到了以下信息:

循环 1:1.017 秒
循环 2:2.019 秒
循环 3:0(小于 1ms)
循环 4:2.016 秒
循环 5 : .001 秒

.. 2 循环模式继续(偶数运行 2.01x 秒,奇数运行 0-1 毫秒)在剩余的运行中。这意味着我平均每秒获得的样本少于 8000 个(每运行 10 分钟损失似乎约为 3 秒)。这与其他收集的数据不能很好地同步。此外,我们希望以大约 1 秒的间隔处理数据,而不是每 2 秒左右有 2 个背靠背进程。
作为附加检查,我打印出缓冲区值正在设置硬件参数,我得到以下信息:

缓冲区大小:43690
周期 : 5
期间大小:8000
周期时间:1000000
费率 : 8000

所以最后我有两个问题:

1) 为什么我得到低于 8 Khz 的实际数据? (可能的理论,实际硬件并不完全在 8KHz,即使 ALSA 认为它可以做到)。

2)为什么读取的 2 秒/0 秒循环应该是 1 秒?怎样才能让它达到真正的 1 秒周期?

谢谢您的帮助。
戴尔·彭宁顿

最佳答案

snd_pcm_readi()返回尽可能多的可用样本。如果设备处于非阻塞模式,它不会等待更多。

你只有 retval sample 。如果您想一次处理 8000 个样本,请调用 snd_pcm_readi()在与剩余缓冲区的循环中。

关于c++ - ALSA 捕获丢失的帧,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/59546482/

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