c - ALSA - 非阻塞(交错)读取

标签 c alsa

我继承了一些在 Linux 嵌入式平台上运行的 ALSA 代码。 现有的实现使用 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 内容。
在这一点上值得注意的是:

  • 我们将采样率设置为 48,000 [Hz]
  • 样本类型为有符号32位整数
  • 设备总是将我们请求的周期大小覆盖为 1024 帧

像这样读取流:

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

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

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

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

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

我是不是误解了 ALSA API?还是我的代码缺少一个重要步骤?

最佳答案

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

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

关于c - ALSA - 非阻塞(交错)读取,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/56886610/

相关文章:

c - 尝试将数组转换为具有空字符的字符串时程序崩溃

c++ - 当我使用 ALSA 库的函数 `snd_pcm_readi` 时它崩溃了

c - 为什么 portaudio 会突然返回回调?

audio - 如何处理音频流中的时钟偏差

arrays - C中的String和Null终止字符数组在字面上有什么区别吗

c - 如何比较C中字符串的结尾?

c - sizeof() 运算符的输出数据类型

c - gmp库的mdi_init的C实现

vlc - Pulseaudio 将 RTP 输出到互联网

python - 如何以编程方式更改 Ubuntu 中的音量