arduino-audio-tools
AudioEffectsSuite.h
1 #pragma once
2 
20 #include <cmath>
21 #include <cstdint>
22 #include <iostream>
23 #include "AudioTools/CoreAudio/AudioEffects/AudioEffect.h"
24 
25 #ifndef PI
26 # define PI 3.141592653589793f
27 #endif
28 
29 namespace audio_tools {
30 
31 typedef float effectsuite_t;
32 
37 static effectsuite_t **interpolationTable = nullptr;
38 
44 class EffectSuiteBase : public AudioEffect {
50  virtual effectsuite_t processDouble(effectsuite_t inputSample) = 0;
51 
57  virtual effect_t process(effect_t inputSample) override {
58  return active_flag ? 32767.0f * processDouble(static_cast<effectsuite_t>(inputSample)/32767.0f) : inputSample;
59  }
60 
61 };
62 
63 
74 public:
76  ModulationBaseClass() { srand(static_cast<unsigned>(time(0))); }
77 
78  ModulationBaseClass(ModulationBaseClass &copy) = default;
79 
80  ModulationBaseClass(effectsuite_t extSampRate) {
81  this->sampleRate = extSampRate;
82  timeStep = 1. / extSampRate;
84  // setInterpTable();
85  srand(static_cast<unsigned>(time(0)));
86  }
88  ~ModulationBaseClass() = default;
89 
95  void setupModulationBaseClass(effectsuite_t extSampRate) {
96  if (waveTable != nullptr) {
97  delete[] waveTable;
98  }
99  sampleRate = extSampRate;
100  timeStep = 1. / extSampRate;
101  allocateMemory();
102  }
103 
107  void setTriangle() {
108  std::fill(waveTable, waveTable + sampleRate, 0);
109  const effectsuite_t radPerSec = 2 * 3.1415926536f * timeStep;
110  for (int i = 0; i < sampleRate; i++) {
111  for (int j = 0; j < 35; j += 1)
112  waveTable[i] += pow(-1., j) *
113  (sin((2. * effectsuite_t(j) + 1) * i * radPerSec)) /
114  (2. * effectsuite_t(j) + 1);
115  }
116  }
120  void setSquare() {
121  std::fill(waveTable, waveTable + sampleRate, 0);
122  const effectsuite_t radPerSec = 2 * 3.1415926536f * timeStep;
123  for (int i = 0; i < sampleRate; i++) {
124  for (int j = 0; j < 35; j += 1)
125  waveTable[i] += (sin((2 * j + 1) * i * radPerSec)) / (2 * j + 1);
126  }
127  }
131  void setSawtooth() {
132  std::fill(waveTable, waveTable + sampleRate, 0);
133  const effectsuite_t radPerSec = 2 * 3.1415926536f * timeStep;
134  for (int i = 0; i < sampleRate; i++) {
135  for (int j = 1; j < 11; j += 1)
136  waveTable[i] += pow(-1, j) * sin(j * radPerSec * i) / effectsuite_t(j);
137  }
138  }
142  void setSine() {
143  const effectsuite_t radPerSec = 2 * 3.1415926536f * timeStep;
144  for (int i = 0; i < sampleRate; i++)
145  waveTable[i] = sin(i * radPerSec);
146  }
150  void setOffSine() {
151  const effectsuite_t radPerSec = 2 * 3.1415926536f * timeStep;
152  for (int i = 0; i < sampleRate; i++)
153  waveTable[i] = (sin(i * radPerSec) + 1) * .5f;
154  }
155 
156  void setNoise() {
157  is_noise = true;
158  }
159 
160  bool isNoise() {
161  return is_noise;
162  }
163 
167  void setDC() {
168  for (int i = 0; i < sampleRate; i++)
169  waveTable[i] = 1.0;
170  }
172  void setRamp() {
173  for (int i = 0; i < sampleRate; i++)
174  waveTable[i] = i / effectsuite_t(sampleRate);
175  }
180  effectsuite_t readNoise() {
181  const effectsuite_t lo = -1.;
182  const effectsuite_t hi = 1.;
183  return lo + static_cast<effectsuite_t>(rand()) /
184  (static_cast<effectsuite_t>(RAND_MAX / (hi - lo)));
185  }
192  void clipWave(effectsuite_t amp) {
193  if (amp < .01) {
194  amp = .01;
195  }
196 
197  for (int i = 0; i < sampleRate; i++)
198  waveTable[i] = tanh(amp * waveTable[i]) / tanh(amp);
199  }
200 
207  effectsuite_t readTable(effectsuite_t freq) {
208  if (freq > 0) {
209  // const effectsuite_t out = getInterpOut(tableIndex);
210  const effectsuite_t out = getSplineOut(tableIndex, int(freq));
211  tableIndex += freq;
212  if (tableIndex - sampleRate > 0)
214 
215  return out;
216  } else {
217  return 0.;
218  }
219  }
220  void printInterpTable() {
221  for (int j = 0; j < res; j++) {
222  for (int i = 0; i < order; i++) {
223  std::cout << interpTable[i][j] << '\t';
224  }
225  std::cout << '\n';
226  }
227  }
232  bool setInterpTable() {
233  effectsuite_t *polynomial_normaliser = new effectsuite_t[order];
234  if (!polynomial_normaliser) {
235  return false;
236  }
237  std::fill(polynomial_normaliser, polynomial_normaliser + order, 1);
238  effectsuite_t *alphas = new effectsuite_t[res];
239  if (!alphas) {
240  return false;
241  }
242 
243  for (int i = 0; i < res; i++) {
244  alphas[i] = (i / float(res)) - 0.5;
245  }
246 
247  effectsuite_t *anchors = new effectsuite_t[order];
248 
249  if ((order % 2) == 0) {
250  for (int i = 0; i < order; i++) {
251  anchors[i] = -(effectsuite_t(order) - 1) * 0.5 + effectsuite_t(i);
252  std::fill(interpTable[i], interpTable[i] + res, 1);
253  }
254  } else {
255  for (int i = 0; i < order; i++) {
256  anchors[i] = (-(effectsuite_t(order)) * 0.5) + effectsuite_t(i);
257  }
258  }
259 
260  // loop for every value of alpha
261  for (int q = 0; q < res; q++) {
262  // loop for sub polynomial
263  for (int j = 0; j < order; j++) {
264  // loop for each point in subpoly
265  for (int m = 0; m < order; m++) {
266  if (m != j) {
267  if (q == 0) {
268  polynomial_normaliser[j] =
269  polynomial_normaliser[j] * (anchors[j] - anchors[m]);
270  }
271  interpTable[j][q] *= (alphas[q] - anchors[m]);
272  }
273  }
274  interpTable[j][q] /= polynomial_normaliser[j];
275  }
276  }
277 
278  delete[] polynomial_normaliser;
279  delete[] alphas;
280  delete[] anchors;
281  return true;
282  }
283 
284 protected:
289  bool allocateMemory() {
290  waveTable = new effectsuite_t[sampleRate];
291  assert(waveTable!=nullptr);
292  if (!waveTable) {
293  return false;
294  }
295  std::fill(waveTable, waveTable + sampleRate, 0);
296  return true;
297  }
304  effectsuite_t getInterpOut(effectsuite_t bufferIndex) {
305  const int order = 4;
306  const int orderHalf = order * .5;
307  const int res = 100;
308  effectsuite_t interpOut = 0;
309  int intBufferIndex = floor(bufferIndex);
310  int alphaIndex = int(floor((bufferIndex - intBufferIndex) * res));
311 
312  for (int i = 0; i < order; i++) {
313  int interpIndex =
314  (((i + 1 - orderHalf) + intBufferIndex) + sampleRate) % sampleRate;
315  interpOut += (interpTable[i][alphaIndex]) * (waveTable[interpIndex]);
316  }
317  return interpOut;
318  }
319 
331  effectsuite_t getSplineOut(effectsuite_t bufferIndex, int freq) {
332  if (freq < 1) {
333  freq = 1;
334  }
335  const int n0 = floor(bufferIndex);
336  const int n1 = (n0 + freq) % sampleRate;
337  const int n2 = (n0 + (2 * freq)) % sampleRate;
338  const effectsuite_t alpha = bufferIndex - n0;
339  const effectsuite_t a = waveTable[n1];
340  const effectsuite_t c = ((3 * (waveTable[n2] - waveTable[n1])) -
341  (3 * (waveTable[n1] - waveTable[n0]))) *
342  .25;
343  const effectsuite_t b = (waveTable[n2] - waveTable[n1]) - ((2 * c)) / 3;
344  const effectsuite_t d = (-c) / 3;
345  return a + (b * alpha) + (c * alpha * alpha) + (d * alpha * alpha * alpha);
346  }
347 
348 public:
350  effectsuite_t tableIndex = 0;
354  effectsuite_t timeStep;
356  effectsuite_t *waveTable;
357 
358 protected:
359  static const int order = 4;
360  static const int res = 100;
361  effectsuite_t interpTable[order][res];// = {1};
362  bool is_noise = false;
363 };
364 
371  template <class T>
373  public:
375  p_mod = &mod;
376  this->freq = freq;
377  }
378  bool begin(AudioInfo info) override{
379  max_value = pow(2, info.bits_per_sample)/2-1;
380  return SoundGenerator<T>::begin(info);
381  }
382  virtual T readSample() override {
383  return p_mod->isNoise() ? max_value * p_mod->readNoise() : max_value * p_mod->readTable(freq);
384  }
385 
386  protected:
387  ModulationBaseClass *p_mod=nullptr;
388  int freq;
389  float max_value=32767;
390 };
391 
392 
403 public:
405  DelayEffectBase() = default;
406 
407  DelayEffectBase(DelayEffectBase &copy) = default;
408 
409  DelayEffectBase(int bufferSizeSamples) {
410  error = setDelayBuffer(bufferSizeSamples);
411  delayTimeSamples = bufferSizeSamples;
412  if (interpolationTable == nullptr) {
414  }
415  }
416 
419  if (delayBuffer != nullptr)
420  delete[] delayBuffer;
421  }
422 
427  void setupDelayEffectBase(const int bufferSizeSamples) {
428  error = setDelayBuffer(bufferSizeSamples);
429  delayTimeSamples = bufferSizeSamples;
430  }
431 
432 protected:
440  static effectsuite_t **setInterpolationTable() {
441  const int order = interpOrder;
442  const int res = interpResolution;
443  effectsuite_t **interpTable = new effectsuite_t *[order];
444  if (!interpTable) {
445  return NULL;
446  }
447 
448  for (int i = 0; i < order; i++) {
449  interpTable[i] = new effectsuite_t[res + 1];
450  if (!interpTable[i]) {
451  return NULL;
452  }
453  std::fill(interpTable[i], interpTable[i] + res, 1);
454  }
455 
456  effectsuite_t *polynomial_normaliser = new effectsuite_t[order];
457  if (!polynomial_normaliser) {
458  return NULL;
459  }
460  std::fill(polynomial_normaliser, polynomial_normaliser + order, 1);
461  effectsuite_t *alphas = new effectsuite_t[res];
462  if (!alphas) {
463  return NULL;
464  }
465 
466  for (int i = 0; i < res; i++) {
467  alphas[i] = (i / float(res)) - 0.5;
468  }
469 
470  effectsuite_t *anchors = new effectsuite_t[order];
471 
472  if ((order % 2) == 0) {
473  for (int i = 0; i < order; i++) {
474  anchors[i] = -(effectsuite_t(order) - 1) * 0.5 + effectsuite_t(i);
475  }
476  } else {
477  for (int i = 0; i < order; i++) {
478  anchors[i] = (-(effectsuite_t(order)) * 0.5) + effectsuite_t(i);
479  }
480  }
481 
482  // loop for every value of alpha
483  for (int q = 0; q < res; q++) {
484  // loop for sub polynomial
485  for (int j = 0; j < order; j++) {
486  // loop for each point in subpoly
487  for (int m = 0; m < order; m++) {
488  if (m != j) {
489  if (q == 0) {
490  polynomial_normaliser[j] =
491  polynomial_normaliser[j] * (anchors[j] - anchors[m]);
492  }
493  interpTable[j][q] *= (alphas[q] - anchors[m]);
494  }
495  }
496  interpTable[j][q] /= polynomial_normaliser[j];
497  }
498  }
499  delete[] polynomial_normaliser;
500  delete[] alphas;
501  delete[] anchors;
502  return interpTable;
503  }
504 
505  // void printInterpTable() {
506  // for (int j = 0; j < interpResolution; j++) {
507  // for (int i = 0; i < interpOrder; i++) {
508  // printf("index %d: %.2f \t", i, interpolationTable[i][j]);
509  // }
510  // printf("\n");
511  // }
512  // }
513 
514 protected:
521  bool setDelayBuffer(int bufferSizeSamples) {
522  maxDelayBufferSize = bufferSizeSamples;
523  delayBuffer = new effectsuite_t[maxDelayBufferSize];
524  if (!delayBuffer) {
525  return false;
526  }
527  std::fill(delayBuffer, delayBuffer + maxDelayBufferSize, 0);
528  return true;
529  }
530 
535  void storeSample(effectsuite_t inputSample) {
536  delayBuffer[currentDelayWriteIndex] = inputSample;
537  }
538 
543  currentDelayWriteIndex++;
544  currentDelayWriteIndex %= delayTimeSamples;
545  }
546 
551  void incDelayBuffReadIndex(effectsuite_t indexInc) {
552  currentDelayReadIndex += indexInc;
553  if (currentDelayReadIndex >= effectsuite_t(delayTimeSamples)) {
554  currentDelayReadIndex = 0;
555  }
556  if (currentDelayReadIndex < 0) {
557  currentDelayReadIndex = 0;
558  }
559  }
560 
565  void setDelayBuffReadIndex(effectsuite_t index) {
566  currentDelayReadIndex = index;
567  if (currentDelayReadIndex >= effectsuite_t(delayTimeSamples)) {
568  currentDelayReadIndex = 0;
569  }
570  if (currentDelayReadIndex < 0) {
571  currentDelayReadIndex = 0;
572  }
573  }
574 
580  void delaySample(effectsuite_t inputSample) {
581  storeSample(inputSample);
583  }
589  effectsuite_t getInterpolatedOut(effectsuite_t bufferIndex) {
590  const int order = interpOrder;
591  const int orderHalf = order * .5;
592  const int res = interpResolution;
593  effectsuite_t interpOut = 0;
594  int intBufferIndex = floor(bufferIndex);
595  int alphaIndex = int(floor((bufferIndex - intBufferIndex) * res));
596 
597  for (int i = 0; i < order; i++) {
598  int interpIndex = (i + 1 - orderHalf) + intBufferIndex;
599  if (interpIndex < 0 || (interpIndex >= maxDelayBufferSize)) {
600  if (interpIndex < 0) {
601  interpIndex = maxDelayBufferSize + interpIndex;
602  } else {
603  interpIndex = interpIndex - maxDelayBufferSize;
604  }
605  }
606 
607  interpOut +=
608  (interpolationTable[i][alphaIndex]) * (delayBuffer[interpIndex]);
609  }
610  return interpOut;
611  }
612 
613 protected: // member variables
615  effectsuite_t *delayBuffer = 0;
617  int maxDelayBufferSize = 441000;
619  int delayTimeSamples = 44100;
620  int currentDelayWriteIndex = 0;
621  effectsuite_t currentDelayReadIndex = 0;
622  static const int interpOrder = 4;
623  static const int interpResolution = 1000;
624 
626  bool error;
627 };
628 
638 public:
641 
642  FilterEffectBase(FilterEffectBase &copy) = default;
643 
645  ~FilterEffectBase() = default;
646 
653  virtual effectsuite_t applyFilter(effectsuite_t sampVal) {
654  effectsuite_t outSample = 0;
655  firBuffer[bufferIndex] = sampVal;
656 
657  for (int j = 0; j < filterOrder; j++) {
658  int i = ((bufferIndex - j) + filterOrder) % filterOrder;
659  outSample +=
661  }
662 
663  iirBuffer[bufferIndex] = outSample;
664  incBufferIndex();
665 
666  return outSample;
667  }
668 
669  virtual effectsuite_t processDouble(effectsuite_t inputSample) override {
670  return applyFilter(inputSample);
671  }
672 
674  virtual effect_t process(effect_t inputSample) override {
675  return active_flag ? 32767.0 * processDouble(static_cast<effectsuite_t>(inputSample)/32767.0) : inputSample;
676  }
677 
683  effectsuite_t envelope(effectsuite_t sample) { return applyFilter(rms(sample)); }
684 
685  // void printBuffers() {
686  // printf("FIRb\t\tIIRb\n");
687  // for (int i = 0; i < filterOrder; i++) {
688  // printf("%.4e\t%.4e\n", firBuffer[i], iirBuffer[i]);
689  // }
690  // printf("\n");
691  // }
692 
693  // void printCoefs() {
694  // printf("FIR\t\tIIR\n");
695  // for (int i = 0; i < filterOrder; i++) {
696  // printf("%.4e\t%.4e\n", firCoefficients[i], iirCoefficients[i]);
697  // }
698  // printf("\n");
699  // }
700 
712  bool setChebyICoefficients(effectsuite_t cutFreq, bool shelfType, effectsuite_t ripple) {
713  // NOTE: coefficient buffers must be cleared as are additive in the
714  // following code
715  std::fill(firCoefficients, firCoefficients + 22, 0);
716  std::fill(iirCoefficients, iirCoefficients + 22, 0);
717 
718  effectsuite_t poles = (effectsuite_t)filterOrder - 1;
719  int order = (int)poles;
720 
721  firCoefficients[2] = 1;
722  iirCoefficients[2] = 1;
723 
724  effectsuite_t Es, Vx, Kx;
725  if (ripple != 0) {
726  Es = sqrt(pow(1 / (1 - ripple), 2) - 1);
727  Vx = (1 / poles) * log(1 / Es + sqrt(1 / (pow(Es, 2)) + 1));
728  Kx = (1 / poles) * log(1 / Es + sqrt(1 / (pow(Es, 2)) - 1));
729  Kx = cosh(Kx);
730  } else {
731  Vx = 1;
732  Kx = 1;
733  }
734 
735  const effectsuite_t T = 2.0f * tan(.5f);
736  const effectsuite_t W = 2.0f * PI * cutFreq;
737 
738  effectsuite_t K;
739 
740  if (shelfType == 0)
741  {
742  K = sin(.5 - W / 2) / sin(.5 + W / 2);
743  } else
744  {
745 
746  K = -cos(.5 + W / 2) / cos(W / 2 - .5);
747  }
748 
750  for (int i = 0; i < (order / 2); i++) {
752  const effectsuite_t alpha = PI / (2 * poles) + (i - 1) * (PI / poles);
753 
754  effectsuite_t Rp, Ip;
755  if (ripple != 0) {
756  Rp = -cos(alpha) * sinh(Vx) / Kx;
757  Ip = sin(alpha) * cosh(Vx) / Kx;
758  } else {
759  Rp = -cos(alpha);
760  Ip = sin(alpha);
761  }
762 
763  const effectsuite_t M = pow(Rp, 2) + pow(Ip, 2);
764  const effectsuite_t D = 4 - 4 * Rp * T + M * T;
765 
766  const effectsuite_t X0 = (pow(T, 2)) / D;
767  const effectsuite_t X1 = (2 * pow(T, 2)) / D;
768  const effectsuite_t X2 = X0;
769 
770  const effectsuite_t Y1 = (8 - (2 * M * pow(T, 2))) / D;
771  const effectsuite_t Y2 = (-4 - 4 * Rp * T - M * T) / D;
772 
773  // renamed and inverted from original algorithm
774  const effectsuite_t _D1 = 1 / (1 + Y1 * K - Y2 * pow(K, 2));
775 
776  const effectsuite_t _A0 = (X0 - X1 * K + X2 * pow(K, 2)) * _D1;
777  effectsuite_t _A1 = (-2 * X0 * K + X1 + X1 * pow(K, 2) - 2 * X2 * K) * _D1;
778  const effectsuite_t _A2 = (X0 * pow(K, 2) - X1 * K + X2) * _D1;
779 
780  effectsuite_t _B1 = (2 * K + Y1 + Y1 * pow(K, 2) - 2 * Y2 * K) * _D1;
781  const effectsuite_t B2 = (-(pow(K, 2)) - Y1 * K + Y2) * _D1;
782 
783  if (shelfType == 1) {
784  _A1 = -_A1;
785  _B1 = -_B1;
786  }
787 
788  for (int j = 0; j < 22; j++) {
789  firTemp[j] = firCoefficients[j];
790  iirTemp[j] = iirCoefficients[j];
791  }
792  for (int j = 2; j < 22; j++) {
793  firCoefficients[j] =
794  _A0 * firTemp[j] + _A1 * firTemp[j - 1] + _A2 * firTemp[j - 2];
795  iirCoefficients[j] =
796  iirTemp[j] - _B1 * iirTemp[j - 1] - B2 * iirTemp[j - 2];
797  }
798  }
799 
800  iirCoefficients[2] = 0;
801  for (int j = 0; j < filterOrder; j++) {
802  firCoefficients[j] = firCoefficients[j + 2];
803  iirCoefficients[j] = -iirCoefficients[j + 2];
804  }
806  effectsuite_t SA = 0;
807  effectsuite_t SB = 0;
808  if (shelfType == 0) {
809  for (int j = 0; j < filterOrder; j++) {
810  SA += firCoefficients[j];
811  SB += iirCoefficients[j];
812  }
813  } else {
814  for (int j = 0; j < order; j++) {
815  SA += firCoefficients[j] * pow(-1, j);
816  SB += iirCoefficients[j] * pow(-1, j);
817  }
818  }
819 
820  const effectsuite_t gain = SA / (1 - SB);
821  for (int j = 0; j < filterOrder; j++) {
822  firCoefficients[j] /= gain;
823  }
824 
825  return true;
826  }
827 
828 protected:
839  bool changeChebyICoefficients(effectsuite_t cutFreq, bool shelfType, effectsuite_t ripple,
840  int poles) {
841  filterOrder = poles + 1;
842  clearMemory();
844  setChebyICoefficients(cutFreq, shelfType, ripple);
845 
846  return true;
847  }
848 
853  bool setSimpleLpf(int order) {
854  filterOrder = order;
855  clearMemory();
857  firCoefficients = new effectsuite_t[filterOrder];
858  iirCoefficients = new effectsuite_t[filterOrder];
860  int coef = 1;
861  effectsuite_t gain = 0;
862  for (int j = 0; j < filterOrder; j++) {
863  if (j == 0) {
864  coef = 1;
865  } else {
866  coef = coef * (filterOrder - j) / j;
867  }
868 
869  firCoefficients[j] = (effectsuite_t)coef;
870  gain += firCoefficients[j];
871  }
872 
873  for (int j = 0; j <= filterOrder; j++) {
874  firCoefficients[j] /= gain;
875  }
876 
877  return true;
878  }
879 
880 protected:
882  void incBufferIndex() {
883  bufferIndex++;
885  }
886 
891  void clearMemory() {
892  if (firCoefficients) {
893  delete[] firCoefficients;
894  }
895 
896  if (iirCoefficients) {
897  delete[] iirCoefficients;
898  }
899  }
900 
906  if (firBuffer) {
907  delete[] firBuffer;
908  }
909 
910  if (iirBuffer) {
911  delete[] iirBuffer;
912  }
913  firBuffer = new effectsuite_t[filterOrder];
914  iirBuffer = new effectsuite_t[filterOrder];
915  std::fill(firBuffer, firBuffer + filterOrder, 0);
916  std::fill(iirBuffer, iirBuffer + filterOrder, 0);
917 
918  if (firCoefficients) {
919  delete[] firCoefficients;
920  }
921 
922  if (iirCoefficients) {
923  delete[] iirCoefficients;
924  }
925 
926  if (firTemp) {
927  delete[] firTemp;
928  }
929 
930  if (iirTemp) {
931  delete[] iirTemp;
932  }
933 
934  firCoefficients = new effectsuite_t[22];
935  iirCoefficients = new effectsuite_t[22];
936  firTemp = new effectsuite_t[22];
937  iirTemp = new effectsuite_t[22];
938  std::fill(firCoefficients, firCoefficients + 22, 0);
939  std::fill(iirCoefficients, iirCoefficients + 22, 0);
940  std::fill(firTemp, firTemp + 22, 0);
941  std::fill(iirTemp, iirTemp + 22, 0);
942  }
943 
945  effectsuite_t rms(effectsuite_t sample) {
946  rmsBuffer[rmsBufferIndex] = sample;
947  effectsuite_t rmsValue = 0;
948  for (int j = 0; j < rmsBufferIndex; j++) {
949  int i = ((rmsBufferIndex - j) + rmsWindowSize) % rmsWindowSize;
950  rmsValue += rmsBuffer[i] * rmsBuffer[i];
951  }
952 
953  // printf("samp: %e\tsum: %e\n", sample, rmsValue);
954  rmsValue /= rmsWindowSize;
955  rmsValue = sqrt(rmsValue);
956 
957  rmsBufferIndex++;
959 
960  return rmsValue;
961  }
962 
963 protected:
968  effectsuite_t *firCoefficients = 0;
972  effectsuite_t *iirCoefficients = 0;
974  effectsuite_t *firTemp = 0;
976  effectsuite_t *iirTemp = 0;
979  effectsuite_t *firBuffer = 0;
982  effectsuite_t *iirBuffer = 0;
984  int bufferIndex = 0;
986  int filterOrder = 0;
987  /***/
988  int samplingRate = 0;
990  const int rmsWindowSize = 128;
992  int rmsBufferIndex = 0;
994  effectsuite_t *rmsBuffer = new effectsuite_t[rmsWindowSize];
995 
996 };
997 
1004 class SimpleLPF : public FilterEffectBase {
1005 public:
1012  SimpleLPF(effectsuite_t cutoff, int order) {
1013  changeChebyICoefficients(cutoff, false, .1, order);
1014  };
1015 
1016  SimpleLPF(SimpleLPF &copy) = default;
1017 
1019  ~SimpleLPF() = default;
1020 
1021  SimpleLPF* clone(){
1022  return new SimpleLPF(*this);
1023  }
1024 
1025 };
1026 
1036  public ModulationBaseClass,
1037  public SimpleLPF{
1038 public:
1044 // SimpleChorus() : SimpleLPF(0.0001, 4) {}
1045  SimpleChorus(int extSampleRate=44100) :
1046  DelayEffectBase(static_cast<int>(0.031 * extSampleRate)),
1047  ModulationBaseClass(extSampleRate),
1048  SimpleLPF(0.0001, 4) {
1049  swing = 0.005 * sampleRate;
1050  base = 0.015 * sampleRate;
1051  if (sampleRate != 0)
1052  setRandLfo();
1053  }
1054 
1055  SimpleChorus(SimpleChorus &copy)=default;
1056 
1057  ~SimpleChorus() = default;
1058 
1064  virtual effectsuite_t processDouble(effectsuite_t inputSample) override {
1065  delaySample(inputSample);
1066  const effectsuite_t waveDelay = getModSignal();
1067  const effectsuite_t delayAmount =
1068  ((int(currentDelayWriteIndex - waveDelay) + delayTimeSamples) %
1069  delayTimeSamples) +
1070  ((currentDelayWriteIndex - waveDelay) -
1071  trunc(currentDelayWriteIndex - waveDelay));
1072  const effectsuite_t out = .0 * inputSample + 1. * getInterpolatedOut(delayAmount);
1073  return out;
1074  }
1075 
1080  void setupChorus(effectsuite_t extSampleRate) {
1081  setupModulationBaseClass(extSampleRate);
1082  setupDelayEffectBase(effectsuite_t(extSampleRate) * .1);
1083  // SimpleLPF(0.0004,4)
1084  setChebyICoefficients(0.00005, false, 0);
1085 
1086  swing = readSpeed * extSampleRate * 5;
1087  base = readSpeed * extSampleRate * 20;
1088  setRandLfo();
1089  }
1090 
1096  void setSwing(effectsuite_t swingAmount) { swing = swingAmount * sampleRate; }
1097 
1102  void setBase(effectsuite_t baseAmount) { base = baseAmount * sampleRate; }
1103 
1104  SimpleChorus* clone() override {
1105  return new SimpleChorus(*this);
1106  }
1107 
1108 protected:
1112  effectsuite_t swing;
1114  effectsuite_t base;
1116  effectsuite_t modMin = .5;
1118  effectsuite_t modMax = .5;
1120  effectsuite_t modNorm = 1 / (modMax - modMin);
1121  const effectsuite_t readSpeed = ((readNoise() + 1) * .5) * .0005;
1122 
1128  effectsuite_t getModSignal() { return (readTable(readSpeed) * swing) + base; }
1129 
1130  void setRandLfo() {
1131  std::fill(iirBuffer, iirBuffer + filterOrder, .5);
1132  for (int i = 0; i < sampleRate; i++) {
1133  waveTable[i] = (readNoise() + 1) * .5;
1134  // waveTable[i] = applyFilter((readNoise()+1)*.5);
1135  if (waveTable[i] < modMin)
1136  modMin = waveTable[i];
1137  if (waveTable[i] > modMax) {
1138  modMax = waveTable[i];
1139  }
1140  }
1141 
1142  modNorm = 1 / (modMax - modMin);
1143 
1144  // normalises the delay signal
1145  for (int i = 0; i < sampleRate; i++) {
1146  waveTable[i] -= modMin;
1147  waveTable[i] *= modNorm;
1148  }
1149 
1150  // setOffSine();
1151 
1152  // this code fades out at the end and fades in at the start
1153  // to avoid any discontinuities int the signal.
1154  // const int fadeSize = 10000;
1155  // const effectsuite_t fadeSpeed = 2*M_PI/fadeSize;
1156  // for (int i = 0; i < fadeSize; i++)
1157  // {
1158  // const int fadeIndex = ((sampleRate-fadeSize/2)+i)%sampleRate;
1159  // waveTable[fadeIndex] *= (1+cos(fadeSpeed*i))*.5;
1160  // }
1161  }
1162 };
1163 
1171 public:
1173  FilteredDelay(int delayInSamples, int sample_rate=44100) : DelayEffectBase(sample_rate) {
1174  delayTimeSamples = delayInSamples;
1175  changeChebyICoefficients(.05, true, .1, 4);
1176  };
1177 
1178  FilteredDelay(FilteredDelay&copy) = default;
1179 
1181  ~FilteredDelay() = default;
1182 
1189  void setDelayGain(effectsuite_t gain) {
1190  capGain(gain);
1191  delayGain = gain;
1192  }
1193 
1201  void setFeedbackGain(effectsuite_t gain) {
1202  capGain(gain);
1203  feedbackGain = gain;
1204  }
1205 
1207  effectsuite_t processDouble(effectsuite_t inputSample) override {
1208  delaySample(
1209  applyFilter((inputSample * delayGain) +
1210  feedbackGain * getInterpolatedOut(currentDelayWriteIndex)));
1211  const effectsuite_t out = getInterpolatedOut(currentDelayWriteIndex) + inputSample;
1212  return out;
1213  }
1214 
1215  effect_t process(effect_t inputSample) override {
1216  return active_flag ? 32767.0 * processDouble(static_cast<effectsuite_t>(inputSample)/32767.0) : inputSample;
1217  }
1218 
1219  FilteredDelay *clone() override {
1220  return new FilteredDelay(*this);
1221  }
1222 
1223 protected:
1228  void capGain(effectsuite_t &gain) {
1229  if (gain > 1.) {
1230  gain = 1.;
1231  } else if (gain < -1.) {
1232  gain = -1.;
1233  }
1234  return;
1235  }
1236 
1237 protected:
1238  effectsuite_t delayGain = .707, feedbackGain = 0.0;
1239 };
1240 
1251 public:
1257  SimpleDelay(int maxDelayInSamples=8810, int samplingRate=44100) {
1258  writeHeadIndex = 0;
1259  readHeadIndex = 1;
1260  currentDelaySamples = maxDelayInSamples;
1261  targetDelaySamples = maxDelayInSamples;
1263  }
1264 
1265  SimpleDelay(SimpleDelay &copy) = default;
1266 
1268  ~SimpleDelay() = default;
1269 
1277  void setDelayGain(effectsuite_t gain) {
1278  capGain(gain);
1279  delayGain = gain;
1280  }
1281 
1289  void setFeedbackGain(effectsuite_t gain) {
1290  capGain(gain);
1291  feedbackGain = gain;
1292  }
1293 
1299  effectsuite_t processDouble(effectsuite_t inputSample) override {
1300  // write sample
1301  delayBuffer[writeHeadIndex] = inputSample;
1302  writeHeadIndex++;
1303  writeHeadIndex %= maxDelayBufferSize;
1304 
1305  // read sample
1306  effectsuite_t outSample = getSplineOut(readHeadIndex) + (inputSample * 1);
1307  if (delayTimeChanged) {
1308  count++;
1309  const effectsuite_t difference = (currentDelaySamples - targetDelaySamples);
1310  const effectsuite_t increment = delayIncrement * (difference / fabs(difference));
1311  currentDelaySamples -= increment;
1312  readHeadIndex += 1 + increment;
1313  readHeadIndex = std::fmod(readHeadIndex, maxDelayBufferSize);
1314  if (count > floor(delayTransitionTimeInSamples)) {
1315  currentDelaySamples = targetDelaySamples;
1316  readHeadIndex = floor(readHeadIndex);
1317  delayTimeChanged = false;
1318  }
1319  } else {
1320  readHeadIndex++;
1321  readHeadIndex = std::fmod(readHeadIndex, maxDelayBufferSize);
1322  }
1323  return outSample;
1324  }
1325 
1326  effect_t process(effect_t inputSample) override {
1327  return active_flag ? 32767.0 * processDouble(static_cast<effectsuite_t>(inputSample)/32767.0) : inputSample;
1328  }
1329 
1334  void setupSimpleDelay(int delayInSamples) {
1335  setupDelayEffectBase(delayInSamples);
1336  }
1341  void setDelayTime(effectsuite_t delayInSamples) {
1342  delayTimeChanged = true;
1343  targetDelaySamples = delayInSamples;
1344  const effectsuite_t delayTimeDifference = currentDelaySamples - targetDelaySamples;
1345  delayIncrement = delayTimeDifference / delayTransitionTimeInSamples;
1346  count = 0;
1347  }
1352  void setDelayTransitionTime(effectsuite_t seconds) {
1353  delayTransitionTime = seconds;
1354  delayTransitionTimeInSamples = seconds * sampleRate;
1355  }
1356 
1357  SimpleDelay* clone() override {
1358  return new SimpleDelay(*this);
1359  }
1360 
1361 protected:
1366  void capGain(effectsuite_t &gain) {
1367  if (gain > 1.) {
1368  gain = 1.;
1369  } else if (gain < -1.) {
1370  gain = -1.;
1371  }
1372  return;
1373  }
1382  effectsuite_t getSplineOut(effectsuite_t bufferIndex) {
1383  const int n0 = floor(bufferIndex);
1384  const int n1 = (n0 + 1) % maxDelayBufferSize;
1385  const int n2 = (n0 + 2) % maxDelayBufferSize;
1386  const effectsuite_t alpha = bufferIndex - n0;
1387 
1388  const effectsuite_t a = delayBuffer[n1];
1389  const effectsuite_t c = ((3 * (delayBuffer[n2] - delayBuffer[n1])) -
1390  (3 * (delayBuffer[n1] - delayBuffer[n0]))) *
1391  0.25;
1392  const effectsuite_t b = (delayBuffer[n2] - delayBuffer[n1]) - (2 * c * 0.33333);
1393  const effectsuite_t d = (-c) * 0.33333;
1394  return a + (b * alpha) + (c * alpha * alpha) + (d * alpha * alpha * alpha);
1395  }
1396 
1397 protected: // member vairables
1398  effectsuite_t delayGain = .707;
1399  effectsuite_t feedbackGain = 0.;
1400  effectsuite_t readHeadIndex;
1401  unsigned int writeHeadIndex;
1402  effectsuite_t currentDelaySamples;
1403  effectsuite_t targetDelaySamples;
1406  effectsuite_t delayIncrement;
1409  effectsuite_t invDelayIncrement;
1411  effectsuite_t delayTransitionTime;
1412  effectsuite_t delayTransitionTimeInSamples;
1413  int sampleRate;
1414  int count = 0;
1415  bool delayTimeChanged = false;
1416 };
1417 
1429 public:
1434  SimpleFlanger() = default;
1435  SimpleFlanger(SimpleFlanger&copy) = default;
1436  SimpleFlanger(effectsuite_t extSampleRate=44100)
1437  : DelayEffectBase(static_cast<int>(extSampleRate * 0.02)) {}
1438 
1440  ~SimpleFlanger() = default;
1441 
1448  void setEffectGain(effectsuite_t gain) { effectGain = capGain(gain); }
1449 
1454  void setDepth(const effectsuite_t depth) {
1455  if (depth > effectsuite_t(delayTimeSamples))
1456  modulationDepth = effectsuite_t(delayTimeSamples) - 1;
1457  else
1458  modulationDepth = depth;
1459  }
1460 
1465  void setRate(const effectsuite_t rate) {
1466  modulationRate = rate;
1467  setAngleDelta();
1468  }
1469 
1476  void setEffectParams(effectsuite_t gain, effectsuite_t depth, effectsuite_t rate) {
1477  setEffectGain(gain);
1478  setDepth(depth);
1479  setRate(rate);
1480  }
1481 
1483  effectsuite_t processDouble(effectsuite_t inputSample) override {
1484  delaySample(inputSample);
1485  const effectsuite_t out = ((1 - fabs(effectGain * .2)) * (inputSample) +
1486  (effectGain * getInterpolatedOut(modulationIndex)));
1487  updateModulation();
1488  return out;
1489  }
1490 
1491  void setupSimpleFlanger(effectsuite_t extSampleRate) {
1492  setupDelayEffectBase(extSampleRate * .02);
1493  timeStep = 1. / extSampleRate;
1494  setEffectParams(.707, extSampleRate * .02, .1);
1495  }
1496 
1497  SimpleFlanger* clone() override {
1498  return new SimpleFlanger(*this);
1499  }
1500 
1501 protected:
1506  effectsuite_t capGain(effectsuite_t gain) {
1507  if (gain > 1.) {
1508  gain = 1.;
1509  } else if (gain < -1.) {
1510  gain = -1.;
1511  }
1512  return gain;
1513  }
1514 
1518  void setAngleDelta() {
1519  const effectsuite_t cyclesPerSample = modulationRate * timeStep;
1520  angleDelta = cyclesPerSample * 2.0f * PI;
1521  }
1522 
1527  modulationAngle += angleDelta;
1528  modulationIndex = (currentDelayWriteIndex -
1529  (modulationDepth * (1 + (sin(modulationAngle))))) -
1530  12;
1531  modulationIndex =
1532  ((int(modulationIndex) + delayTimeSamples) % delayTimeSamples) +
1533  (modulationIndex - floor(modulationIndex));
1534  }
1535 
1536 protected:
1537 
1538  effectsuite_t modulationDepth = 1000, modulationRate = 0, effectGain = .01;
1539 
1540  effectsuite_t modulationIndex = 0;
1541 
1543  effectsuite_t timeStep = 1. / 44100.;
1544 
1546  effectsuite_t modulationConstant, modulationAngle = 0;
1547 
1548  // const effectsuite_t cyclesPerSample = modulationRate * timeStep;
1550  effectsuite_t angleDelta = 2.0f * PI * timeStep;
1551 };
1552 
1560 public:
1563  // NOTE: Initialising chebyshev coeffcients allocates memory, perhaps alter
1564  // so that memory is already pre allocated
1565  changeChebyICoefficients(.01, false, .1, 4);
1566  envelopeFollower.setChebyICoefficients(.00006, false, 0);
1567  };
1568 
1570  ~EnvelopeFilter() = default;
1577  effectsuite_t processDouble(effectsuite_t sample) {
1578  setChebyICoefficients(0.001 + envelopeFollower.envelope(2 * sample), false,
1579  .1); // Offset avoids zero cutoff value
1580  return applyFilter(sample);
1581  }
1582 
1583 protected:
1589 };
1590 
1591 } // namespace effectsuite_tools
1592 
Abstract Base class for Sound Effects.
Definition: AudioEffect.h:21
A Base class for delay based digital effects. Provides the basic methods that are shared amongst Flan...
Definition: AudioEffectsSuite.h:402
void setDelayBuffReadIndex(effectsuite_t index)
Definition: AudioEffectsSuite.h:565
~DelayEffectBase()
Definition: AudioEffectsSuite.h:418
void storeSample(effectsuite_t inputSample)
Definition: AudioEffectsSuite.h:535
static effectsuite_t ** setInterpolationTable()
Definition: AudioEffectsSuite.h:440
void incDelayBuffWriteIndex()
Definition: AudioEffectsSuite.h:542
bool error
Definition: AudioEffectsSuite.h:626
void setupDelayEffectBase(const int bufferSizeSamples)
Definition: AudioEffectsSuite.h:427
int delayTimeSamples
Definition: AudioEffectsSuite.h:619
int maxDelayBufferSize
Definition: AudioEffectsSuite.h:617
bool setDelayBuffer(int bufferSizeSamples)
Definition: AudioEffectsSuite.h:521
effectsuite_t * delayBuffer
Definition: AudioEffectsSuite.h:615
effectsuite_t getInterpolatedOut(effectsuite_t bufferIndex)
Definition: AudioEffectsSuite.h:589
void delaySample(effectsuite_t inputSample)
Definition: AudioEffectsSuite.h:580
void incDelayBuffReadIndex(effectsuite_t indexInc)
Definition: AudioEffectsSuite.h:551
Base Class for Effects.
Definition: AudioEffectsSuite.h:44
EnvelopeFilter.
Definition: AudioEffectsSuite.h:1559
SimpleLPF envelopeFollower
Definition: AudioEffectsSuite.h:1588
EnvelopeFilter()
Definition: AudioEffectsSuite.h:1562
effectsuite_t processDouble(effectsuite_t sample)
Definition: AudioEffectsSuite.h:1577
A Base class for filter based effects including methods for simple high, low and band pass filtering.
Definition: AudioEffectsSuite.h:637
effectsuite_t * firCoefficients
Definition: AudioEffectsSuite.h:968
effectsuite_t * firTemp
Definition: AudioEffectsSuite.h:974
effectsuite_t * iirBuffer
Definition: AudioEffectsSuite.h:982
bool setSimpleLpf(int order)
Definition: AudioEffectsSuite.h:853
virtual effectsuite_t applyFilter(effectsuite_t sampVal)
Definition: AudioEffectsSuite.h:653
effectsuite_t * firBuffer
Definition: AudioEffectsSuite.h:979
int bufferIndex
Definition: AudioEffectsSuite.h:984
bool changeChebyICoefficients(effectsuite_t cutFreq, bool shelfType, effectsuite_t ripple, int poles)
Definition: AudioEffectsSuite.h:839
effectsuite_t envelope(effectsuite_t sample)
Definition: AudioEffectsSuite.h:683
bool setChebyICoefficients(effectsuite_t cutFreq, bool shelfType, effectsuite_t ripple)
Definition: AudioEffectsSuite.h:712
effectsuite_t * iirTemp
Definition: AudioEffectsSuite.h:976
virtual effect_t process(effect_t inputSample) override
see applyFilter
Definition: AudioEffectsSuite.h:674
int filterOrder
Definition: AudioEffectsSuite.h:986
effectsuite_t * iirCoefficients
Definition: AudioEffectsSuite.h:972
FilterEffectBase()
Definition: AudioEffectsSuite.h:640
int rmsBufferIndex
Definition: AudioEffectsSuite.h:992
const int rmsWindowSize
Definition: AudioEffectsSuite.h:990
void allocateBufferMemory()
Definition: AudioEffectsSuite.h:905
void clearMemory()
Definition: AudioEffectsSuite.h:891
effectsuite_t rms(effectsuite_t sample)
Definition: AudioEffectsSuite.h:945
void incBufferIndex()
Definition: AudioEffectsSuite.h:882
virtual effectsuite_t processDouble(effectsuite_t inputSample) override
Main process block for applying audio effect.
Definition: AudioEffectsSuite.h:669
effectsuite_t * rmsBuffer
Definition: AudioEffectsSuite.h:994
Delay effect that filters the repeat delay.
Definition: AudioEffectsSuite.h:1170
effectsuite_t processDouble(effectsuite_t inputSample) override
Definition: AudioEffectsSuite.h:1207
FilteredDelay(int delayInSamples, int sample_rate=44100)
Definition: AudioEffectsSuite.h:1173
effect_t process(effect_t inputSample) override
see applyFilter
Definition: AudioEffectsSuite.h:1215
void capGain(effectsuite_t &gain)
Definition: AudioEffectsSuite.h:1228
void setDelayGain(effectsuite_t gain)
Definition: AudioEffectsSuite.h:1189
void setFeedbackGain(effectsuite_t gain)
Definition: AudioEffectsSuite.h:1201
Class provides a wave table that can be populated with a number of preallocated waveforms....
Definition: AudioEffectsSuite.h:73
effectsuite_t readNoise()
Definition: AudioEffectsSuite.h:180
void clipWave(effectsuite_t amp)
Definition: AudioEffectsSuite.h:192
effectsuite_t tableIndex
Definition: AudioEffectsSuite.h:350
void setRamp()
Definition: AudioEffectsSuite.h:172
effectsuite_t getInterpOut(effectsuite_t bufferIndex)
Definition: AudioEffectsSuite.h:304
void setupModulationBaseClass(effectsuite_t extSampRate)
setup the class with a given sample rate. Basically reperforming the constructor
Definition: AudioEffectsSuite.h:95
void setSine()
Definition: AudioEffectsSuite.h:142
void setSawtooth()
Definition: AudioEffectsSuite.h:131
bool setInterpTable()
Definition: AudioEffectsSuite.h:232
void setDC()
Definition: AudioEffectsSuite.h:167
void setSquare()
Definition: AudioEffectsSuite.h:120
effectsuite_t getSplineOut(effectsuite_t bufferIndex, int freq)
Definition: AudioEffectsSuite.h:331
effectsuite_t * waveTable
Definition: AudioEffectsSuite.h:356
effectsuite_t timeStep
Definition: AudioEffectsSuite.h:354
bool allocateMemory()
Definition: AudioEffectsSuite.h:289
int sampleRate
Definition: AudioEffectsSuite.h:352
effectsuite_t readTable(effectsuite_t freq)
Definition: AudioEffectsSuite.h:207
void setOffSine()
Definition: AudioEffectsSuite.h:150
ModulationBaseClass()
Definition: AudioEffectsSuite.h:76
void setTriangle()
Definition: AudioEffectsSuite.h:107
Simple Chorus effect with a single delay voice and mono output Chorus is effective between 15 and 20 ...
Definition: AudioEffectsSuite.h:1037
effectsuite_t base
Definition: AudioEffectsSuite.h:1114
void setBase(effectsuite_t baseAmount)
Definition: AudioEffectsSuite.h:1102
void setupChorus(effectsuite_t extSampleRate)
Definition: AudioEffectsSuite.h:1080
void setSwing(effectsuite_t swingAmount)
Definition: AudioEffectsSuite.h:1096
effectsuite_t modMax
Definition: AudioEffectsSuite.h:1118
effectsuite_t swing
Definition: AudioEffectsSuite.h:1112
effectsuite_t getModSignal()
Definition: AudioEffectsSuite.h:1128
SimpleChorus(int extSampleRate=44100)
Definition: AudioEffectsSuite.h:1045
virtual effectsuite_t processDouble(effectsuite_t inputSample) override
Definition: AudioEffectsSuite.h:1064
effectsuite_t modNorm
Definition: AudioEffectsSuite.h:1120
effectsuite_t modMin
Definition: AudioEffectsSuite.h:1116
Simple Delay effect consiting of a single tap delay with Effect Gain and feed back controls Construct...
Definition: AudioEffectsSuite.h:1250
effectsuite_t processDouble(effectsuite_t inputSample) override
Definition: AudioEffectsSuite.h:1299
effectsuite_t getSplineOut(effectsuite_t bufferIndex)
Definition: AudioEffectsSuite.h:1382
void setDelayTransitionTime(effectsuite_t seconds)
Definition: AudioEffectsSuite.h:1352
void setDelayTime(effectsuite_t delayInSamples)
Definition: AudioEffectsSuite.h:1341
void setupSimpleDelay(int delayInSamples)
Definition: AudioEffectsSuite.h:1334
effectsuite_t delayIncrement
Definition: AudioEffectsSuite.h:1406
SimpleDelay(int maxDelayInSamples=8810, int samplingRate=44100)
Definition: AudioEffectsSuite.h:1257
effect_t process(effect_t inputSample) override
Definition: AudioEffectsSuite.h:1326
effectsuite_t delayTransitionTime
Definition: AudioEffectsSuite.h:1411
void capGain(effectsuite_t &gain)
Definition: AudioEffectsSuite.h:1366
void setDelayGain(effectsuite_t gain)
Definition: AudioEffectsSuite.h:1277
void setFeedbackGain(effectsuite_t gain)
Definition: AudioEffectsSuite.h:1289
effectsuite_t invDelayIncrement
Definition: AudioEffectsSuite.h:1409
Simple Flanger Effect Consistig of a single voice flanger The flanger has an effective range between ...
Definition: AudioEffectsSuite.h:1428
void updateModulation()
Definition: AudioEffectsSuite.h:1526
effectsuite_t processDouble(effectsuite_t inputSample) override
Definition: AudioEffectsSuite.h:1483
effectsuite_t modulationConstant
Definition: AudioEffectsSuite.h:1546
void setRate(const effectsuite_t rate)
Definition: AudioEffectsSuite.h:1465
void setEffectGain(effectsuite_t gain)
Definition: AudioEffectsSuite.h:1448
effectsuite_t capGain(effectsuite_t gain)
Definition: AudioEffectsSuite.h:1506
void setEffectParams(effectsuite_t gain, effectsuite_t depth, effectsuite_t rate)
Definition: AudioEffectsSuite.h:1476
void setDepth(const effectsuite_t depth)
Definition: AudioEffectsSuite.h:1454
effectsuite_t angleDelta
Definition: AudioEffectsSuite.h:1550
effectsuite_t timeStep
Definition: AudioEffectsSuite.h:1543
void setAngleDelta()
Definition: AudioEffectsSuite.h:1518
SimpleLPF.
Definition: AudioEffectsSuite.h:1004
SimpleLPF(effectsuite_t cutoff, int order)
Definition: AudioEffectsSuite.h:1012
Base class to define the abstract interface for the sound generating classes.
Definition: SoundGenerator.h:25
SoundGenerator using the ModulationBaseClass to generate the samples.
Definition: AudioEffectsSuite.h:372
virtual T readSample() override
Provides a single sample.
Definition: AudioEffectsSuite.h:382
Generic Implementation of sound input and output for desktop environments using portaudio.
Definition: AudioConfig.h:868
static effectsuite_t ** interpolationTable
Table of interpolation values as a 2D array indexed by interpolationTable[pointIndex][alphaIndex].
Definition: AudioEffectsSuite.h:37
Basic Audio information which drives e.g. I2S.
Definition: AudioTypes.h:52
uint8_t bits_per_sample
Number of bits per sample (int16_t = 16 bits)
Definition: AudioTypes.h:59