comparison effects/reverb/Source/MVerb.h @ 0:e32fe563e124

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