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.

182 lines
5.5KB

  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. int frame = 0;
  29. warps::Modulator modulator;
  30. warps::ShortFrame inputFrames[60] = {};
  31. warps::ShortFrame outputFrames[60] = {};
  32. float lights[2] = {};
  33. SchmittTrigger stateTrigger;
  34. Warps();
  35. void step() override;
  36. json_t *toJson() override {
  37. json_t *rootJ = json_object();
  38. warps::Parameters *p = modulator.mutable_parameters();
  39. json_object_set_new(rootJ, "shape", json_integer(p->carrier_shape));
  40. return rootJ;
  41. }
  42. void fromJson(json_t *rootJ) override {
  43. json_t *shapeJ = json_object_get(rootJ, "shape");
  44. warps::Parameters *p = modulator.mutable_parameters();
  45. if (shapeJ) {
  46. p->carrier_shape = json_integer_value(shapeJ);
  47. }
  48. }
  49. void initialize() override {
  50. warps::Parameters *p = modulator.mutable_parameters();
  51. p->carrier_shape = 0;
  52. }
  53. void randomize() override {
  54. warps::Parameters *p = modulator.mutable_parameters();
  55. p->carrier_shape = randomu32() % 4;
  56. }
  57. };
  58. Warps::Warps() : Module(NUM_PARAMS, NUM_INPUTS, NUM_OUTPUTS) {
  59. memset(&modulator, 0, sizeof(modulator));
  60. modulator.Init(96000.0f);
  61. stateTrigger.setThresholds(0.0, 1.0);
  62. }
  63. void Warps::step() {
  64. // State trigger
  65. warps::Parameters *p = modulator.mutable_parameters();
  66. if (stateTrigger.process(params[STATE_PARAM].value)) {
  67. p->carrier_shape = (p->carrier_shape + 1) % 4;
  68. }
  69. lights[0] = p->carrier_shape;
  70. // Buffer loop
  71. if (++frame >= 60) {
  72. frame = 0;
  73. p->channel_drive[0] = clampf(params[LEVEL1_PARAM].value + inputs[LEVEL1_INPUT].value / 5.0, 0.0, 1.0);
  74. p->channel_drive[1] = clampf(params[LEVEL2_PARAM].value + inputs[LEVEL2_INPUT].value / 5.0, 0.0, 1.0);
  75. p->modulation_algorithm = clampf(params[ALGORITHM_PARAM].value / 8.0 + inputs[ALGORITHM_INPUT].value / 5.0, 0.0, 1.0);
  76. lights[1] = p->modulation_algorithm * 8.0;
  77. p->modulation_parameter = clampf(params[TIMBRE_PARAM].value + inputs[TIMBRE_INPUT].value / 5.0, 0.0, 1.0);
  78. p->frequency_shift_pot = params[ALGORITHM_PARAM].value / 8.0;
  79. p->frequency_shift_cv = clampf(inputs[ALGORITHM_INPUT].value / 5.0, -1.0, 1.0);
  80. p->phase_shift = p->modulation_algorithm;
  81. p->note = 60.0 * params[LEVEL1_PARAM].value + 12.0 * inputs[LEVEL1_INPUT].normalize(2.0) + 12.0;
  82. p->note += log2f(96000.0 / engineGetSampleRate()) * 12.0;
  83. modulator.Process(inputFrames, outputFrames, 60);
  84. }
  85. inputFrames[frame].l = clampf(inputs[CARRIER_INPUT].value / 16.0 * 0x8000, -0x8000, 0x7fff);
  86. inputFrames[frame].r = clampf(inputs[MODULATOR_INPUT].value / 16.0 * 0x8000, -0x8000, 0x7fff);
  87. outputs[MODULATOR_OUTPUT].value = (float)outputFrames[frame].l / 0x8000 * 5.0;
  88. outputs[AUX_OUTPUT].value = (float)outputFrames[frame].r / 0x8000 * 5.0;
  89. }
  90. struct WarpsModeLight : ModeValueLight {
  91. WarpsModeLight() {
  92. addColor(COLOR_BLACK_TRANSPARENT);
  93. addColor(COLOR_GREEN);
  94. addColor(COLOR_YELLOW);
  95. addColor(COLOR_RED);
  96. }
  97. };
  98. struct WarpsAlgoLight : ValueLight {
  99. WarpsAlgoLight() {
  100. box.size = Vec(67, 67);
  101. }
  102. void step() override {
  103. // TODO Set these to Warps' actual colors
  104. static NVGcolor colors[9] = {
  105. nvgHSL(0.5, 0.3, 0.85),
  106. nvgHSL(0.6, 0.3, 0.85),
  107. nvgHSL(0.7, 0.3, 0.85),
  108. nvgHSL(0.8, 0.3, 0.85),
  109. nvgHSL(0.9, 0.3, 0.85),
  110. nvgHSL(0.0, 0.3, 0.85),
  111. nvgHSL(0.1, 0.3, 0.85),
  112. nvgHSL(0.2, 0.3, 0.85),
  113. nvgHSL(0.3, 0.3, 0.85),
  114. };
  115. int i = clampi((int) *value, 0, 7);
  116. NVGcolor color0 = colors[i];
  117. NVGcolor color1 = colors[i + 1];
  118. float p = fmodf(*value, 1.0);
  119. color = nvgLerpRGBA(color0, color1, p);
  120. }
  121. };
  122. WarpsWidget::WarpsWidget() {
  123. Warps *module = new Warps();
  124. setModule(module);
  125. box.size = Vec(15*10, 380);
  126. {
  127. Panel *panel = new LightPanel();
  128. panel->backgroundImage = Image::load(assetPlugin(plugin, "res/Warps.png"));
  129. panel->box.size = box.size;
  130. addChild(panel);
  131. }
  132. addChild(createScrew<ScrewSilver>(Vec(15, 0)));
  133. addChild(createScrew<ScrewSilver>(Vec(120, 0)));
  134. addChild(createScrew<ScrewSilver>(Vec(15, 365)));
  135. addChild(createScrew<ScrewSilver>(Vec(120, 365)));
  136. addParam(createParam<Rogan6PSWhite>(Vec(30, 53), module, Warps::ALGORITHM_PARAM, 0.0, 8.0, 0.0));
  137. addParam(createParam<Rogan1PSWhite>(Vec(95, 173), module, Warps::TIMBRE_PARAM, 0.0, 1.0, 0.5));
  138. addParam(createParam<TL1105>(Vec(16, 182), module, Warps::STATE_PARAM, 0.0, 1.0, 0.0));
  139. addParam(createParam<Trimpot>(Vec(15, 214), module, Warps::LEVEL1_PARAM, 0.0, 1.0, 1.0));
  140. addParam(createParam<Trimpot>(Vec(54, 214), module, Warps::LEVEL2_PARAM, 0.0, 1.0, 1.0));
  141. addInput(createInput<PJ301MPort>(Vec(8, 273), module, Warps::LEVEL1_INPUT));
  142. addInput(createInput<PJ301MPort>(Vec(44, 273), module, Warps::LEVEL2_INPUT));
  143. addInput(createInput<PJ301MPort>(Vec(80, 273), module, Warps::ALGORITHM_INPUT));
  144. addInput(createInput<PJ301MPort>(Vec(116, 273), module, Warps::TIMBRE_INPUT));
  145. addInput(createInput<PJ301MPort>(Vec(8, 316), module, Warps::CARRIER_INPUT));
  146. addInput(createInput<PJ301MPort>(Vec(44, 316), module, Warps::MODULATOR_INPUT));
  147. addOutput(createOutput<PJ301MPort>(Vec(80, 316), module, Warps::MODULATOR_OUTPUT));
  148. addOutput(createOutput<PJ301MPort>(Vec(116, 316), module, Warps::AUX_OUTPUT));
  149. addChild(createValueLight<SmallLight<WarpsModeLight>>(Vec(20, 167), &module->lights[0]));
  150. addChild(createValueLight<WarpsAlgoLight>(Vec(41, 64), &module->lights[1]));
  151. }