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.

163 lines
5.6KB

  1. #include <string.h>
  2. #include "AudibleInstruments.hpp"
  3. #include "dsp/digital.hpp"
  4. #include "warps/dsp/modulator.h"
  5. struct Warps : Module {
  6. enum ParamIds {
  7. ALGORITHM_PARAM,
  8. TIMBRE_PARAM,
  9. STATE_PARAM,
  10. LEVEL1_PARAM,
  11. LEVEL2_PARAM,
  12. NUM_PARAMS
  13. };
  14. enum InputIds {
  15. LEVEL1_INPUT,
  16. LEVEL2_INPUT,
  17. ALGORITHM_INPUT,
  18. TIMBRE_INPUT,
  19. CARRIER_INPUT,
  20. MODULATOR_INPUT,
  21. NUM_INPUTS
  22. };
  23. enum OutputIds {
  24. MODULATOR_OUTPUT,
  25. AUX_OUTPUT,
  26. NUM_OUTPUTS
  27. };
  28. enum LightIds {
  29. CARRIER_GREEN_LIGHT, CARRIER_RED_LIGHT,
  30. ALGORITHM_LIGHT,
  31. NUM_LIGHTS = ALGORITHM_LIGHT + 3
  32. };
  33. int frame = 0;
  34. warps::Modulator modulator;
  35. warps::ShortFrame inputFrames[60] = {};
  36. warps::ShortFrame outputFrames[60] = {};
  37. SchmittTrigger stateTrigger;
  38. Warps();
  39. void step() override;
  40. json_t *toJson() override {
  41. json_t *rootJ = json_object();
  42. warps::Parameters *p = modulator.mutable_parameters();
  43. json_object_set_new(rootJ, "shape", json_integer(p->carrier_shape));
  44. return rootJ;
  45. }
  46. void fromJson(json_t *rootJ) override {
  47. json_t *shapeJ = json_object_get(rootJ, "shape");
  48. warps::Parameters *p = modulator.mutable_parameters();
  49. if (shapeJ) {
  50. p->carrier_shape = json_integer_value(shapeJ);
  51. }
  52. }
  53. void onReset() override {
  54. warps::Parameters *p = modulator.mutable_parameters();
  55. p->carrier_shape = 0;
  56. }
  57. void onRandomize() override {
  58. warps::Parameters *p = modulator.mutable_parameters();
  59. p->carrier_shape = randomu32() % 4;
  60. }
  61. };
  62. Warps::Warps() : Module(NUM_PARAMS, NUM_INPUTS, NUM_OUTPUTS, NUM_LIGHTS) {
  63. memset(&modulator, 0, sizeof(modulator));
  64. modulator.Init(96000.0f);
  65. }
  66. void Warps::step() {
  67. // State trigger
  68. warps::Parameters *p = modulator.mutable_parameters();
  69. if (stateTrigger.process(params[STATE_PARAM].value)) {
  70. p->carrier_shape = (p->carrier_shape + 1) % 4;
  71. }
  72. lights[CARRIER_GREEN_LIGHT].value = (p->carrier_shape == 1 || p->carrier_shape == 2) ? 1.0 : 0.0;
  73. lights[CARRIER_RED_LIGHT].value = (p->carrier_shape == 2 || p->carrier_shape == 3) ? 1.0 : 0.0;
  74. // Buffer loop
  75. if (++frame >= 60) {
  76. frame = 0;
  77. p->channel_drive[0] = clamp(params[LEVEL1_PARAM].value + inputs[LEVEL1_INPUT].value / 5.0f, 0.0f, 1.0f);
  78. p->channel_drive[1] = clamp(params[LEVEL2_PARAM].value + inputs[LEVEL2_INPUT].value / 5.0f, 0.0f, 1.0f);
  79. p->modulation_algorithm = clamp(params[ALGORITHM_PARAM].value / 8.0f + inputs[ALGORITHM_INPUT].value / 5.0f, 0.0f, 1.0f);
  80. {
  81. // TODO
  82. // Use the correct light color
  83. NVGcolor algorithmColor = nvgHSL(p->modulation_algorithm, 0.3, 0.4);
  84. lights[ALGORITHM_LIGHT + 0].setBrightness(algorithmColor.r);
  85. lights[ALGORITHM_LIGHT + 1].setBrightness(algorithmColor.g);
  86. lights[ALGORITHM_LIGHT + 2].setBrightness(algorithmColor.b);
  87. }
  88. p->modulation_parameter = clamp(params[TIMBRE_PARAM].value + inputs[TIMBRE_INPUT].value / 5.0f, 0.0f, 1.0f);
  89. p->frequency_shift_pot = params[ALGORITHM_PARAM].value / 8.0;
  90. p->frequency_shift_cv = clamp(inputs[ALGORITHM_INPUT].value / 5.0f, -1.0f, 1.0f);
  91. p->phase_shift = p->modulation_algorithm;
  92. p->note = 60.0 * params[LEVEL1_PARAM].value + 12.0 * inputs[LEVEL1_INPUT].normalize(2.0) + 12.0;
  93. p->note += log2f(96000.0f * engineGetSampleTime()) * 12.0f;
  94. modulator.Process(inputFrames, outputFrames, 60);
  95. }
  96. inputFrames[frame].l = clamp((int) (inputs[CARRIER_INPUT].value / 16.0 * 0x8000), -0x8000, 0x7fff);
  97. inputFrames[frame].r = clamp((int) (inputs[MODULATOR_INPUT].value / 16.0 * 0x8000), -0x8000, 0x7fff);
  98. outputs[MODULATOR_OUTPUT].value = (float)outputFrames[frame].l / 0x8000 * 5.0;
  99. outputs[AUX_OUTPUT].value = (float)outputFrames[frame].r / 0x8000 * 5.0;
  100. }
  101. struct AlgorithmLight : RedGreenBlueLight {
  102. AlgorithmLight() {
  103. box.size = Vec(71, 71);
  104. }
  105. };
  106. struct WarpsWidget : ModuleWidget {
  107. WarpsWidget(Warps *module) : ModuleWidget(module) {
  108. setPanel(SVG::load(assetPlugin(plugin, "res/Warps.svg")));
  109. addChild(Widget::create<ScrewSilver>(Vec(15, 0)));
  110. addChild(Widget::create<ScrewSilver>(Vec(120, 0)));
  111. addChild(Widget::create<ScrewSilver>(Vec(15, 365)));
  112. addChild(Widget::create<ScrewSilver>(Vec(120, 365)));
  113. addParam(ParamWidget::create<Rogan6PSWhite>(Vec(29, 52), module, Warps::ALGORITHM_PARAM, 0.0, 8.0, 0.0));
  114. addParam(ParamWidget::create<Rogan1PSWhite>(Vec(94, 173), module, Warps::TIMBRE_PARAM, 0.0, 1.0, 0.5));
  115. addParam(ParamWidget::create<TL1105>(Vec(16, 182), module, Warps::STATE_PARAM, 0.0, 1.0, 0.0));
  116. addParam(ParamWidget::create<Trimpot>(Vec(14, 213), module, Warps::LEVEL1_PARAM, 0.0, 1.0, 1.0));
  117. addParam(ParamWidget::create<Trimpot>(Vec(53, 213), module, Warps::LEVEL2_PARAM, 0.0, 1.0, 1.0));
  118. addInput(Port::create<PJ301MPort>(Vec(8, 273), Port::INPUT, module, Warps::LEVEL1_INPUT));
  119. addInput(Port::create<PJ301MPort>(Vec(44, 273), Port::INPUT, module, Warps::LEVEL2_INPUT));
  120. addInput(Port::create<PJ301MPort>(Vec(80, 273), Port::INPUT, module, Warps::ALGORITHM_INPUT));
  121. addInput(Port::create<PJ301MPort>(Vec(116, 273), Port::INPUT, module, Warps::TIMBRE_INPUT));
  122. addInput(Port::create<PJ301MPort>(Vec(8, 316), Port::INPUT, module, Warps::CARRIER_INPUT));
  123. addInput(Port::create<PJ301MPort>(Vec(44, 316), Port::INPUT, module, Warps::MODULATOR_INPUT));
  124. addOutput(Port::create<PJ301MPort>(Vec(80, 316), Port::OUTPUT, module, Warps::MODULATOR_OUTPUT));
  125. addOutput(Port::create<PJ301MPort>(Vec(116, 316), Port::OUTPUT, module, Warps::AUX_OUTPUT));
  126. addChild(ModuleLightWidget::create<SmallLight<GreenRedLight>>(Vec(21, 167), module, Warps::CARRIER_GREEN_LIGHT));
  127. addChild(ModuleLightWidget::create<AlgorithmLight>(Vec(40, 63), module, Warps::ALGORITHM_LIGHT));
  128. }
  129. };
  130. Model *modelWarps = Model::create<Warps, WarpsWidget>("Audible Instruments", "Warps", "Meta Modulator", RING_MODULATOR_TAG, WAVESHAPER_TAG);