2014-03-05 20 views
5

幼稚正弦波發生器採用一組n個值的和在每一個上調用sin函數:避免罪()中的音頻合成器調用

for i = 0; i < 2*pi ; i = i+step { 
    output = append(output, sin(i)) 
} 

然而,這使得大量的呼叫到一個潛在的昂貴的sin函數,並且未能利用所有樣本都是連續的這一事實,之前已經計算過,並且將四捨五入爲整數(PCM)。那麼,還有什麼替代方案?我想要沿着Bresenham's circle algorithm或預先計算一個高分辨率的樣本,然後縮小每一個第n個入口的尺寸,但如果有一個'工業強度'解決這個問題,我' d愛聽到它。

+0

你似乎在你的問題中提到sin()值將四捨五入到最接近的整數。這是真的? – user2566092

+0

啊,應該澄清了。這是進入一個wav編碼器,所以它是PCM。因此,任何浮點值都將結束爲一個有符號的16位整數。 –

+0

你需要多大的頻率分辨率? – jaket

回答

4

當你添加到(1,0),其中theta = 2 * pi/step時,你可以計算出給你的向量z(cosθ,sinθ)。然後,將此矢量添加到(1,0)並獲得下一個sin值作爲總和的y座標。然後,通過旋轉角度theta(通過乘以旋轉矩陣通過角度theta)並將其添加到您的前一個矢量(cos theta,sin theta)中,以獲得下一個sin值作爲合成和矢量的y座標。等等。這需要一次計算cosθ和sinθ,然後通過2x2矩陣與2-d向量的矩陣相乘來給出每個更新,然後進行簡單相加,這比使用冪級數計算sin()更快擴張。

+0

不錯的技術。可能明智地做到這一點在雙重精度,以避免陷入誤差的積累。 – 2014-03-05 22:10:23

+0

在精度問題上達成一致,我考慮過這個問題,並不能提出一個圓滑的解決方案來解決舍入問題,所以舍入誤差當前是不可避免的,儘管如果步長不是太小,雙精度是可以忽略的用過的。 – user2566092

+0

對不起,如果我的評論聽起來像挑剔,我只是向不經意的讀者指出這是一個應該避免使用單精度作爲「優化」的例子。 – 2014-03-05 22:33:37