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