ALSA:snd_pcm_writei 返回 EAGAIN

Posted

技术标签:

【中文标题】ALSA:snd_pcm_writei 返回 EAGAIN【英文标题】:ALSA: snd_pcm_writei returns EAGAIN 【发布时间】:2018-09-10 13:49:01 【问题描述】:

我很难理解我在音频播放程序中做错了什么。 我有一个线程从其他线程获取缓冲区并以与此 alsa 示例程序相同的方式播放它们:https://www.alsa-project.org/alsa-doc/alsa-lib/_2test_2pcm_8c-example.html 我指的是 write_loop() 函数。这是 pcm.c 示例程序的设备配置设置(snd_pcm_dump() 的输出):

ALSA <-> PulseAudio PCM I/O Plugin
Its setup is:
  stream       : PLAYBACK
  access       : RW_INTERLEAVED
  format       : S16_LE
  subformat    : STD
  channels     : 1
  rate         : 44100
  exact rate   : 44100 (44100/1)
  msbits       : 16
  buffer_size  : 22050
  period_size  : 4410
  period_time  : 100000
  tstamp_mode  : NONE
  tstamp_type  : GETTIMEOFDAY
  period_step  : 1
  avail_min    : 4410
  period_event : 0
  start_threshold  : 22050
  stop_threshold   : 22050
  silence_threshold: 0
  silence_size : 0
  boundary     : 6206523236469964800

我看到在 snd_pcm_writei() 周围放置一些 printf() 是它直接执行 5 次,并且每个下一个循环 snd_pcm_writei() 需要 100 毫秒才能完成。这正是我期望看到的。

这是我的程序的设备设置:

ALSA <-> PulseAudio PCM I/O Plugin
Its setup is:
  stream       : PLAYBACK
  access       : RW_INTERLEAVED
  format       : FLOAT_LE
  subformat    : STD
  channels     : 1
  rate         : 44100
  exact rate   : 44100 (44100/1)
  msbits       : 32
  buffer_size  : 13230
  period_size  : 4410
  period_time  : 100000
  tstamp_mode  : NONE
  tstamp_type  : GETTIMEOFDAY
  period_step  : 1
  avail_min    : 4410
  period_event : 0
  start_threshold  : 4410
  stop_threshold   : 13230
  silence_threshold: 0
  silence_size : 0
  boundary     : 7447827883763957760

发生的情况是 snd_pcm_writei() 运行 5 次(这没关系),但之后每个新循环都会立即返回 -EAGAIN。连续重试 100 毫秒(100% cpu 使用率)以播放相同的缓冲区,最终它被播放,snd_pcm_writei() 返回一个正数,对于下一个音频缓冲区,我立即得到 -EAGAIN,持续 100 毫秒;等等。但是,音频播放很好。

我不明白为什么它不等待 100 毫秒来播放新缓冲区而不是立即返回 -EAGAIN(在 ALSA 文档中找不到任何关于 snd_pcm_writei() 返回 -EAGAIN 的内容)。

提前感谢您的帮助!

【问题讨论】:

【参考方案1】:

PCM 设备可以处于阻塞模式(等待)或非阻塞模式(返回 -EAGAIN)。

此模式可以在调用snd_pcm_open() 时使用标志设置,也可以使用snd_pcm_nonblock() 设置。

【讨论】:

以上是关于ALSA:snd_pcm_writei 返回 EAGAIN的主要内容,如果未能解决你的问题,请参考以下文章

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

ALSA - 非阻塞(交错)读取

ALSA:如何判断声音何时播放完毕

使用 ALSA API 播放唱名笔记?

Alsa:snd_pci_readi() 和实时线程

ea的顺序图的返回虚线怎么画