Loading...
Searching...
No Matches
juce::MPESynthesiser Class Reference

`#include <juce_MPESynthesiser.h>`

Inheritance diagram for juce::MPESynthesiser:

## Public Member Functions

| MPESynthesiser ()
| MPESynthesiser (MPEInstrument &instrumentToUse)
| ~MPESynthesiser () override
void | clearVoices ()
int | getNumVoices () const noexcept
MPESynthesiserVoice * | getVoice (int index) const
void | addVoice (MPESynthesiserVoice *newVoice)
void | removeVoice (int index)
void | reduceNumVoices (int newNumVoices)
virtual void | turnOffAllVoices (bool allowTailOff)
void | setVoiceStealingEnabled (bool shouldSteal) noexcept
bool | isVoiceStealingEnabled () const noexcept
void | setCurrentPlaybackSampleRate (double newRate) override
void | handleMidiEvent (const MidiMessage &) override
virtual void | handleController (int, int, int)
virtual void | handleProgramChange (int, int)
Public Member Functions inherited from juce::MPESynthesiserBase
| MPESynthesiserBase ()
| MPESynthesiserBase (MPEInstrument &instrument)
MPEZoneLayout | getZoneLayout () const noexcept
void | setZoneLayout (MPEZoneLayout newLayout)
double | getSampleRate () const noexcept
template<typename floatType>
void | renderNextBlock (AudioBuffer< floatType > &outputAudio, const MidiBuffer &inputMidi, int startSample, int numSamples)
void | setMinimumRenderingSubdivisionSize (int numSamples, bool shouldBeStrict=false) noexcept
void | enableLegacyMode (int pitchbendRange=2, Range< int > channelRange=Range< int >(1, 17))
bool | isLegacyModeEnabled () const noexcept
Range< int > | getLegacyModeChannelRange () const noexcept
void | setLegacyModeChannelRange (Range< int > channelRange)
int | getLegacyModePitchbendRange () const noexcept
void | setLegacyModePitchbendRange (int pitchbendRange)
void | setPressureTrackingMode (TrackingMode modeToUse)
void | setPitchbendTrackingMode (TrackingMode modeToUse)
void | setTimbreTrackingMode (TrackingMode modeToUse)
Public Member Functions inherited from juce::MPEInstrument::Listener
virtual | ~Listener ()=default
virtual void | zoneLayoutChanged ()

## Protected Member Functions

void | noteAdded (MPENote newNote) override
void | noteReleased (MPENote finishedNote) override
void | notePressureChanged (MPENote changedNote) override
void | notePitchbendChanged (MPENote changedNote) override
void | noteTimbreChanged (MPENote changedNote) override
void | noteKeyStateChanged (MPENote changedNote) override
void | renderNextSubBlock (AudioBuffer< float > &outputAudio, int startSample, int numSamples) override
void | renderNextSubBlock (AudioBuffer< double > &outputAudio, int startSample, int numSamples) override
virtual MPESynthesiserVoice * | findFreeVoice (MPENote noteToFindVoiceFor, bool stealIfNoneAvailable) const
virtual MPESynthesiserVoice * | findVoiceToSteal (MPENote noteToStealVoiceFor=MPENote()) const
void | startVoice (MPESynthesiserVoice *voice, MPENote noteToStart)
void | stopVoice (MPESynthesiserVoice *voice, MPENote noteToStop, bool allowTailOff)

## Protected Attributes

OwnedArray< MPESynthesiserVoice > | voices
CriticalSection | voicesLock
Protected Attributes inherited from juce::MPESynthesiserBase
MPEInstrument & | instrument

## Additional Inherited Members

Public Types inherited from juce::MPESynthesiserBase
using | TrackingMode = MPEInstrument::TrackingMode

## Detailed Description

Base class for an MPE-compatible musical device that can play sounds.

This class extends MPESynthesiserBase by adding the concept of voices, each of which can play a sound triggered by a MPENote that can be modulated by MPE dimensions like pressure, pitchbend, and timbre, while the note is sounding.

To create a synthesiser, you'll need to create a subclass of MPESynthesiserVoice which can play back one of these sounds at a time.

Then you can use the addVoice() methods to give the synthesiser a set of voices it can use to play notes. If you only give it one voice it will be monophonic - the more voices it has, the more polyphony it'll have available.

Then repeatedly call the renderNextBlock() method to produce the audio (inherited from MPESynthesiserBase). The voices will be started, stopped, and modulated automatically, based on the MPE/MIDI messages that the synthesiser receives.

