这是我想出的,受到尼尔斯想法的启发。在这里粘贴它以防其他人使用。我简单地用最后一个采样的相位变化作为内核大小(或截止值)来分析滤波锯齿波。它工作得很好,在最高音符处有一些可听见的别名,但对于正常使用来说听起来很棒。
为了减少更多的混叠,内核大小可以增加一点,使得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