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.

308 lines
6.6KB

  1. /*
  2. * Grain 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 GrainJUICEPLUGIN_HPP_INCLUDED
  18. #define GrainJUICEPLUGIN_HPP_INCLUDED
  19. #include "DistrhoPlugin.hpp"
  20. #include <cstdlib>
  21. #include <time.h>
  22. #include <vector>
  23. #define MAXGRAINSIZE 0.5f // in seconds
  24. #define MAXSCATTER 3.f // in seconds
  25. #define MAXGRAINS 300 // in grains
  26. START_NAMESPACE_DISTRHO
  27. // -----------------------------------------------------------------------
  28. class GrainJuicePlugin : public Plugin {
  29. public:
  30. enum Parameters {
  31. paramSize = 0,
  32. paramScatter,
  33. paramGain,
  34. paramDensity,
  35. paramLPF,
  36. paramHPF,
  37. paramSizeR,
  38. paramScatterR,
  39. paramGainR,
  40. paramDensityR,
  41. paramLPFR,
  42. paramHPFR,
  43. paramCount
  44. };
  45. GrainJuicePlugin();
  46. protected:
  47. // -------------------------------------------------------------------
  48. // Information
  49. const char* d_getLabel() const noexcept override {
  50. return "GrainJuice";
  51. }
  52. const char* d_getMaker() const noexcept override {
  53. return "Andre Sklenar";
  54. }
  55. const char* d_getLicense() const noexcept override {
  56. return "GPL v2+";
  57. }
  58. uint32_t d_getVersion() const noexcept override {
  59. return 0x1000;
  60. }
  61. long d_getUniqueId() const noexcept override {
  62. return d_cconst('G', 'r', 'n', 'J');
  63. }
  64. // -------------------------------------------------------------------
  65. // Init
  66. void d_initParameter(uint32_t index, Parameter& parameter) override;
  67. void d_initProgramName(uint32_t index, d_string& programName) override;
  68. // -------------------------------------------------------------------
  69. // Internal data
  70. float d_getParameterValue(uint32_t index) const override;
  71. void d_setParameterValue(uint32_t index, float value) override;
  72. void d_setProgram(uint32_t index) override;
  73. // -------------------------------------------------------------------
  74. // Process
  75. void d_activate() override;
  76. void d_run(const float** inputs, float** outputs, uint32_t frames) override;
  77. // -------------------------------------------------------------------
  78. private:
  79. float size, scatter, gain, density, LPF, HPF;
  80. float sizeR, scatterR, gainR, densityR, LPFR, HPFR;
  81. float *nSample;
  82. float *prevSample;
  83. int concurrentFilling;
  84. int eraseIndex;
  85. int eraseGrains[100];
  86. float logTable[1000];
  87. int limit(int what) {
  88. if (what>1000)
  89. return 999;
  90. if (what<0)
  91. return 0;
  92. return what;
  93. }
  94. void newGrain(bool first);
  95. //float *nSample;
  96. bool isNan(float& value ) {
  97. if (((*(uint32_t *) &value) & 0x7fffffff) > 0x7f800000) {
  98. return true;
  99. }
  100. return false;
  101. }
  102. uint32_t prevTotalGrains;
  103. DISTRHO_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR(GrainJuicePlugin)
  104. class CGrain {
  105. public:
  106. CGrain(uint32_t nLength, uint32_t nDelay, float lpf, float hpf, float nGain);
  107. uint32_t getLength();
  108. void fillSample(float *nSample);
  109. bool wantsSample();
  110. float *getSample();
  111. bool donePlaying();
  112. void cleanUp();
  113. bool inDelay();
  114. uint32_t length;
  115. bool repeat();
  116. void setDelay(uint32_t nDelay);
  117. void updateParams(float nDensity, float nScatter, uint32_t nSRT);
  118. float inspectSample(uint32_t index, int channel);
  119. private:
  120. void applyEnvelope();
  121. float samples[(int)(48000*MAXGRAINSIZE)][2];
  122. uint32_t playhead;
  123. bool readyForPlayback;
  124. uint32_t delay;
  125. float *emptySamples;
  126. float density;
  127. float scatter;
  128. float gain;
  129. uint32_t SRT;
  130. class CLPF
  131. {
  132. private:
  133. float r; // reso - 0.1 - 1.4
  134. float f; // freq in Hz
  135. float a1, a2, a3, b1, b2;
  136. float in, in1, in2;
  137. float out, out1, out2;
  138. float c;
  139. float sampleRate;
  140. public:
  141. CLPF() {
  142. r = 1.0f;
  143. f = 0.0f;
  144. a1=a2=a3=b1=b2=0.0f;
  145. in=in1=in2=out=out1=out2=0.0f;
  146. }
  147. void compute() {
  148. c = 1.0 / tan(M_PI * f / sampleRate);
  149. a1 = 1.0 / (1.0 + r*c + c*c);
  150. a2 = 2 * a1;
  151. a3 = a1;
  152. b1 = 2.0 * (1.0 - c*c) * a1;
  153. b2 = (1.0 - r*c + c*c) * a1;
  154. }
  155. void setFreq(float nFreq) {
  156. f = nFreq;
  157. if (f==0) {
  158. f=20;
  159. }
  160. }
  161. void setReso(float nReso) {
  162. r = nReso;
  163. if (r==0) {
  164. r = 0.1f;
  165. }
  166. r = 1.0f;
  167. f = 0.0f;
  168. a1=a2=a3=b1=b2=0.0f;
  169. in=in1=in2=out=out1=out2=0.0f;
  170. }
  171. void setSampleRate(float nSampleRate) {
  172. sampleRate = nSampleRate;
  173. }
  174. float process(float sample) {
  175. in = sample;
  176. out = a1 * in + a2 * in1 + a3 * in2 - b1*out1 - b2*out2;
  177. in2=in1;
  178. in1=in;
  179. out2=out1;
  180. out1 = out;
  181. return out;
  182. }
  183. };
  184. class CHPF
  185. {
  186. private:
  187. float r; // reso - 0.1 - 1.4
  188. float f; // freq in Hz
  189. float a1, a2, a3, b1, b2;
  190. float in, in1, in2;
  191. float out, out1, out2;
  192. float c;
  193. float sampleRate;
  194. public:
  195. CHPF() {
  196. r = 1.0f;
  197. f = 0.0f;
  198. a1=a2=a3=b1=b2=0.0f;
  199. in=in1=in2=out=out1=out2=0.0f;
  200. }
  201. void compute() {
  202. c = tan(M_PI * f / sampleRate);
  203. a1 = 1.0 / (1.0 + r*c + c*c);
  204. a2 = -2*a1;
  205. a3 = a1;
  206. b1 = 2.0 * (c*c - 1.0) * a1;
  207. b2 = (1.0 - r*c + c*c) * a1;
  208. }
  209. void setFreq(float nFreq) {
  210. f = nFreq;
  211. if (f==0) {
  212. f=20;
  213. }
  214. }
  215. void setReso(float nReso) {
  216. r = nReso;
  217. if (r==0) {
  218. r = 0.1f;
  219. }
  220. }
  221. void setSampleRate(float nSampleRate) {
  222. sampleRate = nSampleRate;
  223. }
  224. float process(float sample) {
  225. //compute();
  226. in = sample;
  227. out = a1 * in + a2 * in1 + a3 * in2 - b1*out1 - b2*out2;
  228. in2=in1;
  229. in1=in;
  230. out2=out1;
  231. out1 = out;
  232. return out;
  233. }
  234. };
  235. CHPF highPass[2];
  236. CLPF lowPass[2];
  237. };
  238. std::vector<CGrain*> grains;
  239. };
  240. // -----------------------------------------------------------------------
  241. END_NAMESPACE_DISTRHO
  242. #endif // GrainJUICE_HPP_INCLUDED