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.

659 lines
21KB

  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. SynthesiserSound::SynthesiserSound() {}
  18. SynthesiserSound::~SynthesiserSound() {}
  19. //==============================================================================
  20. SynthesiserVoice::SynthesiserVoice()
  21. : currentSampleRate (44100.0),
  22. currentlyPlayingNote (-1),
  23. currentPlayingMidiChannel (0),
  24. noteOnTime (0),
  25. keyIsDown (false),
  26. sustainPedalDown (false),
  27. sostenutoPedalDown (false)
  28. {
  29. }
  30. SynthesiserVoice::~SynthesiserVoice()
  31. {
  32. }
  33. bool SynthesiserVoice::isPlayingChannel (const int midiChannel) const
  34. {
  35. return currentPlayingMidiChannel == midiChannel;
  36. }
  37. void SynthesiserVoice::setCurrentPlaybackSampleRate (const double newRate)
  38. {
  39. currentSampleRate = newRate;
  40. }
  41. bool SynthesiserVoice::isVoiceActive() const
  42. {
  43. return getCurrentlyPlayingNote() >= 0;
  44. }
  45. void SynthesiserVoice::clearCurrentNote()
  46. {
  47. currentlyPlayingNote = -1;
  48. currentlyPlayingSound = nullptr;
  49. currentPlayingMidiChannel = 0;
  50. }
  51. void SynthesiserVoice::aftertouchChanged (int) {}
  52. void SynthesiserVoice::channelPressureChanged (int) {}
  53. bool SynthesiserVoice::wasStartedBefore (const SynthesiserVoice& other) const noexcept
  54. {
  55. return noteOnTime < other.noteOnTime;
  56. }
  57. void SynthesiserVoice::renderNextBlock (AudioBuffer<double>& outputBuffer,
  58. int startSample, int numSamples)
  59. {
  60. AudioBuffer<double> subBuffer (outputBuffer.getArrayOfWritePointers(),
  61. outputBuffer.getNumChannels(),
  62. startSample, numSamples);
  63. tempBuffer.makeCopyOf (subBuffer);
  64. renderNextBlock (tempBuffer, 0, numSamples);
  65. subBuffer.makeCopyOf (tempBuffer);
  66. }
  67. //==============================================================================
  68. Synthesiser::Synthesiser()
  69. : sampleRate (0),
  70. lastNoteOnCounter (0),
  71. minimumSubBlockSize (32),
  72. subBlockSubdivisionIsStrict (false),
  73. shouldStealNotes (true)
  74. {
  75. for (int i = 0; i < numElementsInArray (lastPitchWheelValues); ++i)
  76. lastPitchWheelValues[i] = 0x2000;
  77. }
  78. Synthesiser::~Synthesiser()
  79. {
  80. }
  81. //==============================================================================
  82. SynthesiserVoice* Synthesiser::getVoice (const int index) const
  83. {
  84. const ScopedLock sl (lock);
  85. return voices [index];
  86. }
  87. void Synthesiser::clearVoices()
  88. {
  89. const ScopedLock sl (lock);
  90. voices.clear();
  91. }
  92. SynthesiserVoice* Synthesiser::addVoice (SynthesiserVoice* const newVoice)
  93. {
  94. const ScopedLock sl (lock);
  95. newVoice->setCurrentPlaybackSampleRate (sampleRate);
  96. return voices.add (newVoice);
  97. }
  98. void Synthesiser::removeVoice (const int index)
  99. {
  100. const ScopedLock sl (lock);
  101. voices.remove (index);
  102. }
  103. void Synthesiser::clearSounds()
  104. {
  105. const ScopedLock sl (lock);
  106. sounds.clear();
  107. }
  108. SynthesiserSound* Synthesiser::addSound (const SynthesiserSound::Ptr& newSound)
  109. {
  110. const ScopedLock sl (lock);
  111. return sounds.add (newSound);
  112. }
  113. void Synthesiser::removeSound (const int index)
  114. {
  115. const ScopedLock sl (lock);
  116. sounds.remove (index);
  117. }
  118. void Synthesiser::setNoteStealingEnabled (const bool shouldSteal)
  119. {
  120. shouldStealNotes = shouldSteal;
  121. }
  122. void Synthesiser::setMinimumRenderingSubdivisionSize (int numSamples, bool shouldBeStrict) noexcept
  123. {
  124. jassert (numSamples > 0); // it wouldn't make much sense for this to be less than 1
  125. minimumSubBlockSize = numSamples;
  126. subBlockSubdivisionIsStrict = shouldBeStrict;
  127. }
  128. //==============================================================================
  129. void Synthesiser::setCurrentPlaybackSampleRate (const double newRate)
  130. {
  131. if (sampleRate != newRate)
  132. {
  133. const ScopedLock sl (lock);
  134. allNotesOff (0, false);
  135. sampleRate = newRate;
  136. for (int i = voices.size(); --i >= 0;)
  137. voices.getUnchecked (i)->setCurrentPlaybackSampleRate (newRate);
  138. }
  139. }
  140. template <typename floatType>
  141. void Synthesiser::processNextBlock (AudioBuffer<floatType>& outputAudio,
  142. const MidiBuffer& midiData,
  143. int startSample,
  144. int numSamples)
  145. {
  146. // must set the sample rate before using this!
  147. jassert (sampleRate != 0);
  148. const int targetChannels = outputAudio.getNumChannels();
  149. MidiBuffer::Iterator midiIterator (midiData);
  150. midiIterator.setNextSamplePosition (startSample);
  151. bool firstEvent = true;
  152. int midiEventPos;
  153. MidiMessage m;
  154. const ScopedLock sl (lock);
  155. while (numSamples > 0)
  156. {
  157. if (! midiIterator.getNextEvent (m, midiEventPos))
  158. {
  159. if (targetChannels > 0)
  160. renderVoices (outputAudio, startSample, numSamples);
  161. return;
  162. }
  163. const int samplesToNextMidiMessage = midiEventPos - startSample;
  164. if (samplesToNextMidiMessage >= numSamples)
  165. {
  166. if (targetChannels > 0)
  167. renderVoices (outputAudio, startSample, numSamples);
  168. handleMidiEvent (m);
  169. break;
  170. }
  171. if (samplesToNextMidiMessage < ((firstEvent && ! subBlockSubdivisionIsStrict) ? 1 : minimumSubBlockSize))
  172. {
  173. handleMidiEvent (m);
  174. continue;
  175. }
  176. firstEvent = false;
  177. if (targetChannels > 0)
  178. renderVoices (outputAudio, startSample, samplesToNextMidiMessage);
  179. handleMidiEvent (m);
  180. startSample += samplesToNextMidiMessage;
  181. numSamples -= samplesToNextMidiMessage;
  182. }
  183. while (midiIterator.getNextEvent (m, midiEventPos))
  184. handleMidiEvent (m);
  185. }
  186. // explicit template instantiation
  187. template void Synthesiser::processNextBlock<float> (AudioBuffer<float>& outputAudio,
  188. const MidiBuffer& midiData,
  189. int startSample,
  190. int numSamples);
  191. template void Synthesiser::processNextBlock<double> (AudioBuffer<double>& outputAudio,
  192. const MidiBuffer& midiData,
  193. int startSample,
  194. int numSamples);
  195. void Synthesiser::renderVoices (AudioBuffer<float>& buffer, int startSample, int numSamples)
  196. {
  197. for (int i = voices.size(); --i >= 0;)
  198. voices.getUnchecked (i)->renderNextBlock (buffer, startSample, numSamples);
  199. }
  200. void Synthesiser::renderVoices (AudioBuffer<double>& buffer, int startSample, int numSamples)
  201. {
  202. for (int i = voices.size(); --i >= 0;)
  203. voices.getUnchecked (i)->renderNextBlock (buffer, startSample, numSamples);
  204. }
  205. void Synthesiser::handleMidiEvent (const MidiMessage& m)
  206. {
  207. const int channel = m.getChannel();
  208. if (m.isNoteOn())
  209. {
  210. noteOn (channel, m.getNoteNumber(), m.getFloatVelocity());
  211. }
  212. else if (m.isNoteOff())
  213. {
  214. noteOff (channel, m.getNoteNumber(), m.getFloatVelocity(), true);
  215. }
  216. else if (m.isAllNotesOff() || m.isAllSoundOff())
  217. {
  218. allNotesOff (channel, true);
  219. }
  220. else if (m.isPitchWheel())
  221. {
  222. const int wheelPos = m.getPitchWheelValue();
  223. lastPitchWheelValues [channel - 1] = wheelPos;
  224. handlePitchWheel (channel, wheelPos);
  225. }
  226. else if (m.isAftertouch())
  227. {
  228. handleAftertouch (channel, m.getNoteNumber(), m.getAfterTouchValue());
  229. }
  230. else if (m.isChannelPressure())
  231. {
  232. handleChannelPressure (channel, m.getChannelPressureValue());
  233. }
  234. else if (m.isController())
  235. {
  236. handleController (channel, m.getControllerNumber(), m.getControllerValue());
  237. }
  238. else if (m.isProgramChange())
  239. {
  240. handleProgramChange (channel, m.getProgramChangeNumber());
  241. }
  242. }
  243. //==============================================================================
  244. void Synthesiser::noteOn (const int midiChannel,
  245. const int midiNoteNumber,
  246. const float velocity)
  247. {
  248. const ScopedLock sl (lock);
  249. for (int i = sounds.size(); --i >= 0;)
  250. {
  251. SynthesiserSound* const sound = sounds.getUnchecked(i);
  252. if (sound->appliesToNote (midiNoteNumber)
  253. && sound->appliesToChannel (midiChannel))
  254. {
  255. // If hitting a note that's still ringing, stop it first (it could be
  256. // still playing because of the sustain or sostenuto pedal).
  257. for (int j = voices.size(); --j >= 0;)
  258. {
  259. SynthesiserVoice* const voice = voices.getUnchecked (j);
  260. if (voice->getCurrentlyPlayingNote() == midiNoteNumber
  261. && voice->isPlayingChannel (midiChannel))
  262. stopVoice (voice, 1.0f, true);
  263. }
  264. startVoice (findFreeVoice (sound, midiChannel, midiNoteNumber, shouldStealNotes),
  265. sound, midiChannel, midiNoteNumber, velocity);
  266. }
  267. }
  268. }
  269. void Synthesiser::startVoice (SynthesiserVoice* const voice,
  270. SynthesiserSound* const sound,
  271. const int midiChannel,
  272. const int midiNoteNumber,
  273. const float velocity)
  274. {
  275. if (voice != nullptr && sound != nullptr)
  276. {
  277. if (voice->currentlyPlayingSound != nullptr)
  278. voice->stopNote (0.0f, false);
  279. voice->currentlyPlayingNote = midiNoteNumber;
  280. voice->currentPlayingMidiChannel = midiChannel;
  281. voice->noteOnTime = ++lastNoteOnCounter;
  282. voice->currentlyPlayingSound = sound;
  283. voice->keyIsDown = true;
  284. voice->sostenutoPedalDown = false;
  285. voice->sustainPedalDown = sustainPedalsDown[midiChannel];
  286. voice->startNote (midiNoteNumber, velocity, sound,
  287. lastPitchWheelValues [midiChannel - 1]);
  288. }
  289. }
  290. void Synthesiser::stopVoice (SynthesiserVoice* voice, float velocity, const bool allowTailOff)
  291. {
  292. jassert (voice != nullptr);
  293. voice->stopNote (velocity, allowTailOff);
  294. // the subclass MUST call clearCurrentNote() if it's not tailing off! RTFM for stopNote()!
  295. jassert (allowTailOff || (voice->getCurrentlyPlayingNote() < 0 && voice->getCurrentlyPlayingSound() == 0));
  296. }
  297. void Synthesiser::noteOff (const int midiChannel,
  298. const int midiNoteNumber,
  299. const float velocity,
  300. const bool allowTailOff)
  301. {
  302. const ScopedLock sl (lock);
  303. for (int i = voices.size(); --i >= 0;)
  304. {
  305. SynthesiserVoice* const voice = voices.getUnchecked (i);
  306. if (voice->getCurrentlyPlayingNote() == midiNoteNumber
  307. && voice->isPlayingChannel (midiChannel))
  308. {
  309. if (SynthesiserSound* const sound = voice->getCurrentlyPlayingSound())
  310. {
  311. if (sound->appliesToNote (midiNoteNumber)
  312. && sound->appliesToChannel (midiChannel))
  313. {
  314. jassert (! voice->keyIsDown || voice->sustainPedalDown == sustainPedalsDown [midiChannel]);
  315. voice->keyIsDown = false;
  316. if (! (voice->sustainPedalDown || voice->sostenutoPedalDown))
  317. stopVoice (voice, velocity, allowTailOff);
  318. }
  319. }
  320. }
  321. }
  322. }
  323. void Synthesiser::allNotesOff (const int midiChannel, const bool allowTailOff)
  324. {
  325. const ScopedLock sl (lock);
  326. for (int i = voices.size(); --i >= 0;)
  327. {
  328. SynthesiserVoice* const voice = voices.getUnchecked (i);
  329. if (midiChannel <= 0 || voice->isPlayingChannel (midiChannel))
  330. voice->stopNote (1.0f, allowTailOff);
  331. }
  332. sustainPedalsDown.clear();
  333. }
  334. void Synthesiser::handlePitchWheel (const int midiChannel, const int wheelValue)
  335. {
  336. const ScopedLock sl (lock);
  337. for (int i = voices.size(); --i >= 0;)
  338. {
  339. SynthesiserVoice* const voice = voices.getUnchecked (i);
  340. if (midiChannel <= 0 || voice->isPlayingChannel (midiChannel))
  341. voice->pitchWheelMoved (wheelValue);
  342. }
  343. }
  344. void Synthesiser::handleController (const int midiChannel,
  345. const int controllerNumber,
  346. const int controllerValue)
  347. {
  348. switch (controllerNumber)
  349. {
  350. case 0x40: handleSustainPedal (midiChannel, controllerValue >= 64); break;
  351. case 0x42: handleSostenutoPedal (midiChannel, controllerValue >= 64); break;
  352. case 0x43: handleSoftPedal (midiChannel, controllerValue >= 64); break;
  353. default: break;
  354. }
  355. const ScopedLock sl (lock);
  356. for (int i = voices.size(); --i >= 0;)
  357. {
  358. SynthesiserVoice* const voice = voices.getUnchecked (i);
  359. if (midiChannel <= 0 || voice->isPlayingChannel (midiChannel))
  360. voice->controllerMoved (controllerNumber, controllerValue);
  361. }
  362. }
  363. void Synthesiser::handleAftertouch (int midiChannel, int midiNoteNumber, int aftertouchValue)
  364. {
  365. const ScopedLock sl (lock);
  366. for (int i = voices.size(); --i >= 0;)
  367. {
  368. SynthesiserVoice* const voice = voices.getUnchecked (i);
  369. if (voice->getCurrentlyPlayingNote() == midiNoteNumber
  370. && (midiChannel <= 0 || voice->isPlayingChannel (midiChannel)))
  371. voice->aftertouchChanged (aftertouchValue);
  372. }
  373. }
  374. void Synthesiser::handleChannelPressure (int midiChannel, int channelPressureValue)
  375. {
  376. const ScopedLock sl (lock);
  377. for (int i = voices.size(); --i >= 0;)
  378. {
  379. SynthesiserVoice* const voice = voices.getUnchecked (i);
  380. if (midiChannel <= 0 || voice->isPlayingChannel (midiChannel))
  381. voice->channelPressureChanged (channelPressureValue);
  382. }
  383. }
  384. void Synthesiser::handleSustainPedal (int midiChannel, bool isDown)
  385. {
  386. jassert (midiChannel > 0 && midiChannel <= 16);
  387. const ScopedLock sl (lock);
  388. if (isDown)
  389. {
  390. sustainPedalsDown.setBit (midiChannel);
  391. for (int i = voices.size(); --i >= 0;)
  392. {
  393. SynthesiserVoice* const voice = voices.getUnchecked (i);
  394. if (voice->isPlayingChannel (midiChannel) && voice->isKeyDown())
  395. voice->sustainPedalDown = true;
  396. }
  397. }
  398. else
  399. {
  400. for (int i = voices.size(); --i >= 0;)
  401. {
  402. SynthesiserVoice* const voice = voices.getUnchecked (i);
  403. if (voice->isPlayingChannel (midiChannel))
  404. {
  405. voice->sustainPedalDown = false;
  406. if (! voice->isKeyDown())
  407. stopVoice (voice, 1.0f, true);
  408. }
  409. }
  410. sustainPedalsDown.clearBit (midiChannel);
  411. }
  412. }
  413. void Synthesiser::handleSostenutoPedal (int midiChannel, bool isDown)
  414. {
  415. jassert (midiChannel > 0 && midiChannel <= 16);
  416. const ScopedLock sl (lock);
  417. for (int i = voices.size(); --i >= 0;)
  418. {
  419. SynthesiserVoice* const voice = voices.getUnchecked (i);
  420. if (voice->isPlayingChannel (midiChannel))
  421. {
  422. if (isDown)
  423. voice->sostenutoPedalDown = true;
  424. else if (voice->sostenutoPedalDown)
  425. stopVoice (voice, 1.0f, true);
  426. }
  427. }
  428. }
  429. void Synthesiser::handleSoftPedal (int midiChannel, bool /*isDown*/)
  430. {
  431. ignoreUnused (midiChannel);
  432. jassert (midiChannel > 0 && midiChannel <= 16);
  433. }
  434. void Synthesiser::handleProgramChange (int midiChannel, int programNumber)
  435. {
  436. ignoreUnused (midiChannel, programNumber);
  437. jassert (midiChannel > 0 && midiChannel <= 16);
  438. }
  439. //==============================================================================
  440. SynthesiserVoice* Synthesiser::findFreeVoice (SynthesiserSound* soundToPlay,
  441. int midiChannel, int midiNoteNumber,
  442. const bool stealIfNoneAvailable) const
  443. {
  444. const ScopedLock sl (lock);
  445. for (int i = 0; i < voices.size(); ++i)
  446. {
  447. SynthesiserVoice* const voice = voices.getUnchecked (i);
  448. if ((! voice->isVoiceActive()) && voice->canPlaySound (soundToPlay))
  449. return voice;
  450. }
  451. if (stealIfNoneAvailable)
  452. return findVoiceToSteal (soundToPlay, midiChannel, midiNoteNumber);
  453. return nullptr;
  454. }
  455. struct VoiceAgeSorter
  456. {
  457. static int compareElements (SynthesiserVoice* v1, SynthesiserVoice* v2) noexcept
  458. {
  459. return v1->wasStartedBefore (*v2) ? -1 : (v2->wasStartedBefore (*v1) ? 1 : 0);
  460. }
  461. };
  462. SynthesiserVoice* Synthesiser::findVoiceToSteal (SynthesiserSound* soundToPlay,
  463. int /*midiChannel*/, int midiNoteNumber) const
  464. {
  465. // This voice-stealing algorithm applies the following heuristics:
  466. // - Re-use the oldest notes first
  467. // - Protect the lowest & topmost notes, even if sustained, but not if they've been released.
  468. // apparently you are trying to render audio without having any voices...
  469. jassert (voices.size() > 0);
  470. // These are the voices we want to protect (ie: only steal if unavoidable)
  471. SynthesiserVoice* low = nullptr; // Lowest sounding note, might be sustained, but NOT in release phase
  472. SynthesiserVoice* top = nullptr; // Highest sounding note, might be sustained, but NOT in release phase
  473. // this is a list of voices we can steal, sorted by how long they've been running
  474. Array<SynthesiserVoice*> usableVoices;
  475. usableVoices.ensureStorageAllocated (voices.size());
  476. for (int i = 0; i < voices.size(); ++i)
  477. {
  478. SynthesiserVoice* const voice = voices.getUnchecked (i);
  479. if (voice->canPlaySound (soundToPlay))
  480. {
  481. jassert (voice->isVoiceActive()); // We wouldn't be here otherwise
  482. VoiceAgeSorter sorter;
  483. usableVoices.addSorted (sorter, voice);
  484. if (! voice->isPlayingButReleased()) // Don't protect released notes
  485. {
  486. const int note = voice->getCurrentlyPlayingNote();
  487. if (low == nullptr || note < low->getCurrentlyPlayingNote())
  488. low = voice;
  489. if (top == nullptr || note > top->getCurrentlyPlayingNote())
  490. top = voice;
  491. }
  492. }
  493. }
  494. // Eliminate pathological cases (ie: only 1 note playing): we always give precedence to the lowest note(s)
  495. if (top == low)
  496. top = nullptr;
  497. const int numUsableVoices = usableVoices.size();
  498. // The oldest note that's playing with the target pitch is ideal..
  499. for (int i = 0; i < numUsableVoices; ++i)
  500. {
  501. SynthesiserVoice* const voice = usableVoices.getUnchecked (i);
  502. if (voice->getCurrentlyPlayingNote() == midiNoteNumber)
  503. return voice;
  504. }
  505. // Oldest voice that has been released (no finger on it and not held by sustain pedal)
  506. for (int i = 0; i < numUsableVoices; ++i)
  507. {
  508. SynthesiserVoice* const voice = usableVoices.getUnchecked (i);
  509. if (voice != low && voice != top && voice->isPlayingButReleased())
  510. return voice;
  511. }
  512. // Oldest voice that doesn't have a finger on it:
  513. for (int i = 0; i < numUsableVoices; ++i)
  514. {
  515. SynthesiserVoice* const voice = usableVoices.getUnchecked (i);
  516. if (voice != low && voice != top && ! voice->isKeyDown())
  517. return voice;
  518. }
  519. // Oldest voice that isn't protected
  520. for (int i = 0; i < numUsableVoices; ++i)
  521. {
  522. SynthesiserVoice* const voice = usableVoices.getUnchecked (i);
  523. if (voice != low && voice != top)
  524. return voice;
  525. }
  526. // We've only got "protected" voices now: lowest note takes priority
  527. jassert (low != nullptr);
  528. // Duophonic synth: give priority to the bass note:
  529. if (top != nullptr)
  530. return top;
  531. return low;
  532. }