ModFilter.cpp (4446B)
1 /* 2 ZynAddSubFX - a software synthesizer 3 4 ModFilter.cpp - Modulated Filter 5 Copyright (C) 2016 Mark McCurry 6 7 This program is free software; you can redistribute it and/or 8 modify it under the terms of the GNU General Public License 9 as published by the Free Software Foundation; either version 2 10 of the License, or (at your option) any later version. 11 */ 12 #include "ModFilter.h" 13 #include "Envelope.h" 14 #include "LFO.h" 15 #include "../Misc/Util.h" 16 #include "../Misc/Allocator.h" 17 #include "../Params/FilterParams.h" 18 #include "../DSP/Filter.h" 19 #include "../DSP/SVFilter.h" 20 #include "../DSP/AnalogFilter.h" 21 #include "../DSP/FormantFilter.h" 22 #include "../DSP/MoogFilter.h" 23 #include "../DSP/CombFilter.h" 24 #include <cassert> 25 26 namespace zyn { 27 28 ModFilter::ModFilter(const FilterParams &pars_, 29 const SYNTH_T &synth_, 30 const AbsTime &time_, 31 Allocator &alloc_, 32 bool stereo, 33 float notefreq) 34 :pars(pars_), synth(synth_), time(time_), alloc(alloc_), 35 noteFreq(notefreq), 36 left(nullptr), 37 right(nullptr), 38 env(nullptr), 39 lfo(nullptr) 40 { 41 tracking = pars.getfreqtracking(notefreq); 42 baseQ = pars.getq(); 43 baseFreq = pars.getfreq(); 44 45 left = Filter::generate(alloc, &pars, 46 synth.samplerate, synth.buffersize); 47 48 if(stereo) 49 right = Filter::generate(alloc, &pars, 50 synth.samplerate, synth.buffersize); 51 } 52 53 ModFilter::~ModFilter(void) 54 { 55 alloc.dealloc(left); 56 alloc.dealloc(right); 57 } 58 59 void ModFilter::addMod(LFO &lfo_) 60 { 61 lfo = &lfo_; 62 } 63 64 void ModFilter::addMod(Envelope &env_) 65 { 66 env = &env_; 67 } 68 69 //Recompute Filter Parameters 70 void ModFilter::update(float relfreq, float relq) 71 { 72 if(pars.last_update_timestamp == time.time()) { 73 paramUpdate(left); 74 if(right) 75 paramUpdate(right); 76 77 baseFreq = pars.getfreq(); 78 baseQ = pars.getq(); 79 tracking = pars.getfreqtracking(noteFreq); 80 } 81 82 //Controller Free Center Frequency 83 const float Fc = baseFreq 84 + sense 85 + (env ? env->envout() : 0) 86 + (lfo ? lfo->lfoout() : 0); 87 88 const float Fc_mod = Fc + relfreq + tracking; 89 90 //Convert into Hz 91 const float Fc_Hz = Filter::getrealfreq(Fc_mod); 92 93 const float q = baseQ * relq; 94 95 left->setfreq_and_q(Fc_Hz, q); 96 if(right) 97 right->setfreq_and_q(Fc_Hz, q); 98 } 99 100 void ModFilter::updateNoteFreq(float noteFreq_) 101 { 102 noteFreq = noteFreq_; 103 tracking = pars.getfreqtracking(noteFreq_); 104 } 105 106 void ModFilter::updateSense(float velocity, uint8_t scale, 107 uint8_t func) 108 { 109 const float velScale = scale / 127.0f; 110 sense = velScale * 6.0f * (VelF(velocity, func) - 1); 111 } 112 113 void ModFilter::filter(float *l, float *r) 114 { 115 if(left && l) 116 left->filterout(l); 117 if(right && r) 118 right->filterout(r); 119 } 120 121 static int current_category(Filter *f) 122 { 123 if(dynamic_cast<AnalogFilter*>(f)) 124 return 0; 125 else if(dynamic_cast<FormantFilter*>(f)) 126 return 1; 127 else if(dynamic_cast<SVFilter*>(f)) 128 return 2; 129 else if(dynamic_cast<MoogFilter*>(f)) 130 return 3; 131 else if(dynamic_cast<CombFilter*>(f)) 132 return 4; 133 134 assert(false); 135 return -1; 136 } 137 138 void ModFilter::paramUpdate(Filter *&f) 139 { 140 //Common parameters 141 baseQ = pars.getq(); 142 baseFreq = pars.getfreq(); 143 144 if(current_category(f) != pars.Pcategory) { 145 alloc.dealloc(f); 146 f = Filter::generate(alloc, &pars, 147 synth.samplerate, synth.buffersize); 148 return; 149 } 150 151 if(auto *sv = dynamic_cast<SVFilter*>(f)) 152 svParamUpdate(*sv); 153 else if(auto *an = dynamic_cast<AnalogFilter*>(f)) 154 anParamUpdate(*an); 155 else if(auto *mg = dynamic_cast<MoogFilter*>(f)) 156 mgParamUpdate(*mg); 157 else if(auto *cb = dynamic_cast<CombFilter*>(f)) 158 cbParamUpdate(*cb); 159 } 160 161 void ModFilter::svParamUpdate(SVFilter &sv) 162 { 163 sv.settype(pars.Ptype); 164 sv.setstages(pars.Pstages); 165 } 166 167 void ModFilter::anParamUpdate(AnalogFilter &an) 168 { 169 an.settype(pars.Ptype); 170 an.setstages(pars.Pstages); 171 an.setgain(pars.getgain()); 172 } 173 174 void ModFilter::mgParamUpdate(MoogFilter &mg) 175 { 176 mg.settype(pars.Ptype); 177 mg.setgain(pars.getgain()); 178 } 179 180 void ModFilter::cbParamUpdate(CombFilter &cb) 181 { 182 cb.settype(pars.Ptype); 183 cb.setgain(pars.getgain()); 184 } 185 }