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.

249 lines
7.6KB

  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 VECTORJUICEPLUGIN_HPP_INCLUDED
  18. #define VECTORJUICEPLUGIN_HPP_INCLUDED
  19. #include "DistrhoPlugin.hpp"
  20. START_NAMESPACE_DISTRHO
  21. // -----------------------------------------------------------------------
  22. class VectorJuicePlugin : public Plugin
  23. {
  24. public:
  25. enum Parameters
  26. {
  27. paramX = 0,
  28. paramY,
  29. paramOrbitSizeX,
  30. paramOrbitSizeY,
  31. paramOrbitSpeedX,
  32. paramOrbitSpeedY,
  33. paramSubOrbitSpeed,
  34. paramSubOrbitSize,
  35. paramOrbitWaveX,
  36. paramOrbitWaveY,
  37. paramOrbitPhaseX,
  38. paramOrbitPhaseY,
  39. paramSubOrbitSmooth,
  40. paramOrbitOutX,
  41. paramOrbitOutY,
  42. paramSubOrbitOutX,
  43. paramSubOrbitOutY,
  44. paramCount
  45. };
  46. inline float smoothParameter(float in, int axis) {
  47. sZ[axis] = (in * sB[axis]) + (sZ[axis] * sA[axis]);
  48. return sZ[axis];
  49. }
  50. float getSinePhase(float x) {
  51. return (-std::sin(x));
  52. }
  53. float getSawPhase(float x) {
  54. return (-(2/M_PI *std::atan(1/std::tan(x/2))));
  55. }
  56. float getRevSawPhase(float x) {
  57. return ((2/M_PI *std::atan(1/std::tan(x/2))));
  58. }
  59. float getSquarePhase(float x) {
  60. return (std::round((std::sin(x)+1)/2)-0.5)*2;
  61. }
  62. //saw, sqr, sin, revSaw
  63. float getBlendedPhase(float x, float wave)
  64. {
  65. //wave = 2;
  66. if (wave>=1 && wave<2) {
  67. /* saw vs sqr */
  68. waveBlend = wave-1;
  69. return (getSawPhase(x)*(1-waveBlend) + getSquarePhase(x)*waveBlend);
  70. } else if (wave>=2 && wave<3) {
  71. /* sqr vs sin */
  72. waveBlend = wave-2;
  73. return (getSquarePhase(x)*(1-waveBlend) + getSinePhase(x)*waveBlend);
  74. } else if (wave>=3 && wave<=4) {
  75. /* sin vs revSaw */
  76. waveBlend = wave-3;
  77. return (getSinePhase(x)*(1-waveBlend) + getRevSawPhase(x)*waveBlend);
  78. } else {
  79. return 0.0f;
  80. }
  81. }
  82. void resetPhase()
  83. {
  84. const TimePos& time = d_getTimePos();
  85. if (!time.playing)
  86. {
  87. sinePosX = 0;
  88. sinePosY = 0;
  89. sinePos = 0;
  90. }
  91. }
  92. float tN (float x)
  93. {
  94. if (x>0) return x;
  95. else return 0;
  96. }
  97. void animate()
  98. {
  99. //sync orbit with frame, bpm
  100. const TimePos& time = d_getTimePos();
  101. bar = ((120.0/(time.bbt.valid ? time.bbt.beatsPerMinute : 120.0))*(d_getSampleRate()));
  102. int multiplier = 16;//2000*4;
  103. tickX = bar/(std::round(orbitSpeedX))*multiplier;
  104. tickY = bar/(std::round(orbitSpeedY))*multiplier;
  105. tick = bar/(std::round(subOrbitSpeed))*multiplier;
  106. if (time.playing)
  107. {
  108. /* if rolling then sync to timepos */
  109. tickOffsetX = time.frame-std::floor(time.frame/tickX)*tickX;
  110. tickOffsetY = time.frame-std::floor(time.frame/tickY)*tickY;
  111. tickOffset = time.frame-std::floor(time.frame/tick)*tick;
  112. percentageX = tickOffsetX/tickX;
  113. percentageY = tickOffsetY/tickY;
  114. percentage = tickOffset/tick;
  115. sinePosX = (M_PI*2)*percentageX;
  116. sinePosY = (M_PI*2)*percentageY;
  117. sinePos = (M_PI*2)*percentage;
  118. } else {
  119. /* else just keep on wobblin' */
  120. sinePosX += (2*M_PI)/(tickX);
  121. sinePosY += (2*M_PI)/(tickY);
  122. sinePos += (M_PI)/(tick);
  123. if (sinePosX>2*M_PI) {
  124. sinePosX = 0;
  125. }
  126. if (sinePosY>2*M_PI) {
  127. sinePosY = 0;
  128. }
  129. if (sinePos>2*M_PI) {
  130. sinePos = 0;
  131. }
  132. }
  133. //0..1
  134. //0..3
  135. //0, 1, 2, 3
  136. //* 0.25
  137. //0, 0.25, 0.5, 0.75
  138. float tempPhaseX = std::round(orbitPhaseX*3)*0.25;
  139. float tempPhaseY = std::round(orbitPhaseY*3)*0.25;
  140. orbitX = x+getBlendedPhase(sinePosX + tempPhaseX*(2*M_PI), std::round(orbitWaveX))*(orbitSizeX/2);
  141. orbitY = y+getBlendedPhase(sinePosY+M_PI/2 + tempPhaseY*(2*M_PI), std::round(orbitWaveY))*(orbitSizeY/2);
  142. subOrbitX = smoothParameter(orbitX+getBlendedPhase(sinePos, 3)*(subOrbitSize/3), 0);
  143. subOrbitY = smoothParameter(orbitY+getBlendedPhase(sinePos+M_PI/2, 3)*(subOrbitSize/3), 1);
  144. if (orbitX<0) orbitX=0;
  145. if (orbitX>1) orbitX=1;
  146. if (orbitY<0) orbitY=0;
  147. if (orbitY>1) orbitY=1;
  148. if (subOrbitX<0) subOrbitX=0;
  149. if (subOrbitX>1) subOrbitX=1;
  150. if (subOrbitY<0) subOrbitY=0;
  151. if (subOrbitY>1) subOrbitY=1;
  152. }
  153. VectorJuicePlugin();
  154. protected:
  155. // -------------------------------------------------------------------
  156. // Information
  157. const char* d_getLabel() const noexcept override
  158. {
  159. return "VectorJuice";
  160. }
  161. const char* d_getMaker() const noexcept override
  162. {
  163. return "Andre Sklenar";
  164. }
  165. const char* d_getLicense() const noexcept override
  166. {
  167. return "GPL v2+";
  168. }
  169. uint32_t d_getVersion() const noexcept override
  170. {
  171. return 0x1000;
  172. }
  173. long d_getUniqueId() const noexcept override
  174. {
  175. return d_cconst('V', 'e', 'c', 'J');
  176. }
  177. // -------------------------------------------------------------------
  178. // Init
  179. void d_initParameter(uint32_t index, Parameter& parameter) override;
  180. void d_initProgramName(uint32_t index, d_string& programName) override;
  181. // -------------------------------------------------------------------
  182. // Internal data
  183. float d_getParameterValue(uint32_t index) const override;
  184. void d_setParameterValue(uint32_t index, float value) override;
  185. void d_setProgram(uint32_t index) override;
  186. // -------------------------------------------------------------------
  187. // Process
  188. void d_activate() override;
  189. void d_deactivate() override;
  190. void d_run(float** inputs, float** outputs, uint32_t frames) override;
  191. // -------------------------------------------------------------------
  192. private:
  193. float x, y;
  194. float orbitX, orbitY;
  195. float orbitTX, orbitTY; //targetX and targetY for interpolation
  196. float subOrbitX, subOrbitY;
  197. float subOrbitTX, subOrbitTY;
  198. float subOrbitSpeed, subOrbitSize, orbitSpeedX, orbitSpeedY;
  199. float orbitSizeX, orbitSizeY;
  200. float interpolationDivider;
  201. float bar, tickX, tickY, percentageX, percentageY, tickOffsetX, tickOffsetY;
  202. float sinePosX, sinePosY, tick, percentage, tickOffset, sinePos;
  203. float orbitWaveX, orbitWaveY, subOrbitSmooth, waveBlend;
  204. float orbitPhaseX, orbitPhaseY;
  205. //parameter smoothing, for subOrbitX and subOrbitY
  206. float sA[2], sB[2], sZ[2];
  207. };
  208. // -----------------------------------------------------------------------
  209. END_NAMESPACE_DISTRHO
  210. #endif // VECTORJUICE_HPP_INCLUDED