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.

162 lines
4.1KB

  1. #pragma once
  2. #include "FunVCO.h"
  3. #include "IComposite.h"
  4. template <class TBase>
  5. class FunDescription : public IComposite
  6. {
  7. public:
  8. Config getParam(int i) override;
  9. int getNumParams() override;
  10. };
  11. template <class TBase>
  12. class FunVCOComposite : public TBase
  13. {
  14. public:
  15. FunVCOComposite()
  16. {
  17. init();
  18. }
  19. FunVCOComposite(struct Module * module) : TBase(module)
  20. {
  21. init();
  22. }
  23. enum ParamIds
  24. {
  25. MODE_PARAM,
  26. SYNC_PARAM,
  27. FREQ_PARAM,
  28. FINE_PARAM,
  29. FM_PARAM,
  30. PW_PARAM,
  31. PWM_PARAM,
  32. NUM_PARAMS
  33. };
  34. enum InputIds
  35. {
  36. PITCH_INPUT,
  37. FM_INPUT,
  38. SYNC_INPUT,
  39. PW_INPUT,
  40. NUM_INPUTS
  41. };
  42. enum OutputIds
  43. {
  44. SIN_OUTPUT,
  45. TRI_OUTPUT,
  46. SAW_OUTPUT,
  47. SQR_OUTPUT,
  48. NUM_OUTPUTS
  49. };
  50. enum LightIds
  51. {
  52. NUM_LIGHTS
  53. };
  54. /** Implement IComposite
  55. */
  56. static std::shared_ptr<IComposite> getDescription()
  57. {
  58. return std::make_shared<FunDescription<TBase>>();
  59. }
  60. void step() override;
  61. void init()
  62. {
  63. oscillator.init();
  64. }
  65. void setSampleRate(float rate)
  66. {
  67. oscillator.sampleTime = 1.f / rate;
  68. }
  69. private:
  70. #ifdef _ORIGVCO
  71. VoltageControlledOscillatorOrig<16, 16> oscillator;
  72. #else
  73. VoltageControlledOscillator<16, 16> oscillator;
  74. #endif
  75. };
  76. template <class TBase>
  77. int FunDescription<TBase>::getNumParams()
  78. {
  79. return FunVCOComposite<TBase>::NUM_PARAMS;
  80. }
  81. template <class TBase>
  82. inline IComposite::Config FunDescription<TBase>::getParam(int i)
  83. {
  84. Config ret(0, 1, 0, "");
  85. switch(i) {
  86. case FunVCOComposite<TBase>::MODE_PARAM:
  87. ret = {0.0f, 1.0f, 1.0f, "Analog/digital mode"};
  88. break;
  89. case FunVCOComposite<TBase>::SYNC_PARAM:
  90. ret = {0.0f, 1.0f, 1.0f, "Sync hard/soft"};
  91. break;
  92. case FunVCOComposite<TBase>::FREQ_PARAM:
  93. ret = {-54.0f, 54.0f, 0.0f, "Frequency"};
  94. break;
  95. case FunVCOComposite<TBase>::FINE_PARAM:
  96. ret = {-1.0f, 1.0f, 0.0f, "Fine frequency"};
  97. break;
  98. case FunVCOComposite<TBase>::FM_PARAM:
  99. ret = {0.0f, 1.0f, 0.0f, "Pitch modulation depth"};
  100. break;
  101. case FunVCOComposite<TBase>::PW_PARAM:
  102. ret = {0.0f, 1.0f, 0.5f, "Pulse width"};
  103. break;
  104. case FunVCOComposite<TBase>::PWM_PARAM:
  105. ret = {0.0f, 1.0f, 0.0f, "Pulse width modulation depth"};
  106. break;
  107. default:
  108. assert(false);
  109. }
  110. return ret;
  111. }
  112. template <class TBase>
  113. inline void FunVCOComposite<TBase>::step()
  114. {
  115. oscillator.analog = TBase::params[MODE_PARAM].value > 0.0f;
  116. oscillator.soft = TBase::params[SYNC_PARAM].value <= 0.0f;
  117. float pitchFine = 3.0f * sq::quadraticBipolar(TBase::params[FINE_PARAM].value);
  118. float pitchCv = 12.0f * TBase::inputs[PITCH_INPUT].value;
  119. if (TBase::inputs[FM_INPUT].active) {
  120. pitchCv += sq::quadraticBipolar(TBase::params[FM_PARAM].value) * 12.0f * TBase::inputs[FM_INPUT].value;
  121. }
  122. oscillator.setPitch(TBase::params[FREQ_PARAM].value, pitchFine + pitchCv);
  123. oscillator.setPulseWidth(TBase::params[PW_PARAM].value + TBase::params[PWM_PARAM].value * TBase::inputs[PW_INPUT].value / 10.0f);
  124. oscillator.syncEnabled = TBase::inputs[SYNC_INPUT].active;
  125. #ifndef _ORIGVCO
  126. oscillator.sawEnabled = TBase::outputs[SAW_OUTPUT].active;
  127. oscillator.sinEnabled = TBase::outputs[SIN_OUTPUT].active;
  128. oscillator.sqEnabled = TBase::outputs[SQR_OUTPUT].active;
  129. oscillator.triEnabled = TBase::outputs[TRI_OUTPUT].active;
  130. #endif
  131. oscillator.process(TBase::engineGetSampleTime(), TBase::inputs[SYNC_INPUT].value);
  132. // Set output
  133. if (TBase::outputs[SIN_OUTPUT].active)
  134. TBase::outputs[SIN_OUTPUT].value = 5.0f * oscillator.sin();
  135. if (TBase::outputs[TRI_OUTPUT].active)
  136. TBase::outputs[TRI_OUTPUT].value = 5.0f * oscillator.tri();
  137. if (TBase::outputs[SAW_OUTPUT].active)
  138. TBase::outputs[SAW_OUTPUT].value = 5.0f * oscillator.saw();
  139. if (TBase::outputs[SQR_OUTPUT].active)
  140. TBase::outputs[SQR_OUTPUT].value = 5.0f * oscillator.sqr();
  141. }