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.

157 lines
4.5KB

  1. /******************************************************************************
  2. * Copyright 2017-2018 Valerio Orlandini / Sonus Dept. <sonusdept@gmail.com>
  3. *
  4. * This program is free software: you can redistribute it and/or modify
  5. * it under the terms of the GNU General Public License as published by
  6. * the Free Software Foundation, either version 3 of the License, or
  7. * (at your option) any later version.
  8. *
  9. * This program is distributed in the hope that it will be useful,
  10. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  11. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  12. * GNU General Public License for more details.
  13. *
  14. * You should have received a copy of the GNU General Public License
  15. * along with this program. If not, see <http://www.gnu.org/licenses/>.
  16. *****************************************************************************/
  17. #include "sonusmodular.hpp"
  18. namespace rack_plugin_SonusModular {
  19. struct Addiction : Module
  20. {
  21. enum ParamIds
  22. {
  23. OCTAVE,
  24. H1_I1,
  25. H1_I2,
  26. H1_I3,
  27. H1_I4,
  28. H2_I1,
  29. H2_I2,
  30. H2_I3,
  31. H2_I4,
  32. H3_I1,
  33. H3_I2,
  34. H3_I3,
  35. H3_I4,
  36. H4_I1,
  37. H4_I2,
  38. H4_I3,
  39. H4_I4,
  40. NUM_PARAMS
  41. };
  42. enum InputIds
  43. {
  44. CV_FREQ,
  45. CV_H1_I1,
  46. CV_H1_I2,
  47. CV_H1_I3,
  48. CV_H1_I4,
  49. CV_H2_I1,
  50. CV_H2_I2,
  51. CV_H2_I3,
  52. CV_H2_I4,
  53. CV_H3_I1,
  54. CV_H3_I2,
  55. CV_H3_I3,
  56. CV_H3_I4,
  57. CV_H4_I1,
  58. CV_H4_I2,
  59. CV_H4_I3,
  60. CV_H4_I4,
  61. NUM_INPUTS
  62. };
  63. enum OutputIds
  64. {
  65. OUTPUT,
  66. NUM_OUTPUTS
  67. };
  68. enum LightIds
  69. {
  70. NUM_LIGHTS
  71. };
  72. Addiction() : Module(NUM_PARAMS, NUM_INPUTS, NUM_OUTPUTS, NUM_LIGHTS) {}
  73. void step() override;
  74. float amp_sum = 0.0f;
  75. float ramps[16] = {0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f};
  76. float coeff[16] = {1.0f, 1.2f, 1.25f, 1.5f, 2.0f, 2.4f, 2.5f, 3.0f, 3.0f, 3.6f, 3.75f, 4.5f, 4.0f, 4.8f, 5.0f, 6.0f};
  77. };
  78. void Addiction::step()
  79. {
  80. float pitch = params[OCTAVE].value;
  81. pitch += inputs[CV_FREQ].value;
  82. pitch = clamp(pitch, -4.0f, 4.0f);
  83. float freq = 261.626 * powf(2.0f, pitch);
  84. float inv_sample_rate = 1.0 / engineGetSampleRate();
  85. outputs[OUTPUT].value = 0.0;
  86. amp_sum = 0.0;
  87. for (unsigned int i = 0; i < 16; i++)
  88. {
  89. ramps[i] += freq * inv_sample_rate * coeff[i];
  90. if (ramps[i] > 1.0)
  91. {
  92. ramps[i] = -1.0;
  93. }
  94. outputs[OUTPUT].value += sin(ramps[i] * M_PI) * (params[i + 1].value + (inputs[i + 1].value * 0.2));
  95. amp_sum += (params[i + 1].value + (inputs[i + 1].value * 0.2));
  96. }
  97. amp_sum > 0.0 ? outputs[OUTPUT].value /= (amp_sum * 0.2) : outputs[OUTPUT].value = 0.0;
  98. }
  99. struct AddictionWidget : ModuleWidget
  100. {
  101. AddictionWidget(Addiction *module);
  102. float def_amps[4] = {1.0f, 0.7f, 0.0f, 0.8f};
  103. };
  104. AddictionWidget::AddictionWidget(Addiction *module) : ModuleWidget(module)
  105. {
  106. box.size = Vec(15 * 24, 380);
  107. {
  108. SVGPanel *panel = new SVGPanel();
  109. panel->box.size = box.size;
  110. panel->setBackground(SVG::load(assetPlugin(plugin, "res/addiction.svg")));
  111. addChild(panel);
  112. }
  113. addChild(Widget::create<SonusScrew>(Vec(0, 0)));
  114. addChild(Widget::create<SonusScrew>(Vec(box.size.x - 15, 0)));
  115. addChild(Widget::create<SonusScrew>(Vec(0, 365)));
  116. addChild(Widget::create<SonusScrew>(Vec(box.size.x - 15, 365)));
  117. addParam(ParamWidget::create<SonusKnob>(Vec(20, 64), module, Addiction::OCTAVE, -3.0, 3.0, 0.0));
  118. addInput(Port::create<PJ301MPort>(Vec(25.5, 137), Port::INPUT, module, Addiction::CV_FREQ));
  119. addOutput(Port::create<PJ301MPort>(Vec(25.5, 277), Port::OUTPUT, module, Addiction::OUTPUT));
  120. for (unsigned int a = 0; a < Addiction::NUM_PARAMS - 1; a++)
  121. {
  122. addParam(ParamWidget::create<SonusKnob>(Vec(150 + (50 * (a % 4)), 64 + (70 * floorf(a * 0.25))), module, a + 1, 0.0, 1.0, def_amps[(int)(a % 4)]));
  123. addInput(Port::create<PJ301MPort>(Vec(155.5 + (50 * (a % 4)), 102 + (70 * floorf(a * 0.25))), Port::INPUT, module, a + 1));
  124. }
  125. }
  126. } // namespace rack_plugin_SonusModular
  127. using namespace rack_plugin_SonusModular;
  128. RACK_PLUGIN_MODEL_INIT(SonusModular, Addiction) {
  129. Model *modelAddiction = Model::create<Addiction, AddictionWidget>("Sonus Modular", "Addiction", "Addiction | Additive Oscillator", OSCILLATOR_TAG);
  130. return modelAddiction;
  131. }