我在非交错模式下播放单声道音频。当我将音频数据写入扬声器时,我变得不安全: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

最佳答案

我假设此代码在一个紧密循环中运行,并且打算在snd_pcm_writen()上进行阻止。没有给出采样率;我假设48kHz,因为数字都很好地相除。

我认为这里的内容如下:

  • snd_pcm_write()不保证写出所有提供的帧(仅检查返回值是否有错误情况)。从snd_pcm_avail()的日志记录来看,实际上每个帧都在消耗avail_min144帧。这是3毫秒的音频。
  • 假设此时音频未运行,则在两次写入之后,缓冲区中的帧数等于start_threshold-在288样本处;音频输出开始
  • 调用printf()块,我似乎还记得snd_pcm_avail()必须与音频输出硬件同步,并且也可能会阻塞。由于您现在比回放快6毫秒,因此在第三次调用snd_pcm_writen()
  • 的过程中,缓冲区完全有可能耗尽

    总而言之,您此时不应该调用printf(),并且您可能需要弥补snd_pcm_writen()并没有消耗pSpeakerBuf中的所有帧这一事实。

    关于c - ALSA:防止扬声器欠载的方法,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/14601666/

    10-16 05:15