在Numpy中,正弦波从一个音高到另一个音高

时间:2010-06-22 02:22:47

标签: python math audio numpy trigonometry

我一直致力于一个程序,我需要慢慢平稳地将正弦波的音高从一个音高变换到另一个音高。我能够在任何给定的时刻获得一个频率阵列的频率(例如,[440,526.5,634.2 794.8,880],虽然更多,更长)但似乎我无法实际应用该频率一波。我最好的尝试是:

numpy.sin(2*math.pi*x*freq/self.sample_rate)

其中“freq”是频率数组,x是枚举数组([0,1,2,3,4 ...])。这种方法有效,但它会使频率超出预期频率,然后再降低。我一直在研究这个问题很长一段时间,并且无法在找到更合适的方法方面取得任何进展。有什么建议?我是否足够明确表达我的困境?

谢谢。

2 个答案:

答案 0 :(得分:7)

问题在于,当您在频率上匝道时,每个频率在给定时间内有效地具有不同的相位。当您快速连续地滚动这些相位时,它们会以更高的频率驱动正弦波(或者更低的频率)。

想象一下,例如,你瞬间改变了频率 - 要做到这一点,你必须提供相位校正p_1 = p_0 + 2*pi*t*(f_0-f_1)以使相位在时间t匹配。正如您所做的那样,这是一个很小的步骤,您还必须进行类似的相位校正,每次相位校正都会增加到之前的相位。

这是结果图,下面是代码。上图是没有相位校正的中间频率,底部有连续校正的相位。

enter image description here

from pylab import *

sample_rate = .001
f0, f1 = 10, 20
t_change = 2

times = arange(0, 4, sample_rate)

ramp = 1./(1+exp(-6.*(times-t_change)))
freq = f0*(1-ramp)+f1*ramp
phase_correction = add.accumulate(times*concatenate((zeros(1), 2*pi*(freq[:-1]-freq[1:]))))

figure()
subplot(311)
plot(times, freq)
subplot(312)
plot(times, sin(2*pi*freq*times))
subplot(313)
plot(times, sin(2*pi*freq*times+phase_correction))

show()

答案 1 :(得分:0)

我喜欢将频率视为您踩踏声音样本的速率 - 在这种情况下是正弦波。这是尝试一些Python代码来做你想要的。我们假设freq()方法将频率作为时间的函数。出于您的目的,它将是某种指数。我们正在尝试填充一个名为wave的预分配列表。

index = 0
t = 0
while t < len(wave):
  wave[t] = math.sin(2*math.pi*index/sample_rate)
  t = t+1
  index = index + freq(t/sample_rate)

请原谅我的Python,我还在学习这门语言。