annotate effects/reverb/Source/MVerb.h @ 1:04e171d2a747 tip

JUCE 4 compatible. Standardised paths on Mac: modules '../../juce/modules'; VST folder '~/SDKs/vstsdk2.4' (JUCE default). Replaced deprecated 'getSampleData(channel)'; getToggleState(...); setToggleState(...); setSelectedId(...). Removed unused variables. Ignore JUCE code and build files.
author Brecht De Man <b.deman@qmul.ac.uk>
date Sun, 22 Nov 2015 15:23:40 +0000
parents e32fe563e124
children
rev   line source
andrewm@0 1 // Copyright (c) 2010 Martin Eastwood
andrewm@0 2 // This code is distributed under the terms of the GNU General Public License
andrewm@0 3
andrewm@0 4 // MVerb is free software: you can redistribute it and/or modify
andrewm@0 5 // it under the terms of the GNU General Public License as published by
andrewm@0 6 // the Free Software Foundation, either version 3 of the License, or
andrewm@0 7 // at your option) any later version.
andrewm@0 8 //
andrewm@0 9 // MVerb is distributed in the hope that it will be useful,
andrewm@0 10 // but WITHOUT ANY WARRANTY; without even the implied warranty of
andrewm@0 11 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
andrewm@0 12 // GNU General Public License for more details.
andrewm@0 13 //
andrewm@0 14 // You should have received a copy of the GNU General Public License
andrewm@0 15 // along with this MVerb. If not, see <http://www.gnu.org/licenses/>.
andrewm@0 16
andrewm@0 17 #ifndef EMVERB_H
andrewm@0 18 #define EMVERB_H
andrewm@0 19
andrewm@0 20 //forward declaration
andrewm@0 21 template<typename T, int maxLength> class Allpass;
andrewm@0 22 template<typename T, int maxLength> class StaticAllpassFourTap;
andrewm@0 23 template<typename T, int maxLength> class StaticDelayLine;
andrewm@0 24 template<typename T, int maxLength> class StaticDelayLineFourTap;
andrewm@0 25 template<typename T, int maxLength> class StaticDelayLineEightTap;
andrewm@0 26 template<typename T, int OverSampleCount> class StateVariable;
andrewm@0 27
andrewm@0 28 template<typename T>
andrewm@0 29 class MVerb
andrewm@0 30 {
andrewm@0 31 private:
andrewm@0 32 Allpass<T, 96000> allpass[4];
andrewm@0 33 StaticAllpassFourTap<T, 96000> allpassFourTap[4];
andrewm@0 34 StateVariable<T,4> bandwidthFilter[2];
andrewm@0 35 StateVariable<T,4> damping[2];
andrewm@0 36 StaticDelayLine<T, 96000> predelay;
andrewm@0 37 StaticDelayLineFourTap<T, 96000> staticDelayLine[4];
andrewm@0 38 StaticDelayLineEightTap<T, 96000> earlyReflectionsDelayLine[2];
andrewm@0 39 T SampleRate, DampingFreq, Density1, Density2, BandwidthFreq, PreDelayTime, Decay, Gain, Mix, EarlyMix, Size;
andrewm@0 40 T MixSmooth, EarlyLateSmooth, BandwidthSmooth, DampingSmooth, PredelaySmooth, SizeSmooth, DensitySmooth, DecaySmooth;
andrewm@0 41 T PreviousLeftTank, PreviousRightTank;
andrewm@0 42 int ControlRate, ControlRateCounter;
andrewm@0 43
andrewm@0 44 public:
andrewm@0 45 enum
andrewm@0 46 {
andrewm@0 47 DAMPINGFREQ=0,
andrewm@0 48 DENSITY,
andrewm@0 49 BANDWIDTHFREQ,
andrewm@0 50 DECAY,
andrewm@0 51 PREDELAY,
andrewm@0 52 SIZE,
andrewm@0 53 GAIN,
andrewm@0 54 MIX,
andrewm@0 55 EARLYMIX,
andrewm@0 56 NUM_PARAMS
andrewm@0 57 };
andrewm@0 58
andrewm@0 59 MVerb(){
andrewm@0 60 setParameter (DAMPINGFREQ, 0.0);
andrewm@0 61 setParameter (DENSITY, 0.5);
andrewm@0 62 setParameter (BANDWIDTHFREQ, 1.0);
andrewm@0 63 setParameter (DECAY, 0.5);
andrewm@0 64 setParameter (PREDELAY, 0.0);
andrewm@0 65 setParameter (SIZE, 0.5);
andrewm@0 66 setParameter (GAIN, 1.0);
andrewm@0 67 setParameter (MIX, 0.15);
andrewm@0 68 setParameter (EARLYMIX, 0.75);
andrewm@0 69
andrewm@0 70 SampleRate = 44100.;
andrewm@0 71 PreviousLeftTank = 0.;
andrewm@0 72 PreviousRightTank = 0.;
andrewm@0 73 PreDelayTime = 100 * (SampleRate / 1000);
andrewm@0 74 MixSmooth = EarlyLateSmooth = BandwidthSmooth = DampingSmooth = PredelaySmooth = SizeSmooth = DecaySmooth = DensitySmooth = 0.;
andrewm@0 75 ControlRate = SampleRate / 1000;
andrewm@0 76 ControlRateCounter = 0;
andrewm@0 77 reset();
andrewm@0 78 }
andrewm@0 79
andrewm@0 80 ~MVerb(){
andrewm@0 81 //nowt to do here
andrewm@0 82 }
andrewm@0 83
andrewm@0 84 void process(T **inputs, T **outputs, int sampleFrames){
andrewm@0 85 T OneOverSampleFrames = 1. / sampleFrames;
andrewm@0 86 T MixDelta = (Mix - MixSmooth) * OneOverSampleFrames;
andrewm@0 87 T EarlyLateDelta = (EarlyMix - EarlyLateSmooth) * OneOverSampleFrames;
andrewm@0 88 T BandwidthDelta = (((BandwidthFreq * 18400.) + 100.) - BandwidthSmooth) * OneOverSampleFrames;
andrewm@0 89 T DampingDelta = (((DampingFreq * 18400.) + 100.) - DampingSmooth) * OneOverSampleFrames;
andrewm@0 90 T PredelayDelta = ((PreDelayTime * 200 * (SampleRate / 1000)) - PredelaySmooth) * OneOverSampleFrames;
andrewm@0 91 T SizeDelta = (Size - SizeSmooth) * OneOverSampleFrames;
andrewm@0 92 T DecayDelta = (((0.7995f * Decay) + 0.005) - DecaySmooth) * OneOverSampleFrames;
andrewm@0 93 T DensityDelta = (((0.7995f * Density1) + 0.005) - DensitySmooth) * OneOverSampleFrames;
andrewm@0 94 for(int i=0;i<sampleFrames;++i){
andrewm@0 95 T left = inputs[0][i];
andrewm@0 96 T right = inputs[1][i];
andrewm@0 97 MixSmooth += MixDelta;
andrewm@0 98 EarlyLateSmooth += EarlyLateDelta;
andrewm@0 99 BandwidthSmooth += BandwidthDelta;
andrewm@0 100 DampingSmooth += DampingDelta;
andrewm@0 101 PredelaySmooth += PredelayDelta;
andrewm@0 102 SizeSmooth += SizeDelta;
andrewm@0 103 DecaySmooth += DecayDelta;
andrewm@0 104 DensitySmooth += DensityDelta;
andrewm@0 105 if (ControlRateCounter >= ControlRate){
andrewm@0 106 ControlRateCounter = 0;
andrewm@0 107 bandwidthFilter[0].Frequency(BandwidthSmooth);
andrewm@0 108 bandwidthFilter[1].Frequency(BandwidthSmooth);
andrewm@0 109 damping[0].Frequency(DampingSmooth);
andrewm@0 110 damping[1].Frequency(DampingSmooth);
andrewm@0 111 }
andrewm@0 112 ++ControlRateCounter;
andrewm@0 113 predelay.SetLength(PredelaySmooth);
andrewm@0 114 Density2 = DecaySmooth + 0.15;
andrewm@0 115 if (Density2 > 0.5)
andrewm@0 116 Density2 = 0.5;
andrewm@0 117 if (Density2 < 0.25)
andrewm@0 118 Density2 = 0.25;
andrewm@0 119 allpassFourTap[1].SetFeedback(Density2);
andrewm@0 120 allpassFourTap[3].SetFeedback(Density2);
andrewm@0 121 allpassFourTap[0].SetFeedback(Density1);
andrewm@0 122 allpassFourTap[2].SetFeedback(Density1);
andrewm@0 123 T bandwidthLeft = bandwidthFilter[0](left) ;
andrewm@0 124 T bandwidthRight = bandwidthFilter[1](right) ;
andrewm@0 125 T earlyReflectionsL = earlyReflectionsDelayLine[0] ( bandwidthLeft * 0.5 + bandwidthRight * 0.3 )
andrewm@0 126 + earlyReflectionsDelayLine[0].GetIndex(2) * 0.6
andrewm@0 127 + earlyReflectionsDelayLine[0].GetIndex(3) * 0.4
andrewm@0 128 + earlyReflectionsDelayLine[0].GetIndex(4) * 0.3
andrewm@0 129 + earlyReflectionsDelayLine[0].GetIndex(5) * 0.3
andrewm@0 130 + earlyReflectionsDelayLine[0].GetIndex(6) * 0.1
andrewm@0 131 + earlyReflectionsDelayLine[0].GetIndex(7) * 0.1
andrewm@0 132 + ( bandwidthLeft * 0.4 + bandwidthRight * 0.2 ) * 0.5 ;
andrewm@0 133 T earlyReflectionsR = earlyReflectionsDelayLine[1] ( bandwidthLeft * 0.3 + bandwidthRight * 0.5 )
andrewm@0 134 + earlyReflectionsDelayLine[1].GetIndex(2) * 0.6
andrewm@0 135 + earlyReflectionsDelayLine[1].GetIndex(3) * 0.4
andrewm@0 136 + earlyReflectionsDelayLine[1].GetIndex(4) * 0.3
andrewm@0 137 + earlyReflectionsDelayLine[1].GetIndex(5) * 0.3
andrewm@0 138 + earlyReflectionsDelayLine[1].GetIndex(6) * 0.1
andrewm@0 139 + earlyReflectionsDelayLine[1].GetIndex(7) * 0.1
andrewm@0 140 + ( bandwidthLeft * 0.2 + bandwidthRight * 0.4 ) * 0.5 ;
andrewm@0 141 T predelayMonoInput = predelay(( bandwidthRight + bandwidthLeft ) * 0.5f);
andrewm@0 142 T smearedInput = predelayMonoInput;
andrewm@0 143 for(int j=0;j<4;j++)
andrewm@0 144 smearedInput = allpass[j] ( smearedInput );
andrewm@0 145 T leftTank = allpassFourTap[0] ( smearedInput + PreviousRightTank ) ;
andrewm@0 146 leftTank = staticDelayLine[0] (leftTank);
andrewm@0 147 leftTank = damping[0](leftTank);
andrewm@0 148 leftTank = allpassFourTap[1](leftTank);
andrewm@0 149 leftTank = staticDelayLine[1](leftTank);
andrewm@0 150 T rightTank = allpassFourTap[2] (smearedInput + PreviousLeftTank) ;
andrewm@0 151 rightTank = staticDelayLine[2](rightTank);
andrewm@0 152 rightTank = damping[1] (rightTank);
andrewm@0 153 rightTank = allpassFourTap[3](rightTank);
andrewm@0 154 rightTank = staticDelayLine[3](rightTank);
andrewm@0 155 PreviousLeftTank = leftTank * DecaySmooth;
andrewm@0 156 PreviousRightTank = rightTank * DecaySmooth;
andrewm@0 157 T accumulatorL = (0.6*staticDelayLine[2].GetIndex(1))
andrewm@0 158 +(0.6*staticDelayLine[2].GetIndex(2))
andrewm@0 159 -(0.6*allpassFourTap[3].GetIndex(1))
andrewm@0 160 +(0.6*staticDelayLine[3].GetIndex(1))
andrewm@0 161 -(0.6*staticDelayLine[0].GetIndex(1))
andrewm@0 162 -(0.6*allpassFourTap[1].GetIndex(1))
andrewm@0 163 -(0.6*staticDelayLine[1].GetIndex(1));
andrewm@0 164 T accumulatorR = (0.6*staticDelayLine[0].GetIndex(2))
andrewm@0 165 +(0.6*staticDelayLine[0].GetIndex(3))
andrewm@0 166 -(0.6*allpassFourTap[1].GetIndex(2))
andrewm@0 167 +(0.6*staticDelayLine[1].GetIndex(2))
andrewm@0 168 -(0.6*staticDelayLine[2].GetIndex(3))
andrewm@0 169 -(0.6*allpassFourTap[3].GetIndex(2))
andrewm@0 170 -(0.6*staticDelayLine[3].GetIndex(2));
andrewm@0 171 accumulatorL = ((accumulatorL * EarlyMix) + ((1 - EarlyMix) * earlyReflectionsL));
andrewm@0 172 accumulatorR = ((accumulatorR * EarlyMix) + ((1 - EarlyMix) * earlyReflectionsR));
andrewm@0 173 left = ( left + MixSmooth * ( accumulatorL - left ) ) * Gain;
andrewm@0 174 right = ( right + MixSmooth * ( accumulatorR - right ) ) * Gain;
andrewm@0 175 outputs[0][i] = left;
andrewm@0 176 outputs[1][i] = right;
andrewm@0 177 }
andrewm@0 178 }
andrewm@0 179
andrewm@0 180 void reset(){
andrewm@0 181 ControlRateCounter = 0;
andrewm@0 182 bandwidthFilter[0].SetSampleRate (SampleRate );
andrewm@0 183 bandwidthFilter[1].SetSampleRate (SampleRate );
andrewm@0 184 bandwidthFilter[0].Reset();
andrewm@0 185 bandwidthFilter[1].Reset();
andrewm@0 186 damping[0].SetSampleRate (SampleRate );
andrewm@0 187 damping[1].SetSampleRate (SampleRate );
andrewm@0 188 damping[0].Reset();
andrewm@0 189 damping[1].Reset();
andrewm@0 190 predelay.Clear();
andrewm@0 191 predelay.SetLength(PreDelayTime);
andrewm@0 192 allpass[0].Clear();
andrewm@0 193 allpass[1].Clear();
andrewm@0 194 allpass[2].Clear();
andrewm@0 195 allpass[3].Clear();
andrewm@0 196 allpass[0].SetLength (0.0048 * SampleRate);
andrewm@0 197 allpass[1].SetLength (0.0036 * SampleRate);
andrewm@0 198 allpass[2].SetLength (0.0127 * SampleRate);
andrewm@0 199 allpass[3].SetLength (0.0093 * SampleRate);
andrewm@0 200 allpass[0].SetFeedback (0.75);
andrewm@0 201 allpass[1].SetFeedback (0.75);
andrewm@0 202 allpass[2].SetFeedback (0.625);
andrewm@0 203 allpass[3].SetFeedback (0.625);
andrewm@0 204 allpassFourTap[0].Clear();
andrewm@0 205 allpassFourTap[1].Clear();
andrewm@0 206 allpassFourTap[2].Clear();
andrewm@0 207 allpassFourTap[3].Clear();
andrewm@0 208 allpassFourTap[0].SetLength(0.020 * SampleRate * Size);
andrewm@0 209 allpassFourTap[1].SetLength(0.060 * SampleRate * Size);
andrewm@0 210 allpassFourTap[2].SetLength(0.030 * SampleRate * Size);
andrewm@0 211 allpassFourTap[3].SetLength(0.089 * SampleRate * Size);
andrewm@0 212 allpassFourTap[0].SetFeedback(Density1);
andrewm@0 213 allpassFourTap[1].SetFeedback(Density2);
andrewm@0 214 allpassFourTap[2].SetFeedback(Density1);
andrewm@0 215 allpassFourTap[3].SetFeedback(Density2);
andrewm@0 216 allpassFourTap[0].SetIndex(0,0,0,0);
andrewm@0 217 allpassFourTap[1].SetIndex(0,0.006 * SampleRate * Size, 0.041 * SampleRate * Size, 0);
andrewm@0 218 allpassFourTap[2].SetIndex(0,0,0,0);
andrewm@0 219 allpassFourTap[3].SetIndex(0,0.031 * SampleRate * Size, 0.011 * SampleRate * Size, 0);
andrewm@0 220 staticDelayLine[0].Clear();
andrewm@0 221 staticDelayLine[1].Clear();
andrewm@0 222 staticDelayLine[2].Clear();
andrewm@0 223 staticDelayLine[3].Clear();
andrewm@0 224 staticDelayLine[0].SetLength(0.15 * SampleRate * Size);
andrewm@0 225 staticDelayLine[1].SetLength(0.12 * SampleRate * Size);
andrewm@0 226 staticDelayLine[2].SetLength(0.14 * SampleRate * Size);
andrewm@0 227 staticDelayLine[3].SetLength(0.11 * SampleRate * Size);
andrewm@0 228 staticDelayLine[0].SetIndex(0, 0.067 * SampleRate * Size, 0.011 * SampleRate * Size , 0.121 * SampleRate * Size);
andrewm@0 229 staticDelayLine[1].SetIndex(0, 0.036 * SampleRate * Size, 0.089 * SampleRate * Size , 0);
andrewm@0 230 staticDelayLine[2].SetIndex(0, 0.0089 * SampleRate * Size, 0.099 * SampleRate * Size , 0);
andrewm@0 231 staticDelayLine[3].SetIndex(0, 0.067 * SampleRate * Size, 0.0041 * SampleRate * Size , 0);
andrewm@0 232 earlyReflectionsDelayLine[0].Clear();
andrewm@0 233 earlyReflectionsDelayLine[1].Clear();
andrewm@0 234 earlyReflectionsDelayLine[0].SetLength(0.089 * SampleRate);
andrewm@0 235 earlyReflectionsDelayLine[0].SetIndex (0, 0.0199*SampleRate, 0.0219*SampleRate, 0.0354*SampleRate,0.0389*SampleRate, 0.0414*SampleRate, 0.0692*SampleRate, 0);
andrewm@0 236 earlyReflectionsDelayLine[1].SetLength(0.069 * SampleRate);
andrewm@0 237 earlyReflectionsDelayLine[1].SetIndex (0, 0.0099*SampleRate, 0.011*SampleRate, 0.0182*SampleRate,0.0189*SampleRate, 0.0213*SampleRate, 0.0431*SampleRate, 0);
andrewm@0 238 }
andrewm@0 239
andrewm@0 240 void setParameter(int index, T value){
andrewm@0 241 switch(index){
andrewm@0 242 case DAMPINGFREQ:
andrewm@0 243 DampingFreq = 1. - value;
andrewm@0 244 break;
andrewm@0 245 case DENSITY:
andrewm@0 246 Density1 = value;
andrewm@0 247 break;
andrewm@0 248 case BANDWIDTHFREQ:
andrewm@0 249 BandwidthFreq = value;
andrewm@0 250 break;
andrewm@0 251 case PREDELAY:
andrewm@0 252 PreDelayTime = value;
andrewm@0 253 break;
andrewm@0 254 case SIZE:
andrewm@0 255 Size = (0.95 * value) + 0.05;
andrewm@0 256 allpassFourTap[0].Clear();
andrewm@0 257 allpassFourTap[1].Clear();
andrewm@0 258 allpassFourTap[2].Clear();
andrewm@0 259 allpassFourTap[3].Clear();
andrewm@0 260 allpassFourTap[0].SetLength(0.020 * SampleRate * Size);
andrewm@0 261 allpassFourTap[1].SetLength(0.060 * SampleRate * Size);
andrewm@0 262 allpassFourTap[2].SetLength(0.030 * SampleRate * Size);
andrewm@0 263 allpassFourTap[3].SetLength(0.089 * SampleRate * Size);
andrewm@0 264 allpassFourTap[1].SetIndex(0,0.006 * SampleRate * Size, 0.041 * SampleRate * Size, 0);
andrewm@0 265 allpassFourTap[3].SetIndex(0,0.031 * SampleRate * Size, 0.011 * SampleRate * Size, 0);
andrewm@0 266 staticDelayLine[0].Clear();
andrewm@0 267 staticDelayLine[1].Clear();
andrewm@0 268 staticDelayLine[2].Clear();
andrewm@0 269 staticDelayLine[3].Clear();
andrewm@0 270 staticDelayLine[0].SetLength(0.15 * SampleRate * Size);
andrewm@0 271 staticDelayLine[1].SetLength(0.12 * SampleRate * Size);
andrewm@0 272 staticDelayLine[2].SetLength(0.14 * SampleRate * Size);
andrewm@0 273 staticDelayLine[3].SetLength(0.11 * SampleRate * Size);
andrewm@0 274 staticDelayLine[0].SetIndex(0, 0.067 * SampleRate * Size, 0.011 * SampleRate * Size , 0.121 * SampleRate * Size);
andrewm@0 275 staticDelayLine[1].SetIndex(0, 0.036 * SampleRate * Size, 0.089 * SampleRate * Size , 0);
andrewm@0 276 staticDelayLine[2].SetIndex(0, 0.0089 * SampleRate * Size, 0.099 * SampleRate * Size , 0);
andrewm@0 277 staticDelayLine[3].SetIndex(0, 0.067 * SampleRate * Size, 0.0041 * SampleRate * Size , 0);
andrewm@0 278 break;
andrewm@0 279 case DECAY:
andrewm@0 280 Decay = value;
andrewm@0 281 break;
andrewm@0 282 case GAIN:
andrewm@0 283 Gain = value;
andrewm@0 284 break;
andrewm@0 285 case MIX:
andrewm@0 286 Mix = value;
andrewm@0 287 break;
andrewm@0 288 case EARLYMIX:
andrewm@0 289 EarlyMix = value;
andrewm@0 290 break;
andrewm@0 291 }
andrewm@0 292 }
andrewm@0 293
andrewm@0 294 float getParameter(int index){
andrewm@0 295 switch(index){
andrewm@0 296 case DAMPINGFREQ:
andrewm@0 297 return DampingFreq * 100.;
andrewm@0 298 break;
andrewm@0 299 case DENSITY:
andrewm@0 300 return Density1 * 100.f;
andrewm@0 301 break;
andrewm@0 302 case BANDWIDTHFREQ:
andrewm@0 303 return BandwidthFreq * 100.;
andrewm@0 304 break;
andrewm@0 305 case PREDELAY:
andrewm@0 306 return PreDelayTime * 100.;
andrewm@0 307 break;
andrewm@0 308 case SIZE:
andrewm@0 309 return (((0.95 * Size) + 0.05)*100.);
andrewm@0 310 break;
andrewm@0 311 case DECAY:
andrewm@0 312 return Decay * 100.f;
andrewm@0 313 break;
andrewm@0 314 case GAIN:
andrewm@0 315 return Gain * 100.f;
andrewm@0 316 break;
andrewm@0 317 case MIX:
andrewm@0 318 return Mix * 100.f;
andrewm@0 319 break;
andrewm@0 320 case EARLYMIX:
andrewm@0 321 return EarlyMix * 100.f;
andrewm@0 322 break;
andrewm@0 323 default: return 0.f;
andrewm@0 324 break;
andrewm@0 325
andrewm@0 326 }
andrewm@0 327 }
andrewm@0 328
andrewm@0 329 void setSampleRate(T sr){
andrewm@0 330 SampleRate = sr;
andrewm@0 331 ControlRate = SampleRate / 1000;
andrewm@0 332 reset();
andrewm@0 333 }
andrewm@0 334 };
andrewm@0 335
andrewm@0 336
andrewm@0 337
andrewm@0 338 template<typename T, int maxLength>
andrewm@0 339 class Allpass
andrewm@0 340 {
andrewm@0 341 private:
andrewm@0 342 T buffer[maxLength];
andrewm@0 343 int index;
andrewm@0 344 int Length;
andrewm@0 345 T Feedback;
andrewm@0 346
andrewm@0 347 public:
andrewm@0 348 Allpass()
andrewm@0 349 {
andrewm@0 350 SetLength ( maxLength - 1 );
andrewm@0 351 Clear();
andrewm@0 352 Feedback = 0.5;
andrewm@0 353 }
andrewm@0 354
andrewm@0 355 T operator()(T input)
andrewm@0 356 {
andrewm@0 357 T output;
andrewm@0 358 T bufout;
andrewm@0 359 bufout = buffer[index];
andrewm@0 360 T temp = input * -Feedback;
andrewm@0 361 output = bufout + temp;
andrewm@0 362 buffer[index] = input + ((bufout+temp)*Feedback);
andrewm@0 363 if(++index>=Length) index = 0;
andrewm@0 364 return output;
andrewm@0 365
andrewm@0 366 }
andrewm@0 367
andrewm@0 368 void SetLength (int Length)
andrewm@0 369 {
andrewm@0 370 if( Length >= maxLength )
andrewm@0 371 Length = maxLength;
andrewm@0 372 if( Length < 0 )
andrewm@0 373 Length = 0;
andrewm@0 374
andrewm@0 375 this->Length = Length;
andrewm@0 376 }
andrewm@0 377
andrewm@0 378 void SetFeedback(T feedback)
andrewm@0 379 {
andrewm@0 380 Feedback = feedback;
andrewm@0 381 }
andrewm@0 382
andrewm@0 383 void Clear()
andrewm@0 384 {
andrewm@0 385 memset(buffer, 0, sizeof(buffer));
andrewm@0 386 index = 0;
andrewm@0 387 }
andrewm@0 388
andrewm@0 389 int GetLength() const
andrewm@0 390 {
andrewm@0 391 return Length;
andrewm@0 392 }
andrewm@0 393 };
andrewm@0 394
andrewm@0 395 template<typename T, int maxLength>
andrewm@0 396 class StaticAllpassFourTap
andrewm@0 397 {
andrewm@0 398 private:
andrewm@0 399 T buffer[maxLength];
andrewm@0 400 int index1, index2, index3, index4;
andrewm@0 401 int Length;
andrewm@0 402 T Feedback;
andrewm@0 403
andrewm@0 404 public:
andrewm@0 405 StaticAllpassFourTap()
andrewm@0 406 {
andrewm@0 407 SetLength ( maxLength - 1 );
andrewm@0 408 Clear();
andrewm@0 409 Feedback = 0.5;
andrewm@0 410 }
andrewm@0 411
andrewm@0 412 T operator()(T input)
andrewm@0 413 {
andrewm@0 414 T output;
andrewm@0 415 T bufout;
andrewm@0 416
andrewm@0 417 bufout = buffer[index1];
andrewm@0 418 T temp = input * -Feedback;
andrewm@0 419 output = bufout + temp;
andrewm@0 420 buffer[index1] = input + ((bufout+temp)*Feedback);
andrewm@0 421
andrewm@0 422 if(++index1>=Length)
andrewm@0 423 index1 = 0;
andrewm@0 424 if(++index2 >= Length)
andrewm@0 425 index2 = 0;
andrewm@0 426 if(++index3 >= Length)
andrewm@0 427 index3 = 0;
andrewm@0 428 if(++index4 >= Length)
andrewm@0 429 index4 = 0;
andrewm@0 430
andrewm@0 431 return output;
andrewm@0 432
andrewm@0 433 }
andrewm@0 434
andrewm@0 435 void SetIndex (int Index1, int Index2, int Index3, int Index4)
andrewm@0 436 {
andrewm@0 437 index1 = Index1;
andrewm@0 438 index2 = Index2;
andrewm@0 439 index3 = Index3;
andrewm@0 440 index4 = Index4;
andrewm@0 441 }
andrewm@0 442
andrewm@0 443 T GetIndex (int Index)
andrewm@0 444 {
andrewm@0 445 switch (Index)
andrewm@0 446 {
andrewm@0 447 case 0:
andrewm@0 448 return buffer[index1];
andrewm@0 449 break;
andrewm@0 450 case 1:
andrewm@0 451 return buffer[index2];
andrewm@0 452 break;
andrewm@0 453 case 2:
andrewm@0 454 return buffer[index3];
andrewm@0 455 break;
andrewm@0 456 case 3:
andrewm@0 457 return buffer[index4];
andrewm@0 458 break;
andrewm@0 459 default:
andrewm@0 460 return buffer[index1];
andrewm@0 461 break;
andrewm@0 462 }
andrewm@0 463 }
andrewm@0 464
andrewm@0 465 void SetLength (int Length)
andrewm@0 466 {
andrewm@0 467 if( Length >= maxLength )
andrewm@0 468 Length = maxLength;
andrewm@0 469 if( Length < 0 )
andrewm@0 470 Length = 0;
andrewm@0 471
andrewm@0 472 this->Length = Length;
andrewm@0 473 }
andrewm@0 474
andrewm@0 475
andrewm@0 476 void Clear()
andrewm@0 477 {
andrewm@0 478 memset(buffer, 0, sizeof(buffer));
andrewm@0 479 index1 = index2 = index3 = index4 = 0;
andrewm@0 480 }
andrewm@0 481
andrewm@0 482 void SetFeedback(T feedback)
andrewm@0 483 {
andrewm@0 484 Feedback = feedback;
andrewm@0 485 }
andrewm@0 486
andrewm@0 487
andrewm@0 488 int GetLength() const
andrewm@0 489 {
andrewm@0 490 return Length;
andrewm@0 491 }
andrewm@0 492 };
andrewm@0 493
andrewm@0 494 template<typename T, int maxLength>
andrewm@0 495 class StaticDelayLine
andrewm@0 496 {
andrewm@0 497 private:
andrewm@0 498 T buffer[maxLength];
andrewm@0 499 int index;
andrewm@0 500 int Length;
andrewm@0 501 T Feedback;
andrewm@0 502
andrewm@0 503 public:
andrewm@0 504 StaticDelayLine()
andrewm@0 505 {
andrewm@0 506 SetLength ( maxLength - 1 );
andrewm@0 507 Clear();
andrewm@0 508 }
andrewm@0 509
andrewm@0 510 T operator()(T input)
andrewm@0 511 {
andrewm@0 512 T output = buffer[index];
andrewm@0 513 buffer[index++] = input;
andrewm@0 514 if(index >= Length)
andrewm@0 515 index = 0;
andrewm@0 516 return output;
andrewm@0 517
andrewm@0 518 }
andrewm@0 519
andrewm@0 520 void SetLength (int Length)
andrewm@0 521 {
andrewm@0 522 if( Length >= maxLength )
andrewm@0 523 Length = maxLength;
andrewm@0 524 if( Length < 0 )
andrewm@0 525 Length = 0;
andrewm@0 526
andrewm@0 527 this->Length = Length;
andrewm@0 528 }
andrewm@0 529
andrewm@0 530 void Clear()
andrewm@0 531 {
andrewm@0 532 memset(buffer, 0, sizeof(buffer));
andrewm@0 533 index = 0;
andrewm@0 534 }
andrewm@0 535
andrewm@0 536 int GetLength() const
andrewm@0 537 {
andrewm@0 538 return Length;
andrewm@0 539 }
andrewm@0 540 };
andrewm@0 541
andrewm@0 542 template<typename T, int maxLength>
andrewm@0 543 class StaticDelayLineFourTap
andrewm@0 544 {
andrewm@0 545 private:
andrewm@0 546 T buffer[maxLength];
andrewm@0 547 int index1, index2, index3, index4;
andrewm@0 548 int Length;
andrewm@0 549 T Feedback;
andrewm@0 550
andrewm@0 551 public:
andrewm@0 552 StaticDelayLineFourTap()
andrewm@0 553 {
andrewm@0 554 SetLength ( maxLength - 1 );
andrewm@0 555 Clear();
andrewm@0 556 }
andrewm@0 557
andrewm@0 558 //get ouput and iterate
andrewm@0 559 T operator()(T input)
andrewm@0 560 {
andrewm@0 561 T output = buffer[index1];
andrewm@0 562 buffer[index1++] = input;
andrewm@0 563 if(index1 >= Length)
andrewm@0 564 index1 = 0;
andrewm@0 565 if(++index2 >= Length)
andrewm@0 566 index2 = 0;
andrewm@0 567 if(++index3 >= Length)
andrewm@0 568 index3 = 0;
andrewm@0 569 if(++index4 >= Length)
andrewm@0 570 index4 = 0;
andrewm@0 571 return output;
andrewm@0 572
andrewm@0 573 }
andrewm@0 574
andrewm@0 575 void SetIndex (int Index1, int Index2, int Index3, int Index4)
andrewm@0 576 {
andrewm@0 577 index1 = Index1;
andrewm@0 578 index2 = Index2;
andrewm@0 579 index3 = Index3;
andrewm@0 580 index4 = Index4;
andrewm@0 581 }
andrewm@0 582
andrewm@0 583
andrewm@0 584 T GetIndex (int Index)
andrewm@0 585 {
andrewm@0 586 switch (Index)
andrewm@0 587 {
andrewm@0 588 case 0:
andrewm@0 589 return buffer[index1];
andrewm@0 590 break;
andrewm@0 591 case 1:
andrewm@0 592 return buffer[index2];
andrewm@0 593 break;
andrewm@0 594 case 2:
andrewm@0 595 return buffer[index3];
andrewm@0 596 break;
andrewm@0 597 case 3:
andrewm@0 598 return buffer[index4];
andrewm@0 599 break;
andrewm@0 600 default:
andrewm@0 601 return buffer[index1];
andrewm@0 602 break;
andrewm@0 603 }
andrewm@0 604 }
andrewm@0 605
andrewm@0 606
andrewm@0 607 void SetLength (int Length)
andrewm@0 608 {
andrewm@0 609 if( Length >= maxLength )
andrewm@0 610 Length = maxLength;
andrewm@0 611 if( Length < 0 )
andrewm@0 612 Length = 0;
andrewm@0 613
andrewm@0 614 this->Length = Length;
andrewm@0 615 }
andrewm@0 616
andrewm@0 617
andrewm@0 618 void Clear()
andrewm@0 619 {
andrewm@0 620 memset(buffer, 0, sizeof(buffer));
andrewm@0 621 index1 = index2 = index3 = index4 = 0;
andrewm@0 622 }
andrewm@0 623
andrewm@0 624
andrewm@0 625 int GetLength() const
andrewm@0 626 {
andrewm@0 627 return Length;
andrewm@0 628 }
andrewm@0 629 };
andrewm@0 630
andrewm@0 631 template<typename T, int maxLength>
andrewm@0 632 class StaticDelayLineEightTap
andrewm@0 633 {
andrewm@0 634 private:
andrewm@0 635 T buffer[maxLength];
andrewm@0 636 int index1, index2, index3, index4, index5, index6, index7, index8;
andrewm@0 637 int Length;
andrewm@0 638 T Feedback;
andrewm@0 639
andrewm@0 640 public:
andrewm@0 641 StaticDelayLineEightTap()
andrewm@0 642 {
andrewm@0 643 SetLength ( maxLength - 1 );
andrewm@0 644 Clear();
andrewm@0 645 }
andrewm@0 646
andrewm@0 647 //get ouput and iterate
andrewm@0 648 T operator()(T input)
andrewm@0 649 {
andrewm@0 650 T output = buffer[index1];
andrewm@0 651 buffer[index1++] = input;
andrewm@0 652 if(index1 >= Length)
andrewm@0 653 index1 = 0;
andrewm@0 654 if(++index2 >= Length)
andrewm@0 655 index2 = 0;
andrewm@0 656 if(++index3 >= Length)
andrewm@0 657 index3 = 0;
andrewm@0 658 if(++index4 >= Length)
andrewm@0 659 index4 = 0;
andrewm@0 660 if(++index5 >= Length)
andrewm@0 661 index5 = 0;
andrewm@0 662 if(++index6 >= Length)
andrewm@0 663 index6 = 0;
andrewm@0 664 if(++index7 >= Length)
andrewm@0 665 index7 = 0;
andrewm@0 666 if(++index8 >= Length)
andrewm@0 667 index8 = 0;
andrewm@0 668 return output;
andrewm@0 669
andrewm@0 670 }
andrewm@0 671
andrewm@0 672 void SetIndex (int Index1, int Index2, int Index3, int Index4, int Index5, int Index6, int Index7, int Index8)
andrewm@0 673 {
andrewm@0 674 index1 = Index1;
andrewm@0 675 index2 = Index2;
andrewm@0 676 index3 = Index3;
andrewm@0 677 index4 = Index4;
andrewm@0 678 index5 = Index5;
andrewm@0 679 index6 = Index6;
andrewm@0 680 index7 = Index7;
andrewm@0 681 index8 = Index8;
andrewm@0 682 }
andrewm@0 683
andrewm@0 684
andrewm@0 685 T GetIndex (int Index)
andrewm@0 686 {
andrewm@0 687 switch (Index)
andrewm@0 688 {
andrewm@0 689 case 0:
andrewm@0 690 return buffer[index1];
andrewm@0 691 break;
andrewm@0 692 case 1:
andrewm@0 693 return buffer[index2];
andrewm@0 694 break;
andrewm@0 695 case 2:
andrewm@0 696 return buffer[index3];
andrewm@0 697 break;
andrewm@0 698 case 3:
andrewm@0 699 return buffer[index4];
andrewm@0 700 break;
andrewm@0 701 case 4:
andrewm@0 702 return buffer[index5];
andrewm@0 703 break;
andrewm@0 704 case 5:
andrewm@0 705 return buffer[index6];
andrewm@0 706 break;
andrewm@0 707 case 6:
andrewm@0 708 return buffer[index7];
andrewm@0 709 break;
andrewm@0 710 case 7:
andrewm@0 711 return buffer[index8];
andrewm@0 712 break;
andrewm@0 713 default:
andrewm@0 714 return buffer[index1];
andrewm@0 715 break;
andrewm@0 716 }
andrewm@0 717 }
andrewm@0 718
andrewm@0 719
andrewm@0 720 void SetLength (int Length)
andrewm@0 721 {
andrewm@0 722 if( Length >= maxLength )
andrewm@0 723 Length = maxLength;
andrewm@0 724 if( Length < 0 )
andrewm@0 725 Length = 0;
andrewm@0 726
andrewm@0 727 this->Length = Length;
andrewm@0 728 }
andrewm@0 729
andrewm@0 730
andrewm@0 731 void Clear()
andrewm@0 732 {
andrewm@0 733 memset(buffer, 0, sizeof(buffer));
andrewm@0 734 index1 = index2 = index3 = index4 = index5 = index6 = index7 = index8 = 0;
andrewm@0 735 }
andrewm@0 736
andrewm@0 737
andrewm@0 738 int GetLength() const
andrewm@0 739 {
andrewm@0 740 return Length;
andrewm@0 741 }
andrewm@0 742 };
andrewm@0 743
andrewm@0 744 template<typename T, int OverSampleCount>
andrewm@0 745 class StateVariable
andrewm@0 746 {
andrewm@0 747 public:
andrewm@0 748
andrewm@0 749 enum FilterType
andrewm@0 750 {
andrewm@0 751 LOWPASS,
andrewm@0 752 HIGHPASS,
andrewm@0 753 BANDPASS,
andrewm@0 754 NOTCH,
andrewm@0 755 FilterTypeCount
andrewm@0 756 };
andrewm@0 757
andrewm@0 758 private:
andrewm@0 759
andrewm@0 760 T sampleRate;
andrewm@0 761 T frequency;
andrewm@0 762 T q;
andrewm@0 763 T f;
andrewm@0 764
andrewm@0 765 T low;
andrewm@0 766 T high;
andrewm@0 767 T band;
andrewm@0 768 T notch;
andrewm@0 769
andrewm@0 770 T *out;
andrewm@0 771
andrewm@0 772 public:
andrewm@0 773 StateVariable()
andrewm@0 774 {
andrewm@0 775 SetSampleRate(44100.);
andrewm@0 776 Frequency(1000.);
andrewm@0 777 Resonance(0);
andrewm@0 778 Type(LOWPASS);
andrewm@0 779 Reset();
andrewm@0 780 }
andrewm@0 781
andrewm@0 782 T operator()(T input)
andrewm@0 783 {
andrewm@0 784 for(unsigned int i = 0; i < OverSampleCount; i++)
andrewm@0 785 {
andrewm@0 786 low += f * band + 1e-25;
andrewm@0 787 high = input - low - q * band;
andrewm@0 788 band += f * high;
andrewm@0 789 notch = low + high;
andrewm@0 790 }
andrewm@0 791 return *out;
andrewm@0 792 }
andrewm@0 793
andrewm@0 794 void Reset()
andrewm@0 795 {
andrewm@0 796 low = high = band = notch = 0;
andrewm@0 797 }
andrewm@0 798
andrewm@0 799 void SetSampleRate(T sampleRate)
andrewm@0 800 {
andrewm@0 801 this->sampleRate = sampleRate * OverSampleCount;
andrewm@0 802 UpdateCoefficient();
andrewm@0 803 }
andrewm@0 804
andrewm@0 805 void Frequency(T frequency)
andrewm@0 806 {
andrewm@0 807 this->frequency = frequency;
andrewm@0 808 UpdateCoefficient();
andrewm@0 809 }
andrewm@0 810
andrewm@0 811 void Resonance(T resonance)
andrewm@0 812 {
andrewm@0 813 this->q = 2 - 2 * resonance;
andrewm@0 814 }
andrewm@0 815
andrewm@0 816 void Type(int type)
andrewm@0 817 {
andrewm@0 818 switch(type)
andrewm@0 819 {
andrewm@0 820 case LOWPASS:
andrewm@0 821 out = &low;
andrewm@0 822 break;
andrewm@0 823
andrewm@0 824 case HIGHPASS:
andrewm@0 825 out = &high;
andrewm@0 826 break;
andrewm@0 827
andrewm@0 828 case BANDPASS:
andrewm@0 829 out = &band;
andrewm@0 830 break;
andrewm@0 831
andrewm@0 832 case NOTCH:
andrewm@0 833 out = &notch;
andrewm@0 834 break;
andrewm@0 835
andrewm@0 836 default:
andrewm@0 837 out = &low;
andrewm@0 838 break;
andrewm@0 839 }
andrewm@0 840 }
andrewm@0 841
andrewm@0 842 private:
andrewm@0 843 void UpdateCoefficient()
andrewm@0 844 {
andrewm@0 845 f = 2. * sinf(3.141592654 * frequency / sampleRate);
andrewm@0 846 }
andrewm@0 847 };
andrewm@0 848 #endif