首页 > 解决方案 > ALSA - 非阻塞(交错)读取

问题描述

我继承了一些在 Linux 嵌入式平台上运行的 ALSA 代码。现有的实现使用and来阻塞读写。snd_pcm_readi()snd_pcm_writei()

我的任务是让它在 ARM 处理器上运行,但我发现阻塞的交错读取将 CPU 推到了 99%,所以我正在探索非阻塞读取和写入。

我按预期打开设备:

snd_pcm_handle *handle;
const char* hwname = "plughw:0"; // example name

snd_pcm_open(&handle, hwname, SND_PCM_STREAM_CAPTURE, SND_PCM_NONBLOCK);

然后会发生其他 ALSA 内容,我可以根据要求提供。
在这一点上值得注意的是:

像这样读取流:

int32* buffer; // buffer set up to hold #period_size samples
int actual = snd_pcm_readi(handle, buffer, period_size);

此调用在阻塞模式下完成大约需要 15 [ms]。显然,变量actual将在返回时读取 1024。

问题是; 在非阻塞模式下,此函数也需要 15 毫秒才能完成,并且actual返回时始终读取 1024。

我希望该函数会立即返回,actual<=1024 并且很可能读取“EAGAIN”(-11)。

在读取尝试之间,我计划让线程休眠一段特定的时间,从而将 CPU 时间留给其他进程。

我误解了 ALSA API 吗?或者可能是我的代码缺少关键步骤?

标签: calsa

解决方案


如果函数返回值 1024,则在调用时至少有 1024 帧可用。(有可能 15 毫秒是驱动程序实际启动设备所需的时间。)

无论如何,阻塞或非阻塞模式对 CPU 使用率没有任何影响。要减少 CPU 使用率,请将default设备替换为plughwhw,但随后您将失去设备共享或采样率/格式转换等功能。


推荐阅读