ALSA:防止发言人不足的方法

时间:2013-01-30 10:24:17

标签: c linux audio alsa

我正在以非交错模式播放单声道音频。当我将音频数据写入扬声器时,我得到了不足:ALSA lib pcm.c:7339:(snd_pcm_recover) underrun occurred

以下是我的写作方式:

    printf("%d",snd_pcm_avail (spkhandle));  
    ret = snd_pcm_writen(spkhandle, pSpeakerBuf , framesIn18Millisec);
    if(ret < 0)
    {
        snd_pcm_recover(spkhandle, ret, 0);
    }

有什么不同的方法/参数配置可以阻止ALSA运行?

(我正在使用Linux 3.0,ARM)

编辑: 这是使用snd_pcm_avail()API

的缓冲区测量
      snd_pcm_avail = 2304      << snd_pcm_writen call 1 success
      snd_pcm_avail = 2160      << snd_pcm_writen call 2 success
      snd_pcm_avail = 2016      << snd_pcm_writen call 3 success
      snd_pcm_writen error -32 Broken pipe  << snd_pcm_writen call 4 failure
      ALSA lib pcm.c:7339:(snd_pcm_recover) underrun occurred  << And displays this message

以下是Marko要求的输出:

snd_output_t* out;
....
// Do alsa parameters init .... 
....
snd_output_stdio_attach(&out, stderr, 0);
snd_pcm_dump_sw_setup(spkhandle, out);

  tstamp_mode  : NONE
  period_step  : 1
  avail_min    : 144
  period_event : 0
  start_threshold  : 288
  stop_threshold   : 2304
  silence_threshold: 0
  silence_size : 0
  boundary     : 1207959552

2 个答案:

答案 0 :(得分:5)

我假设此代码在紧密循环中运行,并且旨在阻止snd_pcm_writen()。没有给出采样率;我假设48kHz,因为数字都很好地划分。

我认为这里的内容如下:

  • snd_pcm_write()不保证写入提供的所有帧(仅在错误条件下检查返回值)。从snd_pcm_avail()的日志记录来看,它实际上每个都在消耗avail_min144帧。这是3ms的音频。
  • 假设此时音频没有运行,在两次写入之后,缓冲区中的帧数等于start_threshold - 288个样本;音频输出开始
  • 调用printf()阻止,我似乎记得snd_pcm_avail()必须与音频输出硬件同步,并且还可能阻止。由于您现在比播放时间提前了6ms,因此在第三次调用snd_pcm_writen()
  • 期间,缓冲区完全可能正在运行。

总而言之,此时您不应该调用printf(),而您可能需要补偿snd_pcm_writen()没有消耗pSpeakerBuf <中所有帧的事实/ p>

答案 1 :(得分:0)

这是缓冲区欠载,您可以尝试通过在〜/ .asoundrc文件中明确提及来增加缓冲区大小吗?