zynaddsubfx

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

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 }