You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

169 lines
5.2KB

  1. #include "AudibleInstruments.hpp"
  2. #include <string.h>
  3. #include "clouds/dsp/granular_processor.h"
  4. struct Clouds : Module {
  5. enum ParamIds {
  6. POSITION_PARAM,
  7. SIZE_PARAM,
  8. PITCH_PARAM,
  9. IN_GAIN_PARAM,
  10. DENSITY_PARAM,
  11. TEXTURE_PARAM,
  12. BLEND_PARAM,
  13. NUM_PARAMS
  14. };
  15. enum InputIds {
  16. FREEZE_INPUT,
  17. TRIG_INPUT,
  18. POSITION_INPUT,
  19. SIZE_INPUT,
  20. PITCH_INPUT,
  21. BLEND_INPUT,
  22. IN_L_INPUT,
  23. IN_R_INPUT,
  24. DENSITY_INPUT,
  25. TEXTURE_INPUT,
  26. NUM_INPUTS
  27. };
  28. enum OutputIds {
  29. OUT_L_OUTPUT,
  30. OUT_R_OUTPUT,
  31. NUM_OUTPUTS
  32. };
  33. uint8_t *block_mem;
  34. uint8_t *block_ccm;
  35. clouds::GranularProcessor *processor;
  36. int bufferFrame = 0;
  37. float inL[32] = {};
  38. float inR[32] = {};
  39. float outL[32] = {};
  40. float outR[32] = {};
  41. bool triggered = false;
  42. Clouds();
  43. ~Clouds();
  44. void step();
  45. };
  46. Clouds::Clouds() {
  47. params.resize(NUM_PARAMS);
  48. inputs.resize(NUM_INPUTS);
  49. outputs.resize(NUM_OUTPUTS);
  50. const int memLen = 118784;
  51. const int ccmLen = 65536 - 128;
  52. block_mem = new uint8_t[memLen];
  53. memset(block_mem, 0, memLen);
  54. block_ccm = new uint8_t[ccmLen];
  55. memset(block_ccm, 0, ccmLen);
  56. processor = new clouds::GranularProcessor();
  57. memset(processor, 0, sizeof(*processor));
  58. processor->Init(block_mem, memLen, block_ccm, ccmLen);
  59. }
  60. Clouds::~Clouds() {
  61. delete processor;
  62. delete[] block_mem;
  63. delete[] block_ccm;
  64. }
  65. void Clouds::step() {
  66. // TODO Sample rate conversion from 32000 Hz
  67. inL[bufferFrame] = getf(inputs[IN_L_INPUT]);
  68. inR[bufferFrame] = getf(inputs[IN_R_INPUT]);
  69. setf(outputs[OUT_L_OUTPUT], outL[bufferFrame]);
  70. setf(outputs[OUT_R_OUTPUT], outR[bufferFrame]);
  71. // Trigger
  72. if (getf(inputs[TRIG_INPUT]) >= 1.0) {
  73. triggered = true;
  74. }
  75. if (++bufferFrame >= 32) {
  76. bufferFrame = 0;
  77. processor->set_num_channels(2);
  78. processor->set_low_fidelity(false);
  79. processor->set_playback_mode(clouds::PLAYBACK_MODE_GRANULAR);
  80. processor->Prepare();
  81. clouds::Parameters* p = processor->mutable_parameters();
  82. p->trigger = triggered;
  83. p->freeze = (getf(inputs[FREEZE_INPUT]) >= 1.0);
  84. p->position = clampf(params[POSITION_PARAM] + getf(inputs[POSITION_INPUT]) / 5.0, 0.0, 1.0);
  85. p->size = clampf(params[SIZE_PARAM] + getf(inputs[SIZE_INPUT]) / 5.0, 0.0, 1.0);
  86. p->pitch = clampf((params[PITCH_PARAM] + getf(inputs[PITCH_INPUT])) * 12.0, -48.0, 48.0);
  87. p->density = clampf(params[DENSITY_PARAM] + getf(inputs[DENSITY_INPUT]) / 5.0, 0.0, 1.0);
  88. p->texture = clampf(params[TEXTURE_PARAM] + getf(inputs[TEXTURE_INPUT]) / 5.0, 0.0, 1.0);
  89. float blend = clampf(params[BLEND_PARAM] + getf(inputs[BLEND_INPUT]) / 5.0, 0.0, 1.0);
  90. p->dry_wet = blend;
  91. p->stereo_spread = 0.0f;
  92. p->feedback = 0.0f;
  93. p->reverb = 0.0f;
  94. clouds::ShortFrame input[32];
  95. clouds::ShortFrame output[32];
  96. for (int j = 0; j < 32; j++) {
  97. input[j].l = clampf(inL[j] * params[IN_GAIN_PARAM] / 5.0, -1.0, 1.0) * 32767;
  98. input[j].r = clampf(inR[j] * params[IN_GAIN_PARAM] / 5.0, -1.0, 1.0) * 32767;
  99. }
  100. processor->Process(input, output, 32);
  101. for (int j = 0; j < 32; j++) {
  102. outL[j] = (float)output[j].l / 32767 * 5.0;
  103. outR[j] = (float)output[j].r / 32767 * 5.0;
  104. }
  105. triggered = false;
  106. }
  107. }
  108. CloudsWidget::CloudsWidget() : ModuleWidget(new Clouds()) {
  109. box.size = Vec(15*18, 380);
  110. {
  111. AudiblePanel *panel = new AudiblePanel();
  112. panel->imageFilename = "plugins/AudibleInstruments/res/Clouds.png";
  113. panel->box.size = box.size;
  114. addChild(panel);
  115. }
  116. addChild(createScrew(Vec(15, 0)));
  117. addChild(createScrew(Vec(240, 0)));
  118. addChild(createScrew(Vec(15, 365)));
  119. addChild(createScrew(Vec(240, 365)));
  120. // TODO
  121. // addParam(createParam<MediumMomentarySwitch>(Vec(211, 51), module, Clouds::POSITION_PARAM, 0.0, 1.0, 0.5));
  122. // addParam(createParam<MediumMomentarySwitch>(Vec(239, 51), module, Clouds::POSITION_PARAM, 0.0, 1.0, 0.5));
  123. addParam(createParam<LargeRedKnob>(Vec(42-14, 108-14), module, Clouds::POSITION_PARAM, 0.0, 1.0, 0.5));
  124. addParam(createParam<LargeGreenKnob>(Vec(123-14, 108-14), module, Clouds::SIZE_PARAM, 0.0, 1.0, 0.5));
  125. addParam(createParam<LargeWhiteKnob>(Vec(205-14, 108-14), module, Clouds::PITCH_PARAM, -2.0, 2.0, 0.0));
  126. addParam(createParam<SmallRedKnob>(Vec(25-10, 191-10), module, Clouds::IN_GAIN_PARAM, 0.0, 1.0, 0.5));
  127. addParam(createParam<SmallRedKnob>(Vec(92-10, 191-10), module, Clouds::DENSITY_PARAM, 0.0, 1.0, 0.5));
  128. addParam(createParam<SmallGreenKnob>(Vec(157-10, 191-10), module, Clouds::TEXTURE_PARAM, 0.0, 1.0, 0.5));
  129. addParam(createParam<SmallWhiteKnob>(Vec(224-10, 191-10), module, Clouds::BLEND_PARAM, 0.0, 1.0, 0.5));
  130. addInput(createInput(Vec(17, 275), module, Clouds::FREEZE_INPUT));
  131. addInput(createInput(Vec(60, 275), module, Clouds::TRIG_INPUT));
  132. addInput(createInput(Vec(103, 275), module, Clouds::POSITION_INPUT));
  133. addInput(createInput(Vec(146, 275), module, Clouds::SIZE_INPUT));
  134. addInput(createInput(Vec(190, 275), module, Clouds::PITCH_INPUT));
  135. addInput(createInput(Vec(233, 275), module, Clouds::BLEND_INPUT));
  136. addInput(createInput(Vec(17, 318), module, Clouds::IN_L_INPUT));
  137. addInput(createInput(Vec(60, 318), module, Clouds::IN_R_INPUT));
  138. addInput(createInput(Vec(103, 318), module, Clouds::DENSITY_INPUT));
  139. addInput(createInput(Vec(146, 318), module, Clouds::TEXTURE_INPUT));
  140. addOutput(createOutput(Vec(190, 318), module, Clouds::OUT_L_OUTPUT));
  141. addOutput(createOutput(Vec(233, 318), module, Clouds::OUT_R_OUTPUT));
  142. }