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.

309 lines
11KB

  1. #include "LFSR.hpp"
  2. #include "dsp/digital.hpp"
  3. namespace rack_plugin_alto777_LFSR {
  4. struct a7Utility : Module {
  5. enum ParamIds {
  6. ENUMS(MBUTTON_PARAM, 2),
  7. ENUMS(MMODE_PARAM, 2),
  8. ENUMS(CCTRL_PARAM, 2),
  9. ENUMS(CAMP_PARAM, 2),
  10. ENUMS(CRANGE_PARAM, 2),
  11. ENUMS(WIDTH_PARAM, 2),
  12. NUM_PARAMS
  13. };
  14. enum InputIds {
  15. ENUMS(CCTRL_INPUT, 2),
  16. ENUMS(EDGE_INPUT, 2),
  17. NUM_INPUTS
  18. };
  19. enum OutputIds {
  20. ENUMS(MGATE_OUTPUT, 2),
  21. ENUMS(MTRIG_OUTPUT, 2),
  22. ENUMS(COUT_OUTPUT, 2),
  23. ENUMS(RISE_OUTPUT, 2),
  24. ENUMS(FALL_OUTPUT, 2),
  25. ENUMS(CLOCK_INV_OUTPUT, 2),
  26. NUM_OUTPUTS
  27. };
  28. enum LightIds {
  29. ENUMS(M_LIGHT, 2),
  30. ENUMS(RISE_LIGHT, 2),
  31. ENUMS(FALL_LIGHT, 2),
  32. NUM_LIGHTS
  33. };
  34. /* buttons */
  35. SchmittTrigger manualButton[2];
  36. PulseGenerator manualTriggerPulse[2];
  37. bool mState[2] = {0, 0};
  38. /* constants - no variables */
  39. /* edge detector */
  40. bool signalState[2] = {0, 0};
  41. PulseGenerator risingEdgePulse[2];
  42. PulseGenerator fallingEdgePulse[2];
  43. PulseGenerator risingEdgeLampStab[2];
  44. PulseGenerator fallingEdgeLampStab[2];
  45. a7Utility() : Module(NUM_PARAMS, NUM_INPUTS, NUM_OUTPUTS, NUM_LIGHTS) {}
  46. void step() override;
  47. void onReset() override {
  48. mState[0] = 0;
  49. };
  50. /**/
  51. json_t *toJson() override {
  52. json_t *rootJ = json_object();
  53. json_t *mstate = json_array();
  54. for (int i = 0; i < 2; i++)
  55. json_array_insert_new(mstate, i, json_integer((int) mState[i]));
  56. json_object_set_new(rootJ, "mstate", mstate);
  57. return rootJ;
  58. }
  59. void fromJson(json_t *rootJ) override {
  60. json_t *mstate = json_object_get(rootJ, "mstate");
  61. if (mstate) {
  62. for (int i = 0; i < 2; i++) {
  63. json_t *wha = json_array_get(mstate, i);
  64. if (wha)
  65. mState[i] = json_integer_value(wha); // warning C4800: 'json_int_t': forcing value to bool 'true' or 'false' (performance warning)
  66. }
  67. }
  68. }
  69. /**/
  70. };
  71. void a7Utility::step() {
  72. float deltaTime = 1.0 / engineGetSampleRate();
  73. /* manual button to gate / trigger section */
  74. for (int i = 0; i < 2; i++) {
  75. // mode 0 = momentary 1 = toggle
  76. bool mode = params[MMODE_PARAM + i].value > 0.0f;
  77. if (!mode)
  78. mState[i] = 0;
  79. if (manualButton[i].process(params[MBUTTON_PARAM + i].value)) {
  80. manualTriggerPulse[i].trigger(0.001);
  81. if (mode) mState[i] ^= 1;
  82. }
  83. bool bState = manualButton[i].isHigh();
  84. if (mState[i] || (!mode && bState)) {
  85. outputs[MGATE_OUTPUT + i].value = 10.0f;
  86. lights[M_LIGHT + i].value = 1.0f;
  87. }
  88. else {
  89. outputs[MGATE_OUTPUT + i].value = 0.0f;
  90. lights[M_LIGHT + i].value = 0.0;
  91. }
  92. outputs[MTRIG_OUTPUT + i].value = manualTriggerPulse[i].process(deltaTime) ? 10.0f : 0.0;
  93. }
  94. /* constant from knob switched by control */
  95. for (int i = 0; i < 2; i++) {
  96. bool isOn = params[CCTRL_PARAM + i].value <= 0.0f;
  97. bool rangeX10 = params[CRANGE_PARAM + i].value <= 0.0f;
  98. bool extControl = inputs[CCTRL_INPUT + i].active;
  99. bool nonZero = 0;
  100. if (isOn) nonZero = 1;
  101. else {
  102. if (extControl) {
  103. if (inputs[CCTRL_INPUT + i].value > 0.0f) nonZero = 1;
  104. }
  105. else nonZero = 1;
  106. }
  107. outputs[COUT_OUTPUT + i].value = nonZero ? (params[CAMP_PARAM + i].value * (rangeX10 ? 10.0f : 1.0f)) : 0;
  108. }
  109. /* generate pulse on clock edges */
  110. for (int i = 0; i < 2; i++) {
  111. if (signalState[i]) {
  112. if (inputs[EDGE_INPUT + i].value < 0.3f) {
  113. signalState[i] = 0;
  114. fallingEdgePulse[i].trigger(0.001); // (params[WIDTH_PARAM + i].value <= 0.0f ? 0.005f : 0.0005f);
  115. fallingEdgeLampStab[i].trigger(0.25); // (params[WIDTH_PARAM + i].value <= 0.0f ? 0.005f : 0.0005f);
  116. }
  117. }
  118. else {
  119. if (inputs[EDGE_INPUT + i].value > 0.7f) {
  120. signalState[i] = 1;
  121. risingEdgePulse[i].trigger(0.001); // (params[WIDTH_PARAM + i].value <= 0.0f ? 0.005f : 0.0005f);
  122. risingEdgeLampStab[i].trigger(0.25); // params[WIDTH_PARAM + i].value <= 0.0f ? 0.33f : 0.1f);
  123. }
  124. }
  125. outputs[RISE_OUTPUT + i].value = risingEdgePulse[i].process(deltaTime) ? 10.0f : 0.0;
  126. outputs[FALL_OUTPUT + i].value = fallingEdgePulse[i].process(deltaTime) ? 10.0f : 0.0;
  127. outputs[CLOCK_INV_OUTPUT + i].value = signalState[i] ? 0.0f : 10.0f;
  128. //! outputs[CLOCK_INV_OUTPUT + i].value = (inputs[EDGE_INPUT + i].value < 0.3f) ? 10.0f : 0.0f;
  129. lights[RISE_LIGHT + i].value = risingEdgeLampStab[i].process(deltaTime) ? 1.0f : 0.0;
  130. lights[FALL_LIGHT + i].value = fallingEdgeLampStab[i].process(deltaTime) ? 1.0f : 0.0;
  131. }
  132. }
  133. /* why oh */
  134. struct myCKSS : SVGSwitch, ToggleSwitch {
  135. myCKSS() {
  136. addFrame(SVG::load(assetPlugin(plugin, "res/myCKSS_0.svg")));
  137. addFrame(SVG::load(assetPlugin(plugin, "res/myCKSS_1.svg")));
  138. }
  139. };
  140. struct myHCKSS : SVGSwitch, ToggleSwitch {
  141. myHCKSS() {
  142. addFrame(SVG::load(assetPlugin(plugin, "res/myHCKSS_0.svg")));
  143. addFrame(SVG::load(assetPlugin(plugin, "res/myHCKSS_1.svg")));
  144. }
  145. };
  146. struct HexCapScrew0 : SVGScrew {
  147. HexCapScrew0() {
  148. sw->setSVG(SVG::load(assetPlugin(plugin, "res/HexCapScrewSilver.svg")));
  149. box.size = sw->box.size;
  150. }
  151. };
  152. struct HexCapScrew1 : SVGScrew {
  153. HexCapScrew1() {
  154. sw->setSVG(SVG::load(assetPlugin(plugin, "res/HexCapScrewSilver9.svg")));
  155. box.size = sw->box.size;
  156. }
  157. };
  158. struct HexCapScrew2 : SVGScrew {
  159. HexCapScrew2() {
  160. sw->setSVG(SVG::load(assetPlugin(plugin, "res/HexCapScrewSilver13.svg")));
  161. box.size = sw->box.size;
  162. }
  163. };
  164. struct HexCapScrew3 : SVGScrew {
  165. HexCapScrew3() {
  166. sw->setSVG(SVG::load(assetPlugin(plugin, "res/HexCapScrewSilver21.svg")));
  167. box.size = sw->box.size;
  168. }
  169. };
  170. struct a7UtilityWidget : ModuleWidget {
  171. a7UtilityWidget(a7Utility *module) : ModuleWidget(module) {
  172. setPanel(SVG::load(assetPlugin(plugin, "res/a7Utility.svg")));
  173. /*
  174. addChild(Widget::create<ScrewSilver>(Vec(0, 0)));
  175. addChild(Widget::create<ScrewSilver>(Vec(box.size.x - RACK_GRID_WIDTH, 0)));
  176. addChild(Widget::create<ScrewSilver>(Vec(0, RACK_GRID_HEIGHT - RACK_GRID_WIDTH)));
  177. addChild(Widget::create<ScrewSilver>(Vec(box.size.x - RACK_GRID_WIDTH, RACK_GRID_HEIGHT - RACK_GRID_WIDTH)));
  178. */
  179. addChild(Widget::create<HexCapScrew3>(Vec(0, 0)));
  180. addChild(Widget::create<HexCapScrew2>(Vec(box.size.x - RACK_GRID_WIDTH, 0)));
  181. addChild(Widget::create<HexCapScrew0>(Vec(0, RACK_GRID_HEIGHT - RACK_GRID_WIDTH)));
  182. addChild(Widget::create<HexCapScrew1>(Vec(box.size.x - RACK_GRID_WIDTH, RACK_GRID_HEIGHT - RACK_GRID_WIDTH)));
  183. addParam(ParamWidget::create<LEDBezel>(mm2px(Vec(0.798, 13.042)), module, a7Utility::MBUTTON_PARAM + 0, 0.0, 1.0, 0.0));
  184. addParam(ParamWidget::create<LEDBezel>(mm2px(Vec(25.851, 13.042)), module, a7Utility::MBUTTON_PARAM + 1, 0.0, 1.0, 0.0));
  185. addParam(ParamWidget::create<myCKSS>(mm2px(Vec(13.949, 14.059)), module, a7Utility::MMODE_PARAM + 0, 0.0, 1.0, 0.0));
  186. addParam(ParamWidget::create<myCKSS>(mm2px(Vec(39.003, 14.059)), module, a7Utility::MMODE_PARAM + 1, 0.0, 1.0, 0.0));
  187. addOutput(Port::create<PJ301MPort>(mm2px(Vec(0.37, 23.495)), Port::OUTPUT, module, a7Utility::MTRIG_OUTPUT + 0));
  188. addOutput(Port::create<PJ301MPort>(mm2px(Vec(11.623, 23.495)), Port::OUTPUT, module, a7Utility::MGATE_OUTPUT + 0));
  189. addOutput(Port::create<PJ301MPort>(mm2px(Vec(25.424, 23.495)), Port::OUTPUT, module, a7Utility::MTRIG_OUTPUT + 1));
  190. addOutput(Port::create<PJ301MPort>(mm2px(Vec(36.677, 23.495)), Port::OUTPUT, module, a7Utility::MGATE_OUTPUT + 1));
  191. addChild(ModuleLightWidget::create<LargeLight<RedLight>>(mm2px(Vec(1.958, 14.2)), module, a7Utility::M_LIGHT + 0 ));
  192. addChild(ModuleLightWidget::create<LargeLight<RedLight>>(mm2px(Vec(27.012, 14.2)), module, a7Utility::M_LIGHT + 1));
  193. addParam(ParamWidget::create<myHCKSS>(mm2px(Vec(23.806, 51.25)), module, a7Utility::CCTRL_PARAM + 0, 0.0, 1.0, 0.0));
  194. addParam(ParamWidget::create<RoundBlackKnob>(mm2px(Vec(9.682, 53.452)), module, a7Utility::CAMP_PARAM + 0, 0.0, 1.0, 0.0));
  195. addParam(ParamWidget::create<myCKSS>(mm2px(Vec(2.208, 55.72)), module, a7Utility::CRANGE_PARAM + 0, 0.0, 1.0, 0.0));
  196. addParam(ParamWidget::create<myHCKSS>(mm2px(Vec(23.806, 70.872)), module, a7Utility::CCTRL_PARAM + 1, 0.0, 1.0, 0.0));
  197. addParam(ParamWidget::create<RoundBlackKnob>(mm2px(Vec(9.682, 73.073)), module, a7Utility::CAMP_PARAM + 1, 0.0, 1.0, 0.0));
  198. addParam(ParamWidget::create<myCKSS>(mm2px(Vec(2.208, 75.341)), module, a7Utility::CRANGE_PARAM + 1, 0.0, 1.0, 0.0));
  199. addInput(Port::create<PJ301MPort>(mm2px(Vec(22.359, 57.296)), Port::INPUT, module, a7Utility::CCTRL_INPUT + 0));
  200. addInput(Port::create<PJ301MPort>(mm2px(Vec(22.359, 76.917)), Port::INPUT, module, a7Utility::CCTRL_INPUT + 1));
  201. addOutput(Port::create<PJ301MPort>(mm2px(Vec(34.118, 54.272)), Port::OUTPUT, module, a7Utility::COUT_OUTPUT + 0));
  202. addOutput(Port::create<PJ301MPort>(mm2px(Vec(34.118, 73.894)), Port::OUTPUT, module, a7Utility::COUT_OUTPUT + 1));
  203. // addParam(ParamWidget::create<myCKSS>(mm2px(Vec(36.288, 103.218)), module, a7Utility::WIDTH_PARAM + 0, 0.0, 1.0, 0.0));
  204. // addParam(ParamWidget::create<myCKSS>(mm2px(Vec(36.288, 115.388)), module, a7Utility::WIDTH_PARAM + 1, 0.0, 1.0, 0.0));
  205. addInput(Port::create<PJ301MPort>(mm2px(Vec(4.113, 101.77)), Port::INPUT, module, a7Utility::EDGE_INPUT + 0));
  206. addInput(Port::create<PJ301MPort>(mm2px(Vec(4.113, 113.7)), Port::INPUT, module, a7Utility::EDGE_INPUT + 1));
  207. addOutput(Port::create<PJ301MPort>(mm2px(Vec(14.184, 101.77)), Port::OUTPUT, module, a7Utility::RISE_OUTPUT + 0));
  208. addOutput(Port::create<PJ301MPort>(mm2px(Vec(23.701, 101.77)), Port::OUTPUT, module, a7Utility::FALL_OUTPUT + 0));
  209. addOutput(Port::create<PJ301MPort>(mm2px(Vec(34.118, 101.77)), Port::OUTPUT, module, a7Utility::CLOCK_INV_OUTPUT + 0));
  210. addOutput(Port::create<PJ301MPort>(mm2px(Vec(14.184, 113.7)), Port::OUTPUT, module, a7Utility::RISE_OUTPUT + 1));
  211. addOutput(Port::create<PJ301MPort>(mm2px(Vec(23.701, 113.7)), Port::OUTPUT, module, a7Utility::FALL_OUTPUT + 1));
  212. addOutput(Port::create<PJ301MPort>(mm2px(Vec(34.118, 113.7)), Port::OUTPUT, module, a7Utility::CLOCK_INV_OUTPUT + 1));
  213. addChild(ModuleLightWidget::create<MediumLight<BlueLight>>(mm2px(Vec(16.773, 97.812)), module, a7Utility::RISE_LIGHT + 0));
  214. // addChild(ModuleLightWidget::create<MediumLight<YellowLight>>(mm2px(Vec(16.773, 97.812)), module, a7Utility::RISE_LIGHT + 0));
  215. addChild(ModuleLightWidget::create<MediumLight<YellowLight>>(mm2px(Vec(26.291, 97.812)), module, a7Utility::FALL_LIGHT + 0));
  216. addChild(ModuleLightWidget::create<MediumLight<BlueLight>>(mm2px(Vec(16.773, 122.818)), module, a7Utility::RISE_LIGHT + 1));
  217. // addChild(ModuleLightWidget::create<MediumLight<YellowLight>>(mm2px(Vec(16.773, 122.818)), module, a7Utility::RISE_LIGHT + 1));
  218. addChild(ModuleLightWidget::create<MediumLight<YellowLight>>(mm2px(Vec(26.291, 122.818)), module, a7Utility::FALL_LIGHT + 1));
  219. }
  220. };
  221. } // namespace rack_plugin_alto777_LFSR
  222. using namespace rack_plugin_alto777_LFSR;
  223. RACK_PLUGIN_MODEL_INIT(alto777_LFSR, a7Utility) {
  224. Model *modela7Utility = Model::create<a7Utility, a7UtilityWidget>("alto777_LFSR", "a7Utility", "a7Utility VIS", UTILITY_TAG);
  225. return modela7Utility;
  226. }