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

发布于 2024-11-30 02:03:06 字数 1164 浏览 1 评论 0原文

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

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。显然,我似乎没有传递正确数量的数据。 write(),但我不知道该去哪里。我主要通过找到的示例将这些代码放在一起,并且我刚刚开始使用 alsaaudio / sound,尝试将一些有趣的项目放在一起,所以我还不知道很多。

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

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

I'm trying to record data from my microphone and then play it back through the speakers in real time, and with some delays, but I'm having some problems with it. I chose to use python and alsaaudio, and my current script I'm having problems with can be found here. This works with what I have this far(not the delay part), but produces some clicking. alsaaudio docs has this to say:

The most common reason for problems with playback of PCM audio is that writes to PCM devices must exactly match the data rate of the device.

If too little data is written to the device, it will underrun, and ugly clicking sounds will occur. Conversely, of too much data is written to the device, the write function will either block (PCM_NORMAL mode) or return zero (PCM_NONBLOCK mode).

I seem to be misunderstanding the docs, it says this about write():

PCM.write(data)

Writes (plays) the sound in data. The length of data must be a multiple of the frame size, and should be exactly the size of a period

a period in my script is 160.

it says this about read():

In PCM_NORMAL mode, this function blocks until a full period is available, and then returns a tuple (length,data) where length is the number of frames of captured data, and data is the captured sound frames as a string. The length of the returned data will be periodsize*framesize bytes.

in my script, period_size*frame_size should also be equal to 160, but when I print the length(part of tuple read() returns) i'm getting 940. Obviously I seem to not be passing the right amount of data to out.write(), but I'm not sure where to go. I put this code together mostly through examples I found, and I just started working with alsaaudio / sound, trying to put together some interesting projects, so I don't know a whole lot yet.

I also wanted to record live from the microphone, then playback with a 100ms delay, hence the commented time.sleep(). If I uncomment it, the length seems to go from 940 to -32 repeatedly, eventually causing out.write() to throw an exception (not enough data).

Could someone tell me how (or what's wrong with my script) I'd go about recording and playing back sound data in real time, and with a 100ms delay?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

无所的.畏惧 2024-12-07 02:03:06

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

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

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

you can't use sleep(0.1) to delay the output by 100ms. you need to create a buffer which hold the 100ms audio data:

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

change 10 to some number that will cause 100ms delay.

你怎么这么可爱啊 2024-12-07 02:03:06

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

Have you tried alsaloop? Try "man alsaloop". You can select latency through that command as well.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文