我正在尝试用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代码中生成这些信号?
答案 0 :(得分:6)
你听到了#34; tick"因为您发送的音频存在不连续性。 261.6 Hz的一秒钟包含261.6个周期,因此最终剩下大约半个周期:
您需要更改频率,以便每秒有一整个周期(例如,262 Hz),更改持续时间,使其足够长,持续整数个周期,或者每隔一秒生成一个新的音频片段,从正确的阶段开始,以适应最后一个块离开的位置。
答案 1 :(得分:1)
我正在向您寻找类似的问题,并通过连接一堆预先计算的块找到了一个预先计算长度的变体。
http://milkandtang.com/blog/2013/02/16/making-noise-in-python/
使用带有1秒预先计算的块的for循环" play_tone"函数似乎生成一个平滑的声音输出,但这是在PC上。如果这对你不起作用,可能是树莓派有不同的后端实现,不喜欢连续写入。