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.

291 lines
11KB

  1. /*
  2. FlipOLogic
  3. clock divider and logic gate module that provides a variety of ways to create
  4. interesting rhythmic patterns by combining/comparing different clocksignals.
  5. "main" input (center, below the logic outis feeding a series of 3 flipflops,
  6. creating /2 (FLIP), /4 (FLOP) , /8 (FLAP) divisions of the original clock signal.
  7. it's also the default input for logic input B.
  8. FLOP is fed into the left (AND) column input and into logic input A.
  9. FLAP is fed into the right (XOR) column input and into logic input C.
  10. so, with one clock signal the logic section compares the main input vs
  11. the FLOP and FLAP divisions and then the logic outs get
  12. AND compared on the left side vs the left input and
  13. XOR compared on the right side vs the right input.
  14. this internal routing can be broken with other external sources or by
  15. repatching the module itself for even more interesting combinations.
  16. */////////////////////////////////////////////////////////////////////////////
  17. #include "pvc.hpp"
  18. #include "dsp/digital.hpp" // SchmittTrigger // PulseGenerator
  19. namespace rack_plugin_PvC {
  20. struct FlipOLogic : Module {
  21. enum ParamIds {
  22. // IDEA: logic mode selectors for the left and right column
  23. // IDEA: left and right column outputs source selectors (previous or input)
  24. NUM_PARAMS
  25. };
  26. enum InputIds {
  27. FLIP_IN,
  28. LEFT_IN,
  29. RIGHT_IN,
  30. LGC_A_IN,
  31. LGC_B_IN,
  32. LGC_C_IN,
  33. NUM_INPUTS
  34. };
  35. enum OutputIds {
  36. FLIP_OUT,
  37. FLOP_OUT,
  38. FLAP_OUT,
  39. LGC_AND_OUT,
  40. LGC_NAND_OUT,
  41. LGC_OR_OUT,
  42. LGC_NOR_OUT,
  43. LGC_XOR_OUT,
  44. LGC_XNOR_OUT,
  45. LEFT_VS_AND_OUT,
  46. LEFT_VS_NAND_OUT,
  47. LEFT_VS_OR_OUT,
  48. LEFT_VS_NOR_OUT,
  49. LEFT_VS_XOR_OUT,
  50. LEFT_VS_XNOR_OUT,
  51. RIGHT_VS_AND_OUT,
  52. RIGHT_VS_NAND_OUT,
  53. RIGHT_VS_OR_OUT,
  54. RIGHT_VS_NOR_OUT,
  55. RIGHT_VS_XOR_OUT,
  56. RIGHT_VS_XNOR_OUT,
  57. NUM_OUTPUTS
  58. };
  59. enum LightIds {
  60. FLIP_LED,
  61. FLOP_LED,
  62. FLAP_LED,
  63. LGC_AND_LED,
  64. LGC_NAND_LED,
  65. LGC_OR_LED,
  66. LGC_NOR_LED,
  67. LGC_XOR_LED,
  68. LGC_XNOR_LED,
  69. LEFT_VS_AND_LED,
  70. LEFT_VS_NAND_LED,
  71. LEFT_VS_OR_LED,
  72. LEFT_VS_NOR_LED,
  73. LEFT_VS_XOR_LED,
  74. LEFT_VS_XNOR_LED,
  75. RIGHT_VS_AND_LED,
  76. RIGHT_VS_NAND_LED,
  77. RIGHT_VS_OR_LED,
  78. RIGHT_VS_NOR_LED,
  79. RIGHT_VS_XOR_LED,
  80. RIGHT_VS_XNOR_LED,
  81. NUM_LIGHTS
  82. };
  83. bool flpIn = false;
  84. bool flip = false;
  85. bool flop = false;
  86. bool flap = false;
  87. bool leftIn = false;
  88. bool rightIn = false;
  89. bool lgcInA = false;
  90. bool lgcInB = false;
  91. bool lgcInC = false;
  92. bool lgcAnd = false;
  93. bool lgcNand = false;
  94. bool lgcOr = false;
  95. bool lgcNor = false;
  96. bool lgcXor = false;
  97. bool lgcXnor = false;
  98. SchmittTrigger flipTrigger;
  99. SchmittTrigger flopTrigger;
  100. SchmittTrigger flapTrigger;
  101. FlipOLogic() : Module(NUM_PARAMS, NUM_INPUTS, NUM_OUTPUTS, NUM_LIGHTS) {}
  102. void step() override;
  103. void reset() override {
  104. flpIn = false;
  105. flip = flop = flap = false;
  106. leftIn = rightIn = false;
  107. lgcInA = lgcInB = lgcInC = false;
  108. lgcAnd = lgcNand = lgcOr = lgcNor = lgcXor = lgcXnor = false;
  109. }
  110. };
  111. void FlipOLogic::step() {
  112. flpIn = inputs[FLIP_IN].value > 0 ? true : false;
  113. flip = flipTrigger.process(flpIn) ? !flip : flip;
  114. flop = flopTrigger.process(flip) ? !flop : flop;
  115. flap = flapTrigger.process(flop) ? !flap : flap;
  116. leftIn = inputs[LEFT_IN].normalize(flop) > 0 ? true : false;
  117. rightIn = inputs[RIGHT_IN].normalize(flap) > 0 ? true : false;
  118. lgcInA = inputs[LGC_A_IN].normalize(leftIn) > 0 ? true : false;
  119. lgcInB = inputs[LGC_B_IN].normalize(flip) > 0 ? true : false;
  120. lgcInC = inputs[LGC_C_IN].normalize(rightIn) > 0 ? true : false;
  121. lgcAnd = lgcInA && lgcInB && lgcInC;
  122. lgcNand = !lgcAnd;
  123. lgcOr = lgcInA || lgcInB || lgcInC;
  124. lgcNor = !lgcInA && !lgcInB && !lgcInC;
  125. lgcXor = (lgcInA && !lgcInB && !lgcInC) || (!lgcInA && lgcInB && !lgcInC) || (!lgcInA && !lgcInB && lgcInC);
  126. lgcXnor = !lgcXor;
  127. outputs[FLIP_OUT].value = flip * 10.0f;
  128. lights[FLIP_LED].value = flip;
  129. outputs[FLOP_OUT].value = flop * 10.0f;
  130. lights[FLOP_LED].value = flop;
  131. outputs[FLAP_OUT].value = flap * 10.0f;
  132. lights[FLAP_LED].value = flap;
  133. outputs[LGC_AND_OUT].value = lgcAnd * 10.0f;
  134. lights[LGC_AND_LED].value = lgcAnd;
  135. outputs[LGC_NAND_OUT].value = lgcNand * 10.0f;
  136. lights[LGC_NAND_LED].value = lgcNand;
  137. outputs[LGC_OR_OUT].value = lgcOr * 10.0f;
  138. lights[LGC_OR_LED].value = lgcOr;
  139. outputs[LGC_NOR_OUT].value = lgcNor * 10.0f;
  140. lights[LGC_NOR_LED].value = lgcNor;
  141. outputs[LGC_XOR_OUT].value = lgcXor * 10.0f;
  142. lights[LGC_XOR_LED].value = lgcXor;
  143. outputs[LGC_XNOR_OUT].value = lgcXnor * 10.0f;
  144. lights[LGC_XNOR_LED].value = lgcXnor;
  145. outputs[LEFT_VS_AND_OUT].value = (leftIn && lgcAnd) * 10.0f;
  146. outputs[LEFT_VS_NAND_OUT].value = (leftIn && lgcNand) * 10.0f;
  147. outputs[LEFT_VS_OR_OUT].value = (leftIn && lgcOr) * 10.0f;
  148. outputs[LEFT_VS_NOR_OUT].value = (leftIn && lgcNor) * 10.0f;
  149. outputs[LEFT_VS_XOR_OUT].value = (leftIn && lgcXor) * 10.0f;
  150. outputs[LEFT_VS_XNOR_OUT].value = (leftIn && lgcXnor) * 10.0f;
  151. lights[LEFT_VS_AND_LED].value = (leftIn && lgcAnd);
  152. lights[LEFT_VS_NAND_LED].value = (leftIn && lgcNand);
  153. lights[LEFT_VS_OR_LED].value = (leftIn && lgcOr);
  154. lights[LEFT_VS_NOR_LED].value = (leftIn && lgcNor);
  155. lights[LEFT_VS_XOR_LED].value = (leftIn && lgcXor);
  156. lights[LEFT_VS_XNOR_LED].value = (leftIn && lgcXnor);
  157. outputs[RIGHT_VS_AND_OUT].value = (rightIn != lgcAnd) * 10.0f;
  158. outputs[RIGHT_VS_NAND_OUT].value = (rightIn != lgcNand) * 10.0f;
  159. outputs[RIGHT_VS_OR_OUT].value = (rightIn != lgcOr) * 10.0f;
  160. outputs[RIGHT_VS_NOR_OUT].value = (rightIn != lgcNor) * 10.0f;
  161. outputs[RIGHT_VS_XOR_OUT].value = (rightIn != lgcXor) * 10.0f;
  162. outputs[RIGHT_VS_XNOR_OUT].value = (rightIn != lgcXnor) * 10.0f;
  163. lights[RIGHT_VS_AND_LED].value = (rightIn != lgcAnd);
  164. lights[RIGHT_VS_NAND_LED].value = (rightIn != lgcNand);
  165. lights[RIGHT_VS_OR_LED].value = (rightIn != lgcOr);
  166. lights[RIGHT_VS_NOR_LED].value = (rightIn != lgcNor);
  167. lights[RIGHT_VS_XOR_LED].value = (rightIn != lgcXor);
  168. lights[RIGHT_VS_XNOR_LED].value = (rightIn != lgcXnor);
  169. }
  170. struct FlipOLogicWidget : ModuleWidget {
  171. FlipOLogicWidget(FlipOLogic *module);
  172. };
  173. FlipOLogicWidget::FlipOLogicWidget(FlipOLogic *module) : ModuleWidget(module) {
  174. setPanel(SVG::load(assetPlugin(plugin, "res/panels/FlipOLogic.svg")));
  175. // screws
  176. //addChild(Widget::create<ScrewHead1>(Vec(0, 0)));
  177. addChild(Widget::create<ScrewHead2>(Vec(box.size.x - 15, 0)));
  178. addChild(Widget::create<ScrewHead3>(Vec(0, 365)));
  179. //addChild(Widget::create<ScrewHead4>(Vec(box.size.x - 15, 365)));
  180. addInput(Port::create<InPortBin>(Vec(4,22), Port::INPUT, module,FlipOLogic::LGC_A_IN));
  181. addInput(Port::create<InPortBin>(Vec(34,22), Port::INPUT, module,FlipOLogic::LGC_B_IN));
  182. addInput(Port::create<InPortBin>(Vec(64,22), Port::INPUT, module,FlipOLogic::LGC_C_IN));
  183. addChild(ModuleLightWidget::create<FourPixLight<BlueLED>>(Vec(13,55),module,FlipOLogic::LEFT_VS_AND_LED));
  184. addOutput(Port::create<OutPortBin>(Vec(4,60), Port::OUTPUT, module,FlipOLogic::LEFT_VS_AND_OUT));
  185. addChild(ModuleLightWidget::create<FourPixLight<OrangeLED>>(Vec(43,65),module,FlipOLogic::LGC_AND_LED));
  186. addOutput(Port::create<OutPortBin>(Vec(34,70), Port::OUTPUT, module,FlipOLogic::LGC_AND_OUT));
  187. addChild(ModuleLightWidget::create<FourPixLight<PurpleLED>>(Vec(73,55),module,FlipOLogic::RIGHT_VS_AND_LED));
  188. addOutput(Port::create<OutPortBin>(Vec(64,60), Port::OUTPUT, module,FlipOLogic::RIGHT_VS_AND_OUT));
  189. addChild(ModuleLightWidget::create<FourPixLight<BlueLED>>(Vec(13,95),module,FlipOLogic::LEFT_VS_NAND_LED));
  190. addOutput(Port::create<OutPortBin>(Vec(4,100), Port::OUTPUT, module,FlipOLogic::LEFT_VS_NAND_OUT));
  191. addChild(ModuleLightWidget::create<FourPixLight<OrangeLED>>(Vec(43,105),module,FlipOLogic::LGC_NAND_LED));
  192. addOutput(Port::create<OutPortBin>(Vec(34,110), Port::OUTPUT, module,FlipOLogic::LGC_NAND_OUT));
  193. addChild(ModuleLightWidget::create<FourPixLight<PurpleLED>>(Vec(73,95),module,FlipOLogic::RIGHT_VS_NAND_LED));
  194. addOutput(Port::create<OutPortBin>(Vec(64,100), Port::OUTPUT, module,FlipOLogic::RIGHT_VS_NAND_OUT));
  195. addChild(ModuleLightWidget::create<FourPixLight<BlueLED>>(Vec(13,135),module,FlipOLogic::LEFT_VS_OR_LED));
  196. addOutput(Port::create<OutPortBin>(Vec(4,140), Port::OUTPUT, module,FlipOLogic::LEFT_VS_OR_OUT));
  197. addChild(ModuleLightWidget::create<FourPixLight<OrangeLED>>(Vec(43,145),module,FlipOLogic::LGC_OR_LED));
  198. addOutput(Port::create<OutPortBin>(Vec(34,150), Port::OUTPUT, module,FlipOLogic::LGC_OR_OUT));
  199. addChild(ModuleLightWidget::create<FourPixLight<PurpleLED>>(Vec(73,135),module,FlipOLogic::RIGHT_VS_OR_LED));
  200. addOutput(Port::create<OutPortBin>(Vec(64,140), Port::OUTPUT, module,FlipOLogic::RIGHT_VS_OR_OUT));
  201. addChild(ModuleLightWidget::create<FourPixLight<BlueLED>>(Vec(13,175),module,FlipOLogic::LEFT_VS_NOR_LED));
  202. addOutput(Port::create<OutPortBin>(Vec(4,180), Port::OUTPUT, module,FlipOLogic::LEFT_VS_NOR_OUT));
  203. addChild(ModuleLightWidget::create<FourPixLight<OrangeLED>>(Vec(43,185),module,FlipOLogic::LGC_NOR_LED));
  204. addOutput(Port::create<OutPortBin>(Vec(34,190), Port::OUTPUT, module,FlipOLogic::LGC_NOR_OUT));
  205. addChild(ModuleLightWidget::create<FourPixLight<PurpleLED>>(Vec(73,175),module,FlipOLogic::RIGHT_VS_NOR_LED));
  206. addOutput(Port::create<OutPortBin>(Vec(64,180), Port::OUTPUT, module,FlipOLogic::RIGHT_VS_NOR_OUT));
  207. addChild(ModuleLightWidget::create<FourPixLight<BlueLED>>(Vec(13,215),module,FlipOLogic::LEFT_VS_XOR_LED));
  208. addOutput(Port::create<OutPortBin>(Vec(4,220), Port::OUTPUT, module,FlipOLogic::LEFT_VS_XOR_OUT));
  209. addChild(ModuleLightWidget::create<FourPixLight<OrangeLED>>(Vec(43,225),module,FlipOLogic::LGC_XOR_LED));
  210. addOutput(Port::create<OutPortBin>(Vec(34,230), Port::OUTPUT, module,FlipOLogic::LGC_XOR_OUT));
  211. addChild(ModuleLightWidget::create<FourPixLight<PurpleLED>>(Vec(73,215),module,FlipOLogic::RIGHT_VS_XOR_LED));
  212. addOutput(Port::create<OutPortBin>(Vec(64,220), Port::OUTPUT, module,FlipOLogic::RIGHT_VS_XOR_OUT));
  213. addChild(ModuleLightWidget::create<FourPixLight<BlueLED>>(Vec(13,255),module,FlipOLogic::LEFT_VS_XNOR_LED));
  214. addOutput(Port::create<OutPortBin>(Vec(4,260), Port::OUTPUT, module,FlipOLogic::LEFT_VS_XNOR_OUT));
  215. addChild(ModuleLightWidget::create<FourPixLight<OrangeLED>>(Vec(43,265),module,FlipOLogic::LGC_XNOR_LED));
  216. addOutput(Port::create<OutPortBin>(Vec(34,270), Port::OUTPUT, module,FlipOLogic::LGC_XNOR_OUT));
  217. addChild(ModuleLightWidget::create<FourPixLight<PurpleLED>>(Vec(73,255),module,FlipOLogic::RIGHT_VS_XNOR_LED));
  218. addOutput(Port::create<OutPortBin>(Vec(64,260), Port::OUTPUT, module,FlipOLogic::RIGHT_VS_XNOR_OUT));
  219. addInput(Port::create<InPortBin>(Vec(4,294), Port::INPUT, module,FlipOLogic::LEFT_IN));
  220. addInput(Port::create<InPortBin>(Vec(34,298), Port::INPUT, module,FlipOLogic::FLIP_IN));
  221. addInput(Port::create<InPortBin>(Vec(64,294), Port::INPUT, module,FlipOLogic::RIGHT_IN));
  222. addChild(ModuleLightWidget::create<FourPixLight<BlueLED>>(Vec(13,331),module,FlipOLogic::FLOP_LED));
  223. addOutput(Port::create<OutPortBin>(Vec(4,336), Port::OUTPUT, module,FlipOLogic::FLOP_OUT));
  224. addChild(ModuleLightWidget::create<FourPixLight<OrangeLED>>(Vec(43,331),module,FlipOLogic::FLIP_LED));
  225. addOutput(Port::create<OutPortBin>(Vec(34,336), Port::OUTPUT, module,FlipOLogic::FLIP_OUT));
  226. addChild(ModuleLightWidget::create<FourPixLight<PurpleLED>>(Vec(73,331),module,FlipOLogic::FLAP_LED));
  227. addOutput(Port::create<OutPortBin>(Vec(64,336), Port::OUTPUT, module,FlipOLogic::FLAP_OUT));
  228. }
  229. } // namespace rack_plugin_PvC
  230. using namespace rack_plugin_PvC;
  231. RACK_PLUGIN_MODEL_INIT(PvC, FlipOLogic) {
  232. Model *modelFlipOLogic = Model::create<FlipOLogic, FlipOLogicWidget>(
  233. "PvC", "FlipOLogic", "FlipOLogic", LOGIC_TAG, SWITCH_TAG, CLOCK_MODULATOR_TAG);
  234. return modelFlipOLogic;
  235. }