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.

156 lines
5.2KB

  1. #include "BaconPlugs.hpp"
  2. /*
  3. ** ToDo:
  4. ** Add lights for on/off
  5. ** Add a 7 segment display for step count
  6. */
  7. namespace rack_plugin_BaconMusic {
  8. struct Bitulator : Module {
  9. enum ParamIds {
  10. WET_DRY_MIX,
  11. STEP_COUNT,
  12. AMP_LEVEL,
  13. BITULATE,
  14. CLIPULATE,
  15. NUM_PARAMS
  16. };
  17. enum InputIds {
  18. SIGNAL_INPUT,
  19. NUM_INPUTS
  20. };
  21. enum OutputIds {
  22. CRUNCHED_OUTPUT,
  23. NUM_OUTPUTS
  24. };
  25. enum LightIds {
  26. BITULATING_LIGHT,
  27. CRUNCHING_LIGHT,
  28. NUM_LIGHTS
  29. };
  30. Bitulator() : Module( NUM_PARAMS, NUM_INPUTS, NUM_OUTPUTS, NUM_LIGHTS ) {
  31. params[ WET_DRY_MIX ].value = 1.0;
  32. params[ STEP_COUNT ].value = 6;
  33. params[ AMP_LEVEL ].value = 1;
  34. params[ BITULATE ].value = 1;
  35. params[ CLIPULATE ].value = 1;
  36. lights[ BITULATING_LIGHT ].value = 1;
  37. lights[ CRUNCHING_LIGHT ].value = 1;
  38. }
  39. void step() override
  40. {
  41. float vin = inputs[ SIGNAL_INPUT ].value;
  42. float wd = params[ WET_DRY_MIX ].value;
  43. // Signals are +/-5V signals of course. So
  44. float res = 0;
  45. if( params[ BITULATE ].value > 0 ) {
  46. float qi = params[ STEP_COUNT ].value / 2;
  47. float crunch = (int)( (vin/5.0) * qi ) / qi * 5.0;
  48. res = crunch;
  49. lights[ BITULATING_LIGHT ].value = 1;
  50. }
  51. else
  52. {
  53. res = vin;
  54. lights[ BITULATING_LIGHT ].value = 0;
  55. }
  56. if( params[ CLIPULATE ].value > 0 ) {
  57. float al = params[ AMP_LEVEL ].value;
  58. res = clamp( res * al, -5.0f, 5.0f );
  59. lights[ CRUNCHING_LIGHT ].value = 1;
  60. }
  61. else {
  62. lights[ CRUNCHING_LIGHT ].value = 0;
  63. }
  64. outputs[ CRUNCHED_OUTPUT ].value = wd * res + ( 1.0 - wd ) * vin;
  65. }
  66. };
  67. struct BitulatorWidget : ModuleWidget {
  68. BitulatorWidget( Bitulator *model );
  69. };
  70. BitulatorWidget::BitulatorWidget( Bitulator *model ) : ModuleWidget( model )
  71. {
  72. box.size = Vec( SCREW_WIDTH * 6, RACK_HEIGHT );
  73. BaconBackground *bg = new BaconBackground( box.size, "Bitulator" );
  74. addChild( bg->wrappedInFramebuffer() );
  75. int wdpos = 40;
  76. bg->addLabel( Vec( bg->cx(), wdpos ), "Mix", 14, NVG_ALIGN_CENTER | NVG_ALIGN_MIDDLE );
  77. bg->addLabel( Vec( bg->cx() + 10, wdpos + 72 ), "Wet", 13, NVG_ALIGN_LEFT | NVG_ALIGN_TOP );
  78. bg->addLabel( Vec( bg->cx() - 10, wdpos + 72 ), "Dry", 13, NVG_ALIGN_RIGHT | NVG_ALIGN_TOP );
  79. addParam( ParamWidget::create< RoundHugeBlackKnob >( Vec( bg->cx( 56 ), wdpos + 10 ),
  80. module,
  81. Bitulator::WET_DRY_MIX,
  82. 0, 1, 1 ));
  83. Vec cr( 5, 140 ), rs( box.size.x-10, 70 );
  84. bg->addRoundedBorder( cr, rs );
  85. bg->addLabel( Vec( bg->cx(), cr.y+3 ), "Quantize", 14, NVG_ALIGN_CENTER|NVG_ALIGN_TOP );
  86. addChild( ModuleLightWidget::create< SmallLight< BlueLight > >( cr.plus( Vec( 5, 5 ) ), module, Bitulator::BITULATING_LIGHT ) );
  87. addParam( ParamWidget::create< CKSS >( cr.plus( Vec( 5, 25 ) ), module, Bitulator::BITULATE, 0, 1, 1 ) );
  88. Vec knobPos = Vec( cr.x + rs.x - 36 - 12, cr.y + 18 );
  89. Vec knobCtr = knobPos.plus( Vec( 18, 18 ) );
  90. addParam( ParamWidget::create< RoundLargeBlackKnob >( knobPos,
  91. module,
  92. Bitulator::STEP_COUNT,
  93. 2, 16, 6 ));
  94. bg->addLabel( knobCtr.plus( Vec( 8, 21 ) ), "smth", 10, NVG_ALIGN_LEFT | NVG_ALIGN_TOP );
  95. bg->addLabel( knobCtr.plus( Vec( -8, 21 ) ), "crnch", 10, NVG_ALIGN_RIGHT | NVG_ALIGN_TOP );
  96. cr = Vec( 5, 215 );
  97. bg->addRoundedBorder( cr, rs );
  98. bg->addLabel( Vec( bg->cx( 5 ), cr.y+3 ), "Amp'n'Clip", 14, NVG_ALIGN_CENTER|NVG_ALIGN_TOP );
  99. addChild( ModuleLightWidget::create< SmallLight< BlueLight > >( cr.plus( Vec( 5, 5 ) ), module, Bitulator::CRUNCHING_LIGHT ) );
  100. addParam( ParamWidget::create< CKSS >( cr.plus( Vec( 5, 25 ) ), module, Bitulator::CLIPULATE, 0, 1, 1 ) );
  101. knobPos = Vec( cr.x + rs.x - 36 - 12, cr.y + 18 );
  102. knobCtr = knobPos.plus( Vec( 18, 18 ) );
  103. addParam( ParamWidget::create< RoundLargeBlackKnob >( knobPos,
  104. module,
  105. Bitulator::AMP_LEVEL,
  106. 1, 10, 1 ) );
  107. bg->addLabel( knobCtr.plus( Vec( 12, 21 ) ), "11", 10, NVG_ALIGN_LEFT | NVG_ALIGN_TOP );
  108. bg->addLabel( knobCtr.plus( Vec( -8, 21 ) ), "one", 10, NVG_ALIGN_RIGHT | NVG_ALIGN_TOP );
  109. Vec inP = Vec( 10, RACK_HEIGHT - 15 - 43 );
  110. Vec outP = Vec( box.size.x - 24 - 10, RACK_HEIGHT - 15 - 43 );
  111. bg->addPlugLabel( inP, BaconBackground::SIG_IN, "in" );
  112. addInput( Port::create< PJ301MPort >( inP, Port::INPUT,
  113. module,
  114. Bitulator::SIGNAL_INPUT ) );
  115. bg->addPlugLabel( outP, BaconBackground::SIG_OUT, "out" );
  116. addOutput( Port::create< PJ301MPort >( outP, Port::OUTPUT,
  117. module,
  118. Bitulator::CRUNCHED_OUTPUT ) );
  119. }
  120. } // namespace rack_plugin_BaconMusic
  121. using namespace rack_plugin_BaconMusic;
  122. RACK_PLUGIN_MODEL_INIT(BaconMusic, Bitulator) {
  123. Model *modelBitulator = Model::create< Bitulator, BitulatorWidget >("Bacon Music", "Bitulator", "Bitulator", DISTORTION_TAG);
  124. return modelBitulator;
  125. }