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.

220 lines
5.2KB

  1. #pragma once
  2. #include <iostream>
  3. #include "AH.hpp"
  4. #include "componentlibrary.hpp"
  5. namespace rack_plugin_AmalgamatedHarmonics {
  6. struct ParamEvent {
  7. ParamEvent(int t, int i, float v) : pType(t), pId(i), value(v) {}
  8. int pType;
  9. int pId;
  10. float value;
  11. };
  12. struct AHModule : Module {
  13. float delta;
  14. float rho;
  15. AHModule(int numParams, int numInputs, int numOutputs, int numLights = 0) : Module(numParams, numInputs, numOutputs, numLights) {
  16. delta = engineGetSampleTime();
  17. rho = engineGetSampleRate();
  18. }
  19. void onSampleRateChange() override {
  20. delta = engineGetSampleTime();
  21. rho = engineGetSampleRate();
  22. }
  23. int stepX = 0;
  24. bool debugFlag = false;
  25. inline bool debugEnabled() {
  26. return debugFlag;
  27. }
  28. bool receiveEvents = false;
  29. int keepStateDisplay = 0;
  30. std::string paramState = ">";
  31. virtual void receiveEvent(ParamEvent e) {
  32. paramState = ">";
  33. keepStateDisplay = 0;
  34. }
  35. void step() override {
  36. stepX++;
  37. // Once we start stepping, we can process events
  38. receiveEvents = true;
  39. // Timeout for display
  40. keepStateDisplay++;
  41. if (keepStateDisplay > 50000) {
  42. paramState = ">";
  43. }
  44. }
  45. };
  46. struct StateDisplay : TransparentWidget {
  47. AHModule *module;
  48. int frame = 0;
  49. std::shared_ptr<Font> font;
  50. StateDisplay() {
  51. font = Font::load(assetPlugin(plugin, "res/EurostileBold.ttf"));
  52. }
  53. void draw(NVGcontext *vg) override {
  54. Vec pos = Vec(0, 15);
  55. nvgFontSize(vg, 16);
  56. nvgFontFaceId(vg, font->handle);
  57. nvgTextLetterSpacing(vg, -1);
  58. nvgFillColor(vg, nvgRGBA(255, 0, 0, 0xff));
  59. char text[128];
  60. snprintf(text, sizeof(text), "%s", module->paramState.c_str());
  61. nvgText(vg, pos.x + 10, pos.y + 5, text, NULL);
  62. }
  63. };
  64. struct AHParamWidget { // it's a mix-in
  65. int pType = -1; // Should be set by ste<>(), but if not this allows us to catch pwidgers we are not interested in
  66. int pId;
  67. AHModule *mod = NULL;
  68. virtual ParamEvent generateEvent(float value) {
  69. return ParamEvent(pType,pId,value);
  70. };
  71. template <typename T = AHParamWidget>
  72. static void set(T *param, int pType, int pId) {
  73. param->pType = pType;
  74. param->pId = pId;
  75. }
  76. };
  77. // Not going to monitor buttons
  78. struct AHButton : SVGSwitch, MomentarySwitch {
  79. AHButton() {
  80. addFrame(SVG::load(assetPlugin(plugin,"res/ComponentLibrary/AHButton.svg")));
  81. }
  82. };
  83. struct AHKnob : RoundKnob, AHParamWidget {
  84. void onChange(EventChange &e) override {
  85. // One off cast, don't want to subclass from ParamWidget, so have to grab it here
  86. if (!mod) {
  87. mod = static_cast<AHModule *>(this->module);
  88. }
  89. mod->receiveEvent(generateEvent(value));
  90. RoundKnob::onChange(e);
  91. }
  92. };
  93. struct AHKnobSnap : AHKnob {
  94. AHKnobSnap() {
  95. snap = true;
  96. setSVG(SVG::load(assetPlugin(plugin,"res/ComponentLibrary/AHKnob.svg")));
  97. }
  98. };
  99. struct AHKnobNoSnap : AHKnob {
  100. AHKnobNoSnap() {
  101. snap = false;
  102. setSVG(SVG::load(assetPlugin(plugin,"res/ComponentLibrary/AHKnob.svg")));
  103. }
  104. };
  105. struct AHBigKnobNoSnap : AHKnob {
  106. AHBigKnobNoSnap() {
  107. snap = false;
  108. setSVG(SVG::load(assetPlugin(plugin,"res/ComponentLibrary/AHBigKnob.svg")));
  109. }
  110. };
  111. struct AHBigKnobSnap : AHKnob {
  112. AHBigKnobSnap() {
  113. snap = true;
  114. setSVG(SVG::load(assetPlugin(plugin,"res/ComponentLibrary/AHBigKnob.svg")));
  115. }
  116. };
  117. struct AHTrimpotSnap : AHKnob {
  118. AHTrimpotSnap() {
  119. snap = true;
  120. setSVG(SVG::load(assetPlugin(plugin,"res/ComponentLibrary/AHTrimpot.svg")));
  121. }
  122. };
  123. struct AHTrimpotNoSnap : AHKnob {
  124. AHTrimpotNoSnap() {
  125. snap = false;
  126. setSVG(SVG::load(assetPlugin(plugin,"res/ComponentLibrary/AHTrimpot.svg")));
  127. }
  128. };
  129. struct UI {
  130. enum UIElement {
  131. KNOB = 0,
  132. PORT,
  133. BUTTON,
  134. LIGHT,
  135. TRIMPOT
  136. };
  137. float Y_KNOB[2] = {50.8f, 56.0f}; // w.r.t 22 = 28.8 from bottom
  138. float Y_PORT[2] = {49.7f, 56.0f}; // 27.7
  139. float Y_BUTTON[2] = {53.3f, 56.0f}; // 31.3
  140. float Y_LIGHT[2] = {57.7f, 56.0f}; // 35.7
  141. float Y_TRIMPOT[2] = {52.8f, 56.0f}; // 30.8
  142. float Y_KNOB_COMPACT[2] = {30.1f, 35.0f}; // Calculated relative to PORT=29 and the deltas above
  143. float Y_PORT_COMPACT[2] = {29.0f, 35.0f};
  144. float Y_BUTTON_COMPACT[2] = {32.6f, 35.0f};
  145. float Y_LIGHT_COMPACT[2] = {37.0f, 35.0f};
  146. float Y_TRIMPOT_COMPACT[2] = {32.1f, 35.0f};
  147. float X_KNOB[2] = {12.5f, 48.0f}; // w.r.t 6.5 = 6 from left
  148. float X_PORT[2] = {11.5f, 48.0f}; // 5
  149. float X_BUTTON[2] = {14.7f, 48.0f}; // 8.2
  150. float X_LIGHT[2] = {19.1f, 48.0f}; // 12.6
  151. float X_TRIMPOT[2] = {14.7f, 48.0f}; // 8.2
  152. float X_KNOB_COMPACT[2] = {21.0f, 35.0f}; // 15 + 6, see calc above
  153. float X_PORT_COMPACT[2] = {20.0f, 35.0f}; // 15 + 5
  154. float X_BUTTON_COMPACT[2] = {23.2f, 35.0f}; // 15 + 8.2
  155. float X_LIGHT_COMPACT[2] = {27.6f, 35.0f}; // 15 + 12.6
  156. float X_TRIMPOT_COMPACT[2] = {23.2f, 35.0f}; // 15 + 8.2
  157. Vec getPosition(int type, int xSlot, int ySlot, bool xDense, bool yDense);
  158. /* From the numerical key on a keyboard (0 = C, 11 = B), spacing in px between white keys and a starting x and Y coordinate for the C key (in px)
  159. * calculate the actual X and Y coordinate for a key, and the scale note to which that key belongs (see Midi note mapping)
  160. * http://www.grantmuller.com/MidiReference/doc/midiReference/ScaleReference.html */
  161. void calculateKeyboard(int inKey, float spacing, float xOff, float yOff, float *x, float *y, int *scale);
  162. };
  163. } // namespace rack_plugin_AmalgamatedHarmonics