BogaudioModules

BogaudioModules for VCV Rack
Log | Files | Refs | README | LICENSE

commit b5521a1a509d51199602ccbcc2d9db6a6bd359a7
parent 405f4d07a296924fdd89c809dba6ce1c6bc268b4
Author: Matt Demanett <matt@demanett.net>
Date:   Sun, 23 Aug 2020 09:17:15 -0400

(L)VCF: avoid filter blowup when cutoff is zero at high sampling rates.

Diffstat:
Msrc/LVCF.cpp | 1+
Msrc/VCF.cpp | 2+-
Msrc/dsp/filters/multimode.cpp | 5+++++
Msrc/dsp/filters/multimode.hpp | 2++
4 files changed, 9 insertions(+), 1 deletion(-)

diff --git a/src/LVCF.cpp b/src/LVCF.cpp @@ -15,6 +15,7 @@ void LVCF::Engine::setParams( MultimodeFilter::BandwidthMode bwm ) { frequency = semitoneToFrequency(_frequencySL.next(frequencyToSemitone(frequency))); + frequency = clamp(semitoneToFrequency(_frequencySL.next(frequencyToSemitone(frequency))), LVCF::minFrequency, LVCF::maxFrequency); _filter.setParams( _sampleRate, diff --git a/src/VCF.cpp b/src/VCF.cpp @@ -13,7 +13,7 @@ void VCF::Engine::setParams( float qbw, MultimodeFilter::BandwidthMode bwm ) { - frequency = semitoneToFrequency(_frequencySL.next(frequencyToSemitone(frequency))); + frequency = clamp(semitoneToFrequency(_frequencySL.next(frequencyToSemitone(frequency))), VCF::minFrequency, VCF::maxFrequency); int i = -1, j = -1; std::fill(_gains, _gains + nFilters, 0.0f); diff --git a/src/dsp/filters/multimode.cpp b/src/dsp/filters/multimode.cpp @@ -178,6 +178,10 @@ constexpr float MultimodeTypes::minBWPitch; constexpr float MultimodeTypes::maxBWPitch; +template<int N> float MultimodeDesigner<N>::effectiveMinimumFrequency() { + return minFrequency * std::max(1.0f, roundf(_sampleRate / 44100.0f)); +} + template<int N> void MultimodeDesigner<N>::setParams( BiquadBank<T, N>& biquads, float& outGain, @@ -194,6 +198,7 @@ template<int N> void MultimodeDesigner<N>::setParams( assert(poles >= minPoles && (poles <= N || (poles <= 2*N && (mode == LOWPASS_MODE || mode == HIGHPASS_MODE)))); assert(poles % modPoles == 0); assert(frequency >= minFrequency - 0.00001f && frequency <= maxFrequency); + frequency = std::max(frequency, effectiveMinimumFrequency()); assert(qbw >= minQbw && qbw <= maxQbw); bool repole = _type != type || _mode != mode || _nPoles != poles || (type == CHEBYSHEV_TYPE && (mode == LOWPASS_MODE || mode == HIGHPASS_MODE) && _qbw != qbw); diff --git a/src/dsp/filters/multimode.hpp b/src/dsp/filters/multimode.hpp @@ -124,6 +124,7 @@ struct MultimodeDesigner : MultimodeTypes { Pole _poles[maxPoles / 2]; int _nBiquads = 0; + float effectiveMinimumFrequency(); void setParams( BiquadBank<T, N>& biquads, float& outGain, @@ -157,6 +158,7 @@ struct MultimodeBase : MultimodeFilter { BiquadBank<T, N> _biquads; float _outGain = 1.0f; + inline float effectiveMinimumFrequency() { return _designer.effectiveMinimumFrequency(); } void setParams( float sampleRate, Type type,