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.

197 lines
5.3KB

  1. ///////////////////////////////////////////////////
  2. //
  3. // Dual Counter - VCV Module
  4. //
  5. // Strum 2017
  6. // Thanks to ML for the diaplay code
  7. //
  8. ///////////////////////////////////////////////////
  9. #include "mental.hpp"
  10. #include "dsp/digital.hpp"
  11. #include <sstream>
  12. #include <iomanip>
  13. namespace rack_plugin_mental {
  14. struct MentalCounters : Module {
  15. enum ParamIds {
  16. RST_BUTTON,
  17. COUNT_NUM_PARAM,
  18. RST_BUTTON_2,
  19. COUNT_NUM_PARAM_2,
  20. NUM_PARAMS
  21. };
  22. enum InputIds {
  23. CLK_IN,
  24. RESET_IN,
  25. CLK_IN_2,
  26. RESET_IN_2,
  27. NUM_INPUTS
  28. };
  29. enum OutputIds {
  30. OUTPUT,
  31. OUTPUT_2,
  32. NUM_OUTPUTS
  33. };
  34. SchmittTrigger clock_trigger;
  35. SchmittTrigger reset_trigger;
  36. int count_limit = 0;
  37. int count = 0;
  38. SchmittTrigger clock_trigger_2;
  39. SchmittTrigger reset_trigger_2;
  40. int count_limit_2 = 0;
  41. int count_2 = 0;
  42. MentalCounters();
  43. void step() override;
  44. };
  45. MentalCounters::MentalCounters()
  46. {
  47. params.resize(NUM_PARAMS);
  48. inputs.resize(NUM_INPUTS);
  49. outputs.resize(NUM_OUTPUTS);
  50. }
  51. void MentalCounters::step()
  52. {
  53. count_limit = round(params[COUNT_NUM_PARAM].value);
  54. count_limit_2 = round(params[COUNT_NUM_PARAM_2].value);
  55. bool reset = false;
  56. bool reset_2 = false;
  57. if (reset_trigger.process(params[RST_BUTTON].value) || (reset_trigger.process(inputs[RESET_IN].value)))
  58. {
  59. reset = true;
  60. count = 0;
  61. outputs[OUTPUT].value = 0;
  62. }
  63. if (reset == false)
  64. {
  65. if (clock_trigger.process(inputs[CLK_IN].value) && count <= count_limit)
  66. count++;
  67. }
  68. if (count == count_limit) outputs[OUTPUT].value = 10.0;
  69. if (count > count_limit)
  70. {
  71. count = 0;
  72. outputs[OUTPUT].value = 0;
  73. }
  74. ///////////// counter 2
  75. if (reset_trigger_2.process(params[RST_BUTTON_2].value) || (reset_trigger_2.process(inputs[RESET_IN_2].value)))
  76. {
  77. reset_2 = true;
  78. count_2 = 0;
  79. outputs[OUTPUT_2].value = 0;
  80. }
  81. if (reset_2 == false)
  82. {
  83. if (clock_trigger_2.process(inputs[CLK_IN_2].value) && count_2 <= count_limit_2)
  84. count_2++;
  85. }
  86. if (count_2 == count_limit_2) outputs[OUTPUT_2].value = 10.0;
  87. if (count_2 > count_limit_2)
  88. {
  89. count_2 = 0;
  90. outputs[OUTPUT_2].value = 0;
  91. }
  92. }
  93. ////////////////////////////////////
  94. struct NumberDisplayWidget3 : TransparentWidget {
  95. int *value;
  96. std::shared_ptr<Font> font;
  97. NumberDisplayWidget3() {
  98. font = Font::load(assetPlugin(plugin, "res/Segment7Standard.ttf"));
  99. };
  100. void draw(NVGcontext *vg) override
  101. {
  102. // Background
  103. NVGcolor backgroundColor = nvgRGB(0x00, 0x00, 0x00);
  104. NVGcolor StrokeColor = nvgRGB(0x00, 0x47, 0x7e);
  105. nvgBeginPath(vg);
  106. nvgRoundedRect(vg, -1.0, -1.0, box.size.x+2, box.size.y+2, 4.0);
  107. nvgFillColor(vg, StrokeColor);
  108. nvgFill(vg);
  109. nvgBeginPath(vg);
  110. nvgRoundedRect(vg, 0.0, 0.0, box.size.x, box.size.y, 4.0);
  111. nvgFillColor(vg, backgroundColor);
  112. nvgFill(vg);
  113. // text
  114. nvgFontSize(vg, 18);
  115. nvgFontFaceId(vg, font->handle);
  116. nvgTextLetterSpacing(vg, 2.5);
  117. std::stringstream to_display;
  118. to_display << std::setw(3) << *value;
  119. Vec textPos = Vec(6.0f, 17.0f);
  120. NVGcolor textColor = nvgRGB(0x00, 0x47, 0x7e);
  121. nvgFillColor(vg, textColor);
  122. nvgText(vg, textPos.x, textPos.y, to_display.str().c_str(), NULL);
  123. }
  124. };
  125. //////////////////////////////////
  126. struct MentalCountersWidget : ModuleWidget {
  127. MentalCountersWidget(MentalCounters *module);
  128. };
  129. MentalCountersWidget::MentalCountersWidget(MentalCounters *module) : ModuleWidget(module)
  130. {
  131. setPanel(SVG::load(assetPlugin(plugin, "res/MentalCounters.svg")));
  132. int group_offset = 190;
  133. addParam(ParamWidget::create<MedKnob>(Vec(2, 20), module, MentalCounters::COUNT_NUM_PARAM, 0.0, 32.0, 0.0));
  134. addInput(Port::create<GateInPort>(Vec(3, 90), Port::INPUT, module, MentalCounters::CLK_IN));
  135. addInput(Port::create<GateInPort>(Vec(3, 120), Port::INPUT, module, MentalCounters::RESET_IN));
  136. addParam(ParamWidget::create<LEDButton>(Vec(5, 145), module, MentalCounters::RST_BUTTON, 0.0, 1.0, 0.0));
  137. addOutput(Port::create<GateOutPort>(Vec(33, 90), Port::OUTPUT, module, MentalCounters::OUTPUT));
  138. NumberDisplayWidget3 *display = new NumberDisplayWidget3();
  139. display->box.pos = Vec(5,50);
  140. display->box.size = Vec(50, 20);
  141. display->value = &module->count_limit;
  142. addChild(display);
  143. /////////// counter 2
  144. addParam(ParamWidget::create<MedKnob>(Vec(2, 20 + group_offset), module, MentalCounters::COUNT_NUM_PARAM_2, 0.0, 32.0, 0.0));
  145. addInput(Port::create<GateInPort>(Vec(3, 90 + group_offset), Port::INPUT, module, MentalCounters::CLK_IN_2));
  146. addInput(Port::create<GateInPort>(Vec(3, 120 + group_offset), Port::INPUT, module, MentalCounters::RESET_IN_2));
  147. addParam(ParamWidget::create<LEDButton>(Vec(5, 145 + group_offset), module, MentalCounters::RST_BUTTON_2, 0.0, 1.0, 0.0));
  148. addOutput(Port::create<GateOutPort>(Vec(33, 90 + group_offset), Port::OUTPUT, module, MentalCounters::OUTPUT_2));
  149. NumberDisplayWidget3 *display_2 = new NumberDisplayWidget3();
  150. display_2->box.pos = Vec(5,50 + group_offset);
  151. display_2->box.size = Vec(50, 20);
  152. display_2->value = &module->count_limit_2;
  153. addChild(display_2);
  154. }
  155. } // namespace rack_plugin_mental
  156. using namespace rack_plugin_mental;
  157. RACK_PLUGIN_MODEL_INIT(mental, MentalCounters) {
  158. Model *modelMentalCounters = Model::create<MentalCounters, MentalCountersWidget>("mental", "MentalCounters", "Counters", UTILITY_TAG);
  159. return modelMentalCounters;
  160. }