在低功率计算机上从 Python 生成流畅的音频

Generating smooth audio from Python on a low-powered computer

我正在尝试在 Python 中编写一个简单的音频函数生成器,成为 Raspberry Pi(模型 2)上的 运行。代码基本上是这样做的:

例如:

import pyaudio
from numpy import linspace,sin,pi,int16

def note(freq, len, amp=1, rate=44100):
 t = linspace(0,len,len*rate)
 data = sin(2*pi*freq*t)*amp
 return data.astype(int16) # two byte integers

RATE = 44100
FREQ = 261.6

pa = pyaudio.PyAudio()
s = pa.open(output=True,
            channels=2,
            rate=RATE,
            format=pyaudio.paInt16,
            output_device_index=2)

# generate 1 second of sound
tone = note(FREQ, 1, amp=10000, rate=RATE)

# play it forever    
while True:
  s.write(tone)

问题是循环的每次迭代都会在音频中产生可听见的 "tick",即使使用外部 USB 声卡也是如此。有什么办法可以避免这种情况,而不是尝试用 C 重写所有内容?

我尝试使用 pyaudio 回调接口,但实际上听起来更糟(好像我的 Pi 胀气了)。

生成的音频需要很短,因为它最终会通过外部控件进行动态调整,任何超过 1 秒的控件更改延迟都会让人感到尴尬。有没有更好的方法从 Python 代码中产生这些信号?

您听到 "tick" 是因为您发送的音频不连续。 261.6 Hz 的一秒包含 261.6 个周期,因此最后还剩下大约半个周期:

您需要更改频率以使每秒有整数个周期(例如 262 Hz),更改持续时间以使其足够长以支持整数个周期,或者生成一个每秒从正确的相位开始的新音频剪辑,以适应最后一个块停止的位置。

我在寻找与您的问题类似的问题,并找到了一个变体,它通过连接一堆预先计算的块来播放预先计算的长度。

http://milkandtang.com/blog/2013/02/16/making-noise-in-python/

使用带有 1 秒预计算块 "play_tone" 函数的 for 循环似乎可以生成平滑的声音输出,但这是在 PC 上。如果这对您不起作用,可能是 raspberry pi 有不同的后端实现,不喜欢连续写入。