1 2 /* 3 rakarrack - a guitar effects software 4 5 Expander.C - Noise Gate Effect 6 7 Copyright (C) 2010 Ryan Billing & Josep Andreu 8 Author: Ryan Billing & Josep Andreu 9 Adapted from swh-plugins Noise Gate by Steve Harris 10 11 This program is free software; you can redistribute it and/or modify 12 it under the terms of version 2 of the GNU General Public License 13 as published by the Free Software Foundation. 14 15 This program is distributed in the hope that it will be useful, 16 but WITHOUT ANY WARRANTY; without even the implied warranty of 17 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 18 GNU General Public License (version 2) for more details. 19 20 You should have received a copy of the GNU General Public License 21 (version2) along with this program; if not, write to the Free Software 22 Foundation, 23 Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 24 25 */ 26 27 #include <math.h> 28 #include "Expander.h" 29 30 31 Expander::Expander (float * efxoutl_, float * efxoutr_, double sample_rate, uint32_t intermediate_bufsize) 32 { 33 34 efxoutl = efxoutl_; 35 efxoutr = efxoutr_; 36 37 38 interpbuf = new float[intermediate_bufsize]; 39 lpfl = new AnalogFilter (2, 22000, 1, 0, sample_rate, interpbuf); 40 lpfr = new AnalogFilter (2, 22000, 1, 0, sample_rate, interpbuf); 41 hpfl = new AnalogFilter (3, 20, 1, 0, sample_rate, interpbuf); 42 hpfr = new AnalogFilter (3, 20, 1, 0, sample_rate, interpbuf); 43 44 env = 0.0; 45 oldgain = 0.0; 46 efollower = 0; 47 fs = sample_rate; 48 49 Expander_Change_Preset(0); 50 51 52 } 53 54 Expander::~Expander () 55 { 56 delete[] interpbuf; 57 delete lpfl; 58 delete lpfr; 59 delete hpfl; 60 delete hpfr; 61 } 62 63 64 65 void 66 Expander::cleanup () 67 { 68 lpfl->cleanup (); 69 hpfl->cleanup (); 70 lpfr->cleanup (); 71 hpfr->cleanup (); 72 oldgain = 0.0f; 73 74 } 75 76 77 78 79 void 80 Expander::setlpf (int value) 81 { 82 Plpf = value; 83 float fr = (float)Plpf; 84 lpfl->setfreq (fr); 85 lpfr->setfreq (fr); 86 }; 87 88 void 89 Expander::sethpf (int value) 90 { 91 Phpf = value; 92 float fr = (float)Phpf; 93 hpfl->setfreq (fr); 94 hpfr->setfreq (fr); 95 }; 96 97 98 void 99 Expander::Expander_Change (int np, int value) 100 { 101 102 switch (np) { 103 104 case 1: 105 Pthreshold = value; 106 tfactor = dB2rap (-((float) Pthreshold)); 107 tlevel = 1.0f/tfactor; 108 break; 109 case 2: 110 Pshape = value; 111 sfactor = dB2rap ((float)Pshape/2); 112 sgain = expf(-sfactor); 113 break; 114 case 3: 115 Pattack = value; 116 a_rate = 1000.0f/((float)Pattack * fs); 117 break; 118 case 4: 119 Pdecay = value; 120 d_rate = 1000.0f/((float)Pdecay * fs); 121 break; 122 case 5: 123 setlpf(value); 124 break; 125 case 6: 126 sethpf(value); 127 break; 128 case 7: 129 Plevel = value; 130 level = dB2rap((float) value/6.0f); 131 break; 132 133 } 134 135 136 } 137 138 int 139 Expander::getpar (int np) 140 { 141 142 switch (np) 143 144 { 145 case 1: 146 return (Pthreshold); 147 break; 148 case 2: 149 return (Pshape); 150 break; 151 case 3: 152 return (Pattack); 153 break; 154 case 4: 155 return (Pdecay); 156 break; 157 case 5: 158 return (Plpf); 159 break; 160 case 6: 161 return (Phpf); 162 break; 163 case 7: 164 return (Plevel); 165 break; 166 } 167 168 return (0); 169 170 } 171 172 173 void 174 Expander::Expander_Change_Preset (int npreset) 175 { 176 177 const int PRESET_SIZE = 7; 178 const int NUM_PRESETS = 3; 179 int pdata[PRESET_SIZE]; 180 int presets[NUM_PRESETS][PRESET_SIZE] = { 181 182 //Noise Gate 183 {-50, 20, 50, 50, 3134, 76, 0}, 184 //Boost Gate 185 {-55, 30, 50, 50, 1441, 157, 50}, 186 //Treble swell 187 {-30, 9, 950, 25, 6703, 526, 90} 188 }; 189 190 if(npreset>NUM_PRESETS-1) { 191 Fpre->ReadPreset(25,npreset-NUM_PRESETS+1,pdata); 192 for (int n = 0; n < PRESET_SIZE; n++) 193 Expander_Change (n+1, pdata[n]); 194 } else { 195 for (int n = 0; n < PRESET_SIZE; n++) 196 Expander_Change (n + 1, presets[npreset][n]); 197 } 198 199 } 200 201 202 203 void 204 Expander::out (float *efxoutl, float *efxoutr, uint32_t period) 205 { 206 207 208 unsigned int i; 209 float delta = 0.0f; 210 float expenv = 0.0f; 211 212 213 lpfl->filterout (efxoutl, period); 214 hpfl->filterout (efxoutl, period); 215 lpfr->filterout (efxoutr, period); 216 hpfr->filterout (efxoutr, period); 217 218 219 for (i = 0; i < period; i++) { 220 221 delta = 0.5f*(fabsf (efxoutl[i]) + fabsf (efxoutr[i])) - env; //envelope follower from Compressor.C 222 if (delta > 0.0) 223 env += a_rate * delta; 224 else 225 env += d_rate * delta; 226 227 //End envelope power detection 228 229 if (env > tlevel) env = tlevel; 230 expenv = sgain * (expf(env*sfactor*tfactor) - 1.0f); //Envelope waveshaping 231 232 gain = (1.0f - d_rate) * oldgain + d_rate * expenv; 233 oldgain = gain; //smooth it out a little bit 234 235 if(efollower) { 236 efxoutl[i] = gain; 237 efxoutr[i] += gain; 238 } else { 239 efxoutl[i] *= gain*level; 240 efxoutr[i] *= gain*level; 241 } 242 243 } 244 245 246 247 }; 248