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.h 29KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649
  1. /*
  2. ==============================================================================
  3. This file is part of the JUCE library.
  4. Copyright (c) 2017 - ROLI Ltd.
  5. JUCE is an open source library subject to commercial or open-source
  6. licensing.
  7. The code included in this file is provided under the terms of the ISC license
  8. http://www.isc.org/downloads/software-support-policy/isc-license. Permission
  9. To use, copy, modify, and/or distribute this software for any purpose with or
  10. without fee is hereby granted provided that the above copyright notice and
  11. this permission notice appear in all copies.
  12. JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER
  13. EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE
  14. DISCLAIMED.
  15. ==============================================================================
  16. */
  17. namespace juce
  18. {
  19. //==============================================================================
  20. /**
  21. Describes one of the sounds that a Synthesiser can play.
  22. A synthesiser can contain one or more sounds, and a sound can choose which
  23. midi notes and channels can trigger it.
  24. The SynthesiserSound is a passive class that just describes what the sound is -
  25. the actual audio rendering for a sound is done by a SynthesiserVoice. This allows
  26. more than one SynthesiserVoice to play the same sound at the same time.
  27. @see Synthesiser, SynthesiserVoice
  28. */
  29. class JUCE_API SynthesiserSound : public ReferenceCountedObject
  30. {
  31. protected:
  32. //==============================================================================
  33. SynthesiserSound();
  34. public:
  35. /** Destructor. */
  36. virtual ~SynthesiserSound();
  37. //==============================================================================
  38. /** Returns true if this sound should be played when a given midi note is pressed.
  39. The Synthesiser will use this information when deciding which sounds to trigger
  40. for a given note.
  41. */
  42. virtual bool appliesToNote (int midiNoteNumber) = 0;
  43. /** Returns true if the sound should be triggered by midi events on a given channel.
  44. The Synthesiser will use this information when deciding which sounds to trigger
  45. for a given note.
  46. */
  47. virtual bool appliesToChannel (int midiChannel) = 0;
  48. /** The class is reference-counted, so this is a handy pointer class for it. */
  49. typedef ReferenceCountedObjectPtr<SynthesiserSound> Ptr;
  50. private:
  51. //==============================================================================
  52. JUCE_LEAK_DETECTOR (SynthesiserSound)
  53. };
  54. //==============================================================================
  55. /**
  56. Represents a voice that a Synthesiser can use to play a SynthesiserSound.
  57. A voice plays a single sound at a time, and a synthesiser holds an array of
  58. voices so that it can play polyphonically.
  59. @see Synthesiser, SynthesiserSound
  60. */
  61. class JUCE_API SynthesiserVoice
  62. {
  63. public:
  64. //==============================================================================
  65. /** Creates a voice. */
  66. SynthesiserVoice();
  67. /** Destructor. */
  68. virtual ~SynthesiserVoice();
  69. //==============================================================================
  70. /** Returns the midi note that this voice is currently playing.
  71. Returns a value less than 0 if no note is playing.
  72. */
  73. int getCurrentlyPlayingNote() const noexcept { return currentlyPlayingNote; }
  74. /** Returns the sound that this voice is currently playing.
  75. Returns nullptr if it's not playing.
  76. */
  77. SynthesiserSound::Ptr getCurrentlyPlayingSound() const noexcept { return currentlyPlayingSound; }
  78. /** Must return true if this voice object is capable of playing the given sound.
  79. If there are different classes of sound, and different classes of voice, a voice can
  80. choose which ones it wants to take on.
  81. A typical implementation of this method may just return true if there's only one type
  82. of voice and sound, or it might check the type of the sound object passed-in and
  83. see if it's one that it understands.
  84. */
  85. virtual bool canPlaySound (SynthesiserSound*) = 0;
  86. /** Called to start a new note.
  87. This will be called during the rendering callback, so must be fast and thread-safe.
  88. */
  89. virtual void startNote (int midiNoteNumber,
  90. float velocity,
  91. SynthesiserSound* sound,
  92. int currentPitchWheelPosition) = 0;
  93. /** Called to stop a note.
  94. This will be called during the rendering callback, so must be fast and thread-safe.
  95. The velocity indicates how quickly the note was released - 0 is slowly, 1 is quickly.
  96. If allowTailOff is false or the voice doesn't want to tail-off, then it must stop all
  97. sound immediately, and must call clearCurrentNote() to reset the state of this voice
  98. and allow the synth to reassign it another sound.
  99. If allowTailOff is true and the voice decides to do a tail-off, then it's allowed to
  100. begin fading out its sound, and it can stop playing until it's finished. As soon as it
  101. finishes playing (during the rendering callback), it must make sure that it calls
  102. clearCurrentNote().
  103. */
  104. virtual void stopNote (float velocity, bool allowTailOff) = 0;
  105. /** Returns true if this voice is currently busy playing a sound.
  106. By default this just checks the getCurrentlyPlayingNote() value, but can
  107. be overridden for more advanced checking.
  108. */
  109. virtual bool isVoiceActive() const;
  110. /** Called to let the voice know that the pitch wheel has been moved.
  111. This will be called during the rendering callback, so must be fast and thread-safe.
  112. */
  113. virtual void pitchWheelMoved (int newPitchWheelValue) = 0;
  114. /** Called to let the voice know that a midi controller has been moved.
  115. This will be called during the rendering callback, so must be fast and thread-safe.
  116. */
  117. virtual void controllerMoved (int controllerNumber, int newControllerValue) = 0;
  118. /** Called to let the voice know that the aftertouch has changed.
  119. This will be called during the rendering callback, so must be fast and thread-safe.
  120. */
  121. virtual void aftertouchChanged (int newAftertouchValue);
  122. /** Called to let the voice know that the channel pressure has changed.
  123. This will be called during the rendering callback, so must be fast and thread-safe.
  124. */
  125. virtual void channelPressureChanged (int newChannelPressureValue);
  126. //==============================================================================
  127. /** Renders the next block of data for this voice.
  128. The output audio data must be added to the current contents of the buffer provided.
  129. Only the region of the buffer between startSample and (startSample + numSamples)
  130. should be altered by this method.
  131. If the voice is currently silent, it should just return without doing anything.
  132. If the sound that the voice is playing finishes during the course of this rendered
  133. block, it must call clearCurrentNote(), to tell the synthesiser that it has finished.
  134. The size of the blocks that are rendered can change each time it is called, and may
  135. involve rendering as little as 1 sample at a time. In between rendering callbacks,
  136. the voice's methods will be called to tell it about note and controller events.
  137. */
  138. virtual void renderNextBlock (AudioBuffer<float>& outputBuffer,
  139. int startSample,
  140. int numSamples) = 0;
  141. /** A double-precision version of renderNextBlock() */
  142. virtual void renderNextBlock (AudioBuffer<double>& outputBuffer,
  143. int startSample,
  144. int numSamples);
  145. /** Changes the voice's reference sample rate.
  146. The rate is set so that subclasses know the output rate and can set their pitch
  147. accordingly.
  148. This method is called by the synth, and subclasses can access the current rate with
  149. the currentSampleRate member.
  150. */
  151. virtual void setCurrentPlaybackSampleRate (double newRate);
  152. /** Returns true if the voice is currently playing a sound which is mapped to the given
  153. midi channel.
  154. If it's not currently playing, this will return false.
  155. */
  156. virtual bool isPlayingChannel (int midiChannel) const;
  157. /** Returns the current target sample rate at which rendering is being done.
  158. Subclasses may need to know this so that they can pitch things correctly.
  159. */
  160. double getSampleRate() const noexcept { return currentSampleRate; }
  161. /** Returns true if the key that triggered this voice is still held down.
  162. Note that the voice may still be playing after the key was released (e.g because the
  163. sostenuto pedal is down).
  164. */
  165. bool isKeyDown() const noexcept { return keyIsDown; }
  166. /** Allows you to modify the flag indicating that the key that triggered this voice is still held down.
  167. @see isKeyDown
  168. */
  169. void setKeyDown (bool isNowDown) noexcept { keyIsDown = isNowDown; }
  170. /** Returns true if the sustain pedal is currently active for this voice. */
  171. bool isSustainPedalDown() const noexcept { return sustainPedalDown; }
  172. /** Modifies the sustain pedal flag. */
  173. void setSustainPedalDown (bool isNowDown) noexcept { sustainPedalDown = isNowDown; }
  174. /** Returns true if the sostenuto pedal is currently active for this voice. */
  175. bool isSostenutoPedalDown() const noexcept { return sostenutoPedalDown; }
  176. /** Modifies the sostenuto pedal flag. */
  177. void setSostenutoPedalDown (bool isNowDown) noexcept { sostenutoPedalDown = isNowDown; }
  178. /** Returns true if a voice is sounding in its release phase **/
  179. bool isPlayingButReleased() const noexcept
  180. {
  181. return isVoiceActive() && ! (isKeyDown() || isSostenutoPedalDown() || isSustainPedalDown());
  182. }
  183. /** Returns true if this voice started playing its current note before the other voice did. */
  184. bool wasStartedBefore (const SynthesiserVoice& other) const noexcept;
  185. protected:
  186. /** Resets the state of this voice after a sound has finished playing.
  187. The subclass must call this when it finishes playing a note and becomes available
  188. to play new ones.
  189. It must either call it in the stopNote() method, or if the voice is tailing off,
  190. then it should call it later during the renderNextBlock method, as soon as it
  191. finishes its tail-off.
  192. It can also be called at any time during the render callback if the sound happens
  193. to have finished, e.g. if it's playing a sample and the sample finishes.
  194. */
  195. void clearCurrentNote();
  196. private:
  197. //==============================================================================
  198. friend class Synthesiser;
  199. double currentSampleRate = 44100.0;
  200. int currentlyPlayingNote = -1, currentPlayingMidiChannel = 0;
  201. uint32 noteOnTime = 0;
  202. SynthesiserSound::Ptr currentlyPlayingSound;
  203. bool keyIsDown = false, sustainPedalDown = false, sostenutoPedalDown = false;
  204. AudioBuffer<float> tempBuffer;
  205. #if JUCE_CATCH_DEPRECATED_CODE_MISUSE
  206. // Note the new parameters for this method.
  207. virtual int stopNote (bool) { return 0; }
  208. #endif
  209. JUCE_LEAK_DETECTOR (SynthesiserVoice)
  210. };
  211. //==============================================================================
  212. /**
  213. Base class for a musical device that can play sounds.
  214. To create a synthesiser, you'll need to create a subclass of SynthesiserSound
  215. to describe each sound available to your synth, and a subclass of SynthesiserVoice
  216. which can play back one of these sounds.
  217. Then you can use the addVoice() and addSound() methods to give the synthesiser a
  218. set of sounds, and a set of voices it can use to play them. If you only give it
  219. one voice it will be monophonic - the more voices it has, the more polyphony it'll
  220. have available.
  221. Then repeatedly call the renderNextBlock() method to produce the audio. Any midi
  222. events that go in will be scanned for note on/off messages, and these are used to
  223. start and stop the voices playing the appropriate sounds.
  224. While it's playing, you can also cause notes to be triggered by calling the noteOn(),
  225. noteOff() and other controller methods.
  226. Before rendering, be sure to call the setCurrentPlaybackSampleRate() to tell it
  227. what the target playback rate is. This value is passed on to the voices so that
  228. they can pitch their output correctly.
  229. */
  230. class JUCE_API Synthesiser
  231. {
  232. public:
  233. //==============================================================================
  234. /** Creates a new synthesiser.
  235. You'll need to add some sounds and voices before it'll make any sound.
  236. */
  237. Synthesiser();
  238. /** Destructor. */
  239. virtual ~Synthesiser();
  240. //==============================================================================
  241. /** Deletes all voices. */
  242. void clearVoices();
  243. /** Returns the number of voices that have been added. */
  244. int getNumVoices() const noexcept { return voices.size(); }
  245. /** Returns one of the voices that have been added. */
  246. SynthesiserVoice* getVoice (int index) const;
  247. /** Adds a new voice to the synth.
  248. All the voices should be the same class of object and are treated equally.
  249. The object passed in will be managed by the synthesiser, which will delete
  250. it later on when no longer needed. The caller should not retain a pointer to the
  251. voice.
  252. */
  253. SynthesiserVoice* addVoice (SynthesiserVoice* newVoice);
  254. /** Deletes one of the voices. */
  255. void removeVoice (int index);
  256. //==============================================================================
  257. /** Deletes all sounds. */
  258. void clearSounds();
  259. /** Returns the number of sounds that have been added to the synth. */
  260. int getNumSounds() const noexcept { return sounds.size(); }
  261. /** Returns one of the sounds. */
  262. SynthesiserSound* getSound (int index) const noexcept { return sounds [index]; }
  263. /** Adds a new sound to the synthesiser.
  264. The object passed in is reference counted, so will be deleted when the
  265. synthesiser and all voices are no longer using it.
  266. */
  267. SynthesiserSound* addSound (const SynthesiserSound::Ptr& newSound);
  268. /** Removes and deletes one of the sounds. */
  269. void removeSound (int index);
  270. //==============================================================================
  271. /** If set to true, then the synth will try to take over an existing voice if
  272. it runs out and needs to play another note.
  273. The value of this boolean is passed into findFreeVoice(), so the result will
  274. depend on the implementation of this method.
  275. */
  276. void setNoteStealingEnabled (bool shouldStealNotes);
  277. /** Returns true if note-stealing is enabled.
  278. @see setNoteStealingEnabled
  279. */
  280. bool isNoteStealingEnabled() const noexcept { return shouldStealNotes; }
  281. //==============================================================================
  282. /** Triggers a note-on event.
  283. The default method here will find all the sounds that want to be triggered by
  284. this note/channel. For each sound, it'll try to find a free voice, and use the
  285. voice to start playing the sound.
  286. Subclasses might want to override this if they need a more complex algorithm.
  287. This method will be called automatically according to the midi data passed into
  288. renderNextBlock(), but may be called explicitly too.
  289. The midiChannel parameter is the channel, between 1 and 16 inclusive.
  290. */
  291. virtual void noteOn (int midiChannel,
  292. int midiNoteNumber,
  293. float velocity);
  294. /** Triggers a note-off event.
  295. This will turn off any voices that are playing a sound for the given note/channel.
  296. If allowTailOff is true, the voices will be allowed to fade out the notes gracefully
  297. (if they can do). If this is false, the notes will all be cut off immediately.
  298. This method will be called automatically according to the midi data passed into
  299. renderNextBlock(), but may be called explicitly too.
  300. The midiChannel parameter is the channel, between 1 and 16 inclusive.
  301. */
  302. virtual void noteOff (int midiChannel,
  303. int midiNoteNumber,
  304. float velocity,
  305. bool allowTailOff);
  306. /** Turns off all notes.
  307. This will turn off any voices that are playing a sound on the given midi channel.
  308. If midiChannel is 0 or less, then all voices will be turned off, regardless of
  309. which channel they're playing. Otherwise it represents a valid midi channel, from
  310. 1 to 16 inclusive.
  311. If allowTailOff is true, the voices will be allowed to fade out the notes gracefully
  312. (if they can do). If this is false, the notes will all be cut off immediately.
  313. This method will be called automatically according to the midi data passed into
  314. renderNextBlock(), but may be called explicitly too.
  315. */
  316. virtual void allNotesOff (int midiChannel,
  317. bool allowTailOff);
  318. /** Sends a pitch-wheel message to any active voices.
  319. This will send a pitch-wheel message to any voices that are playing sounds on
  320. the given midi channel.
  321. This method will be called automatically according to the midi data passed into
  322. renderNextBlock(), but may be called explicitly too.
  323. @param midiChannel the midi channel, from 1 to 16 inclusive
  324. @param wheelValue the wheel position, from 0 to 0x3fff, as returned by MidiMessage::getPitchWheelValue()
  325. */
  326. virtual void handlePitchWheel (int midiChannel,
  327. int wheelValue);
  328. /** Sends a midi controller message to any active voices.
  329. This will send a midi controller message to any voices that are playing sounds on
  330. the given midi channel.
  331. This method will be called automatically according to the midi data passed into
  332. renderNextBlock(), but may be called explicitly too.
  333. @param midiChannel the midi channel, from 1 to 16 inclusive
  334. @param controllerNumber the midi controller type, as returned by MidiMessage::getControllerNumber()
  335. @param controllerValue the midi controller value, between 0 and 127, as returned by MidiMessage::getControllerValue()
  336. */
  337. virtual void handleController (int midiChannel,
  338. int controllerNumber,
  339. int controllerValue);
  340. /** Sends an aftertouch message.
  341. This will send an aftertouch message to any voices that are playing sounds on
  342. the given midi channel and note number.
  343. This method will be called automatically according to the midi data passed into
  344. renderNextBlock(), but may be called explicitly too.
  345. @param midiChannel the midi channel, from 1 to 16 inclusive
  346. @param midiNoteNumber the midi note number, 0 to 127
  347. @param aftertouchValue the aftertouch value, between 0 and 127,
  348. as returned by MidiMessage::getAftertouchValue()
  349. */
  350. virtual void handleAftertouch (int midiChannel, int midiNoteNumber, int aftertouchValue);
  351. /** Sends a channel pressure message.
  352. This will send a channel pressure message to any voices that are playing sounds on
  353. the given midi channel.
  354. This method will be called automatically according to the midi data passed into
  355. renderNextBlock(), but may be called explicitly too.
  356. @param midiChannel the midi channel, from 1 to 16 inclusive
  357. @param channelPressureValue the pressure value, between 0 and 127, as returned
  358. by MidiMessage::getChannelPressureValue()
  359. */
  360. virtual void handleChannelPressure (int midiChannel, int channelPressureValue);
  361. /** Handles a sustain pedal event. */
  362. virtual void handleSustainPedal (int midiChannel, bool isDown);
  363. /** Handles a sostenuto pedal event. */
  364. virtual void handleSostenutoPedal (int midiChannel, bool isDown);
  365. /** Can be overridden to handle soft pedal events. */
  366. virtual void handleSoftPedal (int midiChannel, bool isDown);
  367. /** Can be overridden to handle an incoming program change message.
  368. The base class implementation of this has no effect, but you may want to make your
  369. own synth react to program changes.
  370. */
  371. virtual void handleProgramChange (int midiChannel,
  372. int programNumber);
  373. //==============================================================================
  374. /** Tells the synthesiser what the sample rate is for the audio it's being used to render.
  375. This value is propagated to the voices so that they can use it to render the correct
  376. pitches.
  377. */
  378. virtual void setCurrentPlaybackSampleRate (double sampleRate);
  379. /** Creates the next block of audio output.
  380. This will process the next numSamples of data from all the voices, and add that output
  381. to the audio block supplied, starting from the offset specified. Note that the
  382. data will be added to the current contents of the buffer, so you should clear it
  383. before calling this method if necessary.
  384. The midi events in the inputMidi buffer are parsed for note and controller events,
  385. and these are used to trigger the voices. Note that the startSample offset applies
  386. both to the audio output buffer and the midi input buffer, so any midi events
  387. with timestamps outside the specified region will be ignored.
  388. */
  389. inline void renderNextBlock (AudioBuffer<float>& outputAudio,
  390. const MidiBuffer& inputMidi,
  391. int startSample,
  392. int numSamples)
  393. { processNextBlock (outputAudio, inputMidi, startSample, numSamples); }
  394. inline void renderNextBlock (AudioBuffer<double>& outputAudio,
  395. const MidiBuffer& inputMidi,
  396. int startSample,
  397. int numSamples)
  398. { processNextBlock (outputAudio, inputMidi, startSample, numSamples); }
  399. /** Returns the current target sample rate at which rendering is being done.
  400. Subclasses may need to know this so that they can pitch things correctly.
  401. */
  402. double getSampleRate() const noexcept { return sampleRate; }
  403. /** Sets a minimum limit on the size to which audio sub-blocks will be divided when rendering.
  404. When rendering, the audio blocks that are passed into renderNextBlock() will be split up
  405. into smaller blocks that lie between all the incoming midi messages, and it is these smaller
  406. sub-blocks that are rendered with multiple calls to renderVoices().
  407. Obviously in a pathological case where there are midi messages on every sample, then
  408. renderVoices() could be called once per sample and lead to poor performance, so this
  409. setting allows you to set a lower limit on the block size.
  410. The default setting is 32, which means that midi messages are accurate to about < 1ms
  411. accuracy, which is probably fine for most purposes, but you may want to increase or
  412. decrease this value for your synth.
  413. If shouldBeStrict is true, the audio sub-blocks will strictly never be smaller than numSamples.
  414. If shouldBeStrict is false (default), the first audio sub-block in the buffer is allowed
  415. to be smaller, to make sure that the first MIDI event in a buffer will always be sample-accurate
  416. (this can sometimes help to avoid quantisation or phasing issues).
  417. */
  418. void setMinimumRenderingSubdivisionSize (int numSamples, bool shouldBeStrict = false) noexcept;
  419. protected:
  420. //==============================================================================
  421. /** This is used to control access to the rendering callback and the note trigger methods. */
  422. CriticalSection lock;
  423. OwnedArray<SynthesiserVoice> voices;
  424. ReferenceCountedArray<SynthesiserSound> sounds;
  425. /** The last pitch-wheel values for each midi channel. */
  426. int lastPitchWheelValues [16];
  427. /** Renders the voices for the given range.
  428. By default this just calls renderNextBlock() on each voice, but you may need
  429. to override it to handle custom cases.
  430. */
  431. virtual void renderVoices (AudioBuffer<float>& outputAudio,
  432. int startSample, int numSamples);
  433. virtual void renderVoices (AudioBuffer<double>& outputAudio,
  434. int startSample, int numSamples);
  435. /** Searches through the voices to find one that's not currently playing, and
  436. which can play the given sound.
  437. Returns nullptr if all voices are busy and stealing isn't enabled.
  438. To implement a custom note-stealing algorithm, you can either override this
  439. method, or (preferably) override findVoiceToSteal().
  440. */
  441. virtual SynthesiserVoice* findFreeVoice (SynthesiserSound* soundToPlay,
  442. int midiChannel,
  443. int midiNoteNumber,
  444. bool stealIfNoneAvailable) const;
  445. /** Chooses a voice that is most suitable for being re-used.
  446. The default method will attempt to find the oldest voice that isn't the
  447. bottom or top note being played. If that's not suitable for your synth,
  448. you can override this method and do something more cunning instead.
  449. */
  450. virtual SynthesiserVoice* findVoiceToSteal (SynthesiserSound* soundToPlay,
  451. int midiChannel,
  452. int midiNoteNumber) const;
  453. /** Starts a specified voice playing a particular sound.
  454. You'll probably never need to call this, it's used internally by noteOn(), but
  455. may be needed by subclasses for custom behaviours.
  456. */
  457. void startVoice (SynthesiserVoice* voice,
  458. SynthesiserSound* sound,
  459. int midiChannel,
  460. int midiNoteNumber,
  461. float velocity);
  462. /** Stops a given voice.
  463. You should never need to call this, it's used internally by noteOff, but is protected
  464. in case it's useful for some custom subclasses. It basically just calls through to
  465. SynthesiserVoice::stopNote(), and has some assertions to sanity-check a few things.
  466. */
  467. void stopVoice (SynthesiserVoice*, float velocity, bool allowTailOff);
  468. /** Can be overridden to do custom handling of incoming midi events. */
  469. virtual void handleMidiEvent (const MidiMessage&);
  470. private:
  471. //==============================================================================
  472. template <typename floatType>
  473. void processNextBlock (AudioBuffer<floatType>& outputAudio,
  474. const MidiBuffer& inputMidi,
  475. int startSample,
  476. int numSamples);
  477. //==============================================================================
  478. double sampleRate = 0;
  479. uint32 lastNoteOnCounter = 0;
  480. int minimumSubBlockSize = 32;
  481. bool subBlockSubdivisionIsStrict = false;
  482. bool shouldStealNotes = true;
  483. BigInteger sustainPedalsDown;
  484. #if JUCE_CATCH_DEPRECATED_CODE_MISUSE
  485. // Note the new parameters for these methods.
  486. virtual int findFreeVoice (const bool) const { return 0; }
  487. virtual int noteOff (int, int, int) { return 0; }
  488. virtual int findFreeVoice (SynthesiserSound*, const bool) { return 0; }
  489. virtual int findVoiceToSteal (SynthesiserSound*) const { return 0; }
  490. #endif
  491. JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (Synthesiser)
  492. };
  493. } // namespace juce