阿尔萨:snd_pcm_writei returns EAGAIN
ALSA: snd_pcm_writei returns EAGAIN
我很难理解我在音频播放例程中做错了什么。
我有一个线程从其他线程获取缓冲区并以与此 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 次(这没关系),但之后每个新循环它 returns 立即使用 -EAGAIN。连续重试 100 毫秒(100% cpu 使用率)播放相同的缓冲区,最终它被播放,snd_pcm_writei() returns 一个正数,对于下一个音频缓冲区,我立即得到 -EAGAIN,持续 100 毫秒;等等。不过音频播放还好。
我不明白的是为什么它不等待 100 毫秒来播放新缓冲区而不是立即返回 -EAGAIN(在 ALSA 文档中找不到任何关于 snd_pcm_writei() 返回 -EAGAIN 的信息)。
在此先感谢您的帮助!
PCM 设备可以处于阻塞模式(等待)或处于 non-blocking 模式(返回 -EAGAIN)。
此模式可以在调用 snd_pcm_open()
时用标志设置,或用 snd_pcm_nonblock()
.
我很难理解我在音频播放例程中做错了什么。 我有一个线程从其他线程获取缓冲区并以与此 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 次(这没关系),但之后每个新循环它 returns 立即使用 -EAGAIN。连续重试 100 毫秒(100% cpu 使用率)播放相同的缓冲区,最终它被播放,snd_pcm_writei() returns 一个正数,对于下一个音频缓冲区,我立即得到 -EAGAIN,持续 100 毫秒;等等。不过音频播放还好。
我不明白的是为什么它不等待 100 毫秒来播放新缓冲区而不是立即返回 -EAGAIN(在 ALSA 文档中找不到任何关于 snd_pcm_writei() 返回 -EAGAIN 的信息)。
在此先感谢您的帮助!
PCM 设备可以处于阻塞模式(等待)或处于 non-blocking 模式(返回 -EAGAIN)。
此模式可以在调用 snd_pcm_open()
时用标志设置,或用 snd_pcm_nonblock()
.