這是我想出的,受到尼爾斯想法的啓發。在這裏粘貼它以防其他人使用。我簡單地用最後一個採樣的相位變化作爲內核大小(或截止值)來分析濾波鋸齒波。它工作得很好,在最高音符處有一些可聽見的別名,但對於正常使用來說聽起來很棒。
爲了減少更多的混疊,內核大小可以增加一點,使得2 * phaseChange例如聽起來不錯,儘管你失去了一些最高頻率。
另外,這裏是我在瀏覽類似主題的SP時發現的另一個很好的DSP資源:The Synthesis ToolKit in C++ (STK)。這是一個擁有很多有用的DSP工具的類庫。它甚至可以使用帶限波形發生器。他們使用的方法是整合sinc,就像我在第一篇文章中所描述的那樣(儘管我猜他們做得更好,然後我......)。
float getSaw(float phaseChange)
{
static float phase = 0.0f;
phase = fmod(phase + phaseChange, 1.0f);
return getBoxFilteredSaw(phase, phaseChange);
}
float getPulse(float phaseChange, float pulseWidth)
{
static float phase = 0.0f;
phase = fmod(phase + phaseChange, 1.0f);
return getBoxFilteredSaw(phase, phaseChange) - getBoxFilteredSaw(fmod(phase + pulseWidth, 1.0f), phaseChange);
}
float getBoxFilteredSaw(float phase, float kernelSize)
{
float a, b;
// Check if kernel is longer that one cycle
if (kernelSize >= 1.0f) {
return 0.0f;
}
// Remap phase and kernelSize from [0.0, 1.0] to [-1.0, 1.0]
kernelSize *= 2.0f;
phase = phase * 2.0f - 1.0f;
if (phase + kernelSize > 1.0f)
{
// Kernel wraps around edge of [-1.0, 1.0]
a = phase;
b = phase + kernelSize - 2.0f;
}
else
{
// Kernel fits nicely in [-1.0, 1.0]
a = phase;
b = phase + kernelSize;
}
// Integrate and divide with kernelSize
return (b * b - a * a)/(2.0f * kernelSize);
}
我意識到這是一年前問過的,但對於其他任何人磕磕絆絆,我會推薦搜索友好和高度勝任的[DSP和插件開發](http://www.kvraudio.com/論壇/ viewforum.php?f = 33)論壇在[KVR](http://www.kvraudio.com/) – 2009-10-03 07:15:43