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.

168 lines
4.6KB

  1. #include "alikins.hpp"
  2. #include "dsp/digital.hpp"
  3. namespace rack_plugin_Alikins {
  4. struct BigMuteButton : Module {
  5. enum ParamIds {
  6. BIG_MUTE_BUTTON_PARAM,
  7. NUM_PARAMS
  8. };
  9. enum InputIds {
  10. LEFT_INPUT,
  11. RIGHT_INPUT,
  12. NUM_INPUTS
  13. };
  14. enum OutputIds {
  15. LEFT_OUTPUT,
  16. RIGHT_OUTPUT,
  17. NUM_OUTPUTS
  18. };
  19. enum LightIds {
  20. NUM_LIGHTS
  21. };
  22. float gain_mult = 1.0f;
  23. enum FadeState {
  24. UNMUTED_STEADY,
  25. MUTED_STEADY,
  26. MUTED_FADE_DOWN,
  27. UNMUTED_FADE_UP,
  28. INITIAL
  29. };
  30. // FadeState state = UNMUTED_STEADY;
  31. FadeState state = INITIAL;
  32. SchmittTrigger muteOnTrigger;
  33. SchmittTrigger muteOffTrigger;
  34. float gmult2 = 1.0f;
  35. float crossfade_mix = 0.005f;
  36. BigMuteButton() : Module(NUM_PARAMS, NUM_INPUTS, NUM_OUTPUTS, NUM_LIGHTS) {}
  37. void step() override;
  38. void onReset() override {
  39. state = UNMUTED_STEADY;
  40. }
  41. };
  42. void BigMuteButton::step() {
  43. // INITIAL state, choose next state based on current value of BIG_MUTE_BUTTON_PARAM
  44. // since BIG_MUTE_BUTTON_PARAM should be based on either the default, or for a saved
  45. // patch, the value saved to the params JSON.
  46. if (muteOnTrigger.process(params[BIG_MUTE_BUTTON_PARAM].value)) {
  47. // debug("MUTE ON");
  48. state = MUTED_FADE_DOWN;
  49. gmult2 = 1.0f;
  50. }
  51. if (muteOffTrigger.process(!params[BIG_MUTE_BUTTON_PARAM].value)) {
  52. // debug("MUTE OFF");
  53. state = UNMUTED_FADE_UP;
  54. gmult2 = 0.0f;
  55. }
  56. switch(state) {
  57. case INITIAL:
  58. state = (params[BIG_MUTE_BUTTON_PARAM].value == 0.0f) ? UNMUTED_STEADY : MUTED_STEADY;
  59. break;
  60. case MUTED_STEADY:
  61. gmult2 = 0.0f;
  62. break;
  63. case UNMUTED_STEADY:
  64. gmult2 = 1.0f;
  65. break;
  66. case MUTED_FADE_DOWN:
  67. if (isNear(gmult2, 0.0f)) {
  68. state = MUTED_STEADY;
  69. // debug("faded down crossfade to 0.0");
  70. gmult2 = 0.0f;
  71. break;
  72. }
  73. gmult2 = crossfade(gmult2, 0.0f, crossfade_mix);
  74. break;
  75. case UNMUTED_FADE_UP:
  76. if (isNear(gmult2, 1.0f)) {
  77. state = UNMUTED_STEADY;
  78. // debug("faded up crossfade to 1.0");
  79. gmult2 = 1.0f;
  80. break;
  81. }
  82. gmult2 = crossfade(gmult2, 1.0f, crossfade_mix);
  83. break;
  84. }
  85. gmult2 = clamp(gmult2, 0.0f, 1.0f);
  86. outputs[LEFT_OUTPUT].value = inputs[LEFT_INPUT].value * gmult2;
  87. outputs[RIGHT_OUTPUT].value = inputs[RIGHT_INPUT].value * gmult2;
  88. // debug("state: %d, gmult2: %f", state, gmult2);
  89. // TODO: to eliminate worse case DC thump, also apply a RC filter of some sort?
  90. }
  91. struct BigSwitch : SVGSwitch, ToggleSwitch {
  92. BigSwitch() {
  93. addFrame(SVG::load(assetPlugin(plugin, "res/BigMuteButtonMute.svg")));
  94. addFrame(SVG::load(assetPlugin(plugin, "res/BigMuteButtonUnmute.svg")));
  95. }
  96. };
  97. struct BigMuteButtonWidget : ModuleWidget {
  98. BigMuteButtonWidget(BigMuteButton *module);
  99. };
  100. BigMuteButtonWidget::BigMuteButtonWidget(BigMuteButton *module) : ModuleWidget(module) {
  101. box.size = Vec(6 * RACK_GRID_WIDTH, RACK_GRID_HEIGHT);
  102. setPanel(SVG::load(assetPlugin(plugin, "res/BigMuteButton.svg")));
  103. addParam(ParamWidget::create<BigSwitch>(Vec(0.0f, 0.0f),
  104. module,
  105. BigMuteButton::BIG_MUTE_BUTTON_PARAM,
  106. 0.0f, 1.0f, 0.0f));
  107. addInput(Port::create<PJ301MPort>(Vec(4.0f, 302.0f),
  108. Port::INPUT,
  109. module,
  110. BigMuteButton::LEFT_INPUT));
  111. addInput(Port::create<PJ301MPort>(Vec(4.0f, 330.0f),
  112. Port::INPUT,
  113. module,
  114. BigMuteButton::RIGHT_INPUT));
  115. addOutput(Port::create<PJ301MPort>(Vec(60.0f, 302.0f),
  116. Port::OUTPUT,
  117. module,
  118. BigMuteButton::LEFT_OUTPUT));
  119. addOutput(Port::create<PJ301MPort>(Vec(60.0f, 330.0f),
  120. Port::OUTPUT,
  121. module,
  122. BigMuteButton::RIGHT_OUTPUT));
  123. addChild(Widget::create<ScrewSilver>(Vec(0.0, 0)));
  124. addChild(Widget::create<ScrewSilver>(Vec(box.size.x-15, 0)));
  125. addChild(Widget::create<ScrewSilver>(Vec(30, 365)));
  126. }
  127. } // namespace rack_plugin_Alikins
  128. using namespace rack_plugin_Alikins;
  129. RACK_PLUGIN_MODEL_INIT(Alikins, BigMuteButton) {
  130. Model *modelBigMuteButton = Model::create<BigMuteButton, BigMuteButtonWidget>(
  131. "Alikins", "BigMuteButton", "Big Mute Button", UTILITY_TAG);
  132. return modelBigMuteButton;
  133. }