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.

juce_Synthesiser.cpp 20KB

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