zynaddsubfx

ZynAddSubFX open source synthesizer
Log | Files | Refs | Submodules | LICENSE

commit 1b51421abb388457628b1175d99c8a5008f42841
parent 5c5207a72a1ae04186f1ac7c1afc62e6c8cc93ef
Author: fundamental <mark.d.mccurry@gmail.com>
Date:   Wed,  3 Feb 2016 12:06:49 -0500

Add Missing ModFilter File

Diffstat:
Asrc/Synth/ModFilter.cpp | 149+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Asrc/Synth/ModFilter.h | 54++++++++++++++++++++++++++++++++++++++++++++++++++++++
2 files changed, 203 insertions(+), 0 deletions(-)

diff --git a/src/Synth/ModFilter.cpp b/src/Synth/ModFilter.cpp @@ -0,0 +1,149 @@ +#include "ModFilter.h" +#include "Envelope.h" +#include "LFO.h" +#include "../Misc/Util.h" +#include "../Misc/Allocator.h" +#include "../Params/FilterParams.h" +#include "../DSP/Filter.h" +#include "../DSP/SVFilter.h" +#include "../DSP/AnalogFilter.h" +#include "../DSP/FormantFilter.h" +#include <cassert> + +ModFilter::ModFilter(const FilterParams &pars_, + const SYNTH_T &synth_, + const AbsTime &time_, + Allocator &alloc_, + bool stereo, + float notefreq) + :pars(pars_), synth(synth_), time(time_), alloc(alloc_), + baseQ(pars.getq()), baseFreq(pars.getfreq()), + noteFreq(notefreq), + left(nullptr), + right(nullptr), + env(nullptr), + lfo(nullptr) +{ + tracking = pars.getfreqtracking(notefreq); + baseQ = pars.getq(); + baseFreq = pars.getfreq(); + + left = Filter::generate(alloc, &pars, + synth.samplerate, synth.buffersize); + + if(stereo) + right = Filter::generate(alloc, &pars, + synth.samplerate, synth.buffersize); +} + +ModFilter::~ModFilter(void) +{ + alloc.dealloc(left); + alloc.dealloc(right); +} + +void ModFilter::addMod(LFO &lfo_) +{ + lfo = &lfo_; +} + +void ModFilter::addMod(Envelope &env_) +{ + env = &env_; +} + +//Recompute Filter Parameters +void ModFilter::update(float relfreq, float relq) +{ + if(pars.last_update_timestamp == time.time()) { + paramUpdate(left); + if(right) + paramUpdate(right); + + baseFreq = pars.getfreq(); + baseQ = pars.getq(); + tracking = pars.getfreqtracking(noteFreq); + } + + //Controller Free Center Frequency + const float Fc = baseFreq + + sense + + (env ? env->envout() : 0) + + (lfo ? lfo->lfoout() : 0); + + const float Fc_mod = Fc + relfreq + tracking; + + //Convert into Hz + const float Fc_Hz = Filter::getrealfreq(Fc_mod); + + const float q = baseQ * relq; + + left->setfreq_and_q(Fc_Hz, q); + if(right) + right->setfreq_and_q(Fc_Hz, q); +} + +void ModFilter::updateNoteFreq(float noteFreq_) +{ + noteFreq = noteFreq_; + tracking = pars.getfreqtracking(noteFreq); +} + +void ModFilter::updateSense(float velocity, uint8_t scale, + uint8_t func) +{ + const float velScale = scale / 127.0f; + sense = velScale * 6.0f * (VelF(velocity, func) - 1); +} + +void ModFilter::filter(float *l, float *r) +{ + if(left && l) + left->filterout(l); + if(right && r) + right->filterout(r); +} + +static int current_category(Filter *f) +{ + if(dynamic_cast<AnalogFilter*>(f)) + return 0; + else if(dynamic_cast<FormantFilter*>(f)) + return 1; + else if(dynamic_cast<SVFilter*>(f)) + return 2; + + assert(false); +} + +void ModFilter::paramUpdate(Filter *&f) +{ + //Common parameters + baseQ = pars.getq(); + baseFreq = pars.getfreq(); + + if(current_category(f) != pars.Pcategory) { + alloc.dealloc(f); + f = Filter::generate(alloc, &pars, + synth.samplerate, synth.buffersize); + return; + } + + if(auto *sv = dynamic_cast<SVFilter*>(f)) + svParamUpdate(*sv); + else if(auto *an = dynamic_cast<AnalogFilter*>(f)) + anParamUpdate(*an); +} + +void ModFilter::svParamUpdate(SVFilter &sv) +{ + sv.settype(pars.Ptype); + sv.setstages(pars.Pstages); +} + +void ModFilter::anParamUpdate(AnalogFilter &an) +{ + an.settype(pars.Ptype); + an.setstages(pars.Pstages); + an.setgain(pars.getgain()); +} diff --git a/src/Synth/ModFilter.h b/src/Synth/ModFilter.h @@ -0,0 +1,54 @@ +#include "../globals.h" +#include "../Misc/Time.h" + +//Modulated instance of one of the filters in src/DSP/ +//Supports stereo modes +class ModFilter +{ + public: + ModFilter(const FilterParams &pars, + const SYNTH_T &synth, + const AbsTime &time, + Allocator &alloc, + bool stereo, + float notefreq_); + ~ModFilter(void); + + void addMod(LFO &lfo); + void addMod(Envelope &env); + + //normal per tick update + void update(float relfreq, float relq); + + //updates typically seen in note-init + void updateNoteFreq(float noteFreq_); + void updateSense(float velocity, + uint8_t scale, uint8_t func); + + //filter stereo/mono signal(s) in-place + void filter(float *l, float *r); + private: + void paramUpdate(Filter *&f); + void svParamUpdate(SVFilter &sv); + void anParamUpdate(AnalogFilter &an); + + + const FilterParams &pars; //Parameters to Pull Updates From + const SYNTH_T &synth; //Synthesizer Buffer Parameters + const AbsTime &time; //Time for RT Updates + Allocator &alloc; //RT Memory Pool + + + + float baseQ; //filter sharpness + float baseFreq; //base filter frequency + float noteFreq; //frequency note was initialized to + float tracking; //shift due to note frequency + float sense; //shift due to note velocity + + + Filter *left; //left channel filter + Filter *right;//right channel filter + Envelope *env; //center freq envelope + LFO *lfo; //center freq lfo +};