首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >在使用snd_pcm_writei()播放音频时,如何正确处理ALSA编程中的xrun?

在使用snd_pcm_writei()播放音频时,如何正确处理ALSA编程中的xrun?
EN

Stack Overflow用户
提问于 2019-12-18 16:51:01
回答 1查看 3.2K关注 0票数 3

我尝试过多个示例程序,这些程序的代码似乎可以在播放时处理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)时,它们会:

代码语言:javascript
运行
复制
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()还是可以使用这些其他调用?有什么关系?我该用什么?

EN

回答 1

Stack Overflow用户

发布于 2019-12-18 22:05:27

处理不足的最好方法是避免通过防止它们来处理它们。这可以通过在缓冲区为空之前尽早编写示例来完成。为了做到这一点,

当您需要调用进程/线程的优先级时(如果可能,这可能的话;如果其他程序干扰您的磁盘OI/O),and/or

  • increase缓冲区大小(这也会增加延迟),则
  • 会重新组织您的程序,以便编写新的示例。

当出现运行不足时,您必须决定如何处理本应播放但未在正确时间写入缓冲区的示例。

  • 要在稍后播放这些示例(即将所有后续示例移到稍后时间),配置设备,使运行不足的设备停止运行。(这是默认设置。)当设备有新的样本时,您的程序必须重新启动。
  • 要同时继续使用以下示例,就好像已经实际播放了丢失的示例一样,配置设备,这样运行不足就不会停止它。这可以通过将停止阈值设置为边界值2来完成。(其他错误,如拔出USB设备,仍将停止该设备。)

当出现运行不足时,设备将播放那些碰巧在环形缓冲区中的示例。默认情况下,这些是一段时间前的旧样本,听起来不正确。若要播放静音(这听起来也不正确,但以不同的方式),请告诉设备在播放后立即清除缓冲区的每一部分,方法是将静音阈值设置为零,将静音大小⁴设置为边界值。

要(尝试)在出现错误( 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():⁴静默大小

票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/59396728

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档