Newer
Older
music / app / src / main / cpp / Instrument.cpp
  1. #include "Instrument.h"
  2. #include "waveforms/Sawtooth.h"
  3. #include "waveforms/Sine.h"
  4. #include "waveforms/Square.h"
  5. #include "waveforms/Triangle.h"
  6. #include "effects/Distortion.h"
  7.  
  8. Instrument::Instrument(AudioHost *host) {
  9. this->host = host;
  10. wave = new Sine();
  11. wave->host = host;
  12. envelope->initialize(host);
  13. auto *filter = new LowPass();
  14. filter->host = host;
  15. effects.push_back(filter);
  16. auto *noise = new Noise();
  17. noise->host = host;
  18. effects.push_back(noise);
  19. auto *distortion = new Distortion();
  20. distortion->host = host;
  21. effects.push_back(distortion);
  22. }
  23.  
  24. void multiply(float *target, float *modulation, uint32_t size) {
  25. for (uint32_t i = 0; i < size; i++) {
  26. target[i] *= modulation[i];
  27. }
  28. }
  29.  
  30. void multiply(float *target, float value, uint32_t size) {
  31. for (uint32_t i = 0; i < size; i++) {
  32. target[i] *= value;
  33. }
  34. }
  35.  
  36. void add(float *target, float *other, uint32_t size) {
  37. for (uint32_t i = 0; i < size; i++) {
  38. target[i] += other[i];
  39. }
  40. }
  41.  
  42. void processEffect(float *waveform, uint32_t count, Effect *effect) {
  43. if (effect->influence < 0.01f) {
  44. return;
  45. }
  46. effect->input = waveform;
  47. float *effectOutput = effect->render(count);
  48. multiply(effectOutput, effect->influence, count);
  49. multiply(waveform, 1 - effect->influence, count);
  50. add(waveform, effectOutput, count);
  51. }
  52.  
  53. void Instrument::render(float *buffer, uint32_t count) {
  54. float *waveform = wave->render(count);
  55. for (auto effect: effects) {
  56. processEffect(waveform, count, effect);
  57. }
  58. multiply(waveform, envelope->render(count), count);
  59. multiply(waveform, volume, count);
  60. add(buffer, waveform, count);
  61. }
  62.  
  63. void Instrument::startNote(float frequency) {
  64. wave->setFrequency(frequency);
  65. envelope->startNote();
  66. for (auto effect: effects) {
  67. effect->frequency = frequency;
  68. effect->update();
  69. }
  70. }
  71.  
  72. void Instrument::endNote() {
  73. envelope->endNote();
  74. }
  75.  
  76. void Instrument::setWaveform(WaveformType waveform) {
  77. Waveform *old = wave;
  78. switch (waveform) {
  79. case SINE:
  80. wave = new Sine();
  81. break;
  82. case SAWTOOTH:
  83. wave = new Sawtooth();
  84. break;
  85. case SQUARE:
  86. wave = new Square();
  87. break;
  88. case TRIANGLE:
  89. wave = new Triangle();
  90. }
  91. wave->host = host;
  92. delete old;
  93. }