在低功率计算机上从 Python 生成流畅的音频
Generating smooth audio from Python on a low-powered computer
我正在尝试在 Python 中编写一个简单的音频函数生成器,成为 Raspberry Pi(模型 2)上的 运行。代码基本上是这样做的:
- 生成 1 秒的音频信号(例如,正弦波或方波等)
- 循环播放
例如:
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 有不同的后端实现,不喜欢连续写入。
我正在尝试在 Python 中编写一个简单的音频函数生成器,成为 Raspberry Pi(模型 2)上的 运行。代码基本上是这样做的:
- 生成 1 秒的音频信号(例如,正弦波或方波等)
- 循环播放
例如:
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 有不同的后端实现,不喜欢连续写入。