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.

202 lines
5.3KB

  1. //***********************************************************************************************
  2. //Engineering Test 1
  3. //
  4. //Based on code from the Fundamental and AudibleInstruments plugins by Andrew Belt
  5. //and graphics from the Component Library by Wes Milholen
  6. //See ./LICENSE.txt for all licenses
  7. //See ./res/fonts/ for font licenses
  8. //
  9. //Module concept by Marc Boulé
  10. //***********************************************************************************************
  11. #include "ImpromptuModular.hpp"
  12. #include "dsp/digital.hpp"
  13. struct EngTest1 : Module {
  14. enum ParamIds {
  15. ENUMS(NOTETYPE_PARAMS, 5),
  16. ENUMS(STEP_PARAMS, 24),
  17. NUM_PARAMS
  18. };
  19. enum InputIds {
  20. NUM_INPUTS
  21. };
  22. enum OutputIds {
  23. NUM_OUTPUTS
  24. };
  25. enum LightIds {
  26. ENUMS(NOTETYPE_LIGHTS, 5),
  27. ENUMS(STEP_LIGHTS, 24 * 2),// room for GreenRed
  28. NUM_LIGHTS
  29. };
  30. // Need to save
  31. int panelTheme;
  32. int noteType;// 0 is full note, 1 is half note, 2 is quarter note, etc...
  33. uint8_t notes[24];
  34. // No need to save
  35. SchmittTrigger noteTypeTriggers[5];
  36. SchmittTrigger stepTriggers[24];
  37. EngTest1() : Module(NUM_PARAMS, NUM_INPUTS, NUM_OUTPUTS, NUM_LIGHTS) {
  38. panelTheme = 0;
  39. for (int i = 0; i < 5; i++)
  40. noteTypeTriggers[i].reset();
  41. for (int i = 0; i < 24; i++)
  42. stepTriggers[i].reset();
  43. onReset();
  44. }
  45. // widgets are not yet created when module is created (and when onReset() is called by constructor)
  46. // onReset() is also called when right-click initialization of module
  47. void onReset() override {
  48. noteType = 2;
  49. for (int i = 0; i < 24; i++) {
  50. notes[i] = (i / 6) * 6;
  51. }
  52. }
  53. // widgets randomized before onRandomize() is called
  54. void onRandomize() override {
  55. }
  56. json_t *toJson() override {
  57. json_t *rootJ = json_object();
  58. return rootJ;
  59. }
  60. // widgets loaded before this fromJson() is called
  61. void fromJson(json_t *rootJ) override {
  62. }
  63. // Advances the module by 1 audio frame with duration 1.0 / engineGetSampleRate()
  64. void step() override {
  65. // Step buttons
  66. for (int i = 0; i < 24; i++) {
  67. if (stepTriggers[i].process(params[STEP_PARAMS + i].value)) {
  68. int count = 3 * (1 << (3 - noteType));
  69. int j;
  70. for (j = 0; j < count; j++) {
  71. if ((i + j) >= 24)
  72. break;
  73. notes[i + j] = i;
  74. }
  75. if ((i + j) < 24) {
  76. int oldVal = notes[i + j];
  77. int newVal = i + j;
  78. for (; j < 24; j++) {// j < 24 is safety
  79. if ((i + j) >= 24)
  80. break;
  81. if (notes[i + j] == oldVal)
  82. notes[i + j] = newVal;
  83. }
  84. }
  85. }
  86. }
  87. // Note type buttons
  88. for (int i = 0; i < 5; i++) {
  89. if (noteTypeTriggers[i].process(params[NOTETYPE_PARAMS + i].value)) {
  90. noteType = i;
  91. }
  92. }
  93. // Step lights
  94. bool isGreen = true;
  95. for (int i = 0; i < 24; i++) {
  96. if (i > 0 && notes[i] != notes[i-1])
  97. isGreen = !isGreen;
  98. setGreenRed(STEP_LIGHTS + i * 2, isGreen ? 1.0f : 0.0f, !isGreen ? 1.0f : 0.0f);
  99. }
  100. // Note type lights
  101. for (int i = 0; i < 5; i++)
  102. lights[NOTETYPE_LIGHTS + i].value = (i == noteType ? 1.0f : 0.0f);
  103. }// step()
  104. void setGreenRed(int id, float green, float red) {
  105. lights[id + 0].value = green;
  106. lights[id + 1].value = red;
  107. }
  108. };// EngTest1 : module
  109. struct EngTest1Widget : ModuleWidget {
  110. EngTest1Widget(EngTest1 *module) : ModuleWidget(module) {
  111. // Main panel from Inkscape
  112. DynamicSVGPanel* panel = new DynamicSVGPanel();
  113. panel->mode = &module->panelTheme;
  114. panel->addPanel(SVG::load(assetPlugin(plugin, "res/light/EngTest1.svg")));
  115. panel->addPanel(SVG::load(assetPlugin(plugin, "res/dark/EngTest1_dark.svg")));
  116. box.size = panel->box.size;
  117. addChild(panel);
  118. // Screws
  119. addChild(createDynamicScrew<IMScrew>(Vec(15, 0), &module->panelTheme));
  120. addChild(createDynamicScrew<IMScrew>(Vec(15, 365), &module->panelTheme));
  121. addChild(createDynamicScrew<IMScrew>(Vec(panel->box.size.x-30, 0), &module->panelTheme));
  122. addChild(createDynamicScrew<IMScrew>(Vec(panel->box.size.x-30, 365), &module->panelTheme));
  123. // ****** Top portion (2 switches and LED button array ******
  124. static const int rowRuler0 = 65;
  125. static const int colRulerSteps = 15;
  126. static const int spacingSteps = 20;
  127. //static const int spacingSteps4 = 4;
  128. // Step LED buttons
  129. int posX = colRulerSteps;
  130. for (int x = 0; x < 24; x++) {
  131. addParam(ParamWidget::create<LEDButton>(Vec(posX, rowRuler0 + 8 - 4.4f), module, EngTest1::STEP_PARAMS + x, 0.0f, 1.0f, 0.0f));
  132. addChild(ModuleLightWidget::create<MediumLight<GreenRedLight>>(Vec(posX + 4.4f, rowRuler0 + 8), module, EngTest1::STEP_LIGHTS + x * 2));
  133. posX += spacingSteps;
  134. //if ((x + 1) % 4 == 0)
  135. //posX += spacingSteps4;
  136. }
  137. // Note type buttons
  138. static const int rowRuler1 = 160;
  139. static const int posLEDvsButton = 25;
  140. static const int spacingButtons = 40;
  141. static const int columnRulerMB1 = colRulerSteps + 10;
  142. for (int x = 0; x < 5; x++) {
  143. addChild(ModuleLightWidget::create<MediumLight<RedLight>>(Vec(columnRulerMB1 + x * spacingButtons + offsetMediumLight, rowRuler1 + offsetMediumLight - posLEDvsButton), module, EngTest1::NOTETYPE_LIGHTS + x));
  144. addParam(createDynamicParam<IMBigPushButton>(Vec(columnRulerMB1 + x * spacingButtons + offsetCKD6b, rowRuler1 + offsetCKD6b), module, EngTest1::NOTETYPE_PARAMS + x, 0.0f, 1.0f, 0.0f, &module->panelTheme));
  145. }
  146. }
  147. };
  148. Model *modelEngTest1 = Model::create<EngTest1, EngTest1Widget>("Impromptu Modular", "Eng-Test-1", "??? - Eng-Test-1", BLANK_TAG);
  149. /*CHANGE LOG
  150. 0.6.10:
  151. created
  152. */