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.

125 lines
4.1KB

  1. //**************************************************************************************
  2. //SawOsc module for VCV Rack by Alfredo Santamaria - AS - https://github.com/AScustomWorks/AS
  3. //
  4. //Code taken from RODENTCAT https://github.com/RODENTCAT/RODENTMODULES
  5. //Code taken from the Fundamentals plugins by Andrew Belt http://www.vcvrack.com
  6. //**************************************************************************************
  7. #include "AS.hpp"
  8. struct SawOsc : Module {
  9. enum ParamIds {
  10. PITCH_PARAM,
  11. BASE_PARAM,
  12. PW_PARAM,
  13. NUM_PARAMS
  14. };
  15. enum InputIds {
  16. PITCH_INPUT,
  17. PW_INPUT,
  18. NUM_INPUTS
  19. };
  20. enum OutputIds {
  21. OSC_OUTPUT,
  22. NUM_OUTPUTS
  23. };
  24. enum LightIds {
  25. FREQ_LIGHT,
  26. NUM_LIGHTS
  27. };
  28. float phase = 0.0f;
  29. float blinkPhase = 0.0f;
  30. float freq = 0.0f;
  31. int base_freq = 0;
  32. SawOsc() : Module(NUM_PARAMS, NUM_INPUTS, NUM_OUTPUTS, NUM_LIGHTS) {}
  33. void step() override;
  34. };
  35. void SawOsc::step() {
  36. // Implement a simple sine oscillator
  37. float deltaTime = 1.0f / engineGetSampleRate();
  38. // Compute the frequency from the pitch parameter and input
  39. base_freq = params[BASE_PARAM].value;
  40. float pitch = params[PITCH_PARAM].value;
  41. pitch += inputs[PITCH_INPUT].value;
  42. pitch = clamp(pitch, -4.0f, 4.0f);
  43. if(base_freq==1){
  44. //Note A4
  45. freq = 440.0f * powf(2.0f, pitch);
  46. }else{
  47. // Note C4
  48. freq = 261.626f * powf(2.0f, pitch);
  49. }
  50. // Accumulate the phase
  51. phase += freq * deltaTime;
  52. if (phase >= 1.0f)
  53. phase -= 1.0f;
  54. //Mod param
  55. float pw = params[PW_PARAM].value*0.1f+1.0f;
  56. //Mod input
  57. float minput = inputs[PW_INPUT].value*0.3f;
  58. //Mod param+input
  59. float pinput = (pw + minput);
  60. // Compute the sine output
  61. //float sine = sinf(2 * M_PI * phase);
  62. //outputs[SINE_OUTPUT].value = 5.0 * sine;
  63. //saw stuff, original dev says square, but it sounds more like a SAW wave, hence this module name hehe
  64. float saw = cos(exp(pinput * M_PI * phase));///0.87;
  65. //dc block
  66. float block_coeff = 1.0f - (2.0f * M_PI * (10.0f / 44100.0f));
  67. float m_prev_in = 0.0f;
  68. float m_prev_out = 0.0f;
  69. m_prev_out = saw - m_prev_in + block_coeff * m_prev_out;
  70. m_prev_in = saw;
  71. //outputs[OSC_OUTPUT].value = 5 * saw;
  72. outputs[OSC_OUTPUT].value = m_prev_out*5;
  73. lights[FREQ_LIGHT].value = (outputs[OSC_OUTPUT].value > 0.0f) ? 1.0f : 0.0f;
  74. }
  75. struct SawOscWidget : ModuleWidget
  76. {
  77. SawOscWidget(SawOsc *module);
  78. };
  79. SawOscWidget::SawOscWidget(SawOsc *module) : ModuleWidget(module) {
  80. setPanel(SVG::load(assetPlugin(plugin, "res/SawOSC.svg")));
  81. //SCREWS - SPECIAL SPACING FOR RACK WIDTH*4
  82. addChild(Widget::create<as_HexScrew>(Vec(0, 0)));
  83. addChild(Widget::create<as_HexScrew>(Vec(box.size.x - RACK_GRID_WIDTH, 0)));
  84. addChild(Widget::create<as_HexScrew>(Vec(0, RACK_GRID_HEIGHT - RACK_GRID_WIDTH)));
  85. addChild(Widget::create<as_HexScrew>(Vec(box.size.x - RACK_GRID_WIDTH, RACK_GRID_HEIGHT - RACK_GRID_WIDTH)));
  86. //LIGHT
  87. addChild(ModuleLightWidget::create<SmallLight<RedLight>>(Vec(22-15, 57), module, SawOsc::FREQ_LIGHT));
  88. //PARAMS
  89. //addParam(ParamWidget::create<as_KnobBlack>(Vec(26, 60), module, SawOsc::PITCH_PARAM, -3.0f, 3.0f, 0.0f));
  90. addParam(ParamWidget::create<as_KnobBlack>(Vec(26-15, 60), module, SawOsc::PITCH_PARAM, -3.0f, 3.0f, 0.0f));
  91. //addParam(ParamWidget::create<as_KnobBlack>(Vec(26-15, 60), module, SawOsc::PITCH_PARAM, -4.75f, 4.75f, -0.75f));
  92. //addParam(ParamWidget::create<as_KnobBlack>(Vec(26, 125), module, SawOsc::PW_PARAM, -4.0, 5.0, -4.0));
  93. addParam(ParamWidget::create<as_KnobBlack>(Vec(26-15, 120), module, SawOsc::PW_PARAM, -4.2f, 5.0f, -4.2f));
  94. //BASE FREQ SWITCH
  95. addParam(ParamWidget::create<as_CKSSH>(Vec(18, 220), module, SawOsc::BASE_PARAM, 0.0f, 1.0f, 1.0f));
  96. //INPUTS
  97. addInput(Port::create<as_PJ301MPort>(Vec(33-15, 180), Port::INPUT, module, SawOsc::PW_INPUT));
  98. addInput(Port::create<as_PJ301MPort>(Vec(33-15, 260), Port::INPUT, module, SawOsc::PITCH_INPUT));
  99. //OUTPUTS
  100. addOutput(Port::create<as_PJ301MPort>(Vec(33-15, 310), Port::OUTPUT, module, SawOsc::OSC_OUTPUT));
  101. }
  102. RACK_PLUGIN_MODEL_INIT(AS, SawOsc) {
  103. Model *modelSawOsc = Model::create<SawOsc, SawOscWidget>("AS", "SawOSC", "TinySawish", OSCILLATOR_TAG);
  104. return modelSawOsc;
  105. }