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.

129 lines
4.2KB

  1. #include "BaconPlugs.hpp"
  2. #include "ChipSym.hpp"
  3. namespace rack_plugin_BaconMusic {
  4. struct ChipWaves : virtual Module {
  5. enum ParamIds {
  6. FREQ_KNOB,
  7. PULSE_CYCLE,
  8. NUM_PARAMS
  9. };
  10. enum InputIds {
  11. FREQ_CV,
  12. NUM_INPUTS
  13. };
  14. enum OutputIds {
  15. PULSE_OUTPUT,
  16. TRI_OUTPUT,
  17. NUM_OUTPUTS
  18. };
  19. enum LightIds {
  20. PULSE_CYCLE_LIGHT,
  21. NUM_LIGHTS
  22. };
  23. ChipSym::NESPulse npulse;
  24. ChipSym::NESTriangle ntri;
  25. ChipWaves() : Module( NUM_PARAMS, NUM_INPUTS, NUM_OUTPUTS, NUM_LIGHTS ),
  26. npulse( -5.0, 5.0, engineGetSampleRate() ),
  27. ntri( -5.0, 5.0, engineGetSampleRate() )
  28. {
  29. npulse.setDigWavelength( 2<<9 );
  30. ntri.setDigWavelength( 2<<8 );
  31. }
  32. float digWFInSeconds( float pitchKnob, float pitchCV )
  33. {
  34. // This is the frequency tuning used in Fundamental/VCO so lets be consistent
  35. float pitch = pitchKnob + pitchCV;
  36. float freq = 261.626f * powf( 2.0f, pitch / 12.0f );
  37. // OK so now we have the frequency. We need the wavelength though. Simple
  38. float wl = 1.0f / freq;
  39. return wl;
  40. }
  41. void step() override
  42. {
  43. float dwf = digWFInSeconds( params[ FREQ_KNOB ].value, 12.0f * inputs[ FREQ_CV ].value );
  44. ntri.setWavelengthInSeconds( dwf );
  45. npulse.setWavelengthInSeconds( dwf );
  46. int dc = clamp( (int)(params[ PULSE_CYCLE ].value ), 0, 3 );
  47. npulse.setDutyCycle( dc );
  48. lights[ PULSE_CYCLE_LIGHT ].value = dc;
  49. if( outputs[ TRI_OUTPUT ].active )
  50. outputs[ TRI_OUTPUT ].value = ntri.step();
  51. if( outputs[ PULSE_OUTPUT ].active )
  52. outputs[ PULSE_OUTPUT ].value = npulse.step();
  53. }
  54. };
  55. struct ChipWavesWidget : ModuleWidget {
  56. ChipWavesWidget( ChipWaves *module);
  57. };
  58. ChipWavesWidget::ChipWavesWidget( ChipWaves *module ) : ModuleWidget( module )
  59. {
  60. box.size = Vec( SCREW_WIDTH * 8, RACK_HEIGHT );
  61. BaconBackground *bg = new BaconBackground( box.size, "ChipWaves" );
  62. addChild( bg->wrappedInFramebuffer());
  63. Vec outP = Vec( bg->cx( 24 ) + 25, RACK_HEIGHT - 15 - 43 );
  64. bg->addPlugLabel( outP, BaconBackground::SIG_OUT, "pulse" );
  65. addOutput( Port::create< PJ301MPort >( outP,
  66. Port::OUTPUT,
  67. module,
  68. ChipWaves::PULSE_OUTPUT ) );
  69. Vec outT = Vec( bg->cx( 24 ) - 25, RACK_HEIGHT - 15 - 43 );
  70. bg->addPlugLabel( outT, BaconBackground::SIG_OUT, "tri" );
  71. addOutput( Port::create< PJ301MPort >( outT,
  72. Port::OUTPUT,
  73. module,
  74. ChipWaves::TRI_OUTPUT ) );
  75. Vec fcv = Vec( bg->cx( 24 ) + 35, 160 );
  76. bg->addPlugLabel( fcv, BaconBackground::SIG_IN, "v/o" );
  77. addInput( Port::create< PJ301MPort >( fcv,
  78. Port::INPUT,
  79. module,
  80. ChipWaves::FREQ_CV ) );
  81. bg->addRoundedBorder( Vec( 10, 140 ), Vec ( 63, 49 ) );
  82. bg->addLabel( Vec( 40, 144 ), "Duty Cycle", 12, NVG_ALIGN_CENTER | NVG_ALIGN_TOP );
  83. int ybot = 140 + 24 + 5 + 20;
  84. addParam( ParamWidget::create< RoundSmallBlackKnob >( Vec( 16, ybot - 3 - 28 ),
  85. module,
  86. ChipWaves::PULSE_CYCLE,
  87. 0, 3, 0 ) );
  88. addChild( ModuleLightWidget::create< SevenSegmentLight< BlueLight, 2 > >( Vec( 47, ybot - 5 - 24 ),
  89. module,
  90. ChipWaves::PULSE_CYCLE_LIGHT ) );
  91. bg->addLabel( Vec( bg->cx(), 45 ), "Freq", 14, NVG_ALIGN_CENTER | NVG_ALIGN_BOTTOM );
  92. addParam( ParamWidget::create< RoundHugeBlackKnob >( Vec( bg->cx( 56 ), 50 ), module,
  93. ChipWaves::FREQ_KNOB, -54.0f, 54.0f, 0.0f ) );
  94. }
  95. } // namespace rack_plugin_BaconMusic
  96. using namespace rack_plugin_BaconMusic;
  97. RACK_PLUGIN_MODEL_INIT(BaconMusic, ChipWaves) {
  98. Model *modelChipWaves = Model::create<ChipWaves, ChipWavesWidget>("Bacon Music", "ChipWaves", "ChipWaves", OSCILLATOR_TAG );
  99. return modelChipWaves;
  100. }