ALSA 需要 MMAP 来在我的游戏中同时播放即时声音吗?

Posted

技术标签:

【中文标题】ALSA 需要 MMAP 来在我的游戏中同时播放即时声音吗?【英文标题】:Is MMAP what I need from ALSA to play simultaneous, immediate sounds in my game? 【发布时间】:2016-04-28 06:33:25 【问题描述】:

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

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

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

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

感谢您的帮助:)

【问题讨论】:

【参考方案1】:

ALSA 出错时返回负值。 77 很可能是 EBADFD,它指示设备处于无效状态(欠载/溢出或根本不运行)。如果发生欠载,您可能使用的缓冲区大小太低。

在任何情况下,都无法修改您已经提交给 alsa 驱动程序 (snd_pcm_mmap_commit/writei/writen) 的音频数据。立即获得音频声音的诀窍就是使用非常小的缓冲区大小,

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

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

【讨论】:

谢谢。这非常有用。万一有人觉得有趣,在阅读此回复时,我已经想出了解决问题的方法,但我仍然无法使用 MMAP。尽管如此,我没想到我可以简单地使用低缓冲区大小。我所做的是使用多个手柄并将每个手柄视为一个“通道”来播放同时声音。不过,这个答案正是我要问的。我很感激。

以上是关于ALSA 需要 MMAP 来在我的游戏中同时播放即时声音吗?的主要内容,如果未能解决你的问题,请参考以下文章

在 buildroot 上找不到 Alsa 工具

ALSA 配置 如何在 asound.conf 中结合 MMAP 仿真和 Ladspa 插件

从 ALSA Raspberry Pi 获取音频幅度

为啥 ALSA 示例使用循环播放/捕获?

我想在我的 Android 游戏中播放音乐以及分析声音数据。使用 Unity C#

如何停止在我的 C 游戏中播放音频?