diff --git a/modules/juce_audio_basics/synthesisers/juce_Synthesiser.cpp b/modules/juce_audio_basics/synthesisers/juce_Synthesiser.cpp index 6af687ede0..1aa248bb04 100644 --- a/modules/juce_audio_basics/synthesisers/juce_Synthesiser.cpp +++ b/modules/juce_audio_basics/synthesisers/juce_Synthesiser.cpp @@ -56,6 +56,8 @@ void SynthesiserVoice::clearCurrentNote() currentlyPlayingSound = nullptr; } +void SynthesiserVoice::aftertouchChanged (int) {} + //============================================================================== Synthesiser::Synthesiser() : sampleRate (0), @@ -191,6 +193,10 @@ void Synthesiser::handleMidiEvent (const MidiMessage& m) handlePitchWheel (channel, wheelPos); } + else if (m.isAftertouch()) + { + handleAftertouch (m.getChannel(), m.getNoteNumber(), m.getAfterTouchValue()); + } else if (m.isController()) { handleController (m.getChannel(), m.getControllerNumber(), m.getControllerValue()); @@ -338,6 +344,20 @@ void Synthesiser::handleController (const int midiChannel, } } +void Synthesiser::handleAftertouch (int midiChannel, int midiNoteNumber, int aftertouchValue) +{ + const ScopedLock sl (lock); + + for (int i = voices.size(); --i >= 0;) + { + SynthesiserVoice* const voice = voices.getUnchecked (i); + + if (voice->getCurrentlyPlayingNote() == midiNoteNumber + && (midiChannel <= 0 || voice->isPlayingChannel (midiChannel))) + voice->aftertouchChanged (aftertouchValue); + } +} + void Synthesiser::handleSustainPedal (int midiChannel, bool isDown) { jassert (midiChannel > 0 && midiChannel <= 16); diff --git a/modules/juce_audio_basics/synthesisers/juce_Synthesiser.h b/modules/juce_audio_basics/synthesisers/juce_Synthesiser.h index 65729e5f52..eca9a54d52 100644 --- a/modules/juce_audio_basics/synthesisers/juce_Synthesiser.h +++ b/modules/juce_audio_basics/synthesisers/juce_Synthesiser.h @@ -141,12 +141,17 @@ public: /** Called to let the voice know that the pitch wheel has been moved. This will be called during the rendering callback, so must be fast and thread-safe. */ - virtual void pitchWheelMoved (int newValue) = 0; + virtual void pitchWheelMoved (int newPitchWheelValue) = 0; /** Called to let the voice know that a midi controller has been moved. This will be called during the rendering callback, so must be fast and thread-safe. */ - virtual void controllerMoved (int controllerNumber, int newValue) = 0; + virtual void controllerMoved (int controllerNumber, int newControllerValue) = 0; + + /** Called to let the voice know that the aftertouch has changed. + This will be called during the rendering callback, so must be fast and thread-safe. + */ + virtual void aftertouchChanged (int newAftertouchValue); //============================================================================== /** Renders the next block of data for this voice. @@ -406,6 +411,20 @@ public: int controllerNumber, int controllerValue); + /** Sends an aftertouch message. + + This will send an aftertouch message to any voices that are playing sounds on + the given midi channel and note number. + + This method will be called automatically according to the midi data passed into + renderNextBlock(), but may be called explicitly too. + + @param midiChannel the midi channel, from 1 to 16 inclusive + @param aftertouchValue the aftertouch value, between 0 and 127, + as returned by MidiMessage::getAftertouchValue() + */ + virtual void handleAftertouch (int midiChannel, int midiNoteNumber, int aftertouchValue); + /** Handles a sustain pedal event. */ virtual void handleSustainPedal (int midiChannel, bool isDown);