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.

207 lines
12KB

  1. //============================================================================================================
  2. //!
  3. //! \file Keys-G1.cpp
  4. //!
  5. //! \brief Keys-G1 is a six input times six voice note monitoring module.
  6. //!
  7. //============================================================================================================
  8. #include "Gratrix.hpp"
  9. namespace rack_plugin_Gratrix {
  10. //============================================================================================================
  11. //! \brief The module.
  12. struct GtxModule_Keys_G1 : Module
  13. {
  14. enum ParamIds {
  15. NUM_PARAMS
  16. };
  17. enum InputIds {
  18. GATE_1R_INPUT, // N+1
  19. GATE_1G_INPUT, // N+1
  20. GATE_1B_INPUT, // N+1
  21. GATE_2R_INPUT, // N+1
  22. GATE_2G_INPUT, // N+1
  23. GATE_2B_INPUT, // N+1
  24. VOCT_1R_INPUT, // N
  25. VOCT_1G_INPUT, // N
  26. VOCT_1B_INPUT, // N
  27. VOCT_2R_INPUT, // N
  28. VOCT_2G_INPUT, // N
  29. VOCT_2B_INPUT, // N
  30. NUM_INPUTS,
  31. };
  32. enum OutputIds {
  33. NUM_OUTPUTS
  34. };
  35. enum LightIds {
  36. KEY_LIGHT_1 = 0,
  37. KEY_LIGHT_2 = KEY_LIGHT_1 + 6 * 12 * 3,
  38. NUM_LIGHTS = KEY_LIGHT_2 + 6 * 12 * 3
  39. };
  40. static constexpr std::size_t imap(std::size_t port, std::size_t bank)
  41. {
  42. return port + bank * NUM_INPUTS;
  43. }
  44. static void decode(float *lights, int offset, const Input &in_gate, const Input &in_voct)
  45. {
  46. bool enable = ((in_gate.active && in_gate.value >= 1.0f) || !in_gate.active) && in_voct.active;
  47. if (enable)
  48. {
  49. int note = static_cast<int>(std::floor(in_voct.value * 12.0f + 0.5f)) + 3*12;
  50. if (note >= 0 && note < 6*12)
  51. {
  52. lights[note * 3 + offset] = 1.0f;
  53. }
  54. }
  55. }
  56. GtxModule_Keys_G1()
  57. :
  58. Module(NUM_PARAMS, ((GTX__N+1) * NUM_INPUTS/2) + (GTX__N * NUM_INPUTS/2), NUM_OUTPUTS, NUM_LIGHTS)
  59. {}
  60. void step() override
  61. {
  62. float leds[NUM_LIGHTS] = {};
  63. for (std::size_t i=0; i<GTX__N; ++i)
  64. {
  65. if (inputs[imap(GATE_1R_INPUT, i)].active) decode(&leds[KEY_LIGHT_1], 0, inputs[imap(GATE_1R_INPUT, i)], inputs[imap(VOCT_1R_INPUT, i)]);
  66. else decode(&leds[KEY_LIGHT_1], 0, inputs[imap(GATE_1R_INPUT, GTX__N)], inputs[imap(VOCT_1R_INPUT, i)]);
  67. if (inputs[imap(GATE_1G_INPUT, i)].active) decode(&leds[KEY_LIGHT_1], 1, inputs[imap(GATE_1G_INPUT, i)], inputs[imap(VOCT_1G_INPUT, i)]);
  68. else decode(&leds[KEY_LIGHT_1], 1, inputs[imap(GATE_1G_INPUT, GTX__N)], inputs[imap(VOCT_1G_INPUT, i)]);
  69. if (inputs[imap(GATE_1B_INPUT, i)].active) decode(&leds[KEY_LIGHT_1], 2, inputs[imap(GATE_1B_INPUT, i)], inputs[imap(VOCT_1B_INPUT, i)]);
  70. else decode(&leds[KEY_LIGHT_1], 2, inputs[imap(GATE_1B_INPUT, GTX__N)], inputs[imap(VOCT_1B_INPUT, i)]);
  71. if (inputs[imap(GATE_2R_INPUT, i)].active) decode(&leds[KEY_LIGHT_2], 0, inputs[imap(GATE_2R_INPUT, i)], inputs[imap(VOCT_2R_INPUT, i)]);
  72. else decode(&leds[KEY_LIGHT_2], 0, inputs[imap(GATE_2R_INPUT, GTX__N)], inputs[imap(VOCT_2R_INPUT, i)]);
  73. if (inputs[imap(GATE_2G_INPUT, i)].active) decode(&leds[KEY_LIGHT_2], 1, inputs[imap(GATE_2G_INPUT, i)], inputs[imap(VOCT_2G_INPUT, i)]);
  74. else decode(&leds[KEY_LIGHT_2], 1, inputs[imap(GATE_2G_INPUT, GTX__N)], inputs[imap(VOCT_2G_INPUT, i)]);
  75. if (inputs[imap(GATE_2B_INPUT, i)].active) decode(&leds[KEY_LIGHT_2], 2, inputs[imap(GATE_2B_INPUT, i)], inputs[imap(VOCT_2B_INPUT, i)]);
  76. else decode(&leds[KEY_LIGHT_2], 2, inputs[imap(GATE_2B_INPUT, GTX__N)], inputs[imap(VOCT_2B_INPUT, i)]);
  77. }
  78. // Write output in one go, seems to prevent flicker
  79. for (std::size_t i=0; i<NUM_LIGHTS; ++i)
  80. {
  81. lights[i].value = leds[i];
  82. }
  83. }
  84. };
  85. //============================================================================================================
  86. //! \brief The widget.
  87. struct GtxWidget_Keys_G1 : ModuleWidget
  88. {
  89. GtxWidget_Keys_G1(GtxModule_Keys_G1 *module) : ModuleWidget(module)
  90. {
  91. GTX__WIDGET();
  92. box.size = Vec(36*15, 380);
  93. #if GTX__SAVE_SVG
  94. {
  95. PanelGen pg(assetPlugin(plugin, "build/res/Keys-G1.svg"), box.size, "KEYS-G1");
  96. pg.line(Vec(fx(0-.4), fy(0.36)), Vec(fx(2+.4), fy(0.36)), "fill:none;stroke:#7092BE;stroke-width:1");
  97. pg.line(Vec(fx(3-.4), fy(0.36)), Vec(fx(5+.4), fy(0.36)), "fill:none;stroke:#7092BE;stroke-width:1");
  98. pg.nob_med(0, 0.7, "RED" ); pg.nob_med(0, -0.28, "C1-B1");
  99. pg.nob_med(1, 0.55, "UPPER"); pg.nob_med(1, 0.7, "GREEN"); pg.nob_med(1, -0.28, "C2-B2");
  100. pg.nob_med(2, 0.7, "BLUE" ); pg.nob_med(2, -0.28, "C3-B3");
  101. pg.nob_med(3, 0.7, "RED" ); pg.nob_med(3, -0.28, "C4-B4");
  102. pg.nob_med(4, 0.55, "LOWER"); pg.nob_med(4, 0.7, "GREEN"); pg.nob_med(4, -0.28, "C5-B5");
  103. pg.nob_med(5, 0.7, "BLUE" ); pg.nob_med(5, -0.28, "C6-B6");
  104. pg.bus_in(0, 1, "GATE"); pg.bus_in(0, 2, "V/OCT");
  105. pg.bus_in(1, 1, "GATE"); pg.bus_in(1, 2, "V/OCT");
  106. pg.bus_in(2, 1, "GATE"); pg.bus_in(2, 2, "V/OCT");
  107. pg.bus_in(3, 1, "GATE"); pg.bus_in(3, 2, "V/OCT");
  108. pg.bus_in(4, 1, "GATE"); pg.bus_in(4, 2, "V/OCT");
  109. pg.bus_in(5, 1, "GATE"); pg.bus_in(5, 2, "V/OCT");
  110. }
  111. #endif
  112. setPanel(SVG::load(assetPlugin(plugin, "res/Keys-G1.svg")));
  113. addChild(Widget::create<ScrewSilver>(Vec(15, 0)));
  114. addChild(Widget::create<ScrewSilver>(Vec(box.size.x-30, 0)));
  115. addChild(Widget::create<ScrewSilver>(Vec(15, 365)));
  116. addChild(Widget::create<ScrewSilver>(Vec(box.size.x-30, 365)));
  117. for (std::size_t i=0; i<GTX__N; ++i)
  118. {
  119. addInput(createInputGTX<PortInMed>(Vec(px(0, i), py(1, i)), module, GtxModule_Keys_G1::imap(GtxModule_Keys_G1::GATE_1R_INPUT, i)));
  120. addInput(createInputGTX<PortInMed>(Vec(px(1, i), py(1, i)), module, GtxModule_Keys_G1::imap(GtxModule_Keys_G1::GATE_1G_INPUT, i)));
  121. addInput(createInputGTX<PortInMed>(Vec(px(2, i), py(1, i)), module, GtxModule_Keys_G1::imap(GtxModule_Keys_G1::GATE_1B_INPUT, i)));
  122. addInput(createInputGTX<PortInMed>(Vec(px(3, i), py(1, i)), module, GtxModule_Keys_G1::imap(GtxModule_Keys_G1::GATE_2R_INPUT, i)));
  123. addInput(createInputGTX<PortInMed>(Vec(px(4, i), py(1, i)), module, GtxModule_Keys_G1::imap(GtxModule_Keys_G1::GATE_2G_INPUT, i)));
  124. addInput(createInputGTX<PortInMed>(Vec(px(5, i), py(1, i)), module, GtxModule_Keys_G1::imap(GtxModule_Keys_G1::GATE_2B_INPUT, i)));
  125. addInput(createInputGTX<PortInMed>(Vec(px(0, i), py(2, i)), module, GtxModule_Keys_G1::imap(GtxModule_Keys_G1::VOCT_1R_INPUT, i)));
  126. addInput(createInputGTX<PortInMed>(Vec(px(1, i), py(2, i)), module, GtxModule_Keys_G1::imap(GtxModule_Keys_G1::VOCT_1G_INPUT, i)));
  127. addInput(createInputGTX<PortInMed>(Vec(px(2, i), py(2, i)), module, GtxModule_Keys_G1::imap(GtxModule_Keys_G1::VOCT_1B_INPUT, i)));
  128. addInput(createInputGTX<PortInMed>(Vec(px(3, i), py(2, i)), module, GtxModule_Keys_G1::imap(GtxModule_Keys_G1::VOCT_2R_INPUT, i)));
  129. addInput(createInputGTX<PortInMed>(Vec(px(4, i), py(2, i)), module, GtxModule_Keys_G1::imap(GtxModule_Keys_G1::VOCT_2G_INPUT, i)));
  130. addInput(createInputGTX<PortInMed>(Vec(px(5, i), py(2, i)), module, GtxModule_Keys_G1::imap(GtxModule_Keys_G1::VOCT_2B_INPUT, i)));
  131. }
  132. addInput(createInputGTX<PortInMed>(Vec(gx(0), gy(1)), module, GtxModule_Keys_G1::imap(GtxModule_Keys_G1::GATE_1R_INPUT, GTX__N)));
  133. addInput(createInputGTX<PortInMed>(Vec(gx(1), gy(1)), module, GtxModule_Keys_G1::imap(GtxModule_Keys_G1::GATE_1G_INPUT, GTX__N)));
  134. addInput(createInputGTX<PortInMed>(Vec(gx(2), gy(1)), module, GtxModule_Keys_G1::imap(GtxModule_Keys_G1::GATE_1B_INPUT, GTX__N)));
  135. addInput(createInputGTX<PortInMed>(Vec(gx(3), gy(1)), module, GtxModule_Keys_G1::imap(GtxModule_Keys_G1::GATE_2R_INPUT, GTX__N)));
  136. addInput(createInputGTX<PortInMed>(Vec(gx(4), gy(1)), module, GtxModule_Keys_G1::imap(GtxModule_Keys_G1::GATE_2G_INPUT, GTX__N)));
  137. addInput(createInputGTX<PortInMed>(Vec(gx(5), gy(1)), module, GtxModule_Keys_G1::imap(GtxModule_Keys_G1::GATE_2B_INPUT, GTX__N)));
  138. for (std::size_t i=0; i<6; ++i)
  139. {
  140. addChild(ModuleLightWidget::create<SmallLight<RedGreenBlueLight>>(l_s(gx(i) - 30, fy(0+0.08) + 5), module, GtxModule_Keys_G1::KEY_LIGHT_2 + 3 * (i * 12 + 0))); // C
  141. addChild(ModuleLightWidget::create<SmallLight<RedGreenBlueLight>>(l_s(gx(i) - 25, fy(0+0.08) - 5), module, GtxModule_Keys_G1::KEY_LIGHT_2 + 3 * (i * 12 + 1))); // C#
  142. addChild(ModuleLightWidget::create<SmallLight<RedGreenBlueLight>>(l_s(gx(i) - 20, fy(0+0.08) + 5), module, GtxModule_Keys_G1::KEY_LIGHT_2 + 3 * (i * 12 + 2))); // D
  143. addChild(ModuleLightWidget::create<SmallLight<RedGreenBlueLight>>(l_s(gx(i) - 15, fy(0+0.08) - 5), module, GtxModule_Keys_G1::KEY_LIGHT_2 + 3 * (i * 12 + 3))); // Eb
  144. addChild(ModuleLightWidget::create<SmallLight<RedGreenBlueLight>>(l_s(gx(i) - 10, fy(0+0.08) + 5), module, GtxModule_Keys_G1::KEY_LIGHT_2 + 3 * (i * 12 + 4))); // E
  145. addChild(ModuleLightWidget::create<SmallLight<RedGreenBlueLight>>(l_s(gx(i) , fy(0+0.08) + 5), module, GtxModule_Keys_G1::KEY_LIGHT_2 + 3 * (i * 12 + 5))); // F
  146. addChild(ModuleLightWidget::create<SmallLight<RedGreenBlueLight>>(l_s(gx(i) + 5, fy(0+0.08) - 5), module, GtxModule_Keys_G1::KEY_LIGHT_2 + 3 * (i * 12 + 6))); // Fs
  147. addChild(ModuleLightWidget::create<SmallLight<RedGreenBlueLight>>(l_s(gx(i) + 10, fy(0+0.08) + 5), module, GtxModule_Keys_G1::KEY_LIGHT_2 + 3 * (i * 12 + 7))); // G
  148. addChild(ModuleLightWidget::create<SmallLight<RedGreenBlueLight>>(l_s(gx(i) + 15, fy(0+0.08) - 5), module, GtxModule_Keys_G1::KEY_LIGHT_2 + 3 * (i * 12 + 8))); // Ab
  149. addChild(ModuleLightWidget::create<SmallLight<RedGreenBlueLight>>(l_s(gx(i) + 20, fy(0+0.08) + 5), module, GtxModule_Keys_G1::KEY_LIGHT_2 + 3 * (i * 12 + 9))); // A
  150. addChild(ModuleLightWidget::create<SmallLight<RedGreenBlueLight>>(l_s(gx(i) + 25, fy(0+0.08) - 5), module, GtxModule_Keys_G1::KEY_LIGHT_2 + 3 * (i * 12 + 10))); // Bb
  151. addChild(ModuleLightWidget::create<SmallLight<RedGreenBlueLight>>(l_s(gx(i) + 30, fy(0+0.08) + 5), module, GtxModule_Keys_G1::KEY_LIGHT_2 + 3 * (i * 12 + 11))); // B
  152. }
  153. for (std::size_t i=0; i<6; ++i)
  154. {
  155. addChild(ModuleLightWidget::create<SmallLight<RedGreenBlueLight>>(l_s(gx(i) - 30, fy(0-0.28) + 5), module, GtxModule_Keys_G1::KEY_LIGHT_1 + 3 * (i * 12 + 0))); // C
  156. addChild(ModuleLightWidget::create<SmallLight<RedGreenBlueLight>>(l_s(gx(i) - 25, fy(0-0.28) - 5), module, GtxModule_Keys_G1::KEY_LIGHT_1 + 3 * (i * 12 + 1))); // C#
  157. addChild(ModuleLightWidget::create<SmallLight<RedGreenBlueLight>>(l_s(gx(i) - 20, fy(0-0.28) + 5), module, GtxModule_Keys_G1::KEY_LIGHT_1 + 3 * (i * 12 + 2))); // D
  158. addChild(ModuleLightWidget::create<SmallLight<RedGreenBlueLight>>(l_s(gx(i) - 15, fy(0-0.28) - 5), module, GtxModule_Keys_G1::KEY_LIGHT_1 + 3 * (i * 12 + 3))); // Eb
  159. addChild(ModuleLightWidget::create<SmallLight<RedGreenBlueLight>>(l_s(gx(i) - 10, fy(0-0.28) + 5), module, GtxModule_Keys_G1::KEY_LIGHT_1 + 3 * (i * 12 + 4))); // E
  160. addChild(ModuleLightWidget::create<SmallLight<RedGreenBlueLight>>(l_s(gx(i) , fy(0-0.28) + 5), module, GtxModule_Keys_G1::KEY_LIGHT_1 + 3 * (i * 12 + 5))); // F
  161. addChild(ModuleLightWidget::create<SmallLight<RedGreenBlueLight>>(l_s(gx(i) + 5, fy(0-0.28) - 5), module, GtxModule_Keys_G1::KEY_LIGHT_1 + 3 * (i * 12 + 6))); // Fs
  162. addChild(ModuleLightWidget::create<SmallLight<RedGreenBlueLight>>(l_s(gx(i) + 10, fy(0-0.28) + 5), module, GtxModule_Keys_G1::KEY_LIGHT_1 + 3 * (i * 12 + 7))); // G
  163. addChild(ModuleLightWidget::create<SmallLight<RedGreenBlueLight>>(l_s(gx(i) + 15, fy(0-0.28) - 5), module, GtxModule_Keys_G1::KEY_LIGHT_1 + 3 * (i * 12 + 8))); // Ab
  164. addChild(ModuleLightWidget::create<SmallLight<RedGreenBlueLight>>(l_s(gx(i) + 20, fy(0-0.28) + 5), module, GtxModule_Keys_G1::KEY_LIGHT_1 + 3 * (i * 12 + 9))); // A
  165. addChild(ModuleLightWidget::create<SmallLight<RedGreenBlueLight>>(l_s(gx(i) + 25, fy(0-0.28) - 5), module, GtxModule_Keys_G1::KEY_LIGHT_1 + 3 * (i * 12 + 10))); // Bb
  166. addChild(ModuleLightWidget::create<SmallLight<RedGreenBlueLight>>(l_s(gx(i) + 30, fy(0-0.28) + 5), module, GtxModule_Keys_G1::KEY_LIGHT_1 + 3 * (i * 12 + 11))); // B
  167. }
  168. }
  169. };
  170. } // namespace rack_plugin_Gratrix
  171. using namespace rack_plugin_Gratrix;
  172. RACK_PLUGIN_MODEL_INIT(Gratrix, Keys_G1) {
  173. Model *model = Model::create<GtxModule_Keys_G1, GtxWidget_Keys_G1>("Gratrix", "Keys-G1", "Keys-G1", VISUAL_TAG);
  174. return model;
  175. }