ALSA:途径prevent欠载扬声器 [英] ALSA: Ways to prevent underrun for speaker

查看:1925
本文介绍了ALSA:途径prevent欠载扬声器的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我玩在非交错模式单个信道音频。我得到溢的时候我写aduio数据转换成喇叭: ALSA lib目录pcm.c:7339:(snd_pcm_recover)发生欠载

下面是如何我写:

 的printf(%d个,snd_pcm_avail(spkhandle));
    RET = snd_pcm_writen(spkhandle,pSpeakerBuf,framesIn18Millisec);
    如果(RET℃下)
    {
        snd_pcm_recover(spkhandle,RET,0);
    }

根据什么是运行在不同的方式/参数配置,以prevent ALSA?

(我使用Linux 3.0,ARM)

编辑:
下面是使用snd_pcm_avail()API一个缓冲区测量

  snd_pcm_avail = 2304<< snd_pcm_writen电话1成功
      snd_pcm_avail = 2160<< snd_pcm_writen呼叫2成功
      snd_pcm_avail = 2016年<< snd_pcm_writen通话3分成功
      snd_pcm_writen错误-32断管<< snd_pcm_writen呼叫失败4
      ALSA lib目录pcm.c:7339:发生(snd_pcm_recover)欠载<<并显示此消息

下面是马尔科请求的输出:

  snd_output_t *总分;
....
//做ALSA参数初始化....
....
snd_output_stdio_attach(安培;出,标准错误,0);
snd_pcm_dump_sw_setup(spkhandle,出);  tstamp_mode:无
  period_step:1
  avail_min:144
  period_event:0
  start_threshold:288
  stop_threshold:2304
  silence_threshold:0
  silence_size:0
  边界:1207959552


解决方案

我想这code在紧密循环运行,并打算在 snd_pcm_writen()。取样率没有给出;我认为48kHz的,因为号码均能分裂。

我想会在这里如下:


  • snd_pcm_write()并不能保证写出提供(返回值只会检查错误条件)的所有帧。从的snd_pcm_avail()这实际上消耗 avail_min 144 每帧。这是音频为3ms。

  • 假设音频没有在这一点上运行时,两个写后,在缓冲的帧的数目等于 start_threshold - 在 288 样本;音频输出开始

  • 来电的printf()块,我似乎记得 snd_pcm_avail()已与同步音频输出硬件也可能阻挡。既然你现在提前为6ms的播放,这是完全有可能的缓冲运行在干燥的第三个电话的时间 snd_pcm_writen()

在总之,你不应该调用的printf()在这一点上,你可能需要补偿事实,即 snd_pcm_writen() 不消耗所有的帧的 pSpeakerBuf

I am playing a single channel audio in non-interleaved mode. I am getting underrun when I am writing aduio data into speaker : ALSA lib pcm.c:7339:(snd_pcm_recover) underrun occurred

Here is how I write:

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

What are the different ways/parameter configurations to prevent ALSA under run ?

(I am using Linux 3.0, ARM )

Edit: Here is a buffer measurement using 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

Here is the output that Marko requested for:

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

解决方案

I assume this code runs in a tight loop and is intended to block on snd_pcm_writen(). The sample-rate isn't given; I assume 48kHz since the numbers all divide nicely.

What I think is going here is as follows:

  • snd_pcm_write() doesn't guarantee to write all frames provided (the return value is only ever checked for error conditions). Judging from the logging of snd_pcm_avail() it's in fact consuming avail_min or 144 frames on each. This is 3ms of audio.
  • Assuming that audio is not running at this point, after two writes, the number of frames in the buffer is equal to start_threshold - at 288 samples; audio output starts
  • calls to printf() block, and I seem to remember that snd_pcm_avail() has to synchronise with the audio output hardware and might also block. Since you are now 6ms ahead of the playback, it's entirely possible that the buffer is running dry during the time of the third call of snd_pcm_writen()

In summary, you shouldn't be calling printf() at this point, and you probably need to compensate for fact that snd_pcm_writen() isn't consuming all of the frames in pSpeakerBuf

这篇关于ALSA:途径prevent欠载扬声器的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