尝试从麦克风录制并实时播放

Posted

技术标签:

【中文标题】尝试从麦克风录制并实时播放【英文标题】:Trying to record from microphone and playback in real time 【发布时间】:2011-10-29 11:34:15 【问题描述】:

我正在尝试从我的麦克风记录数据,然后通过扬声器实时回放,但有一些延迟,但我遇到了一些问题。我选择使用 python 和 alsaaudio,我当前遇到问题的脚本可以在 here 找到。这适用于我目前所拥有的(不是延迟部分),但会产生一些点击。 alsaaudio 文档有 this 说:

PCM 音频播放出现问题的最常见原因是写入 PCM 设备的数据必须与设备的数据速率完全匹配。

如果写入设备的数据太少,设备就会欠载,并且会发出难听的点击声。反之,写入设备的数据过多,写入函数将阻塞(PCM_NORMAL 模式)或返回零(PCM_NONBLOCK 模式)。

我似乎误解了文档,它说的是关于 write():

PCM.write(数据)

在数据中写入(播放)声音。数据长度必须是帧大小的倍数,并且应该正好是一个句点的大小

我脚本中的句号是 160。

它是这么说 read() 的:

在 PCM_NORMAL 模式下,该函数阻塞直到一个完整的周期可用,然后返回一个元组 (length,data),其中 length 是捕获数据的帧数,data 是捕获的声音帧作为字符串。返回数据的长度为 periodsize*framesize 字节。

在我的脚本中,period_size*frame_size 也应该等于 160,但是当我打印长度(元组 read() 返回的一部分)时,我得到 940。显然我似乎没有传递正确数量的数据到 out.write(),但我不知道该去哪里。我主要通过我找到的示例将这段代码放在一起,并且我刚开始使用 alsaaudio / sound,尝试将一些有趣的项目放在一起,所以我还不是很了解。

我还想通过麦克风实时录制,然后以 100 毫秒的延迟播放,因此注释为 time.sleep()。如果我取消注释,长度似乎从 940 到 -32 重复,最终导致 out.write() 抛出异常(数据不足)。

有人能告诉我如何(或我的脚本有什么问题)我会实时录制和播放声音数据,并有 100 毫秒的延迟吗?

【问题讨论】:

【参考方案1】:

您不能使用 sleep(0.1) 将输出延迟 100 毫秒。您需要创建一个缓冲区来保存 100 毫秒的音频数据:

buf = []
while True:
    l, data = inp.read()
    buf.append(data)
    if len(buffer)>=10:
        out.write(buf[0])
        del buf[0]

将 10 更改为会导致 100 毫秒延迟的某个数字。

【讨论】:

我明白了,谢谢。我已经这样做了,它肯定会延迟(仍然可以点击),但我不确定如何确定什么数字会导致正确的延迟。我尝试像this 这样打印经过的时间并摆弄数字,但它似乎没有改变。这似乎更能呼应 别管回声了,哈哈。麦克风离扬声器很近,呵呵。【参考方案2】:

你试过 alsaloop 吗?试试“人 alsaloop”。您也可以通过该命令选择延迟。

【讨论】:

以上是关于尝试从麦克风录制并实时播放的主要内容,如果未能解决你的问题,请参考以下文章

来自麦克风的实时音频播放。 C#

如何实时改变音量

来自 Ruby Web 应用程序的实时音频录制/播放

停止录音并继续播放音频

同时录制音频和播放 iPod?

在 iOS 中通过蓝牙播放时从内置麦克风录制