Before rendering, be sure to call the setCurrentPlaybackSampleRate() to tell it what the target playback rate is. This value is passed on to the voices so that they can pitch their output correctly.

See also
  MPESynthesiserBase, MPESynthesiserVoice, MPENote, MPEInstrument

Definition at line 54 of file juce_MPESynthesiser.h.

## Constructor & Destructor Documentation

## MPESynthesiser() [1/2]

juce::MPESynthesiser::MPESynthesiser | ( |  | ) |

Constructor. You'll need to add some voices before it'll make any sound.

See also
  addVoice

Definition at line 26 of file juce_MPESynthesiser.cpp.

## MPESynthesiser() [2/2]

juce::MPESynthesiser::MPESynthesiser | ( | MPEInstrument & | instrumentToUse | ) |

Constructor to pass to the synthesiser a custom MPEInstrument object to handle the MPE note state, MIDI channel assignment etc. (in case you need custom logic for this that goes beyond MIDI and MPE).

See also
  MPESynthesiserBase, MPEInstrument

Definition at line 30 of file juce_MPESynthesiser.cpp.

## ~MPESynthesiser()

juce::MPESynthesiser::~MPESynthesiser | ( |  | ) |

override

Destructor.

Definition at line 35 of file juce_MPESynthesiser.cpp.

## Member Function Documentation

## addVoice()

void juce::MPESynthesiser::addVoice | ( | MPESynthesiserVoice * | newVoice | ) |

Adds a new voice to the synth.

All the voices should be the same class of object and are treated equally.

The object passed in will be managed by the synthesiser, which will delete it later on when no longer needed. The caller should not retain a pointer to the voice.

Definition at line 261 of file juce_MPESynthesiser.cpp.

## clearVoices()

void juce::MPESynthesiser::clearVoices | ( |  | ) |

Deletes all voices.

Definition at line 275 of file juce_MPESynthesiser.cpp.

## findFreeVoice()

MPESynthesiserVoice * juce::MPESynthesiser::findFreeVoice | ( | MPENote | noteToFindVoiceFor,
|  | bool | stealIfNoneAvailable ) const

protected virtual

Searches through the voices to find one that's not currently playing, and which can play the given MPE note.

If all voices are active and stealIfNoneAvailable is false, this returns a nullptr. If all voices are active and stealIfNoneAvailable is true, this will call findVoiceToSteal() to find a voice.

If you need to find a free voice for something else than playing a note (e.g. for deleting it), you can pass an invalid (default-constructed) MPENote.

Definition at line 157 of file juce_MPESynthesiser.cpp.

Referenced by noteAdded(), and reduceNumVoices().

## findVoiceToSteal()

MPESynthesiserVoice * juce::MPESynthesiser::findVoiceToSteal | ( | MPENote | noteToStealVoiceFor = MPENote() | ) | const

protected virtual

Chooses a voice that is most suitable for being re-used to play a new note, or for being deleted by reduceNumVoices.

The default method will attempt to find the oldest voice that isn't the bottom or top note being played. If that's not suitable for your synth, you can override this method and do something more cunning instead.

If you pass a valid MPENote for the optional argument, then the note number of that note will be taken into account for finding the ideal voice to steal. If you pass an invalid (default-constructed) MPENote instead, this part of the algorithm will be ignored.

Definition at line 173 of file juce_MPESynthesiser.cpp.

Referenced by findFreeVoice().

## getNumVoices()

int juce::MPESynthesiser::getNumVoices | ( |  | ) | const

inline noexcept

Returns the number of voices that have been added.

Definition at line 81 of file juce_MPESynthesiser.h.

## getVoice()

MPESynthesiserVoice * juce::MPESynthesiser::getVoice | ( | int | index | ) | const

Returns one of the voices that have been added.

Definition at line 281 of file juce_MPESynthesiser.cpp.

## handleController()

virtual void juce::MPESynthesiser::handleController | ( | int | ,
|  | int | ,
|  | int | )

inline virtual

Callback for MIDI controller messages. The default implementation provided here does nothing; override this method if you need custom MIDI controller handling on top of MPE.

This method will be called automatically according to the midi data passed into renderNextBlock().

Definition at line 162 of file juce_MPESynthesiser.h.

Referenced by handleMidiEvent().

## handleMidiEvent()

void juce::MPESynthesiser::handleMidiEvent | ( | const MidiMessage & | m | ) |

override virtual

