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.

137 lines
6.2KB

  1. #include "plugin.hpp"
  2. struct Mutes : Module {
  3. enum ParamIds {
  4. ENUMS(MUTE_PARAMS, 10),
  5. NUM_PARAMS
  6. };
  7. enum InputIds {
  8. ENUMS(IN_INPUTS, 10),
  9. NUM_INPUTS
  10. };
  11. enum OutputIds {
  12. ENUMS(OUT_OUTPUTS, 10),
  13. NUM_OUTPUTS
  14. };
  15. enum LightIds {
  16. ENUMS(MUTE_LIGHTS, 10),
  17. NUM_LIGHTS
  18. };
  19. Mutes() {
  20. config(NUM_PARAMS, NUM_INPUTS, NUM_OUTPUTS, NUM_LIGHTS);
  21. for (int i = 0; i < 10; i++) {
  22. configSwitch(MUTE_PARAMS + i, 0.f, 1.f, 0.f, string::f("Row %d mute", i + 1));
  23. configInput(IN_INPUTS + i, string::f("Row %d", i + 1));
  24. configOutput(OUT_OUTPUTS + i, string::f("Row %d", i + 1));
  25. configBypass(IN_INPUTS + i, OUT_OUTPUTS + i);
  26. }
  27. }
  28. void process(const ProcessArgs& args) override {
  29. const float zero[16] = {};
  30. float out[16] = {};
  31. // Iterate rows
  32. for (int i = 0; i < 10; i++) {
  33. int channels = 1;
  34. bool mute = params[MUTE_PARAMS + i].getValue() > 0.f;
  35. // Get input
  36. // Inputs are normalized to the input above it, so only set if connected
  37. if (inputs[IN_INPUTS + i].isConnected()) {
  38. channels = inputs[IN_INPUTS + i].getChannels();
  39. inputs[IN_INPUTS + i].readVoltages(out);
  40. }
  41. // Set output
  42. if (outputs[OUT_OUTPUTS + i].isConnected()) {
  43. outputs[OUT_OUTPUTS + i].setChannels(channels);
  44. outputs[OUT_OUTPUTS + i].writeVoltages(mute ? zero : out);
  45. }
  46. // Set light
  47. lights[MUTE_LIGHTS + i].setBrightness(mute);
  48. }
  49. }
  50. void dataFromJson(json_t* rootJ) override {
  51. // In <2.0, states were stored in data
  52. json_t* statesJ = json_object_get(rootJ, "states");
  53. if (statesJ) {
  54. for (int i = 0; i < 10; i++) {
  55. json_t* stateJ = json_array_get(statesJ, i);
  56. if (stateJ)
  57. params[MUTE_PARAMS + i].setValue(!json_boolean_value(stateJ));
  58. }
  59. }
  60. }
  61. void invert() {
  62. for (int i = 0; i < 10; i++) {
  63. params[MUTE_PARAMS + i].setValue(!params[MUTE_PARAMS + i].getValue());
  64. }
  65. }
  66. };
  67. struct MutesWidget : ModuleWidget {
  68. MutesWidget(Mutes* module) {
  69. setModule(module);
  70. setPanel(createPanel(asset::plugin(pluginInstance, "res/Mutes.svg"), asset::plugin(pluginInstance, "res/Mutes-dark.svg")));
  71. addChild(createWidget<ThemedScrew>(Vec(RACK_GRID_WIDTH, 0)));
  72. addChild(createWidget<ThemedScrew>(Vec(box.size.x - 2 * RACK_GRID_WIDTH, 0)));
  73. addChild(createWidget<ThemedScrew>(Vec(RACK_GRID_WIDTH, RACK_GRID_HEIGHT - RACK_GRID_WIDTH)));
  74. addChild(createWidget<ThemedScrew>(Vec(box.size.x - 2 * RACK_GRID_WIDTH, RACK_GRID_HEIGHT - RACK_GRID_WIDTH)));
  75. addParam(createLightParamCentered<VCVLightBezelLatch<>>(mm2px(Vec(20.312, 21.968)), module, Mutes::MUTE_PARAMS + 0, Mutes::MUTE_LIGHTS + 0));
  76. addParam(createLightParamCentered<VCVLightBezelLatch<>>(mm2px(Vec(20.312, 32.095)), module, Mutes::MUTE_PARAMS + 1, Mutes::MUTE_LIGHTS + 1));
  77. addParam(createLightParamCentered<VCVLightBezelLatch<>>(mm2px(Vec(20.312, 42.222)), module, Mutes::MUTE_PARAMS + 2, Mutes::MUTE_LIGHTS + 2));
  78. addParam(createLightParamCentered<VCVLightBezelLatch<>>(mm2px(Vec(20.312, 52.35)), module, Mutes::MUTE_PARAMS + 3, Mutes::MUTE_LIGHTS + 3));
  79. addParam(createLightParamCentered<VCVLightBezelLatch<>>(mm2px(Vec(20.312, 62.477)), module, Mutes::MUTE_PARAMS + 4, Mutes::MUTE_LIGHTS + 4));
  80. addParam(createLightParamCentered<VCVLightBezelLatch<>>(mm2px(Vec(20.312, 72.605)), module, Mutes::MUTE_PARAMS + 5, Mutes::MUTE_LIGHTS + 5));
  81. addParam(createLightParamCentered<VCVLightBezelLatch<>>(mm2px(Vec(20.312, 82.732)), module, Mutes::MUTE_PARAMS + 6, Mutes::MUTE_LIGHTS + 6));
  82. addParam(createLightParamCentered<VCVLightBezelLatch<>>(mm2px(Vec(20.312, 92.86)), module, Mutes::MUTE_PARAMS + 7, Mutes::MUTE_LIGHTS + 7));
  83. addParam(createLightParamCentered<VCVLightBezelLatch<>>(mm2px(Vec(20.312, 102.987)), module, Mutes::MUTE_PARAMS + 8, Mutes::MUTE_LIGHTS + 8));
  84. addParam(createLightParamCentered<VCVLightBezelLatch<>>(mm2px(Vec(20.312, 113.115)), module, Mutes::MUTE_PARAMS + 9, Mutes::MUTE_LIGHTS + 9));
  85. addInput(createInputCentered<ThemedPJ301MPort>(mm2px(Vec(7.291, 21.968)), module, Mutes::IN_INPUTS + 0));
  86. addInput(createInputCentered<ThemedPJ301MPort>(mm2px(Vec(7.291, 32.095)), module, Mutes::IN_INPUTS + 1));
  87. addInput(createInputCentered<ThemedPJ301MPort>(mm2px(Vec(7.291, 42.222)), module, Mutes::IN_INPUTS + 2));
  88. addInput(createInputCentered<ThemedPJ301MPort>(mm2px(Vec(7.291, 52.35)), module, Mutes::IN_INPUTS + 3));
  89. addInput(createInputCentered<ThemedPJ301MPort>(mm2px(Vec(7.291, 62.477)), module, Mutes::IN_INPUTS + 4));
  90. addInput(createInputCentered<ThemedPJ301MPort>(mm2px(Vec(7.291, 72.605)), module, Mutes::IN_INPUTS + 5));
  91. addInput(createInputCentered<ThemedPJ301MPort>(mm2px(Vec(7.291, 82.732)), module, Mutes::IN_INPUTS + 6));
  92. addInput(createInputCentered<ThemedPJ301MPort>(mm2px(Vec(7.291, 92.86)), module, Mutes::IN_INPUTS + 7));
  93. addInput(createInputCentered<ThemedPJ301MPort>(mm2px(Vec(7.291, 102.987)), module, Mutes::IN_INPUTS + 8));
  94. addInput(createInputCentered<ThemedPJ301MPort>(mm2px(Vec(7.291, 113.115)), module, Mutes::IN_INPUTS + 9));
  95. addOutput(createOutputCentered<ThemedPJ301MPort>(mm2px(Vec(33.332, 21.968)), module, Mutes::OUT_OUTPUTS + 0));
  96. addOutput(createOutputCentered<ThemedPJ301MPort>(mm2px(Vec(33.332, 32.095)), module, Mutes::OUT_OUTPUTS + 1));
  97. addOutput(createOutputCentered<ThemedPJ301MPort>(mm2px(Vec(33.332, 42.222)), module, Mutes::OUT_OUTPUTS + 2));
  98. addOutput(createOutputCentered<ThemedPJ301MPort>(mm2px(Vec(33.332, 52.35)), module, Mutes::OUT_OUTPUTS + 3));
  99. addOutput(createOutputCentered<ThemedPJ301MPort>(mm2px(Vec(33.332, 62.477)), module, Mutes::OUT_OUTPUTS + 4));
  100. addOutput(createOutputCentered<ThemedPJ301MPort>(mm2px(Vec(33.332, 72.605)), module, Mutes::OUT_OUTPUTS + 5));
  101. addOutput(createOutputCentered<ThemedPJ301MPort>(mm2px(Vec(33.332, 82.732)), module, Mutes::OUT_OUTPUTS + 6));
  102. addOutput(createOutputCentered<ThemedPJ301MPort>(mm2px(Vec(33.332, 92.86)), module, Mutes::OUT_OUTPUTS + 7));
  103. addOutput(createOutputCentered<ThemedPJ301MPort>(mm2px(Vec(33.332, 102.987)), module, Mutes::OUT_OUTPUTS + 8));
  104. addOutput(createOutputCentered<ThemedPJ301MPort>(mm2px(Vec(33.332, 113.115)), module, Mutes::OUT_OUTPUTS + 9));
  105. }
  106. void appendContextMenu(Menu* menu) override {
  107. Mutes* module = dynamic_cast<Mutes*>(this->module);
  108. assert(module);
  109. menu->addChild(new MenuSeparator);
  110. menu->addChild(createMenuItem("Invert mutes", "",
  111. [=]() {module->invert();}
  112. ));
  113. }
  114. };
  115. Model* modelMutes = createModel<Mutes, MutesWidget>("Mutes");