arduino-audio-tools
AudioEffectsSuite.h
1 #pragma once
2 
20 #ifndef NO_EFFECTS_SUITE
21 #include <cmath>
22 #include <cstdint>
23 #include <iostream>
24 #include "AudioEffects/AudioEffect.h"
25 
26 namespace audio_tools {
27 
28 typedef float effectsuite_t;
29 
34 static effectsuite_t **interpolationTable = nullptr;
35 
41 class EffectSuiteBase : public AudioEffect {
47  virtual effectsuite_t processDouble(effectsuite_t inputSample) = 0;
48 
54  virtual effect_t process(effect_t inputSample) override {
55  return active_flag ? 32767.0f * processDouble(static_cast<effectsuite_t>(inputSample)/32767.0f) : inputSample;
56  }
57 
58 };
59 
60 
71 public:
73  ModulationBaseClass() { srand(static_cast<unsigned>(time(0))); }
74 
75  ModulationBaseClass(ModulationBaseClass &copy) = default;
76 
77  ModulationBaseClass(effectsuite_t extSampRate) {
78  this->sampleRate = extSampRate;
79  timeStep = 1. / extSampRate;
81  // setInterpTable();
82  srand(static_cast<unsigned>(time(0)));
83  }
85  ~ModulationBaseClass() = default;
86 
92  void setupModulationBaseClass(effectsuite_t extSampRate) {
93  if (waveTable != nullptr) {
94  delete[] waveTable;
95  }
96  sampleRate = extSampRate;
97  timeStep = 1. / extSampRate;
99  }
100 
104  void setTriangle() {
105  std::fill(waveTable, waveTable + sampleRate, 0);
106  const effectsuite_t radPerSec = 2 * 3.1415926536f * timeStep;
107  for (int i = 0; i < sampleRate; i++) {
108  for (int j = 0; j < 35; j += 1)
109  waveTable[i] += pow(-1., j) *
110  (sin((2. * effectsuite_t(j) + 1) * i * radPerSec)) /
111  (2. * effectsuite_t(j) + 1);
112  }
113  }
117  void setSquare() {
118  std::fill(waveTable, waveTable + sampleRate, 0);
119  const effectsuite_t radPerSec = 2 * 3.1415926536f * timeStep;
120  for (int i = 0; i < sampleRate; i++) {
121  for (int j = 0; j < 35; j += 1)
122  waveTable[i] += (sin((2 * j + 1) * i * radPerSec)) / (2 * j + 1);
123  }
124  }
128  void setSawtooth() {
129  std::fill(waveTable, waveTable + sampleRate, 0);
130  const effectsuite_t radPerSec = 2 * 3.1415926536f * timeStep;
131  for (int i = 0; i < sampleRate; i++) {
132  for (int j = 1; j < 11; j += 1)
133  waveTable[i] += pow(-1, j) * sin(j * radPerSec * i) / effectsuite_t(j);
134  }
135  }
139  void setSine() {
140  const effectsuite_t radPerSec = 2 * 3.1415926536f * timeStep;
141  for (int i = 0; i < sampleRate; i++)
142  waveTable[i] = sin(i * radPerSec);
143  }
147  void setOffSine() {
148  const effectsuite_t radPerSec = 2 * 3.1415926536f * timeStep;
149  for (int i = 0; i < sampleRate; i++)
150  waveTable[i] = (sin(i * radPerSec) + 1) * .5f;
151  }
152 
153  void setNoise() {
154  is_noise = true;
155  }
156 
157  bool isNoise() {
158  return is_noise;
159  }
160 
164  void setDC() {
165  for (int i = 0; i < sampleRate; i++)
166  waveTable[i] = 1.0;
167  }
169  void setRamp() {
170  for (int i = 0; i < sampleRate; i++)
171  waveTable[i] = i / effectsuite_t(sampleRate);
172  }
177  effectsuite_t readNoise() {
178  const effectsuite_t lo = -1.;
179  const effectsuite_t hi = 1.;
180  return lo + static_cast<effectsuite_t>(rand()) /
181  (static_cast<effectsuite_t>(RAND_MAX / (hi - lo)));
182  }
189  void clipWave(effectsuite_t amp) {
190  if (amp < .01) {
191  amp = .01;
192  }
193 
194  for (int i = 0; i < sampleRate; i++)
195  waveTable[i] = tanh(amp * waveTable[i]) / tanh(amp);
196  }
197 
204  effectsuite_t readTable(effectsuite_t freq) {
205  if (freq > 0) {
206  // const effectsuite_t out = getInterpOut(tableIndex);
207  const effectsuite_t out = getSplineOut(tableIndex, int(freq));
208  tableIndex += freq;
209  if (tableIndex - sampleRate > 0)
211 
212  return out;
213  } else {
214  return 0.;
215  }
216  }
217  void printInterpTable() {
218  for (int j = 0; j < res; j++) {
219  for (int i = 0; i < order; i++) {
220  std::cout << interpTable[i][j] << '\t';
221  }
222  std::cout << '\n';
223  }
224  }
229  bool setInterpTable() {
230  effectsuite_t *polynomial_normaliser = new effectsuite_t[order];
231  if (!polynomial_normaliser) {
232  return false;
233  }
234  std::fill(polynomial_normaliser, polynomial_normaliser + order, 1);
235  effectsuite_t *alphas = new effectsuite_t[res];
236  if (!alphas) {
237  return false;
238  }
239 
240  for (int i = 0; i < res; i++) {
241  alphas[i] = (i / float(res)) - 0.5;
242  }
243 
244  effectsuite_t *anchors = new effectsuite_t[order];
245 
246  if ((order % 2) == 0) {
247  for (int i = 0; i < order; i++) {
248  anchors[i] = -(effectsuite_t(order) - 1) * 0.5 + effectsuite_t(i);
249  std::fill(interpTable[i], interpTable[i] + res, 1);
250  }
251  } else {
252  for (int i = 0; i < order; i++) {
253  anchors[i] = (-(effectsuite_t(order)) * 0.5) + effectsuite_t(i);
254  }
255  }
256 
257  // loop for every value of alpha
258  for (int q = 0; q < res; q++) {
259  // loop for sub polynomial
260  for (int j = 0; j < order; j++) {
261  // loop for each point in subpoly
262  for (int m = 0; m < order; m++) {
263  if (m != j) {
264  if (q == 0) {
265  polynomial_normaliser[j] =
266  polynomial_normaliser[j] * (anchors[j] - anchors[m]);
267  }
268  interpTable[j][q] *= (alphas[q] - anchors[m]);
269  }
270  }
271  interpTable[j][q] /= polynomial_normaliser[j];
272  }
273  }
274 
275  delete[] polynomial_normaliser;
276  delete[] alphas;
277  delete[] anchors;
278  return true;
279  }
280 
281 protected:
286  bool allocateMemory() {
287  waveTable = new effectsuite_t[sampleRate];
288  assert(waveTable!=nullptr);
289  if (!waveTable) {
290  return false;
291  }
292  std::fill(waveTable, waveTable + sampleRate, 0);
293  return true;
294  }
301  effectsuite_t getInterpOut(effectsuite_t bufferIndex) {
302  const int order = 4;
303  const int orderHalf = order * .5;
304  const int res = 100;
305  effectsuite_t interpOut = 0;
306  int intBufferIndex = floor(bufferIndex);
307  int alphaIndex = int(floor((bufferIndex - intBufferIndex) * res));
308 
309  for (int i = 0; i < order; i++) {
310  int interpIndex =
311  (((i + 1 - orderHalf) + intBufferIndex) + sampleRate) % sampleRate;
312  interpOut += (interpTable[i][alphaIndex]) * (waveTable[interpIndex]);
313  }
314  return interpOut;
315  }
316 
328  effectsuite_t getSplineOut(effectsuite_t bufferIndex, int freq) {
329  if (freq < 1) {
330  freq = 1;
331  }
332  const int n0 = floor(bufferIndex);
333  const int n1 = (n0 + freq) % sampleRate;
334  const int n2 = (n0 + (2 * freq)) % sampleRate;
335  const effectsuite_t alpha = bufferIndex - n0;
336  const effectsuite_t a = waveTable[n1];
337  const effectsuite_t c = ((3 * (waveTable[n2] - waveTable[n1])) -
338  (3 * (waveTable[n1] - waveTable[n0]))) *
339  .25;
340  const effectsuite_t b = (waveTable[n2] - waveTable[n1]) - ((2 * c)) / 3;
341  const effectsuite_t d = (-c) / 3;
342  return a + (b * alpha) + (c * alpha * alpha) + (d * alpha * alpha * alpha);
343  }
344 
345 public:
347  effectsuite_t tableIndex = 0;
351  effectsuite_t timeStep;
353  effectsuite_t *waveTable;
354 
355 protected:
356  static const int order = 4;
357  static const int res = 100;
358  effectsuite_t interpTable[order][res];// = {1};
359  bool is_noise = false;
360 };
361 
368  template <class T>
370  public:
372  p_mod = &mod;
373  this->freq = freq;
374  }
375  bool begin(AudioInfo info) override{
376  max_value = pow(2, info.bits_per_sample)/2-1;
377  return SoundGenerator<T>::begin(info);
378  }
379  virtual T readSample() override {
380  return p_mod->isNoise() ? max_value * p_mod->readNoise() : max_value * p_mod->readTable(freq);
381  }
382 
383  protected:
384  ModulationBaseClass *p_mod=nullptr;
385  int freq;
386  float max_value=32767;
387 };
388 
389 
400 public:
402  DelayEffectBase() = default;
403 
404  DelayEffectBase(DelayEffectBase &copy) = default;
405 
406  DelayEffectBase(int bufferSizeSamples) {
407  error = setDelayBuffer(bufferSizeSamples);
408  delayTimeSamples = bufferSizeSamples;
409  if (interpolationTable == nullptr) {
411  }
412  }
413 
416  if (delayBuffer != nullptr)
417  delete[] delayBuffer;
418  }
419 
424  void setupDelayEffectBase(const int bufferSizeSamples) {
425  error = setDelayBuffer(bufferSizeSamples);
426  delayTimeSamples = bufferSizeSamples;
427  }
428 
429 protected:
437  static effectsuite_t **setInterpolationTable() {
438  const int order = interpOrder;
439  const int res = interpResolution;
440  effectsuite_t **interpTable = new effectsuite_t *[order];
441  if (!interpTable) {
442  return NULL;
443  }
444 
445  for (int i = 0; i < order; i++) {
446  interpTable[i] = new effectsuite_t[res + 1];
447  if (!interpTable[i]) {
448  return NULL;
449  }
450  std::fill(interpTable[i], interpTable[i] + res, 1);
451  }
452 
453  effectsuite_t *polynomial_normaliser = new effectsuite_t[order];
454  if (!polynomial_normaliser) {
455  return NULL;
456  }
457  std::fill(polynomial_normaliser, polynomial_normaliser + order, 1);
458  effectsuite_t *alphas = new effectsuite_t[res];
459  if (!alphas) {
460  return NULL;
461  }
462 
463  for (int i = 0; i < res; i++) {
464  alphas[i] = (i / float(res)) - 0.5;
465  }
466 
467  effectsuite_t *anchors = new effectsuite_t[order];
468 
469  if ((order % 2) == 0) {
470  for (int i = 0; i < order; i++) {
471  anchors[i] = -(effectsuite_t(order) - 1) * 0.5 + effectsuite_t(i);
472  }
473  } else {
474  for (int i = 0; i < order; i++) {
475  anchors[i] = (-(effectsuite_t(order)) * 0.5) + effectsuite_t(i);
476  }
477  }
478 
479  // loop for every value of alpha
480  for (int q = 0; q < res; q++) {
481  // loop for sub polynomial
482  for (int j = 0; j < order; j++) {
483  // loop for each point in subpoly
484  for (int m = 0; m < order; m++) {
485  if (m != j) {
486  if (q == 0) {
487  polynomial_normaliser[j] =
488  polynomial_normaliser[j] * (anchors[j] - anchors[m]);
489  }
490  interpTable[j][q] *= (alphas[q] - anchors[m]);
491  }
492  }
493  interpTable[j][q] /= polynomial_normaliser[j];
494  }
495  }
496  delete[] polynomial_normaliser;
497  delete[] alphas;
498  delete[] anchors;
499  return interpTable;
500  }
501 
502  // void printInterpTable() {
503  // for (int j = 0; j < interpResolution; j++) {
504  // for (int i = 0; i < interpOrder; i++) {
505  // printf("index %d: %.2f \t", i, interpolationTable[i][j]);
506  // }
507  // printf("\n");
508  // }
509  // }
510 
511 protected:
518  bool setDelayBuffer(int bufferSizeSamples) {
519  maxDelayBufferSize = bufferSizeSamples;
520  delayBuffer = new effectsuite_t[maxDelayBufferSize];
521  if (!delayBuffer) {
522  return false;
523  }
524  std::fill(delayBuffer, delayBuffer + maxDelayBufferSize, 0);
525  return true;
526  }
527 
532  void storeSample(effectsuite_t inputSample) {
533  delayBuffer[currentDelayWriteIndex] = inputSample;
534  }
535 
540  currentDelayWriteIndex++;
541  currentDelayWriteIndex %= delayTimeSamples;
542  }
543 
548  void incDelayBuffReadIndex(effectsuite_t indexInc) {
549  currentDelayReadIndex += indexInc;
550  if (currentDelayReadIndex >= effectsuite_t(delayTimeSamples)) {
551  currentDelayReadIndex = 0;
552  }
553  if (currentDelayReadIndex < 0) {
554  currentDelayReadIndex = 0;
555  }
556  }
557 
562  void setDelayBuffReadIndex(effectsuite_t index) {
563  currentDelayReadIndex = index;
564  if (currentDelayReadIndex >= effectsuite_t(delayTimeSamples)) {
565  currentDelayReadIndex = 0;
566  }
567  if (currentDelayReadIndex < 0) {
568  currentDelayReadIndex = 0;
569  }
570  }
571 
577  void delaySample(effectsuite_t inputSample) {
578  storeSample(inputSample);
580  }
586  effectsuite_t getInterpolatedOut(effectsuite_t bufferIndex) {
587  const int order = interpOrder;
588  const int orderHalf = order * .5;
589  const int res = interpResolution;
590  effectsuite_t interpOut = 0;
591  int intBufferIndex = floor(bufferIndex);
592  int alphaIndex = int(floor((bufferIndex - intBufferIndex) * res));
593 
594  for (int i = 0; i < order; i++) {
595  int interpIndex = (i + 1 - orderHalf) + intBufferIndex;
596  if (interpIndex < 0 || (interpIndex >= maxDelayBufferSize)) {
597  if (interpIndex < 0) {
598  interpIndex = maxDelayBufferSize + interpIndex;
599  } else {
600  interpIndex = interpIndex - maxDelayBufferSize;
601  }
602  }
603 
604  interpOut +=
605  (interpolationTable[i][alphaIndex]) * (delayBuffer[interpIndex]);
606  }
607  return interpOut;
608  }
609 
610 protected: // member variables
612  effectsuite_t *delayBuffer = 0;
614  int maxDelayBufferSize = 441000;
616  int delayTimeSamples = 44100;
617  int currentDelayWriteIndex = 0;
618  effectsuite_t currentDelayReadIndex = 0;
619  static const int interpOrder = 4;
620  static const int interpResolution = 1000;
621 
623  bool error;
624 };
625 
635 public:
638 
639  FilterEffectBase(FilterEffectBase &copy) = default;
640 
642  ~FilterEffectBase() = default;
643 
650  virtual effectsuite_t applyFilter(effectsuite_t sampVal) {
651  effectsuite_t outSample = 0;
652  firBuffer[bufferIndex] = sampVal;
653 
654  for (int j = 0; j < filterOrder; j++) {
655  int i = ((bufferIndex - j) + filterOrder) % filterOrder;
656  outSample +=
658  }
659 
660  iirBuffer[bufferIndex] = outSample;
661  incBufferIndex();
662 
663  return outSample;
664  }
665 
666  virtual effectsuite_t processDouble(effectsuite_t inputSample) override {
667  return applyFilter(inputSample);
668  }
669 
671  virtual effect_t process(effect_t inputSample) override {
672  return active_flag ? 32767.0 * processDouble(static_cast<effectsuite_t>(inputSample)/32767.0) : inputSample;
673  }
674 
680  effectsuite_t envelope(effectsuite_t sample) { return applyFilter(rms(sample)); }
681 
682  // void printBuffers() {
683  // printf("FIRb\t\tIIRb\n");
684  // for (int i = 0; i < filterOrder; i++) {
685  // printf("%.4e\t%.4e\n", firBuffer[i], iirBuffer[i]);
686  // }
687  // printf("\n");
688  // }
689 
690  // void printCoefs() {
691  // printf("FIR\t\tIIR\n");
692  // for (int i = 0; i < filterOrder; i++) {
693  // printf("%.4e\t%.4e\n", firCoefficients[i], iirCoefficients[i]);
694  // }
695  // printf("\n");
696  // }
697 
709  bool setChebyICoefficients(effectsuite_t cutFreq, bool shelfType, effectsuite_t ripple) {
710  // NOTE: coefficient buffers must be cleared as are additive in the
711  // following code
712  std::fill(firCoefficients, firCoefficients + 22, 0);
713  std::fill(iirCoefficients, iirCoefficients + 22, 0);
714 
715  effectsuite_t poles = (effectsuite_t)filterOrder - 1;
716  int order = (int)poles;
717 
718  firCoefficients[2] = 1;
719  iirCoefficients[2] = 1;
720 
721  effectsuite_t Es, Vx, Kx;
722  if (ripple != 0) {
723  Es = sqrt(pow(1 / (1 - ripple), 2) - 1);
724  Vx = (1 / poles) * log(1 / Es + sqrt(1 / (pow(Es, 2)) + 1));
725  Kx = (1 / poles) * log(1 / Es + sqrt(1 / (pow(Es, 2)) - 1));
726  Kx = cosh(Kx);
727  } else {
728  Vx = 1;
729  Kx = 1;
730  }
731 
732  const effectsuite_t T = 2 * tan(.5);
733  const effectsuite_t W = 2 * pi * cutFreq;
734 
735  effectsuite_t K;
736 
737  if (shelfType == 0)
738  {
739  K = sin(.5 - W / 2) / sin(.5 + W / 2);
740  } else
741  {
742 
743  K = -cos(.5 + W / 2) / cos(W / 2 - .5);
744  }
745 
747  for (int i = 0; i < (order / 2); i++) {
749  const effectsuite_t alpha = pi / (2 * poles) + (i - 1) * (pi / poles);
750 
751  effectsuite_t Rp, Ip;
752  if (ripple != 0) {
753  Rp = -cos(alpha) * sinh(Vx) / Kx;
754  Ip = sin(alpha) * cosh(Vx) / Kx;
755  } else {
756  Rp = -cos(alpha);
757  Ip = sin(alpha);
758  }
759 
760  const effectsuite_t M = pow(Rp, 2) + pow(Ip, 2);
761  const effectsuite_t D = 4 - 4 * Rp * T + M * T;
762 
763  const effectsuite_t X0 = (pow(T, 2)) / D;
764  const effectsuite_t X1 = (2 * pow(T, 2)) / D;
765  const effectsuite_t X2 = X0;
766 
767  const effectsuite_t Y1 = (8 - (2 * M * pow(T, 2))) / D;
768  const effectsuite_t Y2 = (-4 - 4 * Rp * T - M * T) / D;
769 
770  // renamed and inverted from original algorithm
771  const effectsuite_t _D1 = 1 / (1 + Y1 * K - Y2 * pow(K, 2));
772 
773  const effectsuite_t _A0 = (X0 - X1 * K + X2 * pow(K, 2)) * _D1;
774  effectsuite_t _A1 = (-2 * X0 * K + X1 + X1 * pow(K, 2) - 2 * X2 * K) * _D1;
775  const effectsuite_t _A2 = (X0 * pow(K, 2) - X1 * K + X2) * _D1;
776 
777  effectsuite_t _B1 = (2 * K + Y1 + Y1 * pow(K, 2) - 2 * Y2 * K) * _D1;
778  const effectsuite_t B2 = (-(pow(K, 2)) - Y1 * K + Y2) * _D1;
779 
780  if (shelfType == 1) {
781  _A1 = -_A1;
782  _B1 = -_B1;
783  }
784 
785  for (int j = 0; j < 22; j++) {
786  firTemp[j] = firCoefficients[j];
787  iirTemp[j] = iirCoefficients[j];
788  }
789  for (int j = 2; j < 22; j++) {
790  firCoefficients[j] =
791  _A0 * firTemp[j] + _A1 * firTemp[j - 1] + _A2 * firTemp[j - 2];
792  iirCoefficients[j] =
793  iirTemp[j] - _B1 * iirTemp[j - 1] - B2 * iirTemp[j - 2];
794  }
795  }
796 
797  iirCoefficients[2] = 0;
798  for (int j = 0; j < filterOrder; j++) {
799  firCoefficients[j] = firCoefficients[j + 2];
800  iirCoefficients[j] = -iirCoefficients[j + 2];
801  }
803  effectsuite_t SA = 0;
804  effectsuite_t SB = 0;
805  if (shelfType == 0) {
806  for (int j = 0; j < filterOrder; j++) {
807  SA += firCoefficients[j];
808  SB += iirCoefficients[j];
809  }
810  } else {
811  for (int j = 0; j < order; j++) {
812  SA += firCoefficients[j] * pow(-1, j);
813  SB += iirCoefficients[j] * pow(-1, j);
814  }
815  }
816 
817  const effectsuite_t gain = SA / (1 - SB);
818  for (int j = 0; j < filterOrder; j++) {
819  firCoefficients[j] /= gain;
820  }
821 
822  return true;
823  }
824 
825 protected:
836  bool changeChebyICoefficients(effectsuite_t cutFreq, bool shelfType, effectsuite_t ripple,
837  int poles) {
838  filterOrder = poles + 1;
839  clearMemory();
841  setChebyICoefficients(cutFreq, shelfType, ripple);
842 
843  return true;
844  }
845 
850  bool setSimpleLpf(int order) {
851  filterOrder = order;
852  clearMemory();
854  firCoefficients = new effectsuite_t[filterOrder];
855  iirCoefficients = new effectsuite_t[filterOrder];
857  int coef = 1;
858  effectsuite_t gain = 0;
859  for (int j = 0; j < filterOrder; j++) {
860  if (j == 0) {
861  coef = 1;
862  } else {
863  coef = coef * (filterOrder - j) / j;
864  }
865 
866  firCoefficients[j] = (effectsuite_t)coef;
867  gain += firCoefficients[j];
868  }
869 
870  for (int j = 0; j <= filterOrder; j++) {
871  firCoefficients[j] /= gain;
872  }
873 
874  return true;
875  }
876 
877 protected:
879  void incBufferIndex() {
880  bufferIndex++;
882  }
883 
888  void clearMemory() {
889  if (firCoefficients) {
890  delete[] firCoefficients;
891  }
892 
893  if (iirCoefficients) {
894  delete[] iirCoefficients;
895  }
896  }
897 
903  if (firBuffer) {
904  delete[] firBuffer;
905  }
906 
907  if (iirBuffer) {
908  delete[] iirBuffer;
909  }
910  firBuffer = new effectsuite_t[filterOrder];
911  iirBuffer = new effectsuite_t[filterOrder];
912  std::fill(firBuffer, firBuffer + filterOrder, 0);
913  std::fill(iirBuffer, iirBuffer + filterOrder, 0);
914 
915  if (firCoefficients) {
916  delete[] firCoefficients;
917  }
918 
919  if (iirCoefficients) {
920  delete[] iirCoefficients;
921  }
922 
923  if (firTemp) {
924  delete[] firTemp;
925  }
926 
927  if (iirTemp) {
928  delete[] iirTemp;
929  }
930 
931  firCoefficients = new effectsuite_t[22];
932  iirCoefficients = new effectsuite_t[22];
933  firTemp = new effectsuite_t[22];
934  iirTemp = new effectsuite_t[22];
935  std::fill(firCoefficients, firCoefficients + 22, 0);
936  std::fill(iirCoefficients, iirCoefficients + 22, 0);
937  std::fill(firTemp, firTemp + 22, 0);
938  std::fill(iirTemp, iirTemp + 22, 0);
939  }
940 
942  effectsuite_t rms(effectsuite_t sample) {
943  rmsBuffer[rmsBufferIndex] = sample;
944  effectsuite_t rmsValue = 0;
945  for (int j = 0; j < rmsBufferIndex; j++) {
946  int i = ((rmsBufferIndex - j) + rmsWindowSize) % rmsWindowSize;
947  rmsValue += rmsBuffer[i] * rmsBuffer[i];
948  }
949 
950  // printf("samp: %e\tsum: %e\n", sample, rmsValue);
951  rmsValue /= rmsWindowSize;
952  rmsValue = sqrt(rmsValue);
953 
954  rmsBufferIndex++;
956 
957  return rmsValue;
958  }
959 
960 public:
961 protected:
966  effectsuite_t *firCoefficients = 0;
970  effectsuite_t *iirCoefficients = 0;
972  effectsuite_t *firTemp = 0;
974  effectsuite_t *iirTemp = 0;
977  effectsuite_t *firBuffer = 0;
980  effectsuite_t *iirBuffer = 0;
982  int bufferIndex = 0;
984  int filterOrder = 0;
985  /***/
986  int samplingRate = 0;
988  const int rmsWindowSize = 128;
990  int rmsBufferIndex = 0;
992  effectsuite_t *rmsBuffer = new effectsuite_t[rmsWindowSize];
993 
994 protected: // variables
995  constexpr static const effectsuite_t pi = 3.141592653589793;
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.0 * internal_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:
1539  constexpr static const effectsuite_t internal_Pi = 3.141592653589793;
1540 
1541  effectsuite_t modulationDepth = 1000, modulationRate = 0, effectGain = .01;
1542 
1543  effectsuite_t modulationIndex = 0;
1544 
1546  effectsuite_t timeStep = 1. / 44100.;
1547 
1549  effectsuite_t modulationConstant, modulationAngle = 0;
1550 
1551  // const effectsuite_t cyclesPerSample = modulationRate * timeStep;
1553  effectsuite_t angleDelta = 2 * internal_Pi * timeStep;
1554 };
1555 
1563 public:
1566  // NOTE: Initialising chebyshev coeffcients allocates memory, perhaps alter
1567  // so that memory is already pre allocated
1568  changeChebyICoefficients(.01, false, .1, 4);
1569  envelopeFollower.setChebyICoefficients(.00006, false, 0);
1570  };
1571 
1573  ~EnvelopeFilter() = default;
1580  effectsuite_t processDouble(effectsuite_t sample) {
1581  setChebyICoefficients(0.001 + envelopeFollower.envelope(2 * sample), false,
1582  .1); // Offset avoids zero cutoff value
1583  return applyFilter(sample);
1584  }
1585 
1586 protected:
1592 };
1593 
1594 } // namespace effectsuite_tools
1595 
1596 #endif
Abstract Base class for Sound Effects.
Definition: AudioEffect.h:20
A Base class for delay based digital effects. Provides the basic methods that are shared amongst Flan...
Definition: AudioEffectsSuite.h:399
void setDelayBuffReadIndex(effectsuite_t index)
Definition: AudioEffectsSuite.h:562
~DelayEffectBase()
Definition: AudioEffectsSuite.h:415
void storeSample(effectsuite_t inputSample)
Definition: AudioEffectsSuite.h:532
static effectsuite_t ** setInterpolationTable()
Definition: AudioEffectsSuite.h:437
void incDelayBuffWriteIndex()
Definition: AudioEffectsSuite.h:539
bool error
Definition: AudioEffectsSuite.h:623
void setupDelayEffectBase(const int bufferSizeSamples)
Definition: AudioEffectsSuite.h:424
int delayTimeSamples
Definition: AudioEffectsSuite.h:616
int maxDelayBufferSize
Definition: AudioEffectsSuite.h:614
bool setDelayBuffer(int bufferSizeSamples)
Definition: AudioEffectsSuite.h:518
effectsuite_t * delayBuffer
Definition: AudioEffectsSuite.h:612
effectsuite_t getInterpolatedOut(effectsuite_t bufferIndex)
Definition: AudioEffectsSuite.h:586
void delaySample(effectsuite_t inputSample)
Definition: AudioEffectsSuite.h:577
void incDelayBuffReadIndex(effectsuite_t indexInc)
Definition: AudioEffectsSuite.h:548
Base Class for Effects.
Definition: AudioEffectsSuite.h:41
EnvelopeFilter.
Definition: AudioEffectsSuite.h:1562
SimpleLPF envelopeFollower
Definition: AudioEffectsSuite.h:1591
EnvelopeFilter()
Definition: AudioEffectsSuite.h:1565
effectsuite_t processDouble(effectsuite_t sample)
Definition: AudioEffectsSuite.h:1580
A Base class for filter based effects including methods for simple high, low and band pass filtering.
Definition: AudioEffectsSuite.h:634
effectsuite_t * firCoefficients
Definition: AudioEffectsSuite.h:966
effectsuite_t * firTemp
Definition: AudioEffectsSuite.h:972
effectsuite_t * iirBuffer
Definition: AudioEffectsSuite.h:980
bool setSimpleLpf(int order)
Definition: AudioEffectsSuite.h:850
virtual effectsuite_t applyFilter(effectsuite_t sampVal)
Definition: AudioEffectsSuite.h:650
effectsuite_t * firBuffer
Definition: AudioEffectsSuite.h:977
int bufferIndex
Definition: AudioEffectsSuite.h:982
bool changeChebyICoefficients(effectsuite_t cutFreq, bool shelfType, effectsuite_t ripple, int poles)
Definition: AudioEffectsSuite.h:836
effectsuite_t envelope(effectsuite_t sample)
Definition: AudioEffectsSuite.h:680
bool setChebyICoefficients(effectsuite_t cutFreq, bool shelfType, effectsuite_t ripple)
Definition: AudioEffectsSuite.h:709
effectsuite_t * iirTemp
Definition: AudioEffectsSuite.h:974
virtual effect_t process(effect_t inputSample) override
see applyFilter
Definition: AudioEffectsSuite.h:671
int filterOrder
Definition: AudioEffectsSuite.h:984
effectsuite_t * iirCoefficients
Definition: AudioEffectsSuite.h:970
FilterEffectBase()
Definition: AudioEffectsSuite.h:637
int rmsBufferIndex
Definition: AudioEffectsSuite.h:990
const int rmsWindowSize
Definition: AudioEffectsSuite.h:988
void allocateBufferMemory()
Definition: AudioEffectsSuite.h:902
void clearMemory()
Definition: AudioEffectsSuite.h:888
effectsuite_t rms(effectsuite_t sample)
Definition: AudioEffectsSuite.h:942
void incBufferIndex()
Definition: AudioEffectsSuite.h:879
virtual effectsuite_t processDouble(effectsuite_t inputSample) override
Main process block for applying audio effect.
Definition: AudioEffectsSuite.h:666
effectsuite_t * rmsBuffer
Definition: AudioEffectsSuite.h:992
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:70
effectsuite_t readNoise()
Definition: AudioEffectsSuite.h:177
void clipWave(effectsuite_t amp)
Definition: AudioEffectsSuite.h:189
effectsuite_t tableIndex
Definition: AudioEffectsSuite.h:347
void setRamp()
Definition: AudioEffectsSuite.h:169
effectsuite_t getInterpOut(effectsuite_t bufferIndex)
Definition: AudioEffectsSuite.h:301
void setupModulationBaseClass(effectsuite_t extSampRate)
setup the class with a given sample rate. Basically reperforming the constructor
Definition: AudioEffectsSuite.h:92
void setSine()
Definition: AudioEffectsSuite.h:139
void setSawtooth()
Definition: AudioEffectsSuite.h:128
bool setInterpTable()
Definition: AudioEffectsSuite.h:229
void setDC()
Definition: AudioEffectsSuite.h:164
void setSquare()
Definition: AudioEffectsSuite.h:117
effectsuite_t getSplineOut(effectsuite_t bufferIndex, int freq)
Definition: AudioEffectsSuite.h:328
effectsuite_t * waveTable
Definition: AudioEffectsSuite.h:353
effectsuite_t timeStep
Definition: AudioEffectsSuite.h:351
bool allocateMemory()
Definition: AudioEffectsSuite.h:286
int sampleRate
Definition: AudioEffectsSuite.h:349
effectsuite_t readTable(effectsuite_t freq)
Definition: AudioEffectsSuite.h:204
void setOffSine()
Definition: AudioEffectsSuite.h:147
ModulationBaseClass()
Definition: AudioEffectsSuite.h:73
void setTriangle()
Definition: AudioEffectsSuite.h:104
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
constexpr static const effectsuite_t internal_Pi
Definition: AudioEffectsSuite.h:1539
effectsuite_t modulationConstant
Definition: AudioEffectsSuite.h:1549
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:1553
effectsuite_t timeStep
Definition: AudioEffectsSuite.h:1546
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:369
virtual T readSample() override
Provides a single sample.
Definition: AudioEffectsSuite.h:379
Generic Implementation of sound input and output for desktop environments using portaudio.
Definition: AnalogAudio.h:10
static effectsuite_t ** interpolationTable
Table of interpolation values as a 2D array indexed by interpolationTable[pointIndex][alphaIndex].
Definition: AudioEffectsSuite.h:34
Basic Audio information which drives e.g. I2S.
Definition: AudioTypes.h:50
uint8_t bits_per_sample
Number of bits per sample (int16_t = 16 bits)
Definition: AudioTypes.h:57