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.

109 lines
3.5KB

  1. #include "BaconPlugs.hpp"
  2. #include "ChipSym.hpp"
  3. namespace rack_plugin_BaconMusic {
  4. struct ChipYourWave : virtual Module {
  5. enum ParamIds {
  6. FREQ_KNOB,
  7. WAVEFORM_START,
  8. NUM_PARAMS = WAVEFORM_START + 32
  9. };
  10. enum InputIds {
  11. FREQ_CV,
  12. NUM_INPUTS
  13. };
  14. enum OutputIds {
  15. WAVE_OUTPUT,
  16. NUM_OUTPUTS
  17. };
  18. enum LightIds {
  19. NUM_LIGHTS
  20. };
  21. ChipSym::NESArbitraryWaveform narb;
  22. ChipYourWave() : Module( NUM_PARAMS, NUM_INPUTS, NUM_OUTPUTS, NUM_LIGHTS ),
  23. narb( -5.0, 5.0, engineGetSampleRate() )
  24. {
  25. narb.setDigWavelength( 2<<8 );
  26. }
  27. float digWFInSeconds( float pitchKnob, float pitchCV )
  28. {
  29. // This is the frequency tuning used in Fundamental/VCO so lets be consistent
  30. float pitch = pitchKnob + pitchCV;
  31. float freq = 261.626f * powf( 2.0f, pitch / 12.0f );
  32. // OK so now we have the frequency. We need the wavelength though. Simple
  33. float wl = 1.0f / freq;
  34. return wl;
  35. }
  36. void step() override
  37. {
  38. float dwf = digWFInSeconds( params[ FREQ_KNOB ].value, 12.0f * inputs[ FREQ_CV ].value );
  39. narb.setWavelengthInSeconds( dwf );
  40. for( int i=0; i<32; ++i )
  41. narb.setWaveformPoint( i, params[ WAVEFORM_START + i ].value );
  42. if( outputs[ WAVE_OUTPUT ].active )
  43. outputs[ WAVE_OUTPUT ].value = narb.step();
  44. }
  45. };
  46. struct ChipYourWaveWidget : ModuleWidget {
  47. ChipYourWaveWidget( ChipYourWave *module);
  48. };
  49. ChipYourWaveWidget::ChipYourWaveWidget( ChipYourWave *module ) : ModuleWidget( module )
  50. {
  51. box.size = Vec( SCREW_WIDTH * 23, RACK_HEIGHT );
  52. BaconBackground *bg = new BaconBackground( box.size, "ChipYourWave" );
  53. addChild( bg->wrappedInFramebuffer());
  54. Vec outP = Vec( box.size.x - 40, 45 + 30 );
  55. bg->addPlugLabel( outP, BaconBackground::SIG_OUT, "out" );
  56. addOutput( Port::create< PJ301MPort >( outP,
  57. Port::OUTPUT,
  58. module,
  59. ChipYourWave::WAVE_OUTPUT ) );
  60. bg->addLabel( Vec( 50, 45 ), "Freq", 14, NVG_ALIGN_LEFT | NVG_ALIGN_BOTTOM );
  61. addParam( ParamWidget::create< RoundHugeBlackKnob >( Vec( 10, 50 ), module,
  62. ChipYourWave::FREQ_KNOB, -54.0f, 54.0f, 0.0f ) );
  63. Vec fcv = Vec( 56 + 20, 45 + 30 );
  64. bg->addPlugLabel( fcv, BaconBackground::SIG_IN, "v/o" );
  65. addInput( Port::create< PJ301MPort >( fcv,
  66. Port::INPUT,
  67. module,
  68. ChipYourWave::FREQ_CV ) );
  69. bg->addLabel( Vec( bg->cx(), 135 ), "Draw your Digital Waveform Here", 14, NVG_ALIGN_CENTER | NVG_ALIGN_BOTTOM );
  70. for( int i=0; i<32; ++i )
  71. {
  72. addParam( ParamWidget::create< NStepDraggableLEDWidget< 16, RedGreenFromMiddleColorModel >>( Vec( 10 + 10 * i, 140 ), module,
  73. ChipYourWave::WAVEFORM_START + i,
  74. 0, 15,
  75. module->narb.getWaveformPoint( i )) );
  76. }
  77. }
  78. } // namespace rack_plugin_BaconMusic
  79. using namespace rack_plugin_BaconMusic;
  80. RACK_PLUGIN_MODEL_INIT(BaconMusic, ChipYourWave) {
  81. Model *modelChipYourWave = Model::create<ChipYourWave, ChipYourWaveWidget>("Bacon Music", "ChipYourWave", "ChipYourWave", OSCILLATOR_TAG );
  82. return modelChipYourWave;
  83. }