【问题标题】:Alsa api: how to use mmap in c?Alsa api:如何在 c 中使用 mmap?
【发布时间】:2015-07-28 13:09:30
【问题描述】:

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

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

理解它的工作原理很简单,一切正常,我能听到声音。但是,我想尝试使用 mmap 而不是 writei,但我真的不明白。 我面临缺乏文档和明确的例子。 谁能解释 mmap 如何与 alsa 一起工作,以及如何将我的代码转换为使用 mmap 的东西?基本上,我仍然想使用缓冲区播放我的数组中的内容(所以一个短的数组,大小为一个句点)。谢谢。

【问题讨论】:

  • 您希望从使用 mmap 中获得什么?
  • 第一个原因是我很好奇,我想了解其中的区别,并能够让它发挥作用。我也希望这可以减少延迟(缓冲区稍微短一些),但我不确定会不会是这样......?

标签: c mmap alsa


【解决方案1】:

首先,您需要将访问类型设置为 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() 所做的相同)。 只有在动态生成样本并将它们直接写入设备的缓冲区时,才能减少延迟。

【讨论】:

  • 这对我帮助很大,谢谢。不过,在您的解释中添加一些内容会很好。解释如何填充缓冲区的快速行,就像这样:short* data = (short*) (areas[0].addr + (areas[0].first + offset*areas[0].step) /8 )。实际上,我认为显示如何将 mmap 与 alsa 一起使用的简短代码会很棒。类似的东西:freewebmaster.fr/up/cpp/alsaTest.c.
猜你喜欢
  • 2013-01-26
  • 2015-12-07
  • 2021-08-10
  • 2020-01-15
  • 1970-01-01
  • 2011-01-11
  • 2021-01-15
  • 2021-09-14
  • 2017-06-20
相关资源
最近更新 更多