Aftertouch events not handled per note


#1

I propose these changes to handle aftertouch properly. 

Aftertouch is polyphonic so to handle it you need both the pressure value and the note. See http://www.midi.org/techspecs/midimessages.php

juce_Synthesizer.cpp


void Synthesiser::handleMidiEvent (const MidiMessage& m)
{
    if (m.isNoteOn())
    {
        noteOn (m.getChannel(), m.getNoteNumber(), m.getFloatVelocity());
    }
...
    else if (m.isAftertouch())
    {
        handleAftertouch(m.getChannel(), m.getNoteNumber(), m.getAfterTouchValue());
    }
    else if (m.isController())
    {
        handleController (m.getChannel(), m.getControllerNumber(), m.getControllerValue());
    }
}

...

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);            
        }
    }
}

 

class Synthesiser:

 


/** Sends an aftertouch message.
        This will send an aftertouch message to any voices that are playing sounds on
        the given midi channel and the specified midi note.
        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);

 

class SynthesiserVoice

 


/** 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 /* newValue */) {}

#2

edited (nevermind)

 


#3

Yes, good idea - thanks, will add that shortly..!