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.

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