【问题标题】:Using ALSA, how to record with a microphone what it is just playing out through a speaker?使用 ALSA,如何用麦克风录制刚刚通过扬声器播放的内容?
【发布时间】:2013-04-05 18:32:15
【问题描述】:

我正在尝试使用以下 ALSA API 录制刚刚向演讲者播放的内容:

snd_pcm_mmap_writei()
snd_pcm_mmap_readi()

这两个函数在同一个线程中被一个接一个地调用。 writei() 函数快速返回(我相信它会在播放缓冲区可用时返回),而 readi() 会返回直到捕获指定的样本。但捕获的样本并不是刚刚播出的。我猜ALSA不是在双工模式下,即它必须先完成播放,然后开始录制,它没有记录任何有意义的东西,只是点击。扬声器仍能正确播放声音。

所有硬件/软件参数均已正确设置。如果我只做音频捕捉,我会得到一个很好的声波。 PCM 句柄以正常模式打开(非非阻塞,非异步)。

有人对如何使这项工作提出建议吗?

【问题讨论】:

  • 您必须配置声音硬件以将声音从播放设备路由回捕获设备。这是你做的吗?
  • 我的目的是测试我的扬声器是否正常工作,所以我必须从说话中捕捉声音。因此没有设置从播放到捕获的环回。
  • 你为什么要在同一个程序中这样做?你不能只运行aplayarecord 吗?
  • 是的 aplay 和 arecord 肯定可以工作,但我需要让我的应用程序使用缓冲区来检测运行中的扬声器故障。而且我发现这两个 ALSA API 需要放入不同的线程中,以便同步它们,这仍然很难从播放的那一刻起捕捉声音。

标签: audio capture playback pcm alsa


【解决方案1】:

您不需要使用mmap 函数;正常的writei/readi 调用就足够了。

要同时处理两个 PCM 流,请在单独的线程中运行它们,或者使用非阻塞模式,以便同一个事件循环可以处理两个设备。

您需要在播放数据之前填充播放缓冲区,并且只有在填充了捕捉缓冲区后才能读取捕捉数据,因此总延迟是播放缓冲区大小加上捕捉周期大小加上任何硬件延迟和声音传播延迟。

【讨论】:

    猜你喜欢
    • 2015-10-31
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-04-28
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多