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.

170 lines
4.1KB

  1. #include "cf.hpp"
  2. #include "dsp/digital.hpp"
  3. namespace rack_plugin_cf {
  4. struct FOUR : Module {
  5. enum ParamIds {
  6. S_PARAM,
  7. M_PARAM=S_PARAM + 4,
  8. NUM_PARAMS = M_PARAM + 4
  9. };
  10. enum InputIds {
  11. TRM_INPUT,
  12. TRS_INPUT=TRM_INPUT+4,
  13. IN_INPUT=TRS_INPUT+4,
  14. NUM_INPUTS=IN_INPUT+4
  15. };
  16. enum OutputIds {
  17. OUT_OUTPUT,
  18. NUM_OUTPUTS=OUT_OUTPUT+4
  19. };
  20. enum LightIds {
  21. M_LIGHT,
  22. S_LIGHT=M_LIGHT+4,
  23. NUM_LIGHTS=S_LIGHT+4
  24. };
  25. bool muteState[8] = {};
  26. int solo = 0;
  27. int cligno = 0;
  28. SchmittTrigger muteTrigger[8];
  29. SchmittTrigger soloTrigger[8];
  30. FOUR() : Module(NUM_PARAMS, NUM_INPUTS, NUM_OUTPUTS, NUM_LIGHTS) {onReset();}
  31. void step() override;
  32. void onReset() override {
  33. for (int i = 0; i < 4; i++) {
  34. muteState[i] = true;
  35. muteState[i+4] = false;
  36. }
  37. solo = 0;
  38. }
  39. void onRandomize() override {
  40. for (int i = 0; i < 8; i++) {
  41. muteState[i] = (randomUniform() < 0.5);
  42. }
  43. }
  44. json_t *toJson() override {
  45. json_t *rootJ = json_object();
  46. // states
  47. json_t *mutestatesJ = json_array();
  48. for (int i = 0; i < 8; i++) {
  49. json_t *mutestateJ = json_boolean(muteState[i]);
  50. json_array_append_new(mutestatesJ, mutestateJ);
  51. }
  52. json_object_set_new(rootJ, "mutestates", mutestatesJ);
  53. // solo
  54. json_object_set_new(rootJ, "solo", json_integer(solo));
  55. return rootJ;
  56. }
  57. void fromJson(json_t *rootJ) override {
  58. // states
  59. json_t *mutestatesJ = json_object_get(rootJ, "mutestates");
  60. if (mutestatesJ) {
  61. for (int i = 0; i < 8; i++) {
  62. json_t *mutestateJ = json_array_get(mutestatesJ, i);
  63. if (mutestateJ)
  64. muteState[i] = json_boolean_value(mutestateJ);
  65. }
  66. }
  67. // solo
  68. json_t *soloJ = json_object_get(rootJ, "solo");
  69. if (soloJ)
  70. solo = json_integer_value(soloJ);
  71. }
  72. };
  73. void FOUR::step() {
  74. for (int i = 0; i < 4; i++) {
  75. if (soloTrigger[i].process(params[S_PARAM + i].value)+soloTrigger[i+4].process(inputs[TRS_INPUT + i].value))
  76. {
  77. muteState[i+4] ^= true;
  78. solo = (i+1)*muteState[i+4];
  79. };
  80. if (solo==i+1)
  81. {
  82. float in = inputs[IN_INPUT + i].value;
  83. outputs[OUT_OUTPUT + i].value = in;
  84. } else {muteState[i+4] = false;lights[S_LIGHT + i].value = 0;outputs[OUT_OUTPUT + i].value = 0.0;}
  85. if (muteState[i+4]==true)
  86. {
  87. cligno = cligno + 1;
  88. if (cligno ==10000) {lights[S_LIGHT + i].value = !lights[S_LIGHT + i].value;cligno =0;}
  89. }
  90. }
  91. for (int i = 0; i < 4; i++) {
  92. if (muteTrigger[i].process(params[M_PARAM + i].value)+muteTrigger[i+4].process(inputs[TRM_INPUT + i].value))
  93. muteState[i] ^= true;
  94. float in = inputs[IN_INPUT + i].value;
  95. if (solo == 0) outputs[OUT_OUTPUT + i].value = muteState[i] ? in : 0.0;
  96. lights[M_LIGHT + i].value = muteState[i];
  97. }
  98. }
  99. struct FOURWidget : ModuleWidget {
  100. FOURWidget(FOUR *module);
  101. };
  102. FOURWidget::FOURWidget(FOUR *module) : ModuleWidget(module) {
  103. setPanel(SVG::load(assetPlugin(plugin, "res/FOUR.svg")));
  104. int y = 56;
  105. addChild(Widget::create<ScrewSilver>(Vec(15, 0)));
  106. addChild(Widget::create<ScrewSilver>(Vec(box.size.x-30, 0)));
  107. addChild(Widget::create<ScrewSilver>(Vec(15, 365)));
  108. addChild(Widget::create<ScrewSilver>(Vec(box.size.x-30, 365)));
  109. for (int i = 0; i < 4; i++) {
  110. addInput(Port::create<PJ301MPort>(Vec(15, y),Port::INPUT, module, FOUR::IN_INPUT + i));
  111. addInput(Port::create<PJ301MPort>(Vec(21, y+25),Port::INPUT, module, FOUR::TRS_INPUT + i));
  112. addParam(ParamWidget::create<LEDButton>(Vec(45, y+4), module, FOUR::S_PARAM + i, 0.0f, 1.0f, 0.0f));
  113. addChild(ModuleLightWidget::create<MediumLight<BlueLight>>(Vec(45+4.4, y+8.4), module, FOUR::S_LIGHT + i));
  114. addInput(Port::create<PJ301MPort>(Vec(46, y+31),Port::INPUT, module, FOUR::TRM_INPUT + i));
  115. addParam(ParamWidget::create<LEDButton>(Vec(70, y+4), module, FOUR::M_PARAM + i, 0.0f, 1.0f, 0.0f));
  116. addChild(ModuleLightWidget::create<MediumLight<BlueLight>>(Vec(70+4.4, y+8.4), module, FOUR::M_LIGHT + i));
  117. addOutput(Port::create<PJ301MPort>(Vec(95, y), Port::OUTPUT, module, FOUR::OUT_OUTPUT + i));
  118. y = y + 75 ;
  119. }
  120. }
  121. } // namespace rack_plugin_cf
  122. using namespace rack_plugin_cf;
  123. RACK_PLUGIN_MODEL_INIT(cf, FOUR) {
  124. Model *modelFOUR = Model::create<FOUR, FOURWidget>("cf", "FOUR", "Four", UTILITY_TAG);
  125. return modelFOUR;
  126. }