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

Lun*_*oms 5 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);
    }
Run Code Online (Sandbox Code Playgroud)

有什么不同的方法/参数配置可以防止运行中的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
Run Code Online (Sandbox Code Playgroud)

以下是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
Run Code Online (Sandbox Code Playgroud)

mar*_*rko 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

  • 抱歉,你是怎么得到的,你是如何更新你的 alsa 驱动程序的? (3认同)