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.

155 lines
4.9KB

  1. #include "Bidoo.hpp"
  2. #include "BidooComponents.hpp"
  3. #include "dsp/digital.hpp"
  4. using namespace std;
  5. namespace rack_plugin_Bidoo {
  6. struct RABBIT : Module {
  7. enum ParamIds {
  8. BITOFF_PARAM,
  9. BITREV_PARAM = BITOFF_PARAM + 8,
  10. NUM_PARAMS = BITREV_PARAM + 8
  11. };
  12. enum InputIds {
  13. L_INPUT,
  14. R_INPUT,
  15. BITOFF_INPUT,
  16. BITREV_INPUT = BITOFF_INPUT + 8,
  17. NUM_INPUTS = BITREV_INPUT + 8
  18. };
  19. enum OutputIds {
  20. L_OUTPUT,
  21. R_OUTPUT,
  22. NUM_OUTPUTS
  23. };
  24. enum LightIds {
  25. BITOFF_LIGHTS,
  26. BITREV_LIGHTS = BITOFF_LIGHTS + 8,
  27. NUM_LIGHTS = BITREV_LIGHTS + 8
  28. };
  29. SchmittTrigger bitOffTrigger[8], bitRevTrigger[8];
  30. bool bitOff[8];
  31. bool bitRev[8];
  32. RABBIT() : Module(NUM_PARAMS, NUM_INPUTS, NUM_OUTPUTS, NUM_LIGHTS) {
  33. memset(&bitOff,0,8*sizeof(bool));
  34. memset(&bitRev,0,8*sizeof(bool));
  35. }
  36. ~RABBIT() {
  37. }
  38. json_t *toJson() override {
  39. json_t *rootJ = json_object();
  40. for (int i=0; i<8; i++) {
  41. json_object_set_new(rootJ, ("bitOff" + to_string(i)).c_str(), json_boolean(bitOff[i]));
  42. json_object_set_new(rootJ, ("bitRev" + to_string(i)).c_str(), json_boolean(bitRev[i]));
  43. }
  44. return rootJ;
  45. }
  46. void fromJson(json_t *rootJ) override {
  47. for (int i=0; i<8; i++) {
  48. json_t *jbitOff = json_object_get(rootJ, ("bitOff" + to_string(i)).c_str());
  49. if (jbitOff) {
  50. bitOff[i] = json_is_true(jbitOff) ? 1 : 0;
  51. }
  52. json_t *jbitRev = json_object_get(rootJ, ("bitRev" + to_string(i)).c_str());
  53. if (jbitRev) {
  54. bitRev[i] = json_is_true(jbitRev) ? 1 : 0;
  55. }
  56. }
  57. }
  58. void step() override;
  59. };
  60. void RABBIT::step() {
  61. float in_L = clamp(inputs[L_INPUT].value,-10.0f,10.0f);
  62. float in_R = clamp(inputs[R_INPUT].value,-10.0f,10.0f);
  63. in_L = roundf(clamp(in_L / 20.0f + 0.5f, 0.0f, 1.0f) * 255);
  64. in_R = roundf(clamp(in_R / 20.0f + 0.5f, 0.0f, 1.0f) * 255);
  65. unsigned char red_L = in_L;
  66. unsigned char red_R = in_R;
  67. for (int i = 0 ; i < 8 ; i++ ) {
  68. if (bitOffTrigger[i].process(params[BITOFF_PARAM+i].value + inputs[BITOFF_INPUT+i].value))
  69. {
  70. bitOff[i] = !bitOff[i];
  71. }
  72. if (bitRevTrigger[i].process(params[BITREV_PARAM+i].value + inputs[BITREV_INPUT+i].value))
  73. {
  74. bitRev[i] = !bitRev[i];
  75. }
  76. if (bitOff[i]) {
  77. red_L &= ~(1 << i);
  78. red_R &= ~(1 << i);
  79. }
  80. else {
  81. if (bitRev[i]) {
  82. red_L ^= ~(1 << i);
  83. red_R ^= ~(1 << i);
  84. }
  85. }
  86. lights[BITOFF_LIGHTS + i].value = bitOff[i] ? 1.0f : 0.0f;
  87. lights[BITREV_LIGHTS + i].value = bitRev[i] ? 1.0f : 0.0f;
  88. }
  89. outputs[L_OUTPUT].value = clamp(((((float)red_L/255.0f))-0.5f)*20.0f,-10.0f,10.0f);
  90. outputs[R_OUTPUT].value = clamp(((((float)red_R/255.0f))-0.5f)*20.0f,-10.0f,10.0f);
  91. }
  92. template <typename BASE>
  93. struct RabbitLight : BASE {
  94. RabbitLight() {
  95. this->box.size = mm2px(Vec(6.0f, 6.0f));
  96. }
  97. };
  98. struct RABBITWidget : ModuleWidget {
  99. RABBITWidget(RABBIT *module) : ModuleWidget(module) {
  100. setPanel(SVG::load(assetPlugin(plugin, "res/RABBIT.svg")));
  101. addChild(Widget::create<ScrewSilver>(Vec(RACK_GRID_WIDTH, 0)));
  102. addChild(Widget::create<ScrewSilver>(Vec(box.size.x - 2 * RACK_GRID_WIDTH, 0)));
  103. addChild(Widget::create<ScrewSilver>(Vec(RACK_GRID_WIDTH, RACK_GRID_HEIGHT - RACK_GRID_WIDTH)));
  104. addChild(Widget::create<ScrewSilver>(Vec(box.size.x - 2 * RACK_GRID_WIDTH, RACK_GRID_HEIGHT - RACK_GRID_WIDTH)));
  105. for (int i = 0; i<8; i++) {
  106. addParam(ParamWidget::create<LEDBezel>(Vec(27.0f, 50.0f + 32.0f * i), module, RABBIT::BITOFF_PARAM + i, 0.0f, 1.0f, 0.0f));
  107. addChild(ModuleLightWidget::create<RabbitLight<RedLight>>(Vec(29.0f, 52.0f + 32.0f * i), module, RABBIT::BITOFF_LIGHTS + i));
  108. addInput(Port::create<TinyPJ301MPort>(Vec(8.0f, 54.0f + 32.0f * i), Port::INPUT, module, RABBIT::BITOFF_INPUT + i));
  109. addInput(Port::create<TinyPJ301MPort>(Vec(83.0f, 54.0f + 32.0f * i), Port::INPUT, module, RABBIT::BITREV_INPUT + i));
  110. addParam(ParamWidget::create<LEDBezel>(Vec(57.0f, 50.0f + 32.0f * i), module, RABBIT::BITREV_PARAM + i, 0.0f, 1.0f, 0.0f));
  111. addChild(ModuleLightWidget::create<RabbitLight<BlueLight>>(Vec(59.0f, 52.0f + 32.0f * i), module, RABBIT::BITREV_LIGHTS + i));
  112. }
  113. addInput(Port::create<TinyPJ301MPort>(Vec(24.0f, 319.0f), Port::INPUT, module, RABBIT::L_INPUT));
  114. addInput(Port::create<TinyPJ301MPort>(Vec(24.0f, 339.0f), Port::INPUT, module, RABBIT::R_INPUT));
  115. addOutput(Port::create<TinyPJ301MPort>(Vec(78.0f, 319.0f),Port::OUTPUT, module, RABBIT::L_OUTPUT));
  116. addOutput(Port::create<TinyPJ301MPort>(Vec(78.0f, 339.0f),Port::OUTPUT, module, RABBIT::R_OUTPUT));
  117. }
  118. };
  119. } // namespace rack_plugin_Bidoo
  120. using namespace rack_plugin_Bidoo;
  121. RACK_PLUGIN_MODEL_INIT(Bidoo, RABBIT) {
  122. Model *modelRABBIT = Model::create<RABBIT, RABBITWidget>("Bidoo", "rabBIT", "rabBIT bit crusher", EFFECT_TAG, DIGITAL_TAG, DISTORTION_TAG);
  123. return modelRABBIT;
  124. }