BogaudioModules

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

multimode.hpp (5632B)


      1 #pragma once
      2 
      3 #include <complex>
      4 
      5 #include "filters/filter.hpp"
      6 
      7 #ifdef RACK_SIMD
      8 #include "simd/Vector.hpp"
      9 using rack::simd::float_4;
     10 #endif
     11 
     12 namespace bogaudio {
     13 namespace dsp {
     14 
     15 #ifdef RACK_SIMD
     16 	struct Biquad4 {
     17 		float_4 _a0;
     18 		float_4 _a1;
     19 		float_4 _a2;
     20 		float_4 _b1;
     21 		float_4 _b2;
     22 		float_4 _x[3] {};
     23 		float_4 _y[3] {};
     24 		bool _disable = false;
     25 		int _outputIndex = 3;
     26 
     27 		void setParams(int i, float a0, float a1, float a2, float b0, float b1, float b2);
     28 		void reset();
     29 		void setN(int n, bool minDelay = false);
     30 		inline void disable(bool disable) { _disable = disable; }
     31 		float next(float sample);
     32 	};
     33 #endif
     34 
     35 template<typename T, int N>
     36 struct BiquadBank : ResetableFilter {
     37 #ifdef RACK_SIMD
     38 	Biquad4 _biquads[N / 4];
     39 #else
     40 	BiquadFilter<T> _biquads[N];
     41 	int _n = N;
     42 #endif
     43 
     44 	void setParams(int i, T a0, T a1, T a2, T b0, T b1, T b2);
     45 	void reset() override;
     46 	void setN(int n, bool minDelay = false);
     47 	float next(float sample) override;
     48 };
     49 
     50 struct MultimodeTypes {
     51 	typedef float T;
     52 	typedef std::complex<T> TC;
     53 
     54 	enum Type {
     55 		UNKNOWN_TYPE,
     56 		BUTTERWORTH_TYPE,
     57 		CHEBYSHEV_TYPE
     58 	};
     59 
     60 	enum Mode {
     61 		UNKNOWN_MODE,
     62 		LOWPASS_MODE,
     63 		HIGHPASS_MODE,
     64 		BANDPASS_MODE,
     65 		BANDREJECT_MODE
     66 	};
     67 
     68 	enum BandwidthMode {
     69 		UNKNOWN_BANDWIDTH_MODE,
     70 		LINEAR_BANDWIDTH_MODE,
     71 		PITCH_BANDWIDTH_MODE
     72 	};
     73 
     74 	enum DelayMode {
     75 		UNKNOWN_DELAY_MODE,
     76 		FIXED_DELAY_MODE,
     77 		MINIMUM_DELAY_MODE
     78 	};
     79 
     80 	static constexpr int minPoles = 1;
     81 	static constexpr int maxPoles = 16;
     82 	static constexpr int modPoles = 1;
     83 	static constexpr float minFrequency = 3.0f; // FIXME: this can go down to at least 1.0f if T is double.
     84 	static constexpr float maxFrequency = 21000.0f;
     85 	static constexpr float minQbw = 0.0f;
     86 	static constexpr float maxQbw = 1.0f;
     87 	static constexpr float minBWLinear = 10.0f;
     88 	static constexpr float maxBWLinear = 5000.0f;
     89 	static constexpr float minBWPitch = 1.0f / (1.0f * 12.0f * 100.0f / 25.0f);
     90 	static constexpr float maxBWPitch = 2.0f;
     91 };
     92 
     93 template<int N>
     94 struct MultimodeDesigner : MultimodeTypes {
     95 	struct Pole {
     96 		TC p;
     97 		T x = 0.0;
     98 		T y = 0.0;
     99 		TC pc;
    100 		TC p2;
    101 		TC i2p;
    102 		TC i2pc;
    103 		T r = 0.0;
    104 
    105 		Pole() {}
    106 		Pole(T re, T im, T x, T y) : p(TC(re, im)), x(x), y(y) {
    107 			pc = std::conj(p);
    108 			p2 = p * p;
    109 			i2p = (T)1.0 / ((T)2.0 * p);
    110 			i2pc = (T)1.0 / ((T)2.0 * pc);
    111 			r = std::abs(p);
    112 		}
    113 	};
    114 
    115 	float _sampleRate = 44100.0f;
    116 	float _half2PiST = 0.0f;
    117 	Type _type = UNKNOWN_TYPE;
    118 	Mode _mode = UNKNOWN_MODE;
    119 	int _nPoles = 0;
    120 	float _frequency = -1.0f;
    121 	float _qbw = -1.0f;
    122 	BandwidthMode _bandwidthMode = UNKNOWN_BANDWIDTH_MODE;
    123 	DelayMode _delayMode = UNKNOWN_DELAY_MODE;
    124 	Pole _poles[maxPoles / 2];
    125 	int _nBiquads = 0;
    126 
    127 	float effectiveMinimumFrequency();
    128 	void setParams(
    129 		BiquadBank<T, N>& biquads,
    130 		float& outGain,
    131 		float sampleRate,
    132 		Type type,
    133 		int poles,
    134 		Mode mode,
    135 		float frequency,
    136 		float qbw,
    137 		BandwidthMode bwm = PITCH_BANDWIDTH_MODE,
    138 		DelayMode dm = FIXED_DELAY_MODE
    139 	);
    140 };
    141 
    142 struct MultimodeFilter : MultimodeTypes, ResetableFilter {
    143 	virtual void setParams(
    144 		float sampleRate,
    145 		Type type,
    146 		int poles,
    147 		Mode mode,
    148 		float frequency,
    149 		float qbw,
    150 		BandwidthMode bwm = PITCH_BANDWIDTH_MODE,
    151 		DelayMode dm = FIXED_DELAY_MODE
    152 	) = 0;
    153 };
    154 
    155 template<int N>
    156 struct MultimodeBase : MultimodeFilter {
    157 	MultimodeDesigner<N> _designer;
    158 	BiquadBank<T, N> _biquads;
    159 	float _outGain = 1.0f;
    160 
    161 	inline float effectiveMinimumFrequency() { return _designer.effectiveMinimumFrequency(); }
    162 	void setParams(
    163 		float sampleRate,
    164 		Type type,
    165 		int poles,
    166 		Mode mode,
    167 		float frequency,
    168 		float qbw,
    169 		BandwidthMode bwm = PITCH_BANDWIDTH_MODE,
    170 		DelayMode dm = FIXED_DELAY_MODE
    171 	) override;
    172 	float next(float sample) override;
    173 	void reset() override;
    174 };
    175 
    176 typedef MultimodeBase<16> MultimodeFilter16;
    177 typedef MultimodeBase<8> MultimodeFilter8;
    178 typedef MultimodeBase<4> MultimodeFilter4;
    179 
    180 struct FourPoleButtworthLowpassFilter {
    181 	MultimodeFilter4 _filter;
    182 
    183 	inline void setParams(
    184 		float sampleRate,
    185 		float frequency,
    186 		float q
    187 	) {
    188 		_filter.setParams(
    189 			sampleRate,
    190 			MultimodeFilter::BUTTERWORTH_TYPE,
    191 			4,
    192 			MultimodeFilter::LOWPASS_MODE,
    193 			frequency,
    194 			q
    195 		);
    196 	}
    197 	inline float next(float sample) { return _filter.next(sample); }
    198 	inline void reset() { _filter.reset(); }
    199 };
    200 
    201 struct FourPoleButtworthHighpassFilter {
    202 	MultimodeFilter4 _filter;
    203 
    204 	inline void setParams(
    205 		float sampleRate,
    206 		float frequency,
    207 		float q
    208 	) {
    209 		_filter.setParams(
    210 			sampleRate,
    211 			MultimodeFilter::BUTTERWORTH_TYPE,
    212 			4,
    213 			MultimodeFilter::HIGHPASS_MODE,
    214 			frequency,
    215 			q
    216 		);
    217 	}
    218 	inline float next(float sample) { return _filter.next(sample); }
    219 	inline void reset() { _filter.reset(); }
    220 };
    221 
    222 struct TwoPoleButtworthBandpassFilter {
    223 	MultimodeFilter4 _filter;
    224 
    225 	inline void setParams(
    226 		float sampleRate,
    227 		float frequency,
    228 		float bw,
    229 		MultimodeFilter::BandwidthMode bwm = MultimodeFilter::PITCH_BANDWIDTH_MODE
    230 	) {
    231 		_filter.setParams(
    232 			sampleRate,
    233 			MultimodeFilter::BUTTERWORTH_TYPE,
    234 			2,
    235 			MultimodeFilter::BANDPASS_MODE,
    236 			frequency,
    237 			bw,
    238 			bwm
    239 		);
    240 	}
    241 	inline float next(float sample) { return _filter.next(sample); }
    242 	inline void reset() { _filter.reset(); }
    243 };
    244 
    245 struct FourPoleButtworthBandpassFilter {
    246 	MultimodeFilter4 _filter;
    247 
    248 	inline void setParams(
    249 		float sampleRate,
    250 		float frequency,
    251 		float bw,
    252 		MultimodeFilter::BandwidthMode bwm = MultimodeFilter::PITCH_BANDWIDTH_MODE
    253 	) {
    254 		_filter.setParams(
    255 			sampleRate,
    256 			MultimodeFilter::BUTTERWORTH_TYPE,
    257 			4,
    258 			MultimodeFilter::BANDPASS_MODE,
    259 			frequency,
    260 			bw,
    261 			bwm
    262 		);
    263 	}
    264 	inline float next(float sample) { return _filter.next(sample); }
    265 	inline void reset() { _filter.reset(); }
    266 };
    267 
    268 } // namespace dsp
    269 } // namespace bogaudio