DISTRHO Juice Plugins
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.

740 lines
15KB

  1. #ifndef CMODULE_HXX_INCLUDED
  2. #define CMODULE_HXX_INCLUDED
  3. #include <time.h> //rand
  4. #include <algorithm> //min
  5. // -----------------------------------------------------------------------
  6. // SubModules
  7. class LPF
  8. {
  9. private:
  10. float r; // reso - 0.1 - 1.4
  11. float f; // freq in Hz
  12. float a1, a2, a3, b1, b2;
  13. float in, in1, in2;
  14. float out, out1, out2;
  15. float c;
  16. float sampleRate;
  17. void compute() {
  18. c = 1.0 / tan(M_PI * f / sampleRate);
  19. a1 = 1.0 / (1.0 + r*c + c*c);
  20. a2 = 2 * a1;
  21. a3 = a1;
  22. b1 = 2.0 * (1.0 - c*c) * a1;
  23. b2 = (1.0 - r*c + c*c) * a1;
  24. }
  25. public:
  26. LPF() {
  27. r = 1.0f;
  28. f = 0.0f;
  29. a1=a2=a3=b1=b2=0.0f;
  30. in=in1=in2=out=out1=out2=0.0f;
  31. }
  32. void setFreq(float nFreq) {
  33. f = nFreq;
  34. if (f==0) {
  35. f=20;
  36. }
  37. }
  38. void setReso(float nReso) {
  39. r = nReso;
  40. if (r==0) {
  41. r = 0.1f;
  42. }
  43. }
  44. void setSampleRate(float nSampleRate) {
  45. sampleRate = nSampleRate;
  46. }
  47. float process(float sample) {
  48. compute();
  49. in = sample;
  50. out = a1 * in + a2 * in1 + a3 * in2 - b1*out1 - b2*out2;
  51. in2=in1;
  52. in1=in;
  53. out2=out1;
  54. out1 = out;
  55. return out;
  56. }
  57. };
  58. class HPF
  59. {
  60. private:
  61. float r; // reso - 0.1 - 1.4
  62. float f; // freq in Hz
  63. float a1, a2, a3, b1, b2;
  64. float in, in1, in2;
  65. float out, out1, out2;
  66. float c;
  67. float sampleRate;
  68. void compute() {
  69. c = tan(M_PI * f / sampleRate);
  70. a1 = 1.0 / (1.0 + r*c + c*c);
  71. a2 = -2*a1;
  72. a3 = a1;
  73. b1 = 2.0 * (c*c - 1.0) * a1;
  74. b2 = (1.0 - r*c + c*c) * a1;
  75. }
  76. public:
  77. HPF() {
  78. r = 1.0f;
  79. f = 0.0f;
  80. a1=a2=a3=b1=b2=0.0f;
  81. in=in1=in2=out=out1=out2=0.0f;
  82. }
  83. void setFreq(float nFreq) {
  84. f = nFreq;
  85. if (f==0) {
  86. f=20;
  87. }
  88. }
  89. void setReso(float nReso) {
  90. r = nReso;
  91. if (r==0) {
  92. r = 0.1f;
  93. }
  94. }
  95. void setSampleRate(float nSampleRate) {
  96. sampleRate = nSampleRate;
  97. }
  98. float process(float sample) {
  99. compute();
  100. in = sample;
  101. out = a1 * in + a2 * in1 + a3 * in2 - b1*out1 - b2*out2;
  102. in2=in1;
  103. in1=in;
  104. out2=out1;
  105. out1 = out;
  106. return out;
  107. }
  108. };
  109. class CSHIFT {
  110. private:
  111. float fVec0[65536];
  112. float fRec0[2];
  113. int IOTA;
  114. float shiftAmt; //-12 .. 12 semi
  115. float windowSize; // 50 .. 10k samples
  116. float xfade; // 1 .. 10k samples
  117. float sampleRate;
  118. float output;
  119. public:
  120. CSHIFT() {
  121. IOTA = 0;
  122. for (int i = 0; i<65536; i++) {
  123. fVec0[i] = 0.0f;
  124. }
  125. for (int i = 0; i<2; i++) {
  126. fRec0[i] = 0.f;
  127. }
  128. shiftAmt = 0.1f;
  129. windowSize = 200.0f;
  130. xfade = 76.0f;
  131. }
  132. void setSampleRate(float nSampleRate) {
  133. sampleRate = nSampleRate;
  134. }
  135. void setWindowSize(float nWindowSize) {
  136. windowSize = nWindowSize;
  137. }
  138. void setXfade(float nXfade) {
  139. xfade = nXfade;
  140. }
  141. void setShiftAmt(float nShiftAmt) {
  142. shiftAmt = nShiftAmt;
  143. }
  144. float process(float audio) {
  145. float input0 = audio;
  146. float fSlow0 = windowSize;
  147. float fSlow1 = ((1.f + fSlow0) - powf(2.f, (0.0833333f * shiftAmt)));
  148. float fSlow2 = (1.f / xfade);
  149. float fSlow3 = (fSlow0 - 1.f);
  150. float fTemp0 = audio;
  151. fVec0[(IOTA & 65535)] = fTemp0;
  152. fRec0[0] = fmodf((fRec0[1] + fSlow1), fSlow0);
  153. int iTemp1 = int(fRec0[0]);
  154. int iTemp2 = (1 + iTemp1);
  155. float fTemp3 = std::min((fSlow2 * fRec0[0]), 1.f);
  156. float fTemp4 = (fRec0[0] + fSlow0);
  157. int iTemp5 = int(fTemp4);
  158. output = ((((fVec0[((IOTA - int((iTemp1 & 65535))) & 65535)] * (iTemp2 - fRec0[0])) + ((fRec0[0] - iTemp1) * fVec0[((IOTA - int((int(iTemp2) & 65535))) & 65535)])) * fTemp3) + (((fVec0[((IOTA - int((iTemp5 & 65535))) & 65535)] * (0.f - ((fRec0[0] + fSlow3) - float(iTemp5)))) + ((fTemp4 - float(iTemp5)) * fVec0[((IOTA - int((int((1 + iTemp5)) & 65535))) & 65535)])) * (1.f - fTemp3)));
  159. IOTA = (IOTA + 1);
  160. fRec0[1] = fRec0[0];
  161. return output;
  162. }
  163. };
  164. // -----------------------------------------------------------------------
  165. // Modules
  166. class CModule
  167. {
  168. public:
  169. CModule() {
  170. sampleRate = 0;
  171. params[0] = 0.5f;
  172. params[1] = 0.5f;
  173. params[2] = 0.5f;
  174. active = false;
  175. sinePos = 0;
  176. }
  177. virtual void setParam(float value, int index) {
  178. params[index] = value;
  179. }
  180. virtual void process(float &audioL, float &audioR) {}
  181. virtual void initBuffers() {}
  182. void setSampleRate(int nSR) {
  183. sampleRate = nSR;
  184. }
  185. void activate() {
  186. active = true;
  187. }
  188. void deactivate() {
  189. active = false;
  190. }
  191. virtual void setSinePos(float nSinePos) {
  192. sinePos = nSinePos;
  193. }
  194. virtual float getTempoDivider() {
  195. return 1.0f;
  196. }
  197. float getSinePos() {
  198. return sinePos;
  199. }
  200. float isActive() {
  201. return active;
  202. }
  203. void resetSinePos() {
  204. sinePos = 0;
  205. }
  206. float getOutputParam() {
  207. return (sinePos/(2*M_PI));
  208. }
  209. protected:
  210. //vars
  211. float params[3];
  212. int sampleRate;
  213. bool active;//is open?
  214. float getSinePhase(float x) {
  215. return ((-std::cos(x)+1)/2);
  216. }
  217. float getSawPhase(float x) {
  218. return (-((2/M_PI * std::atan(1/std::tan(x/2)))-1)/2);
  219. }
  220. float getRevSawPhase(float x) {
  221. return (((2/M_PI * std::atan(1/std::tan(x/2)))+1)/2);
  222. }
  223. float getSquarePhase(float x) {
  224. return (std::round((std::sin(x)+1)/2));
  225. }
  226. void debug() {
  227. printf("Boo!\n");
  228. }
  229. //saw, sqr, sin, revSaw
  230. float getBlendedPhase(float x, float wave)
  231. {
  232. wave = wave*3+1;
  233. float waveBlend;
  234. //wave = 2;
  235. if (wave>=1 && wave<2) {
  236. /* saw vs sqr */
  237. waveBlend = wave-1;
  238. return (getSawPhase(x)*(1-waveBlend) + getSquarePhase(x)*waveBlend);
  239. } else if (wave>=2 && wave<3) {
  240. /* sqr vs sin */
  241. waveBlend = wave-2;
  242. return (getSquarePhase(x)*(1-waveBlend) + getSinePhase(x)*waveBlend);
  243. } else if (wave>=3 && wave<=4) {
  244. /* sin vs revSaw */
  245. waveBlend = wave-3;
  246. return (getSinePhase(x)*(1-waveBlend) + getRevSawPhase(x)*waveBlend);
  247. } else {
  248. return 0.0f;
  249. }
  250. }
  251. float sinePos;
  252. float tAudioL, tAudioR;
  253. };
  254. class CGate: public CModule
  255. {
  256. public:
  257. void process(float &audioL, float &audioR) {
  258. tAudioL = audioL;
  259. tAudioR = audioR;
  260. tAudioL *= getBlendedPhase(sinePos, params[1]);
  261. tAudioR *= getBlendedPhase(sinePos, params[1]);
  262. if (active) {
  263. audioL = tAudioL;
  264. audioR = tAudioR;
  265. }
  266. }
  267. };
  268. class CReverse: public CModule
  269. {
  270. private:
  271. //two buffers, one is playing (back), one is recording
  272. struct BufferStack {
  273. int32_t start;
  274. float* data;
  275. } bufferL[2], bufferR[2];
  276. //buffer flipper
  277. int flipState;
  278. //buffer size
  279. uint32_t bufferStackCount;
  280. //flip record and play buffers
  281. void flip() {
  282. if (flipState==0) flipState = 1; else flipState = 0;
  283. }
  284. //which side is the play side
  285. int getPlayFlip() {
  286. if (flipState==0) return 1; else return 0;
  287. }
  288. public:
  289. void process(float &audioL, float &audioR) {
  290. tAudioL = audioL;
  291. tAudioR = audioR;
  292. //fill the buffer
  293. bufferL[flipState].data[bufferL[flipState].start] = tAudioL;
  294. bufferR[flipState].data[bufferR[flipState].start] = tAudioR;
  295. //roll playhead forward
  296. if (++bufferL[flipState].start>bufferStackCount) {
  297. bufferL[flipState].start = 0;
  298. }
  299. if (++bufferR[flipState].start>bufferStackCount) {
  300. bufferR[flipState].start = 0;
  301. }
  302. //play the buffer
  303. //audio
  304. tAudioL = bufferL[getPlayFlip()].data[bufferL[getPlayFlip()].start]*params[2] + tAudioL*(1-params[2]);
  305. tAudioR = bufferR[getPlayFlip()].data[bufferR[getPlayFlip()].start]*params[2] + tAudioR*(1-params[2]);
  306. //roll playhead backwards
  307. if (--bufferL[getPlayFlip()].start<0) {
  308. bufferL[getPlayFlip()].start = bufferStackCount;
  309. }
  310. if (--bufferR[getPlayFlip()].start<0) {
  311. bufferR[getPlayFlip()].start = bufferStackCount;
  312. }
  313. if (active) {
  314. audioL = tAudioL;
  315. audioR = tAudioR;
  316. }
  317. }
  318. //custom method, flip buffers when resetting sinePos
  319. void setSinePos(float nSinePos) {
  320. if (sinePos > nSinePos) {
  321. flip();
  322. }
  323. sinePos = nSinePos;
  324. }
  325. void initBuffers() {
  326. flipState = 0;
  327. //set up a 10 second buffer
  328. bufferStackCount = sampleRate*10;
  329. for (int i=0; i<2; i++) {
  330. //allocate
  331. bufferL[i].data = (float*) calloc(bufferStackCount, sizeof(float));
  332. bufferR[i].data = (float*) calloc(bufferStackCount, sizeof(float));
  333. //clear with zeroes
  334. std::memset(bufferL[i].data, 0, sizeof(float)*bufferStackCount);
  335. std::memset(bufferR[i].data, 0, sizeof(float)*bufferStackCount);
  336. //reset playhead
  337. bufferL[i].start = 0;
  338. bufferR[i].start = 0;
  339. }
  340. }
  341. };
  342. class CRepeat: public CModule
  343. {
  344. private:
  345. //two buffers, one is playing (back), one is recording
  346. struct BufferStack {
  347. int32_t start;
  348. float* data;
  349. } bufferL[2], bufferR[2];
  350. //buffer flipper
  351. int flipState;
  352. //buffer size
  353. uint32_t bufferStackCount;
  354. //flip record and play buffers
  355. void flip() {
  356. repeats++;
  357. if (repeats==(round(params[1]*6)+1)) {
  358. if (flipState==0) flipState = 1; else flipState = 0;
  359. }
  360. bufferL[getPlayFlip()].start = (bufferL[getPlayFlip()].start-lag) % bufferStackCount;
  361. bufferR[getPlayFlip()].start = (bufferR[getPlayFlip()].start-lag) % bufferStackCount;
  362. if (repeats==(round(params[1]*6)+1)) {
  363. lag = 0;
  364. repeats = 0;
  365. }
  366. }
  367. //which side is the play side
  368. int getPlayFlip() {
  369. if (flipState==0) return 1; else return 0;
  370. }
  371. int repeats;
  372. uint32_t lag;
  373. public:
  374. void process(float &audioL, float &audioR) {
  375. tAudioL = audioL;
  376. tAudioR = audioR;
  377. //fill the buffer
  378. bufferL[flipState].data[bufferL[flipState].start] = tAudioL;
  379. bufferR[flipState].data[bufferR[flipState].start] = tAudioR;
  380. //roll playhead forward
  381. if (++bufferL[flipState].start>bufferStackCount) {
  382. bufferL[flipState].start = 0;
  383. }
  384. if (++bufferR[flipState].start>bufferStackCount) {
  385. bufferR[flipState].start = 0;
  386. }
  387. if (repeats == 0) {
  388. lag++;
  389. }
  390. //play the buffer
  391. //audio
  392. tAudioL = bufferL[getPlayFlip()].data[bufferL[getPlayFlip()].start]*params[2] + tAudioL*(1-params[2]);
  393. tAudioR = bufferR[getPlayFlip()].data[bufferR[getPlayFlip()].start]*params[2] + tAudioR*(1-params[2]);
  394. //roll playhead forward
  395. if (++bufferL[getPlayFlip()].start>bufferStackCount) {
  396. bufferL[getPlayFlip()].start = 0;
  397. }
  398. if (++bufferR[getPlayFlip()].start>bufferStackCount) {
  399. bufferR[getPlayFlip()].start = 0;
  400. }
  401. if (active) {
  402. audioL = tAudioL;
  403. audioR = tAudioR;
  404. }
  405. }
  406. //custom method, flip buffers when resetting sinePos
  407. void setSinePos(float nSinePos) {
  408. if (sinePos > nSinePos) {
  409. flip();
  410. }
  411. sinePos = nSinePos;
  412. }
  413. void setParam(float value, int index) {
  414. params[index] = value;
  415. repeats = 0;
  416. }
  417. void initBuffers() {
  418. repeats = 0;
  419. flipState = 0;
  420. lag = 0;
  421. //set up a 10 second buffer
  422. bufferStackCount = sampleRate*10;
  423. for (int i=0; i<2; i++) {
  424. //allocate
  425. bufferL[i].data = (float*) calloc(bufferStackCount, sizeof(float));
  426. bufferR[i].data = (float*) calloc(bufferStackCount, sizeof(float));
  427. //clear with zeroes
  428. std::memset(bufferL[i].data, 0, sizeof(float)*bufferStackCount);
  429. std::memset(bufferR[i].data, 0, sizeof(float)*bufferStackCount);
  430. //reset playhead
  431. bufferL[i].start = 0;
  432. bufferR[i].start = 0;
  433. }
  434. }
  435. };
  436. class CSequence: public CModule
  437. {
  438. private:
  439. LPF lpf[2];
  440. HPF hpf[2];
  441. float sequence[9][8] = {
  442. {200.0f, 400.0f, 600.0f, 800.0f, 200.0f, 400.0f, 600.0f, 800.0f}, //1
  443. {800.0f, 200.0f, 400.0f, 800.0f, 200.0f, 800.0f, 400.0f, 200.0f}, //2
  444. {800.0f, 600.0f, 400.0f, 200.0f, 300.0f, 400.0f, 600.0f, 800.0f}, //3
  445. {200.0f, 800.0f, 200.0f, 600.0f, 200.0f, 400.0f, 200.0f, 300.0f}, //4
  446. {200.0f, 800.0f, 200.0f, 800.0f, 200.0f, 400.0f, 600.0f, 800.0f}, //5
  447. {800.0f, 400.0f, 800.0f, 200.0f, 800.0f, 400.0f, 200.0f, 400.0f}, //6
  448. {400.0f, 800.0f, 200.0f, 800.0f, 200.0f, 800.0f, 400.0f, 300.0f}, //7
  449. {200.0f, 800.0f, 200.0f, 800.0f, 200.0f, 800.0f, 300.0f, 500.0f}, //8
  450. {800.0f, 300.0f, 200.0f, 800.0f, 300.0f, 200.0f, 400.0f, 600.0f}, //9
  451. };
  452. int sequenceHead;
  453. float peakFreq;
  454. public:
  455. void process(float &audioL, float &audioR) {
  456. tAudioL = audioL;
  457. tAudioR = audioR;
  458. lpf[0].setFreq(peakFreq*2);
  459. lpf[1].setFreq(peakFreq*2);
  460. hpf[0].setFreq(peakFreq);
  461. hpf[1].setFreq(peakFreq);
  462. tAudioL = lpf[0].process(tAudioL);
  463. tAudioR = lpf[1].process(tAudioR);
  464. tAudioL = hpf[0].process(tAudioL);
  465. tAudioR = hpf[1].process(tAudioR);
  466. if (active) {
  467. audioL = tAudioL;
  468. audioR = tAudioR;
  469. }
  470. }
  471. //custom method, move sequenceHead when needed
  472. void setSinePos(float nSinePos) {
  473. if (sinePos > nSinePos) {
  474. sequenceHead++;
  475. if (sequenceHead>7) {
  476. sequenceHead = 0;
  477. }
  478. peakFreq = sequence[(int) round(params[1]*8)][sequenceHead];
  479. peakFreq += (rand() % 400 - 200)*params[2];
  480. peakFreq*=2;
  481. }
  482. sinePos = nSinePos;
  483. }
  484. void initBuffers() {
  485. srand (time(NULL));
  486. sequenceHead = 0;
  487. peakFreq = 200.0f;
  488. for (int i=0; i<2; i++) {
  489. lpf[i].setSampleRate(sampleRate);
  490. lpf[i].setReso(0.5);
  491. hpf[i].setSampleRate(sampleRate);
  492. hpf[i].setReso(0.5);
  493. }
  494. }
  495. };
  496. class CShift: public CModule
  497. {
  498. private:
  499. CSHIFT shifter[2];
  500. public:
  501. void process(float &audioL, float &audioR) {
  502. tAudioL = audioL;
  503. tAudioR = audioR;
  504. float range = 96*params[1];
  505. int variation = round(params[2]*3)+1;
  506. float shiftAmt;
  507. switch (variation) {
  508. case 1:
  509. shiftAmt = (sinePos/(M_PI*2))*range-range/2;
  510. break;
  511. case 2:
  512. shiftAmt = -((sinePos/(M_PI*2))*range-range/2);
  513. break;
  514. case 3:
  515. shiftAmt = (sinePos/(M_PI*2))*range;
  516. break;
  517. case 4:
  518. shiftAmt = -(sinePos/(M_PI*2))*range;
  519. break;
  520. }
  521. //round up to one decimal point
  522. shiftAmt = round(shiftAmt*10)/10;
  523. for (int i=0; i<2; i++) {
  524. shifter[i].setShiftAmt(shiftAmt);
  525. }
  526. //shift!
  527. tAudioL = shifter[0].process(tAudioL);
  528. tAudioR = shifter[1].process(tAudioR);
  529. if (active) {
  530. audioL = tAudioL;
  531. audioR = tAudioR;
  532. }
  533. }
  534. void initBuffers() {
  535. for (int i=0; i<2; i++) {
  536. shifter[i].setSampleRate(sampleRate);
  537. }
  538. }
  539. float getTempoDivider() {
  540. return 8.0f;
  541. }
  542. };
  543. class CFilter: public CModule
  544. {
  545. private:
  546. LPF lpf[2];
  547. HPF hpf[2];
  548. float peakFreq;
  549. public:
  550. void process(float &audioL, float &audioR) {
  551. tAudioL = audioL;
  552. tAudioR = audioR;
  553. //to log scale
  554. peakFreq = std::exp((std::log(16000)-std::log(300))*getBlendedPhase(sinePos, params[1])+std::log(300));
  555. //peakFreq = 500.0f;
  556. lpf[0].setFreq(peakFreq);
  557. lpf[1].setFreq(peakFreq);
  558. hpf[0].setFreq(peakFreq);
  559. hpf[1].setFreq(peakFreq);
  560. int type = params[2]*2+1;
  561. switch (type) {
  562. case 1:
  563. tAudioL = lpf[0].process(tAudioL);
  564. tAudioR = lpf[1].process(tAudioR);
  565. //printf("type: %f\n", tAudioL);
  566. break;
  567. case 2:
  568. tAudioL = lpf[0].process(tAudioL);
  569. tAudioR = lpf[1].process(tAudioR);
  570. tAudioL = hpf[0].process(tAudioL);
  571. tAudioR = hpf[1].process(tAudioR);
  572. break;
  573. case 3:
  574. tAudioL = hpf[0].process(tAudioL);
  575. tAudioR = hpf[1].process(tAudioR);
  576. break;
  577. }
  578. if (active) {
  579. audioL = tAudioL;
  580. audioR = tAudioR;
  581. }
  582. }
  583. void initBuffers() {
  584. peakFreq = 200.0f;
  585. for (int i=0; i<2; i++) {
  586. lpf[i].setSampleRate(sampleRate);
  587. lpf[i].setReso(0.5);
  588. hpf[i].setSampleRate(sampleRate);
  589. hpf[i].setReso(0.5);
  590. }
  591. }
  592. float getTempoDivider() {
  593. return 8.0f;
  594. }
  595. };
  596. #endif // CMODULE_HXX_INCLUDED