2010-06-22 52 views
4

我一直在研究一個程序,我需要從一個音高緩慢而平穩地改變正弦波的音高。我能夠在任何特定時刻獲得球場應該出現的頻率的陣列(例如,[440,526.5,634.2 794.8,880],儘管時間更長),但似乎我無法實際應用該頻率一波。我的最好的嘗試是:Numpy從一個音高到另一個音高的正弦波滑動

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

其中 「頻率」 是頻率和x的陣列是一個枚舉陣列([0,1,2,3,4 ...])。這種方法可以工作,但它會使頻率高於預期的頻率,然後回落。我一直在研究這個問題很長一段時間,並且在尋找更合適的方法方面一直未能取得任何進展。有什麼建議?我是否足夠清楚地表達我的困境?

謝謝。

+0

你想要一個線性掃描或對數掃描? – endolith 2012-03-19 18:03:35

回答

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() 
+0

太棒了!這完美的作品!非常感謝! – user252719 2010-06-22 16:16:55

+0

太好了。我很高興它現在就做你想做的事情......這是一個有趣的問題。 – tom10 2010-06-23 03:50:15

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,我還在學習語言。

相關問題