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.

186 lines
5.9KB

  1. #include "dsp/digital.hpp"
  2. #include <iostream>
  3. #include "RJModules.hpp"
  4. namespace rack_plugin_RJModules {
  5. struct LowFrequencyOscillator {
  6. float phase = 0.0;
  7. float pw = 0.5;
  8. float freq = 1.0;
  9. bool offset = false;
  10. bool invert = false;
  11. SchmittTrigger resetTrigger;
  12. LowFrequencyOscillator() {}
  13. void setPitch(float pitch) {
  14. pitch = fminf(pitch, 8.0);
  15. freq = powf(2.0, pitch);
  16. }
  17. float getFreq() {
  18. return freq;
  19. }
  20. void setReset(float reset) {
  21. if (resetTrigger.process(reset)) {
  22. phase = 0.0;
  23. }
  24. }
  25. void step(float dt) {
  26. float deltaPhase = fminf(freq * dt, 0.5);
  27. phase += deltaPhase;
  28. if (phase >= 1.0)
  29. phase -= 1.0;
  30. }
  31. float sin() {
  32. if (offset)
  33. return 1.0 - cosf(2*M_PI * phase) * (invert ? -1.0 : 1.0);
  34. else
  35. return sinf(2*M_PI * phase) * (invert ? -1.0 : 1.0);
  36. }
  37. float saw(float x) {
  38. return 2.0 * (x - roundf(x));
  39. }
  40. float saw() {
  41. if (offset)
  42. return invert ? 2.0 * (1.0 - phase) : 2.0 * phase;
  43. else
  44. return saw(phase) * (invert ? -1.0 : 1.0);
  45. }
  46. float light() {
  47. return sinf(2*M_PI * phase);
  48. }
  49. };
  50. struct Riser : Module {
  51. enum ParamIds {
  52. OFFSET_PARAM,
  53. INVERT_PARAM,
  54. FREQ_PARAM,
  55. FREQ_PARAM_2,
  56. DETUNE_PARAM,
  57. SHAPE_PARAM,
  58. THREE_OSC_PARAM,
  59. NUM_PARAMS
  60. };
  61. enum InputIds {
  62. FREQ_CV_INPUT,
  63. FREQ_CV_INPUT_2,
  64. SHAPE_CV_INPUT,
  65. RESET_INPUT,
  66. PW_INPUT,
  67. NUM_INPUTS
  68. };
  69. enum OutputIds {
  70. SAW_OUTPUT,
  71. NUM_OUTPUTS
  72. };
  73. enum LightIds {
  74. PHASE_POS_LIGHT,
  75. PHASE_NEG_LIGHT,
  76. PHASE_POS_LIGHT2,
  77. PHASE_NEG_LIGHT2,
  78. NUM_LIGHTS
  79. };
  80. LowFrequencyOscillator oscillator;
  81. LowFrequencyOscillator oscillator2;
  82. float osc0_root = 5.0;
  83. float max = 10.0;
  84. float min = 6.0;
  85. float r_step = .00003;
  86. Riser() : Module(NUM_PARAMS, NUM_INPUTS, NUM_OUTPUTS, NUM_LIGHTS) {}
  87. void step() override;
  88. };
  89. void Riser::step() {
  90. if (osc0_root >= max){
  91. osc0_root = min;
  92. } else {
  93. osc0_root = osc0_root + r_step;
  94. }
  95. oscillator.setPitch(osc0_root);
  96. //oscillator.setPitch(-4.0);
  97. oscillator.step(0.3 / engineGetSampleRate());
  98. // float root_pitch2 = params[FREQ_PARAM_2].value * clamp(inputs[FREQ_CV_INPUT_2].normalize(10.0f) / 10.0f, 0.0f, 1.0f);
  99. // oscillator2.setPitch(root_pitch2);
  100. // oscillator2.offset = (params[OFFSET_PARAM].value > 0.0);
  101. // oscillator2.invert = (params[INVERT_PARAM].value <= 0.0);
  102. // oscillator2.step(0.3 / engineGetSampleRate());
  103. // oscillator2.setReset(inputs[RESET_INPUT].value);
  104. // float root_pitch = params[FREQ_PARAM].value * clamp(inputs[FREQ_CV_INPUT].normalize(10.0f) / 10.0f, 0.0f, 1.0f) * clamp(oscillator2.sin(), 0.0f, 1.0f);
  105. // oscillator.setPitch(root_pitch);
  106. // oscillator.offset = (params[OFFSET_PARAM].value > 0.0);
  107. // oscillator.invert = (params[INVERT_PARAM].value <= 0.0);
  108. // oscillator.step(0.3 / engineGetSampleRate());
  109. // oscillator.setReset(inputs[RESET_INPUT].value);
  110. //float shape_percent = params[SHAPE_PARAM].value * clamp(inputs[SHAPE_CV_INPUT].normalize(10.0f) / 10.0f, 0.0f, 1.0f);
  111. //float mixed = ((oscillator.sin() * shape_percent)) + (oscillator.saw() * (1-shape_percent));
  112. float mixed = oscillator.saw();
  113. // This is from 0 to 2V. Should be mapped?
  114. outputs[SAW_OUTPUT].value = mixed;
  115. lights[PHASE_POS_LIGHT].setBrightnessSmooth(fmaxf(0.0, oscillator.light()));
  116. lights[PHASE_NEG_LIGHT].setBrightnessSmooth(fmaxf(0.0, -oscillator.light()));
  117. lights[PHASE_POS_LIGHT2].setBrightnessSmooth(fmaxf(0.0, oscillator2.light()));
  118. lights[PHASE_NEG_LIGHT2].setBrightnessSmooth(fmaxf(0.0, -oscillator2.light()));
  119. }
  120. struct RiserWidget: ModuleWidget {
  121. RiserWidget(Riser *module);
  122. };
  123. RiserWidget::RiserWidget(Riser *module) : ModuleWidget(module) {
  124. box.size = Vec(15*10, 380);
  125. {
  126. SVGPanel *panel = new SVGPanel();
  127. panel->box.size = box.size;
  128. panel->setBackground(SVG::load(assetPlugin(plugin, "res/Riser.svg")));
  129. addChild(panel);
  130. }
  131. addChild(Widget::create<ScrewSilver>(Vec(15, 0)));
  132. addChild(Widget::create<ScrewSilver>(Vec(box.size.x-30, 0)));
  133. addChild(Widget::create<ScrewSilver>(Vec(15, 365)));
  134. addChild(Widget::create<ScrewSilver>(Vec(box.size.x-30, 365)));
  135. addParam(ParamWidget::create<CKSS>(Vec(119, 100), module, Riser::OFFSET_PARAM, 0.0, 1.0, 1.0));
  136. addParam(ParamWidget::create<CKSS>(Vec(119, 180), module, Riser::INVERT_PARAM, 0.0, 1.0, 1.0));
  137. addParam(ParamWidget::create<RoundHugeBlackKnob>(Vec(47, 61), module, Riser::FREQ_PARAM, 0.0, 8.0, 5.0));
  138. addParam(ParamWidget::create<RoundHugeBlackKnob>(Vec(47, 143), module, Riser::FREQ_PARAM_2, 0.0, 8.0, 0.5));
  139. addParam(ParamWidget::create<RoundHugeBlackKnob>(Vec(47, 228), module, Riser::SHAPE_PARAM, 0.0, 1.0, 1.0));
  140. addInput(Port::create<PJ301MPort>(Vec(22, 100), Port::INPUT, module, Riser::FREQ_CV_INPUT));
  141. addInput(Port::create<PJ301MPort>(Vec(22, 190), Port::INPUT, module, Riser::FREQ_CV_INPUT_2));
  142. addInput(Port::create<PJ301MPort>(Vec(22, 270), Port::INPUT, module, Riser::SHAPE_CV_INPUT));
  143. addInput(Port::create<PJ301MPort>(Vec(38, 310), Port::INPUT, module, Riser::RESET_INPUT));
  144. addOutput(Port::create<PJ301MPort>(Vec(100, 310), Port::OUTPUT, module, Riser::SAW_OUTPUT));
  145. addChild(ModuleLightWidget::create<SmallLight<GreenRedLight>>(Vec(99, 60), module, Riser::PHASE_POS_LIGHT));
  146. addChild(ModuleLightWidget::create<SmallLight<GreenRedLight>>(Vec(99, 140), module, Riser::PHASE_POS_LIGHT2));
  147. }
  148. } // namespace rack_plugin_RJModules
  149. using namespace rack_plugin_RJModules;
  150. RACK_PLUGIN_MODEL_INIT(RJModules, Riser) {
  151. Model *modelRiser = Model::create<Riser, RiserWidget>("RJModules", "Riser", "[GEN] Riser", LFO_TAG);
  152. return modelRiser;
  153. }