【发布时间】:2020-04-11 06:48:41
【问题描述】:
我已经尝试了多个示例程序,这些示例程序似乎具有处理回放下的 xruns 的代码:
https://albertlockett.wordpress.com/2013/11/06/creating-digital-audio-with-alsa/
https://www.linuxjournal.com/article/6735(清单 3)
当使用 snd_pcm_writei() 时,似乎当返回值为 -EPIPE(即 xrun/underrun)时,它们会这样做:
if (rc == -EPIPE) {
/* EPIPE means underrun */
fprintf(stderr, "underrun occurred\n");
snd_pcm_prepare(handle);
}
即在句柄上调用 snd_pcm_prepare()。
但是,当我尝试运行此类程序时,我仍然会口吃。通常情况下,我会得到至少几个,可能是半打 xrun,然后它会流畅连续地播放而无需进一步的 xrun。但是,如果我有其他使用声卡的东西,比如 Firefox,我会得到更多的 xruns,有时只有 xruns。但同样,即使我杀死任何其他使用声卡的程序,我仍然会遇到一些初始 xruns 和扬声器实际卡顿的问题。
这对我来说是不可接受的,我该如何修改这种类型的 xrun 处理以防止卡顿?
我自己尝试解决这个问题:
从 ALSA API,我看到 snd_pcm_prepare() 可以:
准备 PCM 以供使用。
这对像我这样的 ALSA 初学者帮助不大。没有说明如何使用它来恢复 xrun 问题。
我还注意到,来自:https://www.alsa-project.org/alsa-doc/alsa-lib/pcm.html
SND_PCM_STATE_XRUN PCM 设备达到溢出(捕获)或欠载(播放)。您可以使用来自 I/O 函数的 -EPIPE 返回码 (snd_pcm_writei(), snd_pcm_writen(), snd_pcm_readi(), snd_pcm_readn()) 在不检查实际状态的情况下通过以下方式确定此状态 snd_pcm_state() 调用。推荐使用辅助功能 snd_pcm_recover() 从这个状态恢复,但你也可以使用 snd_pcm_prepare()、snd_pcm_drop() 或 snd_pcm_drain() 调用。
我也不清楚。我可以使用 snd_pcm_prepare() 还是可以使用这些其他调用?有什么区别?我应该使用什么?
【问题讨论】: