数字信号处理算法通常有充分的理由被表示为框图-这是考虑它们的绝佳方法.对它们进行编码时,请将其的每个块视为具有固定输入和输出的单独单元.我认为您的某些问题来自试图过早地结合系统的各个要素.
这是Karplus Strong的框图.
对于延迟块,您需要实现分数延迟线.这将包括其自己的低通滤波器,但这是如何实现延迟线的详细信息. Karplus强效果还需要一个低通滤波器.这些过滤器的特性将有所不同.不要试图合并.顺便说一下,您选择的平均低通滤波器具有较差的频率响应,会引入“梳状滤波器”效果.您可能需要设计更复杂的FIR或IIR滤波器.
So how would I go about implementing this? Do I feed the interpolated value back in or what? Do I get rid of the two point averaging low pass filter completely?
您确实将内插的求和样本反馈回延迟线,就像框图所示.在某些情况下,这可能会开始增加系统的净增益,并且如果您担心的是,您可能需要对延迟的输出进行“标准化”,以使其不会失控.
有许多有效的策略可用于实现分数延迟线,包括您提到的内插和全通滤波.这个想法是,您将需要维护对延迟线的读写索引.延迟线的长度不是内存缓冲区的总长度,而是索引之间的差,以延迟线的总长度为模.将延迟线设置为所需的大小,不要担心调整其大小.
我发现将读写视为永不回绕或到期的自由运行计数器最为方便,因为这样
current_delay_length = (write - read) % total_delay_length
current_read_sample = delay_line[read % total_delay_length]
其中%是模量.如果写和读计数器是浮点值或设置为固定点,则它们也可以包含小数长度.无论如何,这使得修改延迟线的长度变得容易.重要的是确保强制执行最小延迟(写>读).
信不信由你,您将通过更改步长的速率来更改延迟线的长度,就像固定长度的缓冲区一样.通常,您将稍微调整读取索引.它不应落后于写指针超过缓冲区长度或不超过缓冲区长度,否则会出现故障.但是在写指针之后,您可以随意将读指针移动到任何地方.更改调制方式将获得不同的效果.
我强调,像glissando这样的效果来自延迟线的读写索引的操作方式,而不是其实现方式.您将从全通滤波器或线性插值延迟线获得类似的声音.例如,更好的分数延迟线将减少混叠噪声并支持读取指针的更快更改.