Audio plugin host https://kx.studio/carla
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.

281 lines
8.4KB

  1. /*
  2. * Vector Juice Plugin
  3. * Copyright (C) 2014 Andre Sklenar <andre.sklenar@gmail.com>, www.juicelab.cz
  4. *
  5. * This program is free software; you can redistribute it and/or
  6. * modify it under the terms of the GNU General Public License as
  7. * published by the Free Software Foundation; either version 2 of
  8. * the License, or any later version.
  9. *
  10. * This program is distributed in the hope that it will be useful,
  11. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  12. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  13. * GNU General Public License for more details.
  14. *
  15. * For a full copy of the GNU General Public License see the doc/GPL.txt file.
  16. */
  17. #ifndef GROOVEJUICEPLUGIN_HPP_INCLUDED
  18. #define GROOVEJUICEPLUGIN_HPP_INCLUDED
  19. #include "DistrhoPlugin.hpp"
  20. #include <iostream>
  21. #include "Synth.hxx"
  22. #include "moogVCF.hxx"
  23. START_NAMESPACE_DISTRHO
  24. // -----------------------------------------------------------------------
  25. class GrooveJuicePlugin : public Plugin
  26. {
  27. public:
  28. enum Parameters
  29. {
  30. paramX = 0,
  31. paramY,
  32. paramOrbitSizeX,
  33. paramOrbitSizeY,
  34. paramOrbitSpeedX,
  35. paramOrbitSpeedY,
  36. paramSubOrbitSpeed,
  37. paramSubOrbitSize,
  38. paramOrbitWaveX,
  39. paramOrbitWaveY,
  40. paramOrbitPhaseX,
  41. paramOrbitPhaseY,
  42. paramSubOrbitSmooth,
  43. paramOrbitOutX,
  44. paramOrbitOutY,
  45. paramSubOrbitOutX,
  46. paramSubOrbitOutY,
  47. w11, w21, m1, c1, r1, s1, re1, sh1,
  48. w12, w22, m2, c2, r2, s2, re2, sh2,
  49. w13, w23, m3, c3, r3, s3, re3, sh3,
  50. w14, w24, m4, c4, r4, s4, re4, sh4,
  51. w15, w25, m5, c5, r5, s5, re5, sh5,
  52. w16, w26, m6, c6, r6, s6, re6, sh6,
  53. w17, w27, m7, c7, r7, s7, re7, sh7,
  54. w18, w28, m8, c8, r8, s8, re8, sh8,
  55. paramW1Out,
  56. paramW2Out,
  57. paramMOut,
  58. paramCOut,
  59. paramROut,
  60. paramSOut,
  61. paramReOut,
  62. paramShOut,
  63. paramCount
  64. };
  65. inline float smoothParameter(float in, int axis) {
  66. sZ[axis] = (in * sB[axis]) + (sZ[axis] * sA[axis]);
  67. return sZ[axis];
  68. }
  69. float getSinePhase(float x) {
  70. return (-std::sin(x));
  71. }
  72. float getSawPhase(float x) {
  73. return (-(2/M_PI *std::atan(1/std::tan(x/2))));
  74. }
  75. float getRevSawPhase(float x) {
  76. return ((2/M_PI *std::atan(1/std::tan(x/2))));
  77. }
  78. float getSquarePhase(float x) {
  79. return (std::round((std::sin(x)+1)/2)-0.5)*2;
  80. }
  81. //saw, sqr, sin, revSaw
  82. float getBlendedPhase(float x, float wave)
  83. {
  84. //wave = 2;
  85. if (wave>=1 && wave<2) {
  86. /* saw vs sqr */
  87. waveBlend = wave-1;
  88. return (getSawPhase(x)*(1-waveBlend) + getSquarePhase(x)*waveBlend);
  89. } else if (wave>=2 && wave<3) {
  90. /* sqr vs sin */
  91. waveBlend = wave-2;
  92. return (getSquarePhase(x)*(1-waveBlend) + getSinePhase(x)*waveBlend);
  93. } else if (wave>=3 && wave<=4) {
  94. /* sin vs revSaw */
  95. waveBlend = wave-3;
  96. return (getSinePhase(x)*(1-waveBlend) + getRevSawPhase(x)*waveBlend);
  97. } else {
  98. return 0.0f;
  99. }
  100. }
  101. void resetPhase()
  102. {
  103. const TimePos& time = d_getTimePos();
  104. if (!time.playing)
  105. {
  106. sinePosX = 0;
  107. sinePosY = 0;
  108. sinePos = 0;
  109. }
  110. }
  111. float tN (float x)
  112. {
  113. if (x>1) x=1;
  114. if (x<0) x=0;
  115. return x;
  116. }
  117. float distance(float x, float y, float tX, float tY) {
  118. float result = pow(tN(1-(sqrt((tX - x)*(tX - x) + (tY - y)*(tY - y)))), 3);
  119. return result;
  120. }
  121. void animate()
  122. {
  123. //sync orbit with frame, bpm
  124. const TimePos& time = d_getTimePos();
  125. bar = ((120.0/(time.bbt.valid ? time.bbt.beatsPerMinute : 120.0))*(d_getSampleRate()));
  126. int multiplier = 16;//2000*4;
  127. tickX = bar/(std::round(orbitSpeedX))*multiplier;
  128. tickY = bar/(std::round(orbitSpeedY))*multiplier;
  129. tick = bar/(std::round(subOrbitSpeed))*multiplier;
  130. if (time.playing)
  131. {
  132. /* if rolling then sync to timepos */
  133. tickOffsetX = time.frame-std::floor(time.frame/tickX)*tickX;
  134. tickOffsetY = time.frame-std::floor(time.frame/tickY)*tickY;
  135. tickOffset = time.frame-std::floor(time.frame/tick)*tick;
  136. percentageX = tickOffsetX/tickX;
  137. percentageY = tickOffsetY/tickY;
  138. percentage = tickOffset/tick;
  139. sinePosX = (M_PI*2)*percentageX;
  140. sinePosY = (M_PI*2)*percentageY;
  141. sinePos = (M_PI*2)*percentage;
  142. } else {
  143. /* else just keep on wobblin' */
  144. sinePosX += (2*M_PI)/(tickX);
  145. sinePosY += (2*M_PI)/(tickY);
  146. sinePos += (M_PI)/(tick);
  147. if (sinePosX>2*M_PI) {
  148. sinePosX = 0;
  149. }
  150. if (sinePosY>2*M_PI) {
  151. sinePosY = 0;
  152. }
  153. if (sinePos>2*M_PI) {
  154. sinePos = 0;
  155. }
  156. }
  157. //0..1
  158. //0..3
  159. //0, 1, 2, 3
  160. //* 0.25
  161. //0, 0.25, 0.5, 0.75
  162. float tempPhaseX = std::round(orbitPhaseX*3)*0.25;
  163. float tempPhaseY = std::round(orbitPhaseY*3)*0.25;
  164. orbitX = x+getBlendedPhase(sinePosX + tempPhaseX*(2*M_PI), std::round(orbitWaveX))*(orbitSizeX/2);
  165. orbitY = y+getBlendedPhase(sinePosY+M_PI/2 + tempPhaseY*(2*M_PI), std::round(orbitWaveY))*(orbitSizeY/2);
  166. subOrbitX = smoothParameter(orbitX+getBlendedPhase(sinePos, 3)*(subOrbitSize/3), 0);
  167. subOrbitY = smoothParameter(orbitY+getBlendedPhase(sinePos+M_PI/2, 3)*(subOrbitSize/3), 1);
  168. if (orbitX<0) orbitX=0;
  169. if (orbitX>1) orbitX=1;
  170. if (orbitY<0) orbitY=0;
  171. if (orbitY>1) orbitY=1;
  172. if (subOrbitX<0) subOrbitX=0;
  173. if (subOrbitX>1) subOrbitX=1;
  174. if (subOrbitY<0) subOrbitY=0;
  175. if (subOrbitY>1) subOrbitY=1;
  176. }
  177. GrooveJuicePlugin();
  178. protected:
  179. // -------------------------------------------------------------------
  180. // Information
  181. const char* d_getLabel() const noexcept override
  182. {
  183. return "GrooveJuice";
  184. }
  185. const char* d_getMaker() const noexcept override
  186. {
  187. return "Andre Sklenar";
  188. }
  189. const char* d_getLicense() const noexcept override
  190. {
  191. return "GPL v2+";
  192. }
  193. uint32_t d_getVersion() const noexcept override
  194. {
  195. return 0x1000;
  196. }
  197. long d_getUniqueId() const noexcept override
  198. {
  199. return d_cconst('G', 'r', 'v', 'J');
  200. }
  201. // -------------------------------------------------------------------
  202. // Init
  203. void d_initParameter(uint32_t index, Parameter& parameter) override;
  204. void d_initProgramName(uint32_t index, d_string& programName) override;
  205. // -------------------------------------------------------------------
  206. // Internal data
  207. float d_getParameterValue(uint32_t index) const override;
  208. void d_setParameterValue(uint32_t index, float value) override;
  209. void d_setProgram(uint32_t index) override;
  210. // -------------------------------------------------------------------
  211. // Process
  212. void d_activate() override;
  213. void d_deactivate() override;
  214. void d_run(const float** inputs, float** outputs, uint32_t frames, const MidiEvent* midiEvents, uint32_t midiEventCount) override;
  215. // -------------------------------------------------------------------
  216. private:
  217. CSynth synthL, synthR;
  218. MoogVCF filterL, filterR;
  219. float x, y;
  220. float orbitX, orbitY;
  221. float orbitTX, orbitTY; //targetX and targetY for interpolation
  222. float subOrbitX, subOrbitY;
  223. float subOrbitTX, subOrbitTY;
  224. float subOrbitSpeed, subOrbitSize, orbitSpeedX, orbitSpeedY;
  225. float orbitSizeX, orbitSizeY;
  226. float interpolationDivider;
  227. float bar, tickX, tickY, percentageX, percentageY, tickOffsetX, tickOffsetY;
  228. float sinePosX, sinePosY, tick, percentage, tickOffset, sinePos;
  229. float orbitWaveX, orbitWaveY, subOrbitSmooth, waveBlend;
  230. float orbitPhaseX, orbitPhaseY;
  231. //parameter smoothing, for subOrbitX and subOrbitY
  232. float sA[2], sB[2], sZ[2];
  233. float synthData[8][8]; //as per gui, [param][page]
  234. float synthSound[8];
  235. };
  236. // -----------------------------------------------------------------------
  237. END_NAMESPACE_DISTRHO
  238. #endif // GROOVEJUICE_HPP_INCLUDED