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.

622 lines
17KB

  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. #include "GrooveJuicePlugin.hpp"
  18. START_NAMESPACE_DISTRHO
  19. // -----------------------------------------------------------------------
  20. GrooveJuicePlugin::GrooveJuicePlugin()
  21. : Plugin(paramCount, 1, 0) // 1 program, 0 states
  22. {
  23. // set default values
  24. d_setProgram(0);
  25. // reset
  26. d_deactivate();
  27. }
  28. // -----------------------------------------------------------------------
  29. // Init
  30. void GrooveJuicePlugin::d_initParameter(uint32_t index, Parameter& parameter)
  31. {
  32. switch (index)
  33. {
  34. case paramX:
  35. parameter.hints = PARAMETER_IS_AUTOMABLE;
  36. parameter.name = "X";
  37. parameter.symbol = "x";
  38. parameter.unit = "";
  39. parameter.ranges.def = 0.5f;
  40. parameter.ranges.min = 0.0f;
  41. parameter.ranges.max = 1.0f;
  42. break;
  43. case paramY:
  44. parameter.hints = PARAMETER_IS_AUTOMABLE;
  45. parameter.name = "Y";
  46. parameter.symbol = "y";
  47. parameter.unit = "";
  48. parameter.ranges.def = 0.5f;
  49. parameter.ranges.min = 0.0f;
  50. parameter.ranges.max = 1.0f;
  51. break;
  52. case paramOrbitSpeedX:
  53. parameter.hints = PARAMETER_IS_AUTOMABLE;
  54. parameter.name = "Orbit Speed X";
  55. parameter.symbol = "";
  56. parameter.unit = "";
  57. parameter.ranges.def = 4.0f;
  58. parameter.ranges.min = 1.0f;
  59. parameter.ranges.max = 128.0f;
  60. break;
  61. case paramOrbitSpeedY:
  62. parameter.hints = PARAMETER_IS_AUTOMABLE;
  63. parameter.name = "Orbit Speed Y";
  64. parameter.symbol = "";
  65. parameter.unit = "";
  66. parameter.ranges.def = 4.0f;
  67. parameter.ranges.min = 1.0f;
  68. parameter.ranges.max = 128.0f;
  69. break;
  70. case paramOrbitSizeX:
  71. parameter.hints = PARAMETER_IS_AUTOMABLE;
  72. parameter.name = "Orbit Size X";
  73. parameter.symbol = "osl";
  74. parameter.unit = "";
  75. parameter.ranges.def = 0.5f;
  76. parameter.ranges.min = 0.0f;
  77. parameter.ranges.max = 1.0f;
  78. break;
  79. case paramOrbitSizeY:
  80. parameter.hints = PARAMETER_IS_AUTOMABLE;
  81. parameter.name = "Orbit Size Y";
  82. parameter.symbol = "osr";
  83. parameter.unit = "";
  84. parameter.ranges.def = 0.5f;
  85. parameter.ranges.min = 0.0f;
  86. parameter.ranges.max = 1.0f;
  87. break;
  88. case paramSubOrbitSpeed:
  89. parameter.hints = PARAMETER_IS_AUTOMABLE;
  90. parameter.name = "SubOrbit Speed";
  91. parameter.symbol = "";
  92. parameter.unit = "";
  93. parameter.ranges.def = 32.0f;
  94. parameter.ranges.min = 1.0f;
  95. parameter.ranges.max = 128.0f;
  96. break;
  97. case paramSubOrbitSize:
  98. parameter.hints = PARAMETER_IS_AUTOMABLE;
  99. parameter.name = "SubOrbit Size";
  100. parameter.symbol = "";
  101. parameter.unit = "";
  102. parameter.ranges.def = 0.5f;
  103. parameter.ranges.min = 0.0f;
  104. parameter.ranges.max = 1.0f;
  105. break;
  106. case paramSubOrbitSmooth:
  107. parameter.hints = PARAMETER_IS_AUTOMABLE;
  108. parameter.name = "SubOrbit Wave";
  109. parameter.symbol = "";
  110. parameter.unit = "";
  111. parameter.ranges.def = 0.5f;
  112. parameter.ranges.min = 0.0f;
  113. parameter.ranges.max = 1.0f;
  114. break;
  115. case paramOrbitWaveX:
  116. parameter.hints = PARAMETER_IS_AUTOMABLE;
  117. parameter.name = "Orbit Wave X";
  118. parameter.symbol = "";
  119. parameter.unit = "";
  120. parameter.ranges.def = 3.0f;
  121. parameter.ranges.min = 1.0f;
  122. parameter.ranges.max = 4.0f;
  123. break;
  124. case paramOrbitPhaseX:
  125. parameter.hints = PARAMETER_IS_AUTOMABLE;
  126. parameter.name = "Orbit Phase X";
  127. parameter.symbol = "";
  128. parameter.unit = "";
  129. parameter.ranges.def = 0.0f;
  130. parameter.ranges.min = 0.0f;
  131. parameter.ranges.max = 1.0f;
  132. break;
  133. case paramOrbitPhaseY:
  134. parameter.hints = PARAMETER_IS_AUTOMABLE;
  135. parameter.name = "Orbit Phase Y";
  136. parameter.symbol = "";
  137. parameter.unit = "";
  138. parameter.ranges.def = 0.0f;
  139. parameter.ranges.min = 0.0f;
  140. parameter.ranges.max = 1.0f;
  141. break;
  142. case paramOrbitWaveY:
  143. parameter.hints = PARAMETER_IS_AUTOMABLE;
  144. parameter.name = "Orbit Wave Y";
  145. parameter.symbol = "";
  146. parameter.unit = "";
  147. parameter.ranges.def = 3.0f;
  148. parameter.ranges.min = 1.0f;
  149. parameter.ranges.max = 4.0f;
  150. break;
  151. case paramOrbitOutX:
  152. parameter.hints = PARAMETER_IS_OUTPUT;
  153. parameter.name = "Orbit X";
  154. parameter.symbol = "orx";
  155. parameter.unit = "";
  156. parameter.ranges.def = 0.5f;
  157. parameter.ranges.min = 0.0f;
  158. parameter.ranges.max = 1.0f;
  159. break;
  160. case paramOrbitOutY:
  161. parameter.hints = PARAMETER_IS_OUTPUT;
  162. parameter.name = "Orbit Y";
  163. parameter.symbol = "ory";
  164. parameter.unit = "";
  165. parameter.ranges.def = 0.5f;
  166. parameter.ranges.min = 0.0f;
  167. parameter.ranges.max = 1.0f;
  168. break;
  169. case paramSubOrbitOutX:
  170. parameter.hints = PARAMETER_IS_OUTPUT;
  171. parameter.name = "SubOrbit X";
  172. parameter.symbol = "sorx";
  173. parameter.unit = "";
  174. parameter.ranges.def = 0.5f;
  175. parameter.ranges.min = 0.0f;
  176. parameter.ranges.max = 1.0f;
  177. break;
  178. case paramSubOrbitOutY:
  179. parameter.hints = PARAMETER_IS_OUTPUT;
  180. parameter.name = "SubOrbit Y";
  181. parameter.symbol = "sory";
  182. parameter.unit = "";
  183. parameter.ranges.def = 0.5f;
  184. parameter.ranges.min = 0.0f;
  185. parameter.ranges.max = 1.0f;
  186. break;
  187. case paramW1Out:
  188. parameter.hints = PARAMETER_IS_OUTPUT;
  189. parameter.name = "";
  190. parameter.symbol = "";
  191. parameter.unit = "";
  192. parameter.ranges.def = 0.5f;
  193. parameter.ranges.min = 0.0f;
  194. parameter.ranges.max = 1.0f;
  195. break;
  196. case paramW2Out:
  197. parameter.hints = PARAMETER_IS_OUTPUT;
  198. parameter.name = "";
  199. parameter.symbol = "";
  200. parameter.unit = "";
  201. parameter.ranges.def = 0.5f;
  202. parameter.ranges.min = 0.0f;
  203. parameter.ranges.max = 1.0f;
  204. break;
  205. case paramMOut:
  206. parameter.hints = PARAMETER_IS_OUTPUT;
  207. parameter.name = "";
  208. parameter.symbol = "";
  209. parameter.unit = "";
  210. parameter.ranges.def = 0.5f;
  211. parameter.ranges.min = 0.0f;
  212. parameter.ranges.max = 1.0f;
  213. break;
  214. case paramCOut:
  215. parameter.hints = PARAMETER_IS_OUTPUT;
  216. parameter.name = "";
  217. parameter.symbol = "";
  218. parameter.unit = "";
  219. parameter.ranges.def = 0.5f;
  220. parameter.ranges.min = 0.0f;
  221. parameter.ranges.max = 1.0f;
  222. break;
  223. case paramROut:
  224. parameter.hints = PARAMETER_IS_OUTPUT;
  225. parameter.name = "";
  226. parameter.symbol = "";
  227. parameter.unit = "";
  228. parameter.ranges.def = 0.5f;
  229. parameter.ranges.min = 0.0f;
  230. parameter.ranges.max = 1.0f;
  231. break;
  232. case paramSOut:
  233. parameter.hints = PARAMETER_IS_OUTPUT;
  234. parameter.name = "";
  235. parameter.symbol = "";
  236. parameter.unit = "";
  237. parameter.ranges.def = 0.5f;
  238. parameter.ranges.min = 0.0f;
  239. parameter.ranges.max = 1.0f;
  240. break;
  241. case paramReOut:
  242. parameter.hints = PARAMETER_IS_OUTPUT;
  243. parameter.name = "";
  244. parameter.symbol = "";
  245. parameter.unit = "";
  246. parameter.ranges.def = 0.5f;
  247. parameter.ranges.min = 0.0f;
  248. parameter.ranges.max = 1.0f;
  249. break;
  250. case paramShOut:
  251. parameter.hints = PARAMETER_IS_OUTPUT;
  252. parameter.name = "";
  253. parameter.symbol = "";
  254. parameter.unit = "";
  255. parameter.ranges.def = 0.5f;
  256. parameter.ranges.min = 0.0f;
  257. parameter.ranges.max = 1.0f;
  258. break;
  259. }
  260. if (index>=17 && index<17+64) {
  261. //int x = (index-17)%8;
  262. //int y = (x+1)/(index-17)
  263. parameter.hints = PARAMETER_IS_AUTOMABLE;
  264. parameter.name = "synth";
  265. parameter.symbol = "";
  266. parameter.unit = "";
  267. parameter.ranges.def = 0.5f;
  268. parameter.ranges.min = 0.0f;
  269. parameter.ranges.max = 1.0f;
  270. }
  271. }
  272. void GrooveJuicePlugin::d_initProgramName(uint32_t index, d_string& programName)
  273. {
  274. if (index != 0)
  275. return;
  276. programName = "Default";
  277. }
  278. // -----------------------------------------------------------------------
  279. // Internal data
  280. float GrooveJuicePlugin::d_getParameterValue(uint32_t index) const
  281. {
  282. if (index<17 || index>=17+64) {
  283. switch (index)
  284. {
  285. case paramX:
  286. return x;
  287. case paramY:
  288. return y;
  289. case paramOrbitSizeX:
  290. return orbitSizeX;
  291. case paramOrbitSizeY:
  292. return orbitSizeY;
  293. case paramOrbitSpeedX:
  294. return orbitSpeedX;
  295. case paramOrbitSpeedY:
  296. return orbitSpeedY;
  297. case paramSubOrbitSpeed:
  298. return subOrbitSpeed;
  299. case paramSubOrbitSize:
  300. return subOrbitSize;
  301. case paramOrbitOutX:
  302. return orbitX;
  303. case paramOrbitOutY:
  304. return orbitY;
  305. case paramSubOrbitOutX:
  306. return subOrbitX;
  307. case paramSubOrbitOutY:
  308. return subOrbitY;
  309. case paramSubOrbitSmooth:
  310. return subOrbitSmooth;
  311. case paramOrbitWaveX:
  312. return orbitWaveX;
  313. case paramOrbitWaveY:
  314. return orbitWaveY;
  315. case paramOrbitPhaseX:
  316. return orbitPhaseY;
  317. case paramOrbitPhaseY:
  318. return orbitPhaseY;
  319. case paramW1Out:
  320. return synthSound[0];
  321. case paramW2Out:
  322. return synthSound[1];
  323. case paramMOut:
  324. return synthSound[2];
  325. case paramCOut:
  326. return synthSound[3];
  327. case paramROut:
  328. return synthSound[4];
  329. case paramSOut:
  330. return synthSound[5];
  331. case paramReOut:
  332. return synthSound[6];
  333. case paramShOut:
  334. return synthSound[7];
  335. default:
  336. return 0.0f;
  337. }
  338. } else {
  339. int num = (index-17); //synth params begin on #17
  340. int x = num%8; //synth param
  341. //synth page
  342. int y = (num-(num%8))/8;
  343. return synthData[x][y];
  344. }
  345. }
  346. void GrooveJuicePlugin::d_setParameterValue(uint32_t index, float value)
  347. {
  348. if (index<17) {
  349. switch (index)
  350. {
  351. case paramX:
  352. x = value;
  353. break;
  354. case paramY:
  355. y = value;
  356. break;
  357. case paramOrbitSpeedX:
  358. orbitSpeedX = value;
  359. resetPhase();
  360. break;
  361. case paramOrbitSpeedY:
  362. orbitSpeedY = value;
  363. resetPhase();
  364. break;
  365. case paramOrbitSizeX:
  366. orbitSizeX = value;
  367. break;
  368. case paramOrbitSizeY:
  369. orbitSizeY = value;
  370. break;
  371. case paramSubOrbitSpeed:
  372. subOrbitSpeed = value;
  373. resetPhase();
  374. break;
  375. case paramSubOrbitSize:
  376. subOrbitSize = value;
  377. break;
  378. case paramSubOrbitSmooth:
  379. subOrbitSmooth = value;
  380. break;
  381. case paramOrbitWaveX:
  382. orbitWaveX = value;
  383. break;
  384. case paramOrbitWaveY:
  385. orbitWaveY = value;
  386. break;
  387. case paramOrbitPhaseX:
  388. orbitPhaseX = value;
  389. resetPhase();
  390. break;
  391. case paramOrbitPhaseY:
  392. orbitPhaseY = value;
  393. resetPhase();
  394. break;
  395. }
  396. } else {
  397. int num = (index-17); //synth params begin on #17
  398. int x = num%8; //synth param
  399. //synth page
  400. int y = (num-(num%8))/8;
  401. synthData[x][y] = value;
  402. }
  403. }
  404. void GrooveJuicePlugin::d_setProgram(uint32_t index)
  405. {
  406. if (index != 0)
  407. return;
  408. /* Default parameter values */
  409. x = 0.5f;
  410. y = 0.5f;
  411. orbitSpeedX = 4.0f;
  412. orbitSpeedY = 4.0f;
  413. orbitSizeX = 0.5f;
  414. orbitSizeY = 0.5f;
  415. subOrbitSize = 0.5f;
  416. subOrbitSpeed = 32.0f;
  417. orbitWaveX = 3.0f;
  418. orbitWaveY = 3.0f;
  419. subOrbitSmooth = 0.5f;
  420. orbitPhaseX = 0.0f;
  421. orbitPhaseY = 0.0f;
  422. /* Default variable values */
  423. orbitX=orbitY=orbitTX=orbitTY=0.5;
  424. subOrbitX=subOrbitY=subOrbitTX=subOrbitTY=0;
  425. interpolationDivider=200;
  426. bar=tickX=tickY=percentageX=percentageY=tickOffsetX=0;
  427. tickOffsetY=sinePosX=sinePosY=tick=percentage=tickOffset=sinePos=0;
  428. waveBlend=0;
  429. synthL.setSampleRate(d_getSampleRate());
  430. synthR.setSampleRate(d_getSampleRate());
  431. //parameter smoothing
  432. for (int i=0; i<2; i++) {
  433. sA[i] = 0.99f;
  434. sB[i] = 1.f - sA[i];
  435. sZ[i] = 0;
  436. }
  437. for (int x=0; x<8; x++)
  438. for (int y=0; y<8; y++)
  439. synthData[x][y] = 0.5;
  440. /* reset filter values */
  441. d_activate();
  442. }
  443. // -----------------------------------------------------------------------
  444. // Process
  445. void GrooveJuicePlugin::d_activate()
  446. {
  447. //sinePos = 0;
  448. }
  449. void GrooveJuicePlugin::d_deactivate()
  450. {
  451. // all values to zero
  452. }
  453. void GrooveJuicePlugin::d_run(const float**, float** outputs, uint32_t frames, const MidiEvent* midiEvents, uint32_t midiEventCount)
  454. {
  455. float out1, out2, tX, tY;
  456. /*
  457. out1 = inputs[0][i]*tN(1-std::sqrt((tX*tX)+(tY*tY)));
  458. out2 = inputs[1][i]*tN(1-std::sqrt((tX*tX)+(tY*tY)));
  459. out1 += inputs[2][i]*tN(1-std::sqrt(((1-tX)*(1-tX))+(tY*tY)));
  460. out2 += inputs[3][i]*tN(1-std::sqrt(((1-tX)*(1-tX))+(tY*tY)));
  461. out1 += inputs[4][i]*tN(1-std::sqrt(((1-tX)*(1-tX))+((1-tY)*(1-tY))));
  462. out2 += inputs[5][i]*tN(1-std::sqrt(((1-tX)*(1-tX))+((1-tY)*(1-tY))));
  463. out1 += inputs[6][i]*tN(1-std::sqrt((tX*tX)+((1-tY)*(1-tY))));
  464. out2 += inputs[7][i]*tN(1-std::sqrt((tX*tX)+((1-tY)*(1-tY))));
  465. */
  466. for (uint32_t i = 0; i<frames; i++) {
  467. animate();
  468. tX = subOrbitX;
  469. tY = subOrbitY;
  470. //sum values
  471. float c = 0.41421f; //mid segment
  472. float d = c/1.41f; //side segments
  473. float distances[8];
  474. distances[0] = distance(d, 0, tX, tY);
  475. distances[1] = distance(c+d, 0, tX, tY);
  476. distances[2] = distance(1, d, tX, tY);
  477. distances[3] = distance(1, c+d, tX, tY);
  478. distances[4] = distance(d, 1, tX, tY);
  479. distances[5] = distance(c+d, 1, tX, tY);
  480. distances[6] = distance(0, d, tX, tY);
  481. distances[7] = distance(0, c+d, tX, tY);
  482. //std::cout << distances[0] << " ";
  483. //std::cout << tX << std::endl;
  484. for (int x=0; x<8; x++) {
  485. float targetValue = 0;
  486. for (int y=0; y<8; y++) {
  487. targetValue += synthData[x][y]*(distances[y]);
  488. }
  489. synthSound[x] = tN(targetValue);
  490. }
  491. //printf("wave1: %f\n", synthSound[0]);
  492. //std::cout << synthSound[0] << std::endl;
  493. synthL.setWave(0, synthSound[0]);
  494. synthR.setWave(0, synthSound[0]);
  495. synthL.setWave(1, synthSound[1]);
  496. synthR.setWave(1, synthSound[1]);
  497. synthL.setMix(synthSound[2]);
  498. synthR.setMix(synthSound[2]);
  499. //synthL.setCut(synthSound[3]);
  500. //synthR.setCut(synthSound[3]);
  501. //synthL.setReso(synthSound[4]);
  502. //synthR.setReso(synthSound[4]);
  503. //synthL.setDecay(synthSound[5]);
  504. //synthR.setDecay(synthSound[5]);
  505. synthL.setSustain(synthSound[5]);
  506. synthR.setSustain(synthSound[5]);
  507. synthL.setRelease(synthSound[6]);
  508. synthR.setRelease(synthSound[6]);
  509. synthL.setStereo(-0.5);
  510. synthR.setStereo(0.5);
  511. synthL.setShape(synthSound[7]);
  512. synthR.setShape(synthSound[7]);
  513. float cutoff = std::exp((std::log(16000)-std::log(500))*synthSound[3]+std::log(500));
  514. filterL.recalc(cutoff, synthSound[4]*0.8, d_getSampleRate(), synthSound[7]);
  515. filterR.recalc(cutoff, synthSound[4]*0.8, d_getSampleRate(), synthSound[7]);
  516. outputs[0][i] = filterL.process(synthL.run());
  517. outputs[1][i] = filterR.process(synthL.run());
  518. }
  519. //outputs = buffer;
  520. for (uint32_t i = 0; i<midiEventCount; i++) {
  521. int mType = midiEvents[i].buf[0] & 0xF0;
  522. //int mChan = midiEvents[i].buf[0] & 0x0F;
  523. int mNum = midiEvents[i].buf[1];
  524. if (mType == 0x90) {
  525. //note on
  526. synthL.play(mNum);
  527. synthR.play(mNum);
  528. } else if (mType == 0x80) {
  529. //note off
  530. synthL.stop(mNum);
  531. synthR.stop(mNum);
  532. }
  533. }
  534. }
  535. // -----------------------------------------------------------------------
  536. Plugin* createPlugin()
  537. {
  538. return new GrooveJuicePlugin();
  539. }
  540. // -----------------------------------------------------------------------
  541. END_NAMESPACE_DISTRHO