我尝试过多个示例程序,这些程序的代码似乎可以在播放时处理xrun:
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,我会得到更多的xrun,有时只运行xrun。但是,即使我杀死了使用声卡的任何其他程序,我仍然会遇到一些初始的xrun和扬声器上的实际口吃问题。
这对我来说是不可接受的,我如何修改这种类型的xrun处理以防止口吃?
我自己也想弄明白这一点:
从ALSA中,我看到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()还是可以使用这些其他调用?有什么关系?我该用什么?
发布于 2019-12-18 22:05:27
处理不足的最好方法是避免通过防止它们来处理它们。这可以通过在缓冲区为空之前尽早编写示例来完成。为了做到这一点,
当您需要调用进程/线程的优先级时(如果可能,这可能的话;如果其他程序干扰您的磁盘OI/O),and/or
当出现运行不足时,您必须决定如何处理本应播放但未在正确时间写入缓冲区的示例。
当出现运行不足时,设备将播放那些碰巧在环形缓冲区中的示例。默认情况下,这些是一段时间前的旧样本,听起来不正确。若要播放静音(这听起来也不正确,但以不同的方式),请告诉设备在播放后立即清除缓冲区的每一部分,方法是将静音阈值设置为零,将静音大小⁴设置为边界值。
要(尝试)在出现错误( xrun或其他错误)后重新初始化设备,可以调用snd_pcm_prepare()
或snd_pcm_recover()
。后者调用前者,并处理挂起的设备(通过等待恢复)。
止损阈值:snd_pcm_sw_params_set_stop_threshold()
平方边值:snd_pcm_sw_params_get_boundary()
静默阈值:snd_pcm_sw_params_set_silence_threshold()
snd_pcm_sw_params_set_silence_size()
:⁴静默大小
https://stackoverflow.com/questions/59396728
复制相似问题