播放音频时Alsa缓冲区溢出

时间:2014-05-21 08:01:49

标签: buffer playback pcm alsa overrun

我已将IMX板连接到电脑背靠背。 我在板上运行二进制文件,每隔5.7ms发送一次1024字节的音频帧。 PC使用

接收帧和写入
printf("snd_pcm_avail %d \n",snd_pcm_avail (FMWK.FMWK_Handler.playback_handle));

err = snd_pcm_writei(FMWK.FMWK_Handler.playback_handle, OutputPointer, PERIOD_BYTES);

当播放发生时,每隔6秒钟我就会破坏管道

成功播放正在运行时的日志

snd_pcm_avail 32 
snd_pcm_avail 17 
snd_pcm_avail 81 
snd_pcm_avail 25 
snd_pcm_avail 89 
snd_pcm_avail 32 
snd_pcm_avail 17 
snd_pcm_avail 81 
snd_pcm_avail 32 
snd_pcm_avail 17 
snd_pcm_avail 81 
snd_pcm_avail 25 
snd_pcm_avail 89 
snd_pcm_avail 32 
snd_pcm_avail 17 
snd_pcm_avail 81 

大约减少56 5秒后,avail增加,缓冲区溢出buffer_size = 256

的配置限制

日志:

snd_pcm_avail 89 
snd_pcm_avail 112 
snd_pcm_avail 96 
snd_pcm_avail 120 
snd_pcm_avail 104 
snd_pcm_avail 129 
snd_pcm_avail 153 
snd_pcm_avail 137 
snd_pcm_avail 160 
snd_pcm_avail 184 
snd_pcm_avail 168 
snd_pcm_avail 193 
snd_pcm_avail 176 
snd_pcm_avail 201 
snd_pcm_avail 224 
snd_pcm_avail 209 
snd_pcm_avail 232 
snd_pcm_avail 217 
snd_pcm_avail 240 
snd_pcm_avail -32 
   (AVB Info)     12:26:11 PM.606306  (Slave)               ==> Broken pipe
snd_pcm_avail 256 
snd_pcm_avail 48 

我将period_size设置为128

我不确定iam是否在snd_pcm的初始配置中遗漏了什么?这是44.1khz音频。

2 个答案:

答案 0 :(得分:3)

会发生什么情况,您的程序无法跟上设备播放PCM数据的步伐。当"断管"发生在它等待新样本的音频设备,但你的程序没有及时发送它们。

你遇到的情况是在线音频系统的祸根;不幸的是,现有的Linux音频架构(ALSA)并不是一件好事。 PulseAudio + RealtimeKit 尝试(恕我直言并不是非常成功)通过做一些奇怪而疯狂的伏都教来消除裂缝,不要让ALSA司机挨饿;一些司机被打破并且没有正确报告回放头的位置,事情变得更好。

在你的情况下,你可以做两件事:

  • 使用更大的帧(缓冲区中的更多样本)
  • 排队更多帧(排队多个缓冲区)并在队列中保留最少数量的帧

答案 1 :(得分:2)

音频设备通常有自己的采样时钟,与系统时钟不同步。

因此,您无法使用系统时钟来控制将样本发送到设备的速度;它几乎在所有系统上运行得太快或太慢。

要以正确的速度发送样品,只需尽可能快地写样品;如果缓冲区已满,snd_pcm_write *将自动等待。

如果您无法从接收方控制发送方的速度(因为它们不在同一台计算机上,并且您没有提供反馈的协议),则必须测量发送方的相对速度和接收器,并适当地重新采样数据。