ALSA捕获丢失的帧

问题描述 投票:1回答:1

我继承了一段代码,该代码块使用ALSA捕获8KHz,8位,1通道的音频输入。该代码看起来非常简单,将通道设置为1,速率设置为8000,周期大小设置为8000。该程序的目标是一次以30分钟以上的时间块收集音频数据。

主循环看起来像

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 ms)。这意味着我平均每秒获得的采样数少于8000个(每运行10分钟大约损失3秒)。这不能与其他收集的数据很好地同步。同样,我们希望以大约1秒的间隔处理数据,而不是每2秒左右进行2次背对背处理。作为另一项检查,我打印出了设置硬件参数的缓冲区值,并得到以下信息:

缓冲区大小:43690期间:5期间大小:8000期间:1000000速率:8000

所以最后我有两个问题:

1)为什么我要获得小于8 Khz的实际数据? (可能的理论是,即使ALSA认为可以做到,实际的硬件也不是8KHz。)

2)为什么读取的2秒/ 0秒周期应为1秒?如何使它达到真正的1秒周期?

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

我已经继承了一大堆使用ALSA捕获8KHz,8位,1通道音频输入的代码。该代码看起来很简单,将通道设置为1,速率设置为8000,周期大小设置为8000。...

c++ alsa
1个回答
0
投票

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

© www.soinside.com 2019 - 2024. All rights reserved.