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.

357 lines
11KB

  1. /*
  2. ==============================================================================
  3. This file is part of the JUCE library.
  4. Copyright (c) 2015 - ROLI Ltd.
  5. Permission is granted to use this software under the terms of either:
  6. a) the GPL v2 (or any later version)
  7. b) the Affero GPL v3
  8. Details of these licenses can be found at: www.gnu.org/licenses
  9. JUCE is distributed in the hope that it will be useful, but WITHOUT ANY
  10. WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
  11. A PARTICULAR PURPOSE. See the GNU General Public License for more details.
  12. ------------------------------------------------------------------------------
  13. To release a closed-source product which uses JUCE, commercial licenses are
  14. available: visit www.juce.com for more information.
  15. ==============================================================================
  16. */
  17. MPESynthesiser::MPESynthesiser()
  18. {
  19. }
  20. MPESynthesiser::MPESynthesiser (MPEInstrument* instrument) : MPESynthesiserBase (instrument)
  21. {
  22. }
  23. MPESynthesiser::~MPESynthesiser()
  24. {
  25. }
  26. //==============================================================================
  27. void MPESynthesiser::startVoice (MPESynthesiserVoice* voice, MPENote noteToStart)
  28. {
  29. jassert (voice != nullptr);
  30. voice->currentlyPlayingNote = noteToStart;
  31. voice->noteStarted();
  32. }
  33. void MPESynthesiser::stopVoice (MPESynthesiserVoice* voice, MPENote noteToStop, bool allowTailOff)
  34. {
  35. jassert (voice != nullptr);
  36. voice->currentlyPlayingNote = noteToStop;
  37. voice->noteStopped (allowTailOff);
  38. }
  39. //==============================================================================
  40. void MPESynthesiser::noteAdded (MPENote newNote)
  41. {
  42. const ScopedLock sl (voicesLock);
  43. if (MPESynthesiserVoice* voice = findFreeVoice (newNote, shouldStealVoices))
  44. startVoice (voice, newNote);
  45. }
  46. void MPESynthesiser::notePressureChanged (MPENote changedNote)
  47. {
  48. const ScopedLock sl (voicesLock);
  49. for (int i = 0; i < voices.size(); ++i)
  50. {
  51. MPESynthesiserVoice* voice = voices.getUnchecked (i);
  52. if (voice->isCurrentlyPlayingNote (changedNote))
  53. {
  54. voice->currentlyPlayingNote = changedNote;
  55. voice->notePressureChanged();
  56. }
  57. }
  58. }
  59. void MPESynthesiser::notePitchbendChanged (MPENote changedNote)
  60. {
  61. const ScopedLock sl (voicesLock);
  62. for (int i = 0; i < voices.size(); ++i)
  63. {
  64. MPESynthesiserVoice* voice = voices.getUnchecked (i);
  65. if (voice->isCurrentlyPlayingNote (changedNote))
  66. {
  67. voice->currentlyPlayingNote = changedNote;
  68. voice->notePitchbendChanged();
  69. }
  70. }
  71. }
  72. void MPESynthesiser::noteTimbreChanged (MPENote changedNote)
  73. {
  74. const ScopedLock sl (voicesLock);
  75. for (int i = 0; i < voices.size(); ++i)
  76. {
  77. MPESynthesiserVoice* voice = voices.getUnchecked (i);
  78. if (voice->isCurrentlyPlayingNote (changedNote))
  79. {
  80. voice->currentlyPlayingNote = changedNote;
  81. voice->noteTimbreChanged();
  82. }
  83. }
  84. }
  85. void MPESynthesiser::noteKeyStateChanged (MPENote changedNote)
  86. {
  87. const ScopedLock sl (voicesLock);
  88. for (int i = 0; i < voices.size(); ++i)
  89. {
  90. MPESynthesiserVoice* voice = voices.getUnchecked (i);
  91. if (voice->isCurrentlyPlayingNote (changedNote))
  92. {
  93. voice->currentlyPlayingNote = changedNote;
  94. voice->noteKeyStateChanged();
  95. }
  96. }
  97. }
  98. void MPESynthesiser::noteReleased (MPENote finishedNote)
  99. {
  100. const ScopedLock sl (voicesLock);
  101. for (int i = voices.size(); --i >= 0;)
  102. {
  103. MPESynthesiserVoice* const voice = voices.getUnchecked (i);
  104. if (voice->isCurrentlyPlayingNote(finishedNote))
  105. stopVoice (voice, finishedNote, true);
  106. }
  107. }
  108. void MPESynthesiser::setCurrentPlaybackSampleRate (const double newRate)
  109. {
  110. MPESynthesiserBase::setCurrentPlaybackSampleRate (newRate);
  111. const ScopedLock sl (voicesLock);
  112. turnOffAllVoices (false);
  113. for (int i = voices.size(); --i >= 0;)
  114. voices.getUnchecked (i)->setCurrentSampleRate (newRate);
  115. }
  116. void MPESynthesiser::handleMidiEvent (const MidiMessage& m)
  117. {
  118. if (m.isController())
  119. handleController (m.getChannel(), m.getControllerNumber(), m.getControllerValue());
  120. else if (m.isProgramChange())
  121. handleProgramChange (m.getChannel(), m.getProgramChangeNumber());
  122. MPESynthesiserBase::handleMidiEvent (m);
  123. }
  124. MPESynthesiserVoice* MPESynthesiser::findFreeVoice (MPENote noteToFindVoiceFor, bool stealIfNoneAvailable) const
  125. {
  126. const ScopedLock sl (voicesLock);
  127. for (int i = 0; i < voices.size(); ++i)
  128. {
  129. MPESynthesiserVoice* const voice = voices.getUnchecked (i);
  130. if (! voice->isActive())
  131. return voice;
  132. }
  133. if (stealIfNoneAvailable)
  134. return findVoiceToSteal (noteToFindVoiceFor);
  135. return nullptr;
  136. }
  137. struct MPEVoiceAgeSorter
  138. {
  139. static int compareElements (MPESynthesiserVoice* v1, MPESynthesiserVoice* v2) noexcept
  140. {
  141. return v1->wasStartedBefore (*v2) ? -1 : (v2->wasStartedBefore (*v1) ? 1 : 0);
  142. }
  143. };
  144. MPESynthesiserVoice* MPESynthesiser::findVoiceToSteal (MPENote noteToStealVoiceFor) const
  145. {
  146. // This voice-stealing algorithm applies the following heuristics:
  147. // - Re-use the oldest notes first
  148. // - Protect the lowest & topmost notes, even if sustained, but not if they've been released.
  149. // apparently you are trying to render audio without having any voices...
  150. jassert (voices.size() > 0);
  151. // These are the voices we want to protect (ie: only steal if unavoidable)
  152. MPESynthesiserVoice* low = nullptr; // Lowest sounding note, might be sustained, but NOT in release phase
  153. MPESynthesiserVoice* top = nullptr; // Highest sounding note, might be sustained, but NOT in release phase
  154. // this is a list of voices we can steal, sorted by how long they've been running
  155. Array<MPESynthesiserVoice*> usableVoices;
  156. usableVoices.ensureStorageAllocated (voices.size());
  157. for (int i = 0; i < voices.size(); ++i)
  158. {
  159. MPESynthesiserVoice* const voice = voices.getUnchecked (i);
  160. jassert (voice->isActive()); // We wouldn't be here otherwise
  161. MPEVoiceAgeSorter sorter;
  162. usableVoices.addSorted (sorter, voice);
  163. if (! voice->isPlayingButReleased()) // Don't protect released notes
  164. {
  165. const int noteNumber = voice->getCurrentlyPlayingNote().initialNote;
  166. if (low == nullptr || noteNumber < low->getCurrentlyPlayingNote().initialNote)
  167. low = voice;
  168. if (top == nullptr || noteNumber > top->getCurrentlyPlayingNote().initialNote)
  169. top = voice;
  170. }
  171. }
  172. // Eliminate pathological cases (ie: only 1 note playing): we always give precedence to the lowest note(s)
  173. if (top == low)
  174. top = nullptr;
  175. const int numUsableVoices = usableVoices.size();
  176. // If we want to re-use the voice to trigger a new note,
  177. // then The oldest note that's playing the same note number is ideal.
  178. if (noteToStealVoiceFor.isValid())
  179. {
  180. for (int i = 0; i < numUsableVoices; ++i)
  181. {
  182. MPESynthesiserVoice* const voice = usableVoices.getUnchecked (i);
  183. if (voice->getCurrentlyPlayingNote().initialNote == noteToStealVoiceFor.initialNote)
  184. return voice;
  185. }
  186. }
  187. // Oldest voice that has been released (no finger on it and not held by sustain pedal)
  188. for (int i = 0; i < numUsableVoices; ++i)
  189. {
  190. MPESynthesiserVoice* const voice = usableVoices.getUnchecked (i);
  191. if (voice != low && voice != top && voice->isPlayingButReleased())
  192. return voice;
  193. }
  194. // Oldest voice that doesn't have a finger on it:
  195. for (int i = 0; i < numUsableVoices; ++i)
  196. {
  197. MPESynthesiserVoice* const voice = usableVoices.getUnchecked (i);
  198. if (voice != low && voice != top
  199. && voice->getCurrentlyPlayingNote().keyState != MPENote::keyDown
  200. && voice->getCurrentlyPlayingNote().keyState != MPENote::keyDownAndSustained)
  201. return voice;
  202. }
  203. // Oldest voice that isn't protected
  204. for (int i = 0; i < numUsableVoices; ++i)
  205. {
  206. MPESynthesiserVoice* const voice = usableVoices.getUnchecked (i);
  207. if (voice != low && voice != top)
  208. return voice;
  209. }
  210. // We've only got "protected" voices now: lowest note takes priority
  211. jassert (low != nullptr);
  212. // Duophonic synth: give priority to the bass note:
  213. if (top != nullptr)
  214. return top;
  215. return low;
  216. }
  217. //==============================================================================
  218. void MPESynthesiser::addVoice (MPESynthesiserVoice* const newVoice)
  219. {
  220. const ScopedLock sl (voicesLock);
  221. newVoice->setCurrentSampleRate (getSampleRate());
  222. voices.add (newVoice);
  223. }
  224. void MPESynthesiser::clearVoices()
  225. {
  226. const ScopedLock sl (voicesLock);
  227. voices.clear();
  228. }
  229. MPESynthesiserVoice* MPESynthesiser::getVoice (const int index) const
  230. {
  231. const ScopedLock sl (voicesLock);
  232. return voices [index];
  233. }
  234. void MPESynthesiser::removeVoice (const int index)
  235. {
  236. const ScopedLock sl (voicesLock);
  237. voices.remove (index);
  238. }
  239. void MPESynthesiser::reduceNumVoices (const int newNumVoices)
  240. {
  241. // we can't possibly get to a negative number of voices...
  242. jassert (newNumVoices >= 0);
  243. const ScopedLock sl (voicesLock);
  244. while (voices.size() > newNumVoices)
  245. {
  246. if (MPESynthesiserVoice* voice = findFreeVoice (MPENote(), true))
  247. voices.removeObject (voice);
  248. else
  249. voices.remove (0); // if there's no voice to steal, kill the oldest voice
  250. }
  251. }
  252. void MPESynthesiser::turnOffAllVoices (bool allowTailOff)
  253. {
  254. // first turn off all voices (it's more efficient to do this immediately
  255. // rather than to go through the MPEInstrument for this).
  256. for (int i = voices.size(); --i >= 0;)
  257. voices.getUnchecked (i)->noteStopped (allowTailOff);
  258. // finally make sure the MPE Instrument also doesn't have any notes anymore.
  259. instrument->releaseAllNotes();
  260. }
  261. //==============================================================================
  262. void MPESynthesiser::renderNextSubBlock (AudioBuffer<float>& buffer, int startSample, int numSamples)
  263. {
  264. for (int i = voices.size(); --i >= 0;)
  265. {
  266. MPESynthesiserVoice* voice = voices.getUnchecked (i);
  267. if (voice->isActive())
  268. voice->renderNextBlock (buffer, startSample, numSamples);
  269. }
  270. }
  271. void MPESynthesiser::renderNextSubBlock (AudioBuffer<double>& buffer, int startSample, int numSamples)
  272. {
  273. for (int i = voices.size(); --i >= 0;)
  274. {
  275. MPESynthesiserVoice* voice = voices.getUnchecked (i);
  276. if (voice->isActive())
  277. voice->renderNextBlock (buffer, startSample, numSamples);
  278. }
  279. }