1 #ifndef INCLUDED_AUDIOFX_FILTER_H 2 #define INCLUDED_AUDIOFX_FILTER_H 3 4 #include <deque> 5 #include <string> 6 #include <vector> 7 8 #include "audiofx.h" 9 #include "samplebuffer_iterators.h" 10 11 /** 12 * Virtual base for filter effects. 13 * @author Kai Vehmanen 14 */ 15 class EFFECT_FILTER : public EFFECT_BASE { 16 17 public: 18 virtual ~EFFECT_FILTER(void); 19 }; 20 21 /** 22 * Base class for butterworth filter effects. 23 * 24 * Based on SPKit Butterworth algorithms. 25 * (for more info, see http://www.music.helsinki.fi/research/spkit) 26 */ 27 class EFFECT_BW_FILTER : public EFFECT_FILTER { 28 29 private: 30 31 SAMPLE_SPECS::sample_t outputSample; 32 SAMPLE_ITERATOR_CHANNELS i; 33 34 std::vector<std::vector<SAMPLE_SPECS::sample_t> > sin; 35 std::vector<std::vector<SAMPLE_SPECS::sample_t> > sout; 36 37 void init_values(void); 38 39 protected: 40 41 std::vector<SAMPLE_SPECS::sample_t> a; 42 std::vector<SAMPLE_SPECS::sample_t> b; 43 44 public: 45 46 void process_notused(SAMPLE_BUFFER* sbuf); 47 virtual void init(SAMPLE_BUFFER *insample); 48 virtual void process(void); 49 50 virtual EFFECT_BW_FILTER* clone(void) const = 0; 51 52 // EFFECT_BW_FILTER(void) : sin(2), sout(2), a(3), b(2) { 53 EFFECT_BW_FILTER(void)54 EFFECT_BW_FILTER(void) : a(3), b(2) { 55 init_values(); 56 } 57 }; 58 59 /** 60 * Bandpass filter 61 * 62 * Based on SPKit Butterworth algorithms 63 * (for more info, see http://www.music.helsinki.fi/research/spkit) 64 */ 65 class EFFECT_BANDPASS: public EFFECT_BW_FILTER { 66 67 private: 68 69 parameter_t center; 70 parameter_t width; 71 72 parameter_t C; 73 parameter_t D; 74 75 public: 76 name(void)77 virtual std::string name(void) const { return("Bandpass filter"); } parameter_names(void)78 virtual std::string parameter_names(void) const { return("center-freq,width"); } 79 80 virtual void set_parameter(int param, parameter_t value); 81 virtual parameter_t get_parameter(int param) const; 82 clone(void)83 EFFECT_BANDPASS* clone(void) const { return new EFFECT_BANDPASS(*this); } new_expr(void)84 EFFECT_BANDPASS* new_expr(void) const { return new EFFECT_BANDPASS(); } 85 EFFECT_BANDPASS (parameter_t centerf = 1000.0, parameter_t width = 1000.0); 86 }; 87 88 /** 89 * Bandreject filter 90 * 91 * Based on SPKit Butterworth algorithms 92 * (for more info, see http://www.music.helsinki.fi/research/spkit) 93 */ 94 class EFFECT_BANDREJECT: public EFFECT_BW_FILTER { 95 96 private: 97 98 parameter_t center; 99 parameter_t width; 100 101 parameter_t C; 102 parameter_t D; 103 104 public: 105 name(void)106 virtual std::string name(void) const { return("Bandreject filter"); } parameter_names(void)107 virtual std::string parameter_names(void) const { return("center-freq,width"); } 108 109 virtual void set_parameter(int param, parameter_t value); 110 virtual parameter_t get_parameter(int param) const; 111 clone(void)112 EFFECT_BANDREJECT* clone(void) const { return new EFFECT_BANDREJECT(*this); } new_expr(void)113 EFFECT_BANDREJECT* new_expr(void) const { return new EFFECT_BANDREJECT(); } 114 EFFECT_BANDREJECT (parameter_t centerf = 1000.0, parameter_t width = 1000.0); 115 }; 116 117 /** 118 * Highpass filter 119 * 120 * Based on SPKit Butterworth algorithms 121 * (for more info, see http://www.music.helsinki.fi/research/spkit) 122 */ 123 class EFFECT_HIGHPASS : public EFFECT_BW_FILTER { 124 125 private: 126 127 parameter_t cutOffFreq; 128 parameter_t C; 129 130 public: 131 name(void)132 virtual std::string name(void) const { return("Highpass filter"); } parameter_names(void)133 virtual std::string parameter_names(void) const { return("cutoff-freq"); } 134 135 virtual void set_parameter(int param, parameter_t value); 136 virtual parameter_t get_parameter(int param) const; 137 clone(void)138 EFFECT_HIGHPASS* clone(void) const { return new EFFECT_HIGHPASS(*this); } new_expr(void)139 EFFECT_HIGHPASS* new_expr(void) const { return new EFFECT_HIGHPASS(); } 140 EFFECT_HIGHPASS (parameter_t cutoff = 1000.0); 141 }; 142 143 /** 144 * Allpass filter 145 */ 146 class EFFECT_ALLPASS_FILTER : public EFFECT_FILTER { 147 148 std::vector<std::deque<SAMPLE_SPECS::sample_t> > inbuf, outbuf; 149 SAMPLE_ITERATOR_CHANNELS i; 150 151 parameter_t feedback_gain; 152 parameter_t D; 153 154 public: 155 name(void)156 virtual std::string name(void) const { return("Allpass filter"); } parameter_names(void)157 virtual std::string parameter_names(void) const { return("delay-samples,feedback-%"); } 158 159 virtual void set_parameter(int param, parameter_t value); 160 virtual parameter_t get_parameter(int param) const; 161 162 virtual void init(SAMPLE_BUFFER *insample); 163 virtual void process(void); 164 clone(void)165 EFFECT_ALLPASS_FILTER* clone(void) const { return new EFFECT_ALLPASS_FILTER(*this); } new_expr(void)166 EFFECT_ALLPASS_FILTER* new_expr(void) const { return new EFFECT_ALLPASS_FILTER(); } 167 EFFECT_ALLPASS_FILTER (void); 168 }; 169 170 171 /** 172 * Comb filter 173 * 174 * The basic theory behind this can be found from Ken Steiglitz's book 175 * "A digital signal processing primer", page 103. 176 */ 177 class EFFECT_COMB_FILTER : public EFFECT_FILTER { 178 179 std::vector<std::deque<SAMPLE_SPECS::sample_t> > buffer; 180 std::vector<SAMPLE_SPECS::sample_t> temp; 181 SAMPLE_ITERATOR_CHANNELS i; 182 183 parameter_t C; 184 parameter_t D; 185 186 public: 187 name(void)188 virtual std::string name(void) const { return("Comb filter"); } parameter_names(void)189 virtual std::string parameter_names(void) const { return("delay-samples,radius"); } 190 191 virtual void set_parameter(int param, parameter_t value); 192 virtual parameter_t get_parameter(int param) const; 193 194 virtual void init(SAMPLE_BUFFER *insample); 195 virtual void process(void); 196 clone(void)197 EFFECT_COMB_FILTER* clone(void) const { return new EFFECT_COMB_FILTER(*this); } new_expr(void)198 EFFECT_COMB_FILTER* new_expr(void) const { return new EFFECT_COMB_FILTER(); } 199 EFFECT_COMB_FILTER (int delay_in_samples = 1, parameter_t constant = 1.0); 200 }; 201 202 /** 203 * Inverse comb filter 204 * 205 * The basic theory behind this can be found from Ken Steiglitz's book 206 * "A digital signal processing primer", page 77. 207 */ 208 class EFFECT_INVERSE_COMB_FILTER : public EFFECT_FILTER { 209 210 std::vector<parameter_t> laskuri; 211 std::vector<std::deque<SAMPLE_SPECS::sample_t> > buffer; 212 std::vector<SAMPLE_SPECS::sample_t> temp; 213 SAMPLE_ITERATOR_CHANNELS i; 214 215 parameter_t C; 216 parameter_t D; 217 218 public: 219 name(void)220 virtual std::string name(void) const { return("Inverse comb filter"); } parameter_names(void)221 virtual std::string parameter_names(void) const { return("delay-samples,radius"); } 222 223 virtual void set_parameter(int param, parameter_t value); 224 virtual parameter_t get_parameter(int param) const; 225 226 virtual void init(SAMPLE_BUFFER *insample); 227 virtual void process(void); 228 clone(void)229 EFFECT_INVERSE_COMB_FILTER* clone(void) const { return new EFFECT_INVERSE_COMB_FILTER(*this); } new_expr(void)230 EFFECT_INVERSE_COMB_FILTER* new_expr(void) const { return new EFFECT_INVERSE_COMB_FILTER(); } 231 EFFECT_INVERSE_COMB_FILTER (int delay_in_samples = 10, parameter_t constant = 1.0); 232 }; 233 234 /** 235 * Lowpass filter 236 * 237 * Based on SPKit Butterworth algorithms 238 * (for more info, see http://www.music.helsinki.fi/research/spkit) 239 */ 240 class EFFECT_LOWPASS: public EFFECT_BW_FILTER { 241 242 private: 243 244 parameter_t cutOffFreq; 245 246 parameter_t C; 247 248 public: 249 name(void)250 virtual std::string name(void) const { return("Lowpass filter"); } parameter_names(void)251 virtual std::string parameter_names(void) const { return("cutoff-freq"); } 252 253 virtual void set_parameter(int param, parameter_t value); 254 virtual parameter_t get_parameter(int param) const; 255 256 void set_cutoff(parameter_t value, long int srate); 257 clone(void)258 EFFECT_LOWPASS* clone(void) const { return new EFFECT_LOWPASS(*this); } new_expr(void)259 EFFECT_LOWPASS* new_expr(void) const { return new EFFECT_LOWPASS(); } 260 EFFECT_LOWPASS (parameter_t cutoff = 1000.0); 261 }; 262 263 /** 264 * A simple lowpass filter 265 * 266 * Algorithm: 1nd order filter. 267 * From Fugue source code: 268 * 269 * output[N] = input[N] * A + input[N-1] * B 270 * 271 * A = 2.0 * pi * center 272 * B = exp(-A / frequency) 273 */ 274 class EFFECT_LOWPASS_SIMPLE : public EFFECT_FILTER { 275 276 private: 277 278 parameter_t cutOffFreq; 279 parameter_t A, B; 280 std::vector<SAMPLE_SPECS::sample_t> outhist, tempin, temphist; 281 SAMPLE_ITERATOR_CHANNELS i; 282 283 public: 284 name(void)285 virtual std::string name(void) const { return("Simple lowpass filter"); } parameter_names(void)286 virtual std::string parameter_names(void) const { return("cutoff-freq"); } 287 288 virtual void init(SAMPLE_BUFFER *insample); 289 virtual void process(void); 290 291 virtual void set_parameter(int param, parameter_t value); 292 virtual parameter_t get_parameter(int param) const; 293 clone(void)294 EFFECT_LOWPASS_SIMPLE* clone(void) const { return new EFFECT_LOWPASS_SIMPLE(*this); } new_expr(void)295 EFFECT_LOWPASS_SIMPLE* new_expr(void) const { return new EFFECT_LOWPASS_SIMPLE(); } 296 EFFECT_LOWPASS_SIMPLE (parameter_t cutoff = 1000.0); 297 }; 298 299 /** 300 * Resonant bandpass filter 301 */ 302 class EFFECT_RESONANT_BANDPASS : public EFFECT_FILTER { 303 304 private: 305 306 std::vector<SAMPLE_SPECS::sample_t> outhist1, outhist2; 307 308 parameter_t center; 309 parameter_t width; 310 311 parameter_t a, b, c, R; 312 parameter_t pole_angle; 313 314 SAMPLE_ITERATOR_CHANNELS i; 315 316 public: 317 name(void)318 virtual std::string name(void) const { return("Resonant bandpass filter"); } parameter_names(void)319 virtual std::string parameter_names(void) const { return("center-freq,width"); } 320 321 virtual void set_parameter(int param, parameter_t value); 322 virtual parameter_t get_parameter(int param) const; 323 324 virtual void init(SAMPLE_BUFFER *insample); 325 virtual void process(void); 326 clone(void)327 EFFECT_RESONANT_BANDPASS* clone(void) const { return new EFFECT_RESONANT_BANDPASS(*this); } new_expr(void)328 EFFECT_RESONANT_BANDPASS* new_expr(void) const { return new EFFECT_RESONANT_BANDPASS(); } 329 EFFECT_RESONANT_BANDPASS (parameter_t centerf = 1000.0, parameter_t width = 1000.0); 330 }; 331 332 /** 333 * Resonant lowpass filter 334 * 335 * Algorithm is based on a sample filter-routine (iir_filter) posted to comp.dsp. 336 */ 337 class EFFECT_RESONANT_LOWPASS : public EFFECT_FILTER { 338 339 SAMPLE_ITERATOR_CHANNELS i; 340 341 std::vector<SAMPLE_SPECS::sample_t> outhist0, outhist1, outhist2, outhist3; 342 std::vector<SAMPLE_SPECS::sample_t> newhist0, newhist1; 343 344 class TRIPLE_COEFS { 345 public: 346 parameter_t a0, a1, a2; // numerator coefficients 347 parameter_t b0, b1, b2; // denominator coefficients 348 }; 349 350 class FILTER_COEFS { 351 public: 352 parameter_t A, B, C, D; // filter coefficients 353 }; 354 355 std::vector<TRIPLE_COEFS> ProtoCoef; // Filter prototype coefficients, 356 // for each filter section 357 std::vector<FILTER_COEFS> Coef; 358 359 parameter_t cutoff, Q, gain, gain_orig; 360 parameter_t pi; 361 parameter_t laskuri; 362 363 parameter_t ad, bd, wp; // for szxform() 364 365 void szxform(int section); 366 void refresh_values(void); 367 368 public: 369 name(void)370 virtual std::string name(void) const { return("Resonant lowpass filter"); } parameter_names(void)371 virtual std::string parameter_names(void) const { return("cutoff-freq,resonance,gain"); } 372 373 virtual void set_parameter(int param, parameter_t value); 374 virtual parameter_t get_parameter(int param) const; 375 376 virtual void init(SAMPLE_BUFFER *insample); 377 virtual void process(void); 378 clone(void)379 EFFECT_RESONANT_LOWPASS* clone(void) const { return new EFFECT_RESONANT_LOWPASS(*this); } new_expr(void)380 EFFECT_RESONANT_LOWPASS* new_expr(void) const { return new EFFECT_RESONANT_LOWPASS(); } 381 EFFECT_RESONANT_LOWPASS (parameter_t cutoff = 1000.0, 382 parameter_t resonance = 1.0, 383 parameter_t gain = 1.0); 384 }; 385 386 /** 387 * Resonating bandpass filter 388 * 389 * Based on a second order all-pole (IIR) band-pass filter from SPKit 390 * (for more info, see: http://www.music.helsinki.fi/research/spkit) 391 */ 392 class EFFECT_RESONATOR : public EFFECT_FILTER { 393 394 private: 395 396 SAMPLE_ITERATOR_CHANNELS i; 397 398 parameter_t center; 399 parameter_t width; 400 401 std::vector<SAMPLE_SPECS::sample_t> cona; 402 std::vector<SAMPLE_SPECS::sample_t> conb; 403 404 std::vector<SAMPLE_SPECS::sample_t> saout0, saout1; 405 406 public: 407 name(void)408 virtual std::string name(void) const { return("Resonator filter"); } parameter_names(void)409 virtual std::string parameter_names(void) const { return("center-freq,width"); } 410 411 virtual void set_parameter(int param, parameter_t value); 412 virtual parameter_t get_parameter(int param) const; 413 414 virtual void init(SAMPLE_BUFFER *insample); 415 virtual void process(void); 416 clone(void)417 EFFECT_RESONATOR* clone(void) const { return new EFFECT_RESONATOR(*this); } new_expr(void)418 EFFECT_RESONATOR* new_expr(void) const { return new EFFECT_RESONATOR(); } 419 EFFECT_RESONATOR (parameter_t center = 1000.0, parameter_t width = 1000.0); 420 }; 421 422 #endif 423