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.

116 lines
3.3KB

  1. #include "BaconPlugs.hpp"
  2. /*
  3. ** Based heavily on http://recherche.ircam.fr/pub/dafx11/Papers/66_e.pdf
  4. */
  5. namespace rack_plugin_BaconMusic {
  6. struct ALingADing : Module {
  7. enum ParamIds {
  8. WET_DRY_MIX, // TODO: Implement this
  9. NUM_PARAMS
  10. };
  11. enum InputIds {
  12. SIGNAL_INPUT,
  13. CARRIER_INPUT,
  14. NUM_INPUTS
  15. };
  16. enum OutputIds {
  17. MODULATED_OUTPUT,
  18. NUM_OUTPUTS
  19. };
  20. enum LightIds {
  21. NUM_LIGHTS
  22. };
  23. ALingADing() : Module( NUM_PARAMS, NUM_INPUTS, NUM_OUTPUTS, NUM_LIGHTS ) {
  24. params[ WET_DRY_MIX ].value = 1.0;
  25. }
  26. inline float diode_sim( float in )
  27. {
  28. if( in < 0 ) return 0;
  29. else return 0.2 * log( 1.0 + exp( 10 * ( in - 1 ) ) );
  30. }
  31. void step() override
  32. {
  33. float vin = inputs[ SIGNAL_INPUT ].value;
  34. float vc = inputs[ CARRIER_INPUT ].value;
  35. float wd = params[ WET_DRY_MIX ].value;
  36. float A = 0.5 * vin + vc;
  37. float B = vc - 0.5 * vin;
  38. float dPA = diode_sim( A );
  39. float dMA = diode_sim( -A );
  40. float dPB = diode_sim( B );
  41. float dMB = diode_sim( -B );
  42. float res = dPA + dMA - dPB - dMB;
  43. outputs[ MODULATED_OUTPUT ].value = wd * res + ( 1.0 - wd ) * vin;
  44. }
  45. };
  46. struct ALingADingWidget : ModuleWidget {
  47. ALingADingWidget(ALingADing *module);
  48. };
  49. ALingADingWidget::ALingADingWidget(ALingADing *module) : ModuleWidget( module )
  50. {
  51. box.size = Vec( SCREW_WIDTH * 5, RACK_HEIGHT );
  52. BaconBackground *bg = new BaconBackground( box.size, "ALingADing" );
  53. addChild( bg->wrappedInFramebuffer() );
  54. bg->addPlugLabel( Vec( 7, 70 ), BaconBackground::SIG_IN, "sig" );
  55. addInput( Port::create< PJ301MPort >( Vec( 7, 70 ),
  56. Port::INPUT,
  57. module,
  58. ALingADing::SIGNAL_INPUT ) );
  59. bg->addPlugLabel( Vec( box.size.x-24-7, 70 ), BaconBackground::SIG_IN, "car" );
  60. addInput( Port::create< PJ301MPort >( Vec( box.size.x-24 - 7, 70 ), // That 24 makes no sense but hey
  61. Port::INPUT,
  62. module,
  63. ALingADing::CARRIER_INPUT ) );
  64. bg->addLabel( Vec( bg->cx(), 140 ), "Mix", 14, NVG_ALIGN_CENTER | NVG_ALIGN_MIDDLE );
  65. bg->addLabel( Vec( bg->cx() + 10, 140 + 72 ),
  66. "Wet", 13, NVG_ALIGN_LEFT | NVG_ALIGN_TOP );
  67. bg->addLabel( Vec( bg->cx() - 10, 140 + 72 ),
  68. "Dry", 13, NVG_ALIGN_RIGHT | NVG_ALIGN_TOP );
  69. addParam( ParamWidget::create< RoundHugeBlackKnob >( Vec( bg->cx( 56 ), 150 ),
  70. module,
  71. ALingADing::WET_DRY_MIX,
  72. 0, 1, 1 ));
  73. Vec outP = Vec( bg->cx( 24 ), RACK_HEIGHT - 15 - 43 );
  74. bg->addPlugLabel( outP, BaconBackground::SIG_OUT, "out" );
  75. addOutput( Port::create< PJ301MPort >( outP,
  76. Port::OUTPUT,
  77. module,
  78. ALingADing::MODULATED_OUTPUT ) );
  79. }
  80. } // namespace rack_plugin_BaconMusic
  81. using namespace rack_plugin_BaconMusic;
  82. RACK_PLUGIN_MODEL_INIT(BaconMusic, ALingADing) {
  83. Model *modelALingADing = Model::create<ALingADing,ALingADingWidget>("Bacon Music", "ALingADing", "ALingADing", RING_MODULATOR_TAG);
  84. return modelALingADing;
  85. }