MMAP 是我需要从 ALSA 获得的在我的游戏中同时播放即时声音的东西吗?

Is MMAP what I need from ALSA to play simultaneous, immediate sounds in my game?

我是 ALSA 的新手,我已经设法在 SND_PCM_ACCESS_RW_INTERLEAVED 模式下播放 PCM 声音。我的问题是我无法找到一种方法来使该模式对我正在尝试做的事情有用。 (如果有人能告诉我怎么做,我会很乐意阅读)。我一直在阅读这个 MMAP 模式,但要找到它的简单示例并不容易。我想知道它是否是我需要的,我该如何实现它。

我想做的是让我的小游戏(一个简单的 space 射击游戏)在我射击或被击中时立即播放声音。如果敌人在播放另一个声音时开枪,则声音应根据需要叠加并饱和,但不应中断任何声音事件。换句话说,我需要能够编辑即将播放的字节。

在我尝试 MMAP 的无用尝试中(并不知道它在实践中是如何工作的;只是遵循模糊的理论指导),我设置了所有与 SND_PCM_ACCESS_RW_INTERLEAVED 相同的内容,但将其更改为 SND_PCM_ACCESS_MMAP_INTERLEAVED.然后我调用 snd_pcm_avail_update,这似乎有效,并且 returns 有大量可用帧。之后,我调用 snd_pcm_mmap_begin,传递参数,之前用合理的数字(例如 10)填充 "frames"。该函数失败并且 returns 错误代码 -77。我没能找到那是什么意思。区域数组保持不变。

这个错误是什么意思?我在哪里可以获得错误列表?我怎样才能克服它?是否有一个好的、简单的示例说明如何使用 MMAP(或其他东西)来执行或多或少像我正在尝试做的事情?

感谢您的帮助:)

ALSA returns 负值错误。 77 很可能是 EBADFD,表示设备处于无效状态(under/overrun 或根本不是 运行)。如果出现欠载,您可能使用的缓冲区大小太低。

在任何情况下,都无法修改您已经提交给 alsa 驱动程序的音频数据 (snd_pcm_mmap_commit/writei/writen)。立即获得音频声音的诀窍是使用非常小的缓冲区大小,< 10ms 就可以了。为此,您需要使用 hw: 设备,其他设备类型通常会增加延迟。

在将声音传递给 alsa 之前,您仍然需要手动将声音混合在一起。 在这个问题的评论中有一个很好的 mmap 示例:Alsa api: how to use mmap in c?.

也就是说,ALSA 是此类应用程序的有效选择,但您不一定需要使用内存映射。 Read/write 访问不会引入额外的延迟,它只是将音频复制多一点。