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.

396 lines
8.7KB

  1. #include "Autodafe.hpp"
  2. #include "dsp/digital.hpp"
  3. namespace rack_plugin_Autodafe {
  4. #define FONT_FILE assetPlugin(plugin, "res/Segment7Standard.ttf")
  5. struct BPMClock : Module {
  6. enum ParamIds {
  7. BPM,BTNUP, BTNDWN,
  8. BTNUPDEC, BTNDWNDEC,
  9. NUM_PARAMS
  10. };
  11. enum InputIds {
  12. NUM_INPUTS
  13. };
  14. enum OutputIds {
  15. OUT_1,
  16. OUT_2,
  17. OUT_3,
  18. OUT_4,
  19. OUT_8,
  20. OUT_12,
  21. OUT_16,
  22. OUT_24,
  23. OUT_1_1,
  24. OUT_1_2,
  25. OUT_1_3,
  26. OUT_1_4,
  27. OUT_1_8,
  28. OUT_1_12,
  29. OUT_1_16,
  30. OUT_1_24,
  31. NUM_OUTPUTS
  32. };
  33. enum LightIds {
  34. CLOCK_LIGHT,
  35. NUM_LIGHTS
  36. };
  37. BPMClock() : Module(NUM_PARAMS, NUM_INPUTS, NUM_OUTPUTS, NUM_LIGHTS) {}
  38. void step();
  39. json_t *toJson() override {
  40. json_t *rootJ = json_object();
  41. json_t *bpmintJ = json_integer((int) bpmint);
  42. json_object_set_new(rootJ, "bpmint", bpmintJ);
  43. json_t *bpmdecJ = json_integer((int) bpmdec);
  44. json_object_set_new(rootJ, "bpmdec", bpmdecJ);
  45. return rootJ;
  46. }
  47. void fromJson(json_t *rootJ) override {
  48. // running
  49. json_t *bpmintJ = json_object_get(rootJ, "bpmint");
  50. if (bpmintJ)
  51. bpmint= json_integer_value(bpmintJ);
  52. json_t *bpmdecJ = json_object_get(rootJ, "bpmdec");
  53. if (bpmdecJ)
  54. bpmdec= json_integer_value(bpmdecJ);
  55. }
  56. void reset() override {
  57. bpmint=120;
  58. bpmdec=0;
  59. }
  60. void randomize() override {
  61. }
  62. float bpm;
  63. int bpmint=120;
  64. int bpmdec=0;
  65. SchmittTrigger btnup;
  66. SchmittTrigger btndwn;
  67. SchmittTrigger btnupdec;
  68. SchmittTrigger btndwndec;
  69. PulseGenerator pulse;
  70. float clock_phase = 0.f;
  71. uint32_t tick = UINT32_MAX;
  72. };
  73. void BPMClock::step() {
  74. if (btnup.process(params[BTNUP].value))
  75. {
  76. if (bpmint<240.0) {
  77. bpmint+=1;
  78. }
  79. else
  80. {
  81. bpmint=0;
  82. }
  83. }
  84. if (btndwn.process(params[BTNDWN].value))
  85. {
  86. if (bpmint>0) {
  87. bpmint-=1;
  88. }
  89. else
  90. {
  91. bpmint=240.0;
  92. }
  93. }
  94. if (btnupdec.process(params[BTNUPDEC].value))
  95. {
  96. if (bpmdec<9) {
  97. bpmdec+=1;
  98. }
  99. else
  100. {
  101. bpmdec=0;
  102. bpmint+=1;
  103. }
  104. }
  105. if (btndwndec.process(params[BTNDWNDEC].value))
  106. {
  107. if (bpmdec>0) {
  108. bpmdec-=1;
  109. }
  110. else
  111. {
  112. bpmdec=9;
  113. bpmint-=1;
  114. }
  115. }
  116. bpm=bpmint+bpmdec*0.1;
  117. //const float bpm = params[BPM].value;
  118. clock_phase += (bpm*4 / 60.f) / engineGetSampleRate() * 12;
  119. bool ticked = false;
  120. if(clock_phase >= 1.f) {
  121. ticked = true;
  122. if(++tick >= 1152u) tick = 0u;
  123. clock_phase -= 1.f;
  124. }
  125. if(ticked) {
  126. //DIVIDER
  127. outputs[OUT_1].value = !(tick % 48u)*5;
  128. outputs[OUT_2].value = !(tick % 96u)*5;
  129. outputs[OUT_3].value = !(tick % 144u)*5;
  130. outputs[OUT_4].value = !(tick % 192u)*5;
  131. outputs[OUT_8].value = !(tick % 384u)*5;
  132. outputs[OUT_12].value = !(tick % 576u)*5;
  133. outputs[OUT_16].value = !(tick % 768u)*5;
  134. outputs[OUT_24].value = !(tick % 1152u)*5;
  135. //MULTIPLIER
  136. outputs[OUT_1_1].value = !(tick % 48u)*5;
  137. outputs[OUT_1_2].value = !(tick % 24u)*5;
  138. outputs[OUT_1_3].value = !(tick % 36u)*5;
  139. outputs[OUT_1_4].value = !(tick % 12u)*5;
  140. outputs[OUT_1_8].value = !(tick % 6u)*5;
  141. outputs[OUT_1_12].value = !(tick % 4u)*5;
  142. outputs[OUT_1_16].value = !(tick % 3u)*5;
  143. outputs[OUT_1_24].value = !(tick % 2u)*5;
  144. } else {
  145. lights[CLOCK_LIGHT].value=0.0;
  146. //DIVIDER
  147. outputs[OUT_1].value = 0.f;
  148. outputs[OUT_2].value = 0.f;
  149. outputs[OUT_4].value = 0.f;
  150. outputs[OUT_8].value = 0.f;
  151. outputs[OUT_12].value = 0.f;
  152. outputs[OUT_16].value = 0.f;
  153. outputs[OUT_24].value = 0.f;
  154. //MULTIPLIER
  155. outputs[OUT_1_1].value = 0.f;
  156. outputs[OUT_1_2].value = 0.f;
  157. outputs[OUT_1_4].value = 0.f;
  158. outputs[OUT_1_8].value = 0.f;
  159. outputs[OUT_1_12].value = 0.f;
  160. outputs[OUT_1_16].value = 0.f;
  161. outputs[OUT_1_24].value = 0.f;
  162. }
  163. }
  164. struct BPMClockModelDisplay : TransparentWidget {
  165. int *valueint;
  166. int *valuedec;
  167. std::shared_ptr<Font> font;
  168. BPMClockModelDisplay() {
  169. font = Font::load(FONT_FILE);
  170. }
  171. void draw(NVGcontext *vg) {
  172. // Background
  173. NVGcolor backgroundColor = nvgRGB(0x20, 0x20, 0x20);
  174. NVGcolor borderColor = nvgRGB(0x10, 0x10, 0x10);
  175. nvgBeginPath(vg);
  176. nvgRoundedRect(vg, 0.0, 0.0, box.size.x, box.size.y, 5.0);
  177. nvgFillColor(vg, backgroundColor);
  178. nvgFill(vg);
  179. nvgStrokeWidth(vg, 1.0);
  180. nvgStrokeColor(vg, borderColor);
  181. nvgStroke(vg);
  182. nvgFontSize(vg, 24);
  183. nvgFontFaceId(vg, font->handle);
  184. nvgTextLetterSpacing(vg, 2.5);
  185. std::string to_displayint = std::to_string(*valueint);
  186. std::string to_displaydec = std::to_string(*valuedec);
  187. std::string to_display = to_displayint +to_displaydec;
  188. Vec textPos = Vec(5.0f, 27.0f);
  189. NVGcolor textColor = nvgRGB(0xdf, 0xd2, 0x2c);
  190. nvgFillColor(vg, nvgTransRGBA(textColor, 16));
  191. nvgText(vg, textPos.x, textPos.y, "~~~~", NULL);
  192. textColor = nvgRGB(0xda, 0xe9, 0x29);
  193. nvgFillColor(vg, nvgTransRGBA(textColor, 16));
  194. nvgText(vg, textPos.x, textPos.y, "\\\\\\\\", NULL);
  195. textColor = nvgRGB(0xf0, 0x00, 0x00);
  196. nvgFillColor(vg, textColor);
  197. std::string z;
  198. if(to_displayint.length()==1){z="00"+to_displayint+to_displaydec;}
  199. else if(to_displayint.length()==2){z="0"+to_displayint+to_displaydec;}
  200. else {z=to_displayint+to_displaydec;}
  201. nvgText(vg, textPos.x, textPos.y, z.c_str(), NULL);
  202. //nvgText(vg, textPos.x, textPos.y, to_display.c_str(), NULL);
  203. nvgText(vg, 41, textPos.y, ".", NULL);
  204. }
  205. };
  206. struct BPMClockWidget : ModuleWidget {
  207. BPMClockWidget(BPMClock *module);
  208. };
  209. BPMClockWidget::BPMClockWidget(BPMClock *module) : ModuleWidget(module) {
  210. box.size = Vec(150, 380);
  211. {
  212. SVGPanel *panel = new SVGPanel();
  213. panel->box.size = box.size;
  214. panel->setBackground(SVG::load(assetPlugin(plugin, "res/BPMClock.svg")));
  215. addChild(panel);
  216. }
  217. addChild(createScrew<ScrewSilver>(Vec(15, 0)));
  218. addChild(createScrew<ScrewSilver>(Vec(box.size.x-30, 0)));
  219. addChild(createScrew<ScrewSilver>(Vec(15, 365)));
  220. addChild(createScrew<ScrewSilver>(Vec(box.size.x-30, 365)));
  221. {
  222. BPMClockModelDisplay *display = new BPMClockModelDisplay();
  223. display->box.pos = Vec(35, 65);
  224. display->box.size = Vec(78, 36);
  225. display->valueint = &module->bpmint;
  226. display->valuedec = &module->bpmdec;
  227. addChild(display);
  228. }
  229. addChild(createLight<MediumLight<RedLight>>(Vec(70, 105), module, BPMClock::CLOCK_LIGHT));
  230. addParam(createParam<BtnUp>(Vec(15, 70), module, BPMClock::BTNUP, 0.0, 1.0, 0.0));
  231. addParam(createParam<BtnDwn>(Vec(15, 88), module, BPMClock::BTNDWN, 0.0, 1.0, 0.0));
  232. addParam(createParam<BtnUp>(Vec(120, 70), module, BPMClock::BTNUPDEC, 0.0, 1.0, 0.0));
  233. addParam(createParam<BtnDwn>(Vec(120, 88), module, BPMClock::BTNDWNDEC, 0.0, 1.0, 0.0));
  234. //addParam(createParam<Davies1900hBlackKnob>(Vec(27, 80), module, BPMClock::BPM, 30.0, 240.0, 120.0));
  235. addOutput(createOutput<PJ301MPort>(Vec(30, 115), module, BPMClock::OUT_1));
  236. addOutput(createOutput<PJ301MPort>(Vec(30, 145), module, BPMClock::OUT_2));
  237. addOutput(createOutput<PJ301MPort>(Vec(30, 175), module, BPMClock::OUT_3));
  238. addOutput(createOutput<PJ301MPort>(Vec(30, 205), module, BPMClock::OUT_4));
  239. addOutput(createOutput<PJ301MPort>(Vec(30, 235), module, BPMClock::OUT_8));
  240. addOutput(createOutput<PJ301MPort>(Vec(30, 265), module, BPMClock::OUT_12));
  241. addOutput(createOutput<PJ301MPort>(Vec(30, 295), module, BPMClock::OUT_16));
  242. addOutput(createOutput<PJ301MPort>(Vec(30, 325), module, BPMClock::OUT_24));
  243. addOutput(createOutput<PJ301MPort>(Vec(90, 115), module, BPMClock::OUT_1_1));
  244. addOutput(createOutput<PJ301MPort>(Vec(90, 145), module, BPMClock::OUT_1_2));
  245. addOutput(createOutput<PJ301MPort>(Vec(90, 175), module, BPMClock::OUT_1_3));
  246. addOutput(createOutput<PJ301MPort>(Vec(90, 205), module, BPMClock::OUT_1_4));
  247. addOutput(createOutput<PJ301MPort>(Vec(90, 235), module, BPMClock::OUT_1_8));
  248. addOutput(createOutput<PJ301MPort>(Vec(90, 265), module, BPMClock::OUT_1_12));
  249. addOutput(createOutput<PJ301MPort>(Vec(90, 295), module, BPMClock::OUT_1_16));
  250. addOutput(createOutput<PJ301MPort>(Vec(90, 325), module, BPMClock::OUT_1_24));
  251. }
  252. } // namespace rack_plugin_Autodafe
  253. using namespace rack_plugin_Autodafe;
  254. RACK_PLUGIN_MODEL_INIT(Autodafe, BPMClock) {
  255. return Model::create<BPMClock, BPMClockWidget>("Autodafe", "BPM Clock", "BPM Clock", UTILITY_TAG, CLOCK_TAG);
  256. }