我想在python的循环中逐帧再现音频信号。为此,我尝试了:
import sounddevice as sd
#Suppose:
nframes = 750
lframe = 882
fs = 44100
#Loop
for i in range(0,nframes):
sd.play(signal[i*lframe:(i+1)*lframe].astype('int16'),fs,blocking=True)
但是我什么也没听到。我已检查sd.play(signal.astype('int16'),fs,blocking=True)
正常工作。
谢谢您的帮助
答案 0 :(得分:1)
我假设nframe为“帧数”,lframe为“帧块的长度”。 让我们假设 我们需要创建长度为lframe的信号数组块,然后分别播放它们。我们将范围更改为xrange,因为xrange在处理块时更容易,并以lframe的步骤创建信号块,然后简单地播放它们。 完整的工作代码:
在这种情况下,nframes nframes = 7500
给出8个长度为882的块。for i in xrange(0, len(signal),lframe):
sd.play(signal[i:i+lframe].astype('int16'),blocking=True)
import numpy as np
import sounddevice as sd
nframes = 7500
lframe = 882
fs = 44100
samples = np.arange(nframes)/float(nframes)
signal = 10000 * np.sin(2 * np.pi * fs * samples)
for i in xrange(0, len(signal),lframe):
sd.play(signal[i:i+lframe].astype('int16'),blocking=True)
答案 1 :(得分:1)
请注意,signal = 10000 * np.sin(2 * np.pi * fs * samples)
的长度与samples
的长度相同。在这种情况下,大多数垃圾signal[i:i+lframe]
是空的。
我的工作示例是:
import numpy as np
import sounddevice as sd
lframe = 882 * 10
fs = 44100
frequency = 880
samples = np.arange(0, 1, step=1/fs)
signal = 10000 * np.sin(2 * np.pi * frequency * samples)
for i in range(0, fs, lframe):
sd.play(signal[i:i+lframe].astype('int16'), blocking=True, latency = 'low')
在这种情况下,不需要nframes
,因为我们可以将其除以fs/lframe
。
主要问题是每个sd.play
之后都会有一些延迟。如果我们采用lframe = 882
,则帧数为每秒50。每帧的长度为0.02s,比延迟短。因此,我将lframe = 882
替换为lframe = 882 * 10
。
在我的笔记本电脑上,最小乘数是lframe = 882 * 8
,因此我可以听到任何信号。使用latency = 'low'
可以帮助我将其简化为lframes = 882 * 4
来听到一些信号。