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.

401 lines
12KB

  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. #ifndef __JUCETICE_VEXCSYNTMODULE_HEADER__
  25. #define __JUCETICE_VEXCSYNTMODULE_HEADER__
  26. #ifdef CARLA_EXPORT
  27. #include "juce_audio_basics.h"
  28. #else
  29. #include "../StandardHeader.h"
  30. #endif
  31. #include "cVoice.h"
  32. class VexSyntModule
  33. {
  34. public:
  35. VexSyntModule(const float* const p)
  36. : parameters(p),
  37. sampleRate(44100),
  38. benchwarmer(0),
  39. playCount(1),
  40. part1(false),
  41. part2(false),
  42. part3(false)
  43. {
  44. for (int i = 0; i < kNumVoices; ++i)
  45. {
  46. vo1[i] = new VexVoice(p, 0, wr1);
  47. vo2[i] = new VexVoice(p, 24, wr2);
  48. vo3[i] = new VexVoice(p, 48, wr3);
  49. }
  50. }
  51. ~VexSyntModule()
  52. {
  53. for (int i = 0; i < kNumVoices; ++i)
  54. {
  55. delete vo1[i];
  56. delete vo2[i];
  57. delete vo3[i];
  58. }
  59. }
  60. #ifdef CARLA_EXPORT
  61. void doProcess(float* const outPtrL, float* const outPtrR, const int numSamples)
  62. {
  63. #else
  64. void doProcess(AudioSampleBuffer& assbf, AudioSampleBuffer& obf, AudioSampleBuffer& ebf1, AudioSampleBuffer& ebf2, AudioSampleBuffer& ebf3)
  65. {
  66. const int numSamples = obf.getNumSamples();
  67. float* const outPtrL = assbf.getSampleData(0,0);
  68. float* const outPtrR = assbf.getSampleData(1,0);
  69. #endif
  70. if (part1)
  71. {
  72. #ifndef CARLA_EXPORT
  73. float right = parameters[86] * parameters[83];
  74. float left = parameters[86] * (1.0f - parameters[83]);
  75. #endif
  76. for (int i = 0; i < kNumVoices; ++i)
  77. {
  78. if (vo1[i]->getIsOn())
  79. {
  80. vo1[i]->doProcess(outPtrL, outPtrR, numSamples);
  81. #ifndef CARLA_EXPORT
  82. obf.addFrom(0, 0, assbf, 0, 0, numSamples, left);
  83. obf.addFrom(1, 0, assbf, 1, 0, numSamples, right);
  84. ebf1.addFrom(0, 0, assbf, 0, 0, numSamples, parameters[22] * left);
  85. ebf1.addFrom(1, 0, assbf, 1, 0, numSamples, parameters[22] * right);
  86. ebf2.addFrom(0, 0, assbf, 0, 0, numSamples, parameters[23] * left);
  87. ebf2.addFrom(1, 0, assbf, 1, 0, numSamples, parameters[23] * right);
  88. ebf3.addFrom(0, 0, assbf, 0, 0, numSamples, parameters[24] * left);
  89. ebf3.addFrom(1, 0, assbf, 1, 0, numSamples, parameters[24] * right);
  90. #endif
  91. }
  92. }
  93. }
  94. if (part2)
  95. {
  96. #ifndef CARLA_EXPORT
  97. float right = parameters[87] * parameters[84];
  98. float left = parameters[87] * (1.0f - parameters[84]);
  99. #endif
  100. for (int i = 0; i < kNumVoices; ++i)
  101. {
  102. if (vo2[i]->getIsOn())
  103. {
  104. vo2[i]->doProcess(outPtrL, outPtrR, numSamples);
  105. #ifndef CARLA_EXPORT
  106. obf.addFrom(0, 0, assbf, 0, 0, numSamples, left);
  107. obf.addFrom(1, 0, assbf, 1, 0, numSamples, right);
  108. ebf1.addFrom(0, 0, assbf, 0, 0, numSamples, parameters[22 + 24] * left);
  109. ebf1.addFrom(1, 0, assbf, 1, 0, numSamples, parameters[22 + 24] * right);
  110. ebf2.addFrom(0, 0, assbf, 0, 0, numSamples, parameters[23 + 24] * left);
  111. ebf2.addFrom(1, 0, assbf, 1, 0, numSamples, parameters[23 + 24] * right);
  112. ebf3.addFrom(0, 0, assbf, 0, 0, numSamples, parameters[24 + 24] * left);
  113. ebf3.addFrom(1, 0, assbf, 1, 0, numSamples, parameters[24 + 24] * right);
  114. #endif
  115. }
  116. }
  117. }
  118. if (part3)
  119. {
  120. #ifndef CARLA_EXPORT
  121. float right = parameters[88] * parameters[85];
  122. float left = parameters[88] * (1.0f - parameters[85]);
  123. #endif
  124. for (int i = 0; i < kNumVoices; ++i)
  125. {
  126. if (vo3[i]->getIsOn())
  127. {
  128. vo3[i]->doProcess(outPtrL, outPtrR, numSamples);
  129. #ifndef CARLA_EXPORT
  130. obf.addFrom(0, 0, assbf, 0, 0, numSamples, left);
  131. obf.addFrom(1, 0, assbf, 1, 0, numSamples, right);
  132. ebf1.addFrom(0, 0, assbf, 0, 0, numSamples, parameters[22 + 48] * left);
  133. ebf1.addFrom(1, 0, assbf, 1, 0, numSamples, parameters[22 + 48] * right);
  134. ebf2.addFrom(0, 0, assbf, 0, 0, numSamples, parameters[23 + 48] * left);
  135. ebf2.addFrom(1, 0, assbf, 1, 0, numSamples, parameters[23 + 48] * right);
  136. ebf3.addFrom(0, 0, assbf, 0, 0, numSamples, parameters[24 + 48] * left);
  137. ebf3.addFrom(1, 0, assbf, 1, 0, numSamples, parameters[24 + 48] * right);
  138. #endif
  139. }
  140. }
  141. }
  142. }
  143. void setSampleRate(const double s)
  144. {
  145. sampleRate = s;
  146. }
  147. void updateParameterPtr(const float* const p)
  148. {
  149. parameters = p;
  150. for (int i = 0; i < kNumVoices; ++i)
  151. {
  152. vo1[i]->updateParameterPtr(parameters);
  153. vo2[i]->updateParameterPtr(parameters);
  154. vo3[i]->updateParameterPtr(parameters);
  155. }
  156. }
  157. void playNote(const int n, const int vel, const int preroll, const int part)
  158. {
  159. VexVoice** v = nullptr;
  160. const int note = n + 12;
  161. switch (part)
  162. {
  163. case 1:
  164. if (!part1) return;
  165. v = vo1;
  166. break;
  167. case 2:
  168. if (!part2) return;
  169. v = vo2;
  170. break;
  171. case 3:
  172. if (!part3) return;
  173. v = vo3;
  174. break;
  175. }
  176. if (v == nullptr)
  177. return;
  178. int OldestOn = kNumVoices-1;
  179. int OldestOff = kNumVoices-1;
  180. int OldestReleased = kNumVoices-1;
  181. int tmpOn = 100000000;
  182. //int tmpOff = 100000000;
  183. int tmpReleased = 100000000;
  184. for (int i = 0; i < kNumVoices; ++i)
  185. {
  186. if (i == benchwarmer)
  187. continue;
  188. if (! v[i]->getIsOn())
  189. {
  190. OldestOff = i;
  191. break;
  192. }
  193. if (vo1[i]->getIsReleased())
  194. {
  195. OldestReleased = (v[i]->getOrdinal() < tmpReleased) ? i : OldestReleased;
  196. tmpReleased = v[OldestReleased]->getOrdinal();
  197. continue;
  198. }
  199. OldestOn = (v[i]->getOrdinal() < tmpOn) ? i : OldestOn;
  200. tmpOn = v[OldestOn]->getOrdinal();
  201. }
  202. float noteInHertz = (float)MidiMessage::getMidiNoteInHertz(note);
  203. playCount++;
  204. if (OldestOff < kNumVoices)
  205. {
  206. v[OldestOff]->start(noteInHertz, float(vel)/127.0f, note, preroll, sampleRate, playCount);
  207. return;
  208. }
  209. if (OldestReleased < kNumVoices)
  210. {
  211. v[benchwarmer]->start(noteInHertz, float(vel)/127.0f, note, preroll, sampleRate, playCount);
  212. benchwarmer = OldestReleased;
  213. v[OldestReleased]->quickRelease();
  214. return;
  215. }
  216. if (OldestOn < kNumVoices)
  217. {
  218. v[benchwarmer]->start(noteInHertz, float(vel)/127.0f, note, preroll, sampleRate, playCount);
  219. benchwarmer = OldestOn;
  220. v[OldestReleased]->quickRelease();
  221. return;
  222. }
  223. }
  224. void releaseNote(const int n, const int preroll, const int part)
  225. {
  226. VexVoice** v = nullptr;
  227. const int note = n + 12;
  228. switch (part)
  229. {
  230. case 1:
  231. if (!part1) return;
  232. v = vo1;
  233. break;
  234. case 2:
  235. if (!part2) return;
  236. v = vo2;
  237. break;
  238. case 3:
  239. if (!part3) return;
  240. v = vo3;
  241. break;
  242. }
  243. if (v == nullptr)
  244. return;
  245. for (int i = 0; i < kNumVoices; ++i)
  246. {
  247. if (v[i]->getNote() == note)
  248. v[i]->release(preroll);
  249. }
  250. }
  251. void releaseAll(const int p)
  252. {
  253. for (int i = 0; i < kNumVoices; ++i)
  254. {
  255. vo1[i]->release(p);
  256. vo2[i]->release(p);
  257. vo3[i]->release(p);
  258. }
  259. }
  260. void kill(const int what = 0)
  261. {
  262. switch (what)
  263. {
  264. case 0:
  265. for (int i = 0; i < kNumVoices; ++i)
  266. {
  267. vo1[i]->kill();
  268. vo2[i]->kill();
  269. vo3[i]->kill();
  270. }
  271. break;
  272. case 1:
  273. for (int i = 0; i < kNumVoices; ++i)
  274. vo1[i]->kill();
  275. break;
  276. case 2:
  277. for (int i = 0; i < kNumVoices; ++i)
  278. vo2[i]->kill();
  279. break;
  280. case 3:
  281. for (int i = 0; i < kNumVoices; ++i)
  282. vo3[i]->kill();
  283. break;
  284. }
  285. }
  286. void setWaveLater(const int part, const String& waveName)
  287. {
  288. switch (part)
  289. {
  290. case 1:
  291. wr1.setWaveLater(waveName);
  292. kill(1);
  293. // REMOVE THIS
  294. wr1.actuallySetWave();
  295. break;
  296. case 2:
  297. wr2.setWaveLater(waveName);
  298. kill(2);
  299. break;
  300. case 3:
  301. wr3.setWaveLater(waveName);
  302. kill(3);
  303. break;
  304. }
  305. }
  306. void update(const int index)
  307. {
  308. if (index == 89)
  309. {
  310. part1 = (parameters[89] > 0.9f);
  311. return;
  312. }
  313. if (index == 90)
  314. {
  315. part2 = (parameters[90] > 0.9f);
  316. return;
  317. }
  318. if (index == 91)
  319. {
  320. part3 = (parameters[91] > 0.9f);
  321. return;
  322. }
  323. for (int i = 0; i < kNumVoices; ++i)
  324. {
  325. vo1[i]->update(index);
  326. vo2[i]->update(index);
  327. vo3[i]->update(index);
  328. }
  329. }
  330. private:
  331. static const int kNumVoices = 8;
  332. const float* parameters;
  333. double sampleRate;
  334. int benchwarmer;
  335. VexVoice* vo1[kNumVoices];
  336. VexVoice* vo2[kNumVoices];
  337. VexVoice* vo3[kNumVoices];
  338. long playCount;
  339. bool part1, part2, part3;
  340. WaveRenderer wr1;
  341. WaveRenderer wr2;
  342. WaveRenderer wr3;
  343. };
  344. #endif