1 /* B.Oops 2 * Glitch effect sequencer LV2 plugin 3 * 4 * Copyright (C) 2020 by Sven Jähnichen 5 * 6 * This program is free software; you can redistribute it and/or modify 7 * it under the terms of the GNU General Public License as published by 8 * the Free Software Foundation; either version 3, or (at your option) 9 * any later version. 10 * 11 * This program is distributed in the hope that it will be useful, 12 * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 * GNU General Public License for more details. 15 * 16 * You should have received a copy of the GNU General Public License 17 * along with this program; if not, write to the Free Software Foundation, 18 * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. 19 */ 20 21 #ifndef FXFLANGER_HPP_ 22 #define FXFLANGER_HPP_ 23 24 #include "Fx.hpp" 25 26 #define FX_FLANGER_MINDELAY 0 27 #define FX_FLANGER_MINDELAYRAND 1 28 #define FX_FLANGER_MODDELAY 2 29 #define FX_FLANGER_MODDELAYRAND 3 30 #define FX_FLANGER_FREQ 4 31 #define FX_FLANGER_FREQRAND 5 32 #define FX_FLANGER_PHASE 6 33 #define FX_FLANGER_PHASERAND 7 34 #define FX_FLANGER_FEEDBACK 8 35 #define FX_FLANGER_FEEDBACKRAND 9 36 37 class FxFlanger : public Fx 38 { 39 public: 40 FxFlanger () = delete; 41 FxFlanger(RingBuffer<Stereo> ** buffer,float * params,Pad * pads,double * framesPerStep,double rate)42 FxFlanger (RingBuffer<Stereo>** buffer, float* params, Pad* pads, double* framesPerStep, double rate) : 43 Fx (buffer, params, pads), 44 samplerate (rate), 45 framesPerStepPtr (framesPerStep), 46 framesPerStep (24000), 47 minDelay (0.0), 48 modDelay (0.01), 49 freq (0.25), 50 phase (0.0), 51 feedback (0.0f) 52 { 53 if (!framesPerStep) throw std::invalid_argument ("Fx initialized with framesPerStep nullptr"); 54 } 55 init(const double position)56 virtual void init (const double position) override 57 { 58 Fx::init (position); 59 const double r1 = bidist (rnd); 60 minDelay = 0.01 * LIMIT (params[SLOTS_OPTPARAMS + FX_FLANGER_MINDELAY] + r1 * params[SLOTS_OPTPARAMS + FX_FLANGER_MINDELAYRAND], 0.0, 1.0); 61 const double r2 = bidist (rnd); 62 modDelay = 0.01 * LIMIT (params[SLOTS_OPTPARAMS + FX_FLANGER_MODDELAY] + r2 * params[SLOTS_OPTPARAMS + FX_FLANGER_MODDELAYRAND], 0.0, 1.0); 63 const double r3 = bidist (rnd); 64 freq = 10.0 * 2.0 * M_PI * pow (LIMIT (params[SLOTS_OPTPARAMS + FX_FLANGER_FREQ] + r3 * params[SLOTS_OPTPARAMS + FX_FLANGER_FREQRAND], 0.0, 1.0), 3.0); 65 const double r4 = bidist (rnd); 66 phase = 2.0 * M_PI * LIMIT (params[SLOTS_OPTPARAMS + FX_FLANGER_PHASE] + r4 * params[SLOTS_OPTPARAMS + FX_FLANGER_PHASERAND], 0.0, 1.0); 67 const double r5 = bidist (rnd); 68 feedback = 2.0 * LIMIT (params[SLOTS_OPTPARAMS + FX_FLANGER_FEEDBACK] + r5 * params[SLOTS_OPTPARAMS + FX_FLANGER_FEEDBACKRAND], 0.0, 1.0) - 1.0; 69 framesPerStep = *framesPerStepPtr; 70 } 71 process(const double position,const double size)72 virtual Stereo process (const double position, const double size) override 73 { 74 const double delayL = minDelay + (0.5 - 0.5 * cos (freq * position * framesPerStep / samplerate)) * modDelay; 75 const double delayR = minDelay + (0.5 - 0.5 * cos (phase + freq * position * framesPerStep / samplerate)) * modDelay; 76 const long frameL = (delayL * samplerate); 77 const long frameR = (delayR * samplerate); 78 return Stereo ((**buffer)[frameL].left, (**buffer)[frameR].right); 79 } 80 playPad(const double position,const double size,const double mixf)81 virtual Stereo playPad (const double position, const double size, const double mixf) override 82 { 83 const Stereo s0 = (**buffer).front(); 84 Stereo s1 = process (position, size); 85 s1 = mix (s0, s1, position, size, mixf); 86 Stereo s2 = s1; 87 (**buffer).front() = s2.mix (s0, 1.0f - feedback); 88 return s1; 89 } 90 play(const double position,const double size,const double mx,const double mixf)91 virtual Stereo play (const double position, const double size, const double mx, const double mixf) override 92 { 93 const Stereo s0 = (**buffer).front(); 94 Stereo s1 = process (position, size); 95 s1 = BUtilities::mix<Stereo> (s0, pan (s0, s1), params[SLOTS_MIX] * mx * mixf); 96 Stereo s2 = s1; 97 (**buffer).front() = s2.mix (s0, 1.0f - feedback); 98 return s1; 99 } 100 101 protected: 102 double samplerate; 103 double* framesPerStepPtr; 104 double framesPerStep; 105 double minDelay; 106 double modDelay; 107 double freq; 108 double phase; 109 float feedback; 110 }; 111 112 #endif /* FXFLANGER_HPP_ */ 113