|
| | MPESynthesiser () |
| | Constructor.
|
| |
| | MPESynthesiser (MPEInstrument &instrumentToUse) |
| | Constructor to pass to the synthesiser a custom MPEInstrument object to handle the MPE note state, MIDI channel assignment etc.
|
| |
| | ~MPESynthesiser () override |
| | Destructor.
|
| |
| void | addVoice (MPESynthesiserVoice *newVoice) |
| | Adds a new voice to the synth.
|
| |
| void | clearVoices () |
| | Deletes all voices.
|
| |
| void | enableLegacyMode (int pitchbendRange=2, Range< int > channelRange=Range< int >(1, 17)) |
| | Puts the synthesiser into legacy mode.
|
| |
| Range< int > | getLegacyModeChannelRange () const noexcept |
| | Returns the range of MIDI channels (1-16) to be used for notes when in legacy mode.
|
| |
| int | getLegacyModePitchbendRange () const noexcept |
| | Returns the pitchbend range in semitones (0-96) to be used for notes when in legacy mode.
|
| |
| int | getNumVoices () const noexcept |
| | Returns the number of voices that have been added.
|
| |
| double | getSampleRate () const noexcept |
| | Returns the current target sample rate at which rendering is being done.
|
| |
| MPESynthesiserVoice * | getVoice (int index) const |
| | Returns one of the voices that have been added.
|
| |
| MPEZoneLayout | getZoneLayout () const noexcept |
| | Returns the synthesiser's internal MPE zone layout.
|
| |
| virtual void | handleController (int, int, int) |
| | Callback for MIDI controller messages.
|
| |
| void | handleMidiEvent (const MidiMessage &) override |
| | Handle incoming MIDI events.
|
| |
| virtual void | handleProgramChange (int, int) |
| | Callback for MIDI program change messages.
|
| |
| bool | isLegacyModeEnabled () const noexcept |
| | Returns true if the instrument is in legacy mode, false otherwise.
|
| |
| bool | isVoiceStealingEnabled () const noexcept |
| | Returns true if note-stealing is enabled.
|
| |
| void | reduceNumVoices (int newNumVoices) |
| | Reduces the number of voices to newNumVoices.
|
| |
| void | removeVoice (int index) |
| | Deletes one of the voices.
|
| |
| template<typename floatType > |
| void | renderNextBlock (AudioBuffer< floatType > &outputAudio, const MidiBuffer &inputMidi, int startSample, int numSamples) |
| | Creates the next block of audio output.
|
| |
| void | setCurrentPlaybackSampleRate (double newRate) override |
| | Tells the synthesiser what the sample rate is for the audio it's being used to render.
|
| |
| void | setLegacyModeChannelRange (Range< int > channelRange) |
| | Re-sets the range of MIDI channels (1-16) to be used for notes when in legacy mode.
|
| |
| void | setLegacyModePitchbendRange (int pitchbendRange) |
| | Re-sets the pitchbend range in semitones (0-96) to be used for notes when in legacy mode.
|
| |
| void | setMinimumRenderingSubdivisionSize (int numSamples, bool shouldBeStrict=false) noexcept |
| | Sets a minimum limit on the size to which audio sub-blocks will be divided when rendering.
|
| |
| void | setPitchbendTrackingMode (TrackingMode modeToUse) |
| | Set the MPE tracking mode for the pitchbend dimension.
|
| |
| void | setPressureTrackingMode (TrackingMode modeToUse) |
| | Set the MPE tracking mode for the pressure dimension.
|
| |
| void | setTimbreTrackingMode (TrackingMode modeToUse) |
| | Set the MPE tracking mode for the timbre dimension.
|
| |
| void | setVoiceStealingEnabled (bool shouldSteal) 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.
|
| |
| void | setZoneLayout (MPEZoneLayout newLayout) |
| | Re-sets the synthesiser's internal MPE zone layout to the one passed in.
|
| |
| virtual void | turnOffAllVoices (bool allowTailOff) |
| | Release all MPE notes and turn off all voices.
|
| |
| virtual void | zoneLayoutChanged () |
| | Implement this callback to be informed whenever the MPE zone layout or legacy mode settings of this instrument have been changed.
|
| |
|
| virtual MPESynthesiserVoice * | findFreeVoice (MPENote noteToFindVoiceFor, bool stealIfNoneAvailable) const |
| | Searches through the voices to find one that's not currently playing, and which can play the given MPE note.
|
| |
| virtual MPESynthesiserVoice * | findVoiceToSteal (MPENote noteToStealVoiceFor=MPENote()) const |
| | Chooses a voice that is most suitable for being re-used to play a new note, or for being deleted by reduceNumVoices.
|
| |
| void | noteAdded (MPENote newNote) override |
| | Attempts to start playing a new note.
|
| |
| void | noteKeyStateChanged (MPENote changedNote) override |
| | Will find any voice that is currently playing changedNote, update its currently playing note, and call its noteKeyStateChanged method.
|
| |
| void | notePitchbendChanged (MPENote changedNote) override |
| | Will find any voice that is currently playing changedNote, update its currently playing note, and call its notePitchbendChanged method.
|
| |
| void | notePressureChanged (MPENote changedNote) override |
| | Will find any voice that is currently playing changedNote, update its currently playing note, and call its notePressureChanged method.
|
| |
| void | noteReleased (MPENote finishedNote) override |
| | Stops playing a note.
|
| |
| void | noteTimbreChanged (MPENote changedNote) override |
| | Will find any voice that is currently playing changedNote, update its currently playing note, and call its noteTimbreChanged method.
|
| |
| void | renderNextSubBlock (AudioBuffer< double > &outputAudio, int startSample, int numSamples) override |
| | This will simply call renderNextBlock for each currently active voice and fill the buffer with the sum.
|
| |
| void | renderNextSubBlock (AudioBuffer< float > &outputAudio, int startSample, int numSamples) override |
| | This will simply call renderNextBlock for each currently active voice and fill the buffer with the sum.
|
| |
| void | startVoice (MPESynthesiserVoice *voice, MPENote noteToStart) |
| | Starts a specified voice and tells it to play a particular MPENote.
|
| |
| void | stopVoice (MPESynthesiserVoice *voice, MPENote noteToStop, bool allowTailOff) |
| | Stops a given voice and tells it to stop playing a particular MPENote (which should be the same note it is actually playing).
|
| |
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
@tags{Audio}
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.
| void juce::MPESynthesiser::handleMidiEvent |
( |
const MidiMessage & |
| ) |
|
|
overridevirtual |
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.
| void juce::MPESynthesiser::noteAdded |
( |
MPENote |
newNote | ) |
|
|
overrideprotectedvirtual |
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.
| void juce::MPESynthesiser::noteReleased |
( |
MPENote |
finishedNote | ) |
|
|
overrideprotectedvirtual |
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.
| void juce::MPESynthesiserBase::setMinimumRenderingSubdivisionSize |
( |
int |
numSamples, |
|
|
bool |
shouldBeStrict = false |
|
) |
| |
|
noexceptinherited |
Sets a minimum limit on the size to which audio sub-blocks will be divided when rendering.
When rendering, the audio blocks that are passed into renderNextBlock() will be split up into smaller blocks that lie between all the incoming midi messages, and it is these smaller sub-blocks that are rendered with multiple calls to renderVoices().
Obviously in a pathological case where there are midi messages on every sample, then renderVoices() could be called once per sample and lead to poor performance, so this setting allows you to set a lower limit on the block size.
The default setting is 32, which means that midi messages are accurate to about < 1ms accuracy, which is probably fine for most purposes, but you may want to increase or decrease this value for your synth.
If shouldBeStrict is true, the audio sub-blocks will strictly never be smaller than numSamples.
If shouldBeStrict is false (default), the first audio sub-block in the buffer is allowed to be smaller, to make sure that the first MIDI event in a buffer will always be sample-accurate (this can sometimes help to avoid quantisation or phasing issues).