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.

VexSyntModule.h 12KB

11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415
  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.getWritePointer(0);
  68. float* const outPtrR = assbf.getWritePointer(1);
  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