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.

269 lines
6.5KB

  1. /*
  2. ==============================================================================
  3. This file is part of the JUCETICE project - Copyright 2008 by Lucio Asnaghi.
  4. JUCETICE is based around the JUCE library - "Jules' Utility Class Extensions"
  5. Copyright 2008 by Julian Storer.
  6. ------------------------------------------------------------------------------
  7. JUCE and JUCETICE can be redistributed and/or modified under the terms of
  8. the GNU Lesser General Public License, as published by the Free Software
  9. Foundation; either version 2 of the License, or (at your option) any later
  10. version.
  11. JUCE and JUCETICE are distributed in the hope that they will be useful,
  12. but WITHOUT ANY WARRANTY; without even the implied warranty of
  13. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  14. GNU General Public License for more details.
  15. You should have received a copy of the GNU Lesser General Public License
  16. along with JUCE and JUCETICE; if not, visit www.gnu.org/licenses or write to
  17. Free Software Foundation, Inc., 59 Temple Place, Suite 330,
  18. Boston, MA 02111-1307 USA
  19. ==============================================================================
  20. @author rockhardbuns
  21. @tweaker Lucio Asnaghi
  22. ==============================================================================
  23. */
  24. #include "cVoice.h"
  25. float convertPitch(float pitch)
  26. {
  27. long convert;
  28. float *p = (float*)&convert;
  29. float fl, fr, warp, out;
  30. fl = std::floor(pitch);
  31. fr = pitch - fl;
  32. warp = fr*0.696f + fr*fr*0.225f + fr*fr*fr*0.079f; // chebychev approx
  33. out = fl+warp;
  34. out *= 8388608.0; //2^23;
  35. out += 127.0 * 8388608.0; //2^23;
  36. convert = (long)out; //magic
  37. return *p;
  38. }
  39. float bipolar(const float in)
  40. {
  41. return in * 2.0f - 1.0f;
  42. }
  43. VexVoice::VexVoice(const float* const p, int po, WaveRenderer& w, float sr)
  44. : wr(w),
  45. parameters(p),
  46. poff(po)
  47. {
  48. Ordinal = 1;
  49. SampleRate = sr;
  50. isOn = false;
  51. note = 0;
  52. lfoC = 2.f * (float)std::sin(float_Pi * 5.0f / SampleRate);
  53. lfoS[0] = 0.3f;
  54. lfoS[1] = 0.0f;
  55. lowL = 0.0f;
  56. bandL = 0.0f;
  57. highL = 0.0f;
  58. lowR = 0.0f;
  59. bandR = 0.0f;
  60. highR = 0.0f;
  61. q = 0.0f;
  62. cut = 0.0f;
  63. }
  64. void VexVoice::updateParameterPtr(const float* const p)
  65. {
  66. parameters = p;
  67. }
  68. void VexVoice::doProcess(float* outBufferL, float* outBufferR, int bufferSize)
  69. {
  70. if (outBufferL == nullptr || outBufferR == nullptr || bufferSize == 0)
  71. return;
  72. //float resAmt = 0.0;
  73. float A, B;
  74. float amod;
  75. wr.fillBuffer(outBufferL, bufferSize, oL);
  76. wr.fillBuffer(outBufferR, bufferSize, oR);
  77. for (int i = 0; i < bufferSize; i++)
  78. {
  79. //LFO
  80. lfoS[0] = lfoS[0] - lfoC * lfoS[1];
  81. lfoS[1] = lfoS[1] + lfoC * lfoS[0];
  82. LFOA = lfoS[0] * parameters[20 + poff];
  83. LFOF = lfoS[0] * parameters[21 + poff];
  84. //Filter Mod
  85. q = 1.1f - parameters[6 + poff];
  86. cut = jlimit(0.001f, 0.999f, parameters[5 + poff]
  87. + (fadsr.getSample() * bipolar(parameters[8 + poff]))
  88. + Fvelocity
  89. + LFOF);
  90. amod = LFOA + Avelocity;
  91. //Filter
  92. //Left
  93. lowL = lowL + cut * bandL;
  94. highL = outBufferL[i] - lowL - (q * bandL);
  95. bandL = cut * highL + bandL;
  96. B = (lowL * ((q * 0.5f) + 0.5f));
  97. A = (highL * ((q * 0.5f) + 0.5f));
  98. outBufferL[i] = A + parameters[7 + poff] * ( B - A );
  99. outBufferL[i] += outBufferL[i] * amod;
  100. //Right
  101. lowR = lowR + cut * bandR;
  102. highR = outBufferR[i] - lowR - (q * bandR);
  103. bandR = cut * highR + bandR;
  104. B = (lowR * ((q * 0.5f) + 0.5f));
  105. A = (highR * ((q * 0.5f) + 0.5f));
  106. outBufferR[i] = A + parameters[7 + poff] * ( B - A );
  107. outBufferR[i] += outBufferR[i] * amod;
  108. }
  109. aadsr.doProcess(outBufferL, outBufferR, bufferSize);
  110. isOn = aadsr.getState();
  111. }
  112. void VexVoice::start(float f, float v, int n, int preroll, double s, long o)
  113. {
  114. Ordinal = o;
  115. SampleRate = s;
  116. float oct = (parameters[1 + poff] - 0.5f) * 4.0f;
  117. float cent = (parameters[2 + poff] - 0.5f) * 0.1f;
  118. BaseFrequency = f * convertPitch(cent + oct);
  119. wr.reset(BaseFrequency, SampleRate, oL);
  120. wr.reset(BaseFrequency, SampleRate, oR);
  121. note = n;
  122. lfoS[0] = 0.5f;
  123. lfoS[1] = 0.0f;
  124. isOn = true;
  125. isReleased = false;
  126. v = (v * v) - 1.0f;
  127. Avelocity = (v * bipolar(parameters[18 + poff]));
  128. Fvelocity = (1.0f + v) * bipolar(parameters[13 + poff]);
  129. aadsr.reset(preroll);
  130. fadsr.reset(preroll);
  131. }
  132. void VexVoice::release(const int p)
  133. {
  134. isReleased = true;
  135. aadsr.release(p);
  136. fadsr.release(p);
  137. }
  138. void VexVoice::quickRelease()
  139. {
  140. isReleased = true;
  141. aadsr.quickRelease();
  142. }
  143. void VexVoice::kill()
  144. {
  145. isOn = false;
  146. }
  147. /*
  148. * params:
  149. 1 = oct
  150. 2 = cent
  151. 3 = phaseOffset
  152. 4 = phaseIncOffset
  153. 5,6,7,8 = filter
  154. 9,10,11,12 = F ADSR
  155. 13 = F velocity
  156. 14,15,16,17 = A ADSR
  157. 18 = A velocity
  158. 19 = lfoC
  159. 20 = lfoA
  160. 21 = lfoF
  161. 22,23,24 = fx volumes
  162. *3
  163. 83,84,85 = panning synths
  164. 86,87,88 = volume synths
  165. 89,90,91 = on/off synths
  166. */
  167. void VexVoice::update(const int index)
  168. {
  169. float p;
  170. switch (index-poff)
  171. {
  172. case 14:
  173. case 15:
  174. case 16:
  175. case 17:
  176. aadsr.setADSR(parameters[14+poff], parameters[15+poff], parameters[16+poff], parameters[17+poff], SampleRate);
  177. break;
  178. case 9:
  179. case 10:
  180. case 11:
  181. case 12:
  182. fadsr.setADSR(parameters[9+poff], parameters[10+poff], parameters[11+poff], parameters[12+poff], SampleRate);
  183. break;
  184. case 19:
  185. lfoC = 2.f * (float)sin(float_Pi*(parameters[19 + poff] * 10.0f) / SampleRate);
  186. break;
  187. case 3:
  188. p = bipolar(parameters[3 + poff]);
  189. oL.phaseOffset = p > 0.0f ? p : 0.0f;
  190. oR.phaseOffset = p < 0.0f ? fabs(p) : 0.0f;
  191. break;
  192. case 4:
  193. p = bipolar(parameters[4 + poff]);
  194. oL.phaseIncOffset = p > 0.0f ? p : 0.0f;
  195. oR.phaseIncOffset = p < 0.0f ? fabs(p) : 0.0f;
  196. break;
  197. }
  198. }
  199. long VexVoice::getOrdinal() const
  200. {
  201. return Ordinal;
  202. }
  203. int VexVoice::getNote() const
  204. {
  205. return note;
  206. }
  207. bool VexVoice::getIsOn() const
  208. {
  209. return isOn;
  210. }
  211. bool VexVoice::getIsReleased() const
  212. {
  213. return isReleased;
  214. }