@@ -209,13 +209,13 @@ class CombFilter : public FilterBase<SampleType, CoeffType>
209209 */
210210 Complex<CoeffType> getComplexResponse (CoeffType responseFrequency) const override
211211 {
212- const auto omega = frequencyToAngular (responseFrequency, static_cast <CoeffType> (this ->sampleRate ));
213- const auto delay = getDelayForResponse ();
214- const auto delayed = polar (static_cast <CoeffType> (1 ), -omega * delay);
212+ const auto delayed = getFractionalDelayResponse (responseFrequency);
215213 const auto denominator = Complex<CoeffType> (static_cast <CoeffType> (1 )) - delayLineFeedback * delayed;
216214
217215 if (std::abs (denominator) <= std::numeric_limits<CoeffType>::epsilon ())
218- return Complex<CoeffType> (static_cast <CoeffType> (1 ));
216+ return Complex<CoeffType> (static_cast <CoeffType> (1 ))
217+ + (static_cast <CoeffType> (0.5 ) * delayed)
218+ / (denominator + Complex<CoeffType> (std::numeric_limits<CoeffType>::epsilon ()));
219219
220220 return Complex<CoeffType> (static_cast <CoeffType> (1 ))
221221 + (static_cast <CoeffType> (0.5 ) * delayed) / denominator;
@@ -359,6 +359,26 @@ class CombFilter : public FilterBase<SampleType, CoeffType>
359359 static_cast <CoeffType> (this ->sampleRate ) / frequency);
360360 }
361361
362+ Complex<CoeffType> getFractionalDelayResponse (CoeffType responseFrequency) const noexcept
363+ {
364+ const auto delay = getDelayForResponse ();
365+ const auto readDelay = static_cast <CoeffType> (std::ceil (delay));
366+ const auto fraction = readDelay - delay;
367+ const auto fraction2 = fraction * fraction;
368+ const auto fraction3 = fraction2 * fraction;
369+
370+ const auto weight0 = static_cast <CoeffType> (-0.5 ) * fraction + fraction2 - static_cast <CoeffType> (0.5 ) * fraction3;
371+ const auto weight1 = static_cast <CoeffType> (1 ) - static_cast <CoeffType> (2.5 ) * fraction2 + static_cast <CoeffType> (1.5 ) * fraction3;
372+ const auto weight2 = static_cast <CoeffType> (0.5 ) * fraction + static_cast <CoeffType> (2 ) * fraction2 - static_cast <CoeffType> (1.5 ) * fraction3;
373+ const auto weight3 = static_cast <CoeffType> (-0.5 ) * fraction2 + static_cast <CoeffType> (0.5 ) * fraction3;
374+ const auto omega = frequencyToAngular (responseFrequency, static_cast <CoeffType> (this ->sampleRate ));
375+
376+ return weight0 * polar (static_cast <CoeffType> (1 ), -omega * (readDelay + static_cast <CoeffType> (1 )))
377+ + weight1 * polar (static_cast <CoeffType> (1 ), -omega * readDelay)
378+ + weight2 * polar (static_cast <CoeffType> (1 ), -omega * (readDelay - static_cast <CoeffType> (1 )))
379+ + weight3 * polar (static_cast <CoeffType> (1 ), -omega * (readDelay - static_cast <CoeffType> (2 )));
380+ }
381+
362382 // ==============================================================================
363383 std::size_t delayLineSizeInSamples = defaultDelayLineSize;
364384 std::size_t delayLineMask = defaultDelayLineSize - 1 ;
0 commit comments