alsa: 每次欠载时延迟都会增加

3 人关注

我正在写一个典型的捕获-处理-回放循环。使用 snd_pcm_readi() 捕获,一些廉价的音频处理,然后通过 snd_pcm_writei() 回放。单线程。 在128个周期大小和96000KHz下,我感觉不到任何延迟。很好。

我周期性地得到一个缓冲区不足( snd_pcm_writei() 返回-EPIPE);没关系,我运行的是普通的Ubuntu 16.04桌面,没有配置低音频延迟。

在一些不足的情况下,延迟变得可察觉。我不明白为什么。

这是我的捕获设备配置。

Plug PCM: Linear Integer <-> Linear Float conversion PCM (S32_LE)
Its setup is:
  stream       : CAPTURE
  access       : RW_INTERLEAVED
  format       : FLOAT_LE
  subformat    : STD
  channels     : 1
  rate         : 96000
  exact rate   : 96000 (96000/1)
  msbits       : 32
  buffer_size  : 4096
  period_size  : 128
  period_time  : 1333
  tstamp_mode  : NONE
  tstamp_type  : MONOTONIC
  period_step  : 1
  avail_min    : 128
  period_event : 0
  start_threshold  : 0
  stop_threshold   : 4096
  silence_threshold: 0
  silence_size : 0

这就是播放设备的配置。

Plug PCM: Linear Integer <-> Linear Float conversion PCM (S32_LE)
Its setup is:
  stream       : PLAYBACK
  access       : RW_INTERLEAVED
  format       : FLOAT_LE
  subformat    : STD
  channels     : 1
  rate         : 96000
  exact rate   : 96000 (96000/1)
  msbits       : 32
  buffer_size  : 384
  period_size  : 128
  period_time  : 1333
  tstamp_mode  : NONE
  tstamp_type  : MONOTONIC
  period_step  : 1
  avail_min    : 128
  period_event : 0
  start_threshold  : 384
  stop_threshold   : 384
  silence_threshold: 0
  silence_size : 0
  boundary     : 6917529027641081856

当欠载发生时,我运行snd_pcm_recover(),忘记了刚刚被snd_pcm_writei()拒绝的音频周期。在我看来,只要我运行snd_pcm_writei(),下一个音频周期就会被播放,我将再次进入一个低延迟的循环。但这是错误的,延迟会增加。

我的循环的捕获端没有错误。

发生了什么事?我做错了什么?

linux
alsa
Claudio
Claudio
发布于 2018-05-25
1 个回答
CL.
CL.
发布于 2018-05-25
已采纳
0 人赞同

捕获缓冲区比播放缓冲区大。这是一个好主意,可以减少捕获超限的风险(如果硬件支持的话,你可能想让它变得更大),但当播放设备短暂停止时,更多的数据将堆积在捕获缓冲区,并且不会比你播放的速度更快。

为了确保捕获和播放设备不失去同步性,要么