c - 阿尔萨 API : how to use mmap in c?

标签 c mmap alsa

我目前正在使用 snd_pcm_writei 播放一个声音文件,该文件之前加载到一个短数组(16 位 PCM 格式)中。为了播放这个声音,我创建了一个缓冲区(短*),其中包含一个句点(或片段)。然后,我使用一个 while 循环来调用 snd_pcm_writei,它给了我那一行:

int err = snd_pcm_writei(handle, buffer, frames);

理解它的工作原理非常简单,一切正常,我能听到声音。但是,我想尝试使用 mmap 而不是 writei,但我不太明白。 我面临着缺乏文档和清晰示例的问题。 谁能解释 mmap 如何与 alsa 一起工作,以及如何将我的代码转换为使用 mmap 的代码?基本上,我仍然想使用缓冲区播放数组中的内容(因此是一个长度为一个周期的 short 数组)。谢谢。

最佳答案

首先,您需要将访问类型设置为 MMAP 类型之一(通常是 SND_PCM_ACCESS_MMAP_INTERLEAVED 而不是 SND_PCM_ACCESS_RW_INTERLEAVED)。

当您想写入缓冲区时,调用 snd_pcm_mmap_begin() 并传入您要写入的帧数。如果此函数成功,它会返回一个指向缓冲区的指针(areas[0].addr,或非交错或复杂访问类型的多个指针),缓冲区中的偏移量(offset ),以及您实际可以写入多少帧。

编写示例后,调用 snd_pcm_mmap_commit() 并使用您编写的实际帧数。


请注意,当您将样本从您自己的缓冲区复制到设备的缓冲区时,使用 mmap 没有任何意义(这完全snd_pcm_writei()已经这样做了)。 只有在动态生成样本并将它们直接写入设备缓冲区时,才能减少延迟。

关于c - 阿尔萨 API : how to use mmap in c?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/30279326/

相关文章:

linux - 如何编写符合 ALSA 的虚拟设备驱动程序?

linux - 使ARM/WM8350音频和电源管理在Linux中工作

c - 为什么 a+++++b 不起作用?

c - 在进程空间之外查看 GDB 中的内存 (mmap)

c - ALSA:如何在设备列表中找到设备,但在打开它时仍然收到 "No such file or directory"?

c++ - 对 mmap 和 munmap 的 undefined reference

linux - O_SYNC 写入何时在页面缓存(mmap 文件)中可见?

c - 当我尝试使用函数中通过引用传递的预分配矩阵读取值时出现段错误

c - 使用 C 例程和 openssl dgst、rsautl 命令时的不同签名

c - 使用 SIMD,如何将 8 位掩码扩展为 16 位掩码?