Handle incoming MIDI events.

This method will be called automatically according to the MIDI data passed into renderNextBlock(), but you can also call it yourself to manually inject MIDI events.

This implementation forwards program change messages and non-MPE-related controller messages to handleProgramChange and handleController, respectively, and then simply calls through to MPESynthesiserBase::handleMidiEvent to deal with MPE-related MIDI messages used for MPE notes, zones etc.

This method can be overridden further if you need to do custom MIDI handling on top of what is provided here.

Reimplemented from juce::MPESynthesiserBase.

Definition at line 147 of file juce_MPESynthesiser.cpp.

## handleProgramChange()

virtual void juce::MPESynthesiser::handleProgramChange | ( | int | ,
|  | int | )

inline virtual

Callback for MIDI program change messages. The default implementation provided here does nothing; override this method if you need to handle those messages.

This method will be called automatically according to the midi data passed into renderNextBlock().

Definition at line 173 of file juce_MPESynthesiser.h.

Referenced by handleMidiEvent().

## isVoiceStealingEnabled()

bool juce::MPESynthesiser::isVoiceStealingEnabled | ( |  | ) | const

inline noexcept

Returns true if note-stealing is enabled.

Definition at line 127 of file juce_MPESynthesiser.h.

## noteAdded()

void juce::MPESynthesiser::noteAdded | ( | MPENote | newNote | ) |

override protected virtual

Attempts to start playing a new note.

The default method here will find a free voice that is appropriate for playing the given MPENote, and use that voice to start playing the sound. If isNoteStealingEnabled returns true (set this by calling setNoteStealingEnabled), the synthesiser will use the voice stealing algorithm to find a free voice for the note (if no voices are free otherwise).

This method will be called automatically according to the midi data passed into renderNextBlock(). Do not call it yourself, otherwise the internal MPE note state will become inconsistent.

Reimplemented from juce::MPEInstrument::Listener.

Definition at line 58 of file juce_MPESynthesiser.cpp.

## noteKeyStateChanged()

void juce::MPESynthesiser::noteKeyStateChanged | ( | MPENote | changedNote | ) |

override protected virtual

Will find any voice that is currently playing changedNote, update its currently playing note, and call its noteKeyStateChanged method.

This method will be called automatically according to the midi data passed into renderNextBlock(). Do not call it yourself.

Reimplemented from juce::MPEInstrument::Listener.

Definition at line 108 of file juce_MPESynthesiser.cpp.

## notePitchbendChanged()

void juce::MPESynthesiser::notePitchbendChanged | ( | MPENote | changedNote | ) |

override protected virtual

Will find any voice that is currently playing changedNote, update its currently playing note, and call its notePitchbendChanged method.

This method will be called automatically according to the midi data passed into renderNextBlock(). Do not call it yourself.

Reimplemented from juce::MPEInstrument::Listener.

Definition at line 80 of file juce_MPESynthesiser.cpp.

## notePressureChanged()

void juce::MPESynthesiser::notePressureChanged | ( | MPENote | changedNote | ) |

override protected virtual

Will find any voice that is currently playing changedNote, update its currently playing note, and call its notePressureChanged method.

This method will be called automatically according to the midi data passed into renderNextBlock(). Do not call it yourself.

Reimplemented from juce::MPEInstrument::Listener.

Definition at line 66 of file juce_MPESynthesiser.cpp.

## noteReleased()

void juce::MPESynthesiser::noteReleased | ( | MPENote | finishedNote | ) |

override protected virtual

Stops playing a note.

This will be called whenever an MPE note is released (either by a note-off message, or by a sustain/sostenuto pedal release for a note that already received a note-off), and should therefore stop playing.

This will find any voice that is currently playing finishedNote, turn its currently playing note off, and call its noteStopped callback.

This method will be called automatically according to the midi data passed into renderNextBlock(). Do not call it yourself, otherwise the internal MPE note state will become inconsistent.

Reimplemented from juce::MPEInstrument::Listener.

Definition at line 122 of file juce_MPESynthesiser.cpp.

## noteTimbreChanged()

void juce::MPESynthesiser::noteTimbreChanged | ( | MPENote | changedNote | ) |

override protected virtual

Will find any voice that is currently playing changedNote, update its currently playing note, and call its noteTimbreChanged method.

This method will be called automatically according to the midi data passed into renderNextBlock(). Do not call it yourself.

Reimplemented from juce::MPEInstrument::Listener.

Definition at line 94 of file juce_MPESynthesiser.cpp.

## reduceNumVoices()

void juce::MPESynthesiser::reduceNumVoices | ( | int | newNumVoices | ) |

Reduces the number of voices to newNumVoices.

This will repeatedly call findVoiceToSteal() and remove that voice, until the total number of voices equals newNumVoices. If newNumVoices is greater than or equal to the current number of voices, this method does nothing.

Definition at line 293 of file juce_MPESynthesiser.cpp.

## removeVoice()

void juce::MPESynthesiser::removeVoice | ( | int | index | ) |

Deletes one of the voices.

Definition at line 287 of file juce_MPESynthesiser.cpp.

## renderNextSubBlock() [1/2]

void juce::MPESynthesiser::renderNextSubBlock | ( | AudioBuffer< double > & | outputAudio,
|  | int | startSample,
|  | int | numSamples )

override protected virtual

This will simply call renderNextBlock for each currently active voice and fill the buffer with the sum. (double-precision version) Override this method if you need to do more work to render your audio.

Reimplemented from juce::MPESynthesiserBase.

Definition at line 341 of file juce_MPESynthesiser.cpp.

## renderNextSubBlock() [2/2]

void juce::MPESynthesiser::renderNextSubBlock | ( | AudioBuffer< float > & | outputAudio,
|  | int | startSample,
|  | int | numSamples )

override protected virtual

This will simply call renderNextBlock for each currently active voice and fill the buffer with the sum. Override this method if you need to do more work to render your audio.

Implements juce::MPESynthesiserBase.

Definition at line 330 of file juce_MPESynthesiser.cpp.

## setCurrentPlaybackSampleRate()

void juce::MPESynthesiser::setCurrentPlaybackSampleRate | ( | double | newRate | ) |

override virtual

Tells the synthesiser what the sample rate is for the audio it's being used to render.

This overrides the implementation in MPESynthesiserBase, to additionally propagate the new value to the voices so that they can use it to render the correct pitches.

Reimplemented from juce::MPESynthesiserBase.

Definition at line 135 of file juce_MPESynthesiser.cpp.

## setVoiceStealingEnabled()

void juce::MPESynthesiser::setVoiceStealingEnabled | ( | bool | shouldSteal | ) |

inline noexcept

If set to true, then the synth will try to take over an existing voice if it runs out and needs to play another note.

The value of this boolean is passed into findFreeVoice(), so the result will depend on the implementation of this method.

Definition at line 124 of file juce_MPESynthesiser.h.

## startVoice()

void juce::MPESynthesiser::startVoice | ( | MPESynthesiserVoice * | voice,
|  | MPENote | noteToStart )

protected

Starts a specified voice and tells it to play a particular MPENote. You should never need to call this, it's called internally by MPESynthesiserBase::instrument via the noteStarted callback, but is protected in case it's useful for some custom subclasses.

Definition at line 40 of file juce_MPESynthesiser.cpp.

Referenced by noteAdded().

## stopVoice()

void juce::MPESynthesiser::stopVoice | ( | MPESynthesiserVoice * | voice,
|  | MPENote | noteToStop,
|  | bool | allowTailOff )

protected

Stops a given voice and tells it to stop playing a particular MPENote (which should be the same note it is actually playing). You should never need to call this, it's called internally by MPESynthesiserBase::instrument via the noteReleased callback, but is protected in case it's useful for some custom subclasses.

Definition at line 49 of file juce_MPESynthesiser.cpp.

Referenced by noteReleased().

## turnOffAllVoices()

void juce::MPESynthesiser::turnOffAllVoices | ( | bool | allowTailOff | ) |

virtual

Release all MPE notes and turn off all voices.

If allowTailOff is true, the voices will be allowed to fade out the notes gracefully (if they can do). If this is false, the notes will all be cut off immediately.

This method is meant to be called by the user, for example to implement a MIDI panic button in a synth.

Definition at line 309 of file juce_MPESynthesiser.cpp.

Referenced by setCurrentPlaybackSampleRate().

## Member Data Documentation

## voices

OwnedArray<MPESynthesiserVoice> juce::MPESynthesiser::voices

protected

Definition at line 300 of file juce_MPESynthesiser.h.

## voicesLock

CriticalSection juce::MPESynthesiser::voicesLock

protected

Definition at line 301 of file juce_MPESynthesiser.h.

The documentation for this class was generated from the following files:

- juce_MPESynthesiser.h
- juce_MPESynthesiser.cpp