使用 Numpy 在 Python 中连接 Waves

Concatenating Waves in Python using Numpy

我正在尝试产生一种音调,该音调可以随时间在任意频率列表之间线性过渡。我正在使用 scipy.signal 创建在频率对之间转换的波,然后将它们连接起来。当频率为整数且彼此相距较远时,此方法有效。当数字靠得很近或不太好时,我会在每次转换之间弹出。

是什么导致了这些爆裂声,为什么只有第一种情况而不是其他两种情况,我该如何解决? (或者如果有 better/easier 方法来做我想做的事情,它是什么?)

如有任何想法,我们将不胜感激。

from scipy.signal import sweep_poly
import numpy
import sounddevice

sample_rate = 44100.0
time = 1.0 
amplitude = 10000
sounddevice.default.samplerate = sample_rate

freq_list = [100, 200, 100, 200]
#freq_list = [100.05,200.21,100.02,200.65,100.16]
#freq_list = [100,101,102,103]

#get samples for each segment
samples = numpy.arange(sample_rate * time) / sample_rate

#make all the different segments
wave_list = []
for i in range(len(freq_list)-1):
    wave_list.append(amplitude * sweep_poly(samples, [float(freq_list[i+1])-float(freq_list[i]),float(freq_list[i])]))

#join them together
wave = numpy.concatenate(wave_list)

#convert it to wav format (16 bits)
wav_wave = numpy.array(wave, dtype=numpy.int16)

sounddevice.play(wav_wave, blocking=True)

我的评论是正确的。问题是,当我发起新一波时,它总是从峰值开始,不一定与旧波一致,导致不连续:

我通过将 sweep_poly 的相位偏移参数设置为 (180/math.pi)*math.acos(prev_point/amplitude) 来解决此问题,其中 prev_point 是前一个正弦波中的最后一个点。

不幸的是,因为正弦不是 one-to-one 有时我会在值匹配的地方得到波浪,但斜率却没有:

我对此的解决方法是检查斜率的符号是否匹配,如果不匹配,则缓慢增加偏移量直到匹配,然后继续缓慢增加偏移量直到不连续性变小 (<10) .我确信这不是解决这个问题的最好或最令人满意的数学方法,但它对我来说效果很好。现在我有了美丽的(非常接近)连续可微的波浪。