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.

132 lines
3.6KB

  1. /*
  2. Geighths
  3. cv input selects one out of eight outputs to fire a gate from.
  4. assumed input range is 0-10V. full range is split into 8 segments.
  5. with a clock signal connected, the unit goes into sample and hold mode.
  6. PLANS/IDEAS:
  7. - option to use 8bit conversion to break up signal
  8. - internal clock (maybe)
  9. - random/stepped mode(s) with no cvIN but clockIN
  10. - trigger sum bus
  11. */////////////////////////////////////////////////////////////////////////////
  12. #include "pvc.hpp"
  13. #include "dsp/digital.hpp" // SchmittTrigger PulseGenerator
  14. namespace rack_plugin_PvC {
  15. struct Geighths : Module {
  16. enum ParamIds {
  17. INPUT_GAIN,
  18. INPUT_OFFSET,
  19. GATE1_LENGTH,
  20. NUM_PARAMS = GATE1_LENGTH + 8
  21. };
  22. enum InputIds {
  23. CV_IN,
  24. CLOCK_IN,
  25. NUM_INPUTS
  26. };
  27. enum OutputIds {
  28. GATE1_OUT,
  29. NUM_OUTPUTS = GATE1_OUT + 8
  30. };
  31. enum LightIds {
  32. GATE1_LIGHT,
  33. NUM_LIGHTS = GATE1_LIGHT + 8
  34. };
  35. SchmittTrigger clockTrigger;
  36. SchmittTrigger gateTrigger[8];
  37. PulseGenerator gatePulse[8];
  38. bool gateOn[8] {};
  39. float inVal = 0.0f;
  40. float sample = 0.0f;
  41. Geighths() : Module(NUM_PARAMS, NUM_INPUTS, NUM_OUTPUTS, NUM_LIGHTS) {}
  42. void step() override;
  43. void reset() override {
  44. inVal = sample = 0.0f;
  45. for (int i = 0; i < 8; i++) {
  46. gateOn[i] = false;
  47. }
  48. }
  49. };
  50. void Geighths::step() {
  51. float input = inputs[CV_IN].normalize(0.0f) * params[INPUT_GAIN].value + params[INPUT_OFFSET].value;
  52. // TODO: nicer input window scaling
  53. input = clamp(input, 0.0f, 10.0f);
  54. input = rescale(input, 0.0f, 10.0f, 0, 8);
  55. sample = clockTrigger.process(inputs[CLOCK_IN].value) ? input : sample;
  56. inVal = (inputs[CLOCK_IN].active) ? sample : input;
  57. // fire pulse on selected out
  58. for (int i = 0; i < 8; i++) {
  59. gateOn[i] = ((inVal > i) && (inVal < i+1)) ? true : false;
  60. if (gateTrigger[i].process(gateOn[i])) {
  61. gatePulse[i].trigger(params[GATE1_LENGTH + i].value);
  62. }
  63. outputs[GATE1_OUT + i].value = gatePulse[i].process(1.0/engineGetSampleRate()) * 10.0f;
  64. // lights[GATE1_LIGHT + i].value = ((gateOn[i]) || (gatePulse[i].process(1.0/engineGetSampleRate()))) ? 1.0f : 0.0f;
  65. lights[GATE1_LIGHT + i].value = gateOn[i] * 0.75f + gatePulse[i].process(1.0/engineGetSampleRate()) * 0.25f;
  66. }
  67. }
  68. struct GeighthsWidget : ModuleWidget {
  69. GeighthsWidget(Geighths *module);
  70. };
  71. GeighthsWidget::GeighthsWidget(Geighths *module) : ModuleWidget(module) {
  72. setPanel(SVG::load(assetPlugin(plugin, "res/panels/Geighths.svg")));
  73. // screws
  74. addChild(Widget::create<ScrewHead1>(Vec(0, 0)));
  75. addChild(Widget::create<ScrewHead2>(Vec(box.size.x - 15, 0)));
  76. addChild(Widget::create<ScrewHead3>(Vec(0, 365)));
  77. addChild(Widget::create<ScrewHead4>(Vec(box.size.x - 15, 365)));
  78. addInput(Port::create<InPortAud>(Vec(4,22), Port::INPUT, module,Geighths::CV_IN));
  79. addInput(Port::create<InPortBin>(Vec(34,22), Port::INPUT, module,Geighths::CLOCK_IN));
  80. addParam(ParamWidget::create<PvCKnob>(Vec(4, 64),module,Geighths::INPUT_GAIN , -2.0f, 2.0f, 1.0f));
  81. addParam(ParamWidget::create<PvCKnob>(Vec(34, 64),module,Geighths::INPUT_OFFSET, -10.0f, 10.0f, 0.0f));
  82. for (int i = 0; i < 8; i++)
  83. {
  84. addChild(ModuleLightWidget::create<PvCBigLED<BlueLED>>(Vec(4,318 - 30*i),module,Geighths::GATE1_LIGHT + i));
  85. addParam(ParamWidget::create<PvCLEDKnob>(Vec(4, 318 - 30*i),module,Geighths::GATE1_LENGTH + i, 0.002f, 2.0f, 0.02f));
  86. addOutput(Port::create<OutPortBin>(Vec(34, 318 - 30*i), Port::OUTPUT, module,Geighths::GATE1_OUT + i));
  87. }
  88. }
  89. } // namespace rack_plugin_PvC
  90. using namespace rack_plugin_PvC;
  91. RACK_PLUGIN_MODEL_INIT(PvC, Geighths) {
  92. Model *modelGeighths = Model::create<Geighths, GeighthsWidget>(
  93. "PvC", "Geighths", "Geighths", LOGIC_TAG, SAMPLE_AND_HOLD_TAG);
  94. return modelGeighths;
  95. }