Midi timestamp resolution

Hi folks,
I have a question regarding timestamps in midi messages.
I want to avoid a pb with a Midi keyboard that sends from time to time an unexpected Note ON to 127 followed by its Note OFF. They is due to a faulty key contact.
I tried to make a small Midi filter VST plugin to try to avoid that pb.
Here is what I did :

void NewProjectAudioProcessor::processBlock (juce::AudioBuffer& buffer, juce::MidiBuffer& midiMessages)
{

buffer.clear();

juce::MidiBuffer processedMidi;
int time;
juce::MidiMessage m;

for (juce::MidiBuffer::Iterator i(midiMessages); i.getNextEvent(m, time);)
{
    // test only duplicate on channel 1 to simplify
    if (m.isNoteOn() && (m.getChannel()==1))
    {
        mNoteOnCounter[m.getNoteNumber()]++;

        if (mNoteOnCounter[m.getNoteNumber()] == 2)
        {
            // Delete this note On because a duplicate note has been detected
            mNoteOnCounter[m.getNoteNumber()]--;
            continue;
        }
        if ((m.getVelocity() == 127))
        {
            DBG("Note ON with velocity 127");
            
            if ((m.getTimeStamp() - mLastNoteOffTime[m.getNoteNumber()]) < 0.002)
            {
                DBG("Bad Note ON received -> Delete");
                
                // Remove bad Note ON
                mLastNoteOnDeleted[m.getNoteNumber()] = true;
                continue;
            }
        }
    }
    else if (m.isNoteOff() && (m.getChannel() == 1))
    {
        mNoteOnCounter[m.getNoteNumber()]--;
        if (mLastNoteOnDeleted[m.getNoteNumber()])
        {
            // Remove bad Note Off
            mLastNoteOnDeleted[m.getNoteNumber()] = false;
            continue;
        }
        else
        { 
            mLastNoteOffTime[m.getNoteNumber()] = m.getTimeStamp();
        }
    }

    processedMidi.addEvent(m, time);
}

midiMessages.swapWith(processedMidi);

}

This code is basically aimed to remove a Note ON of 127 that followed a Note OFF for less of 2 ms + its related Note OFF.
But it seems the Value returned by m.getTimeStamp() is not accurate enough.
Any ideas ?

Thanks in advance.

There are several problems in this code. The Note ON and Note OFF might be in different buffers. Also don’t use getTimeStamp() which is meant for MIDI messages in a MIDI file, compute their position in samples from their “int time” that you get from getNextEvent() and the host transport position:

AudioPlayHead::CurrentPositionInfo pos; 
if (getPlayHead() != 0 && getPlayHead()->getCurrentPosition(pos)) 
{ ...}

Hi Qfactor,
thanks for your answer but as a beginner in Juce I don’t understand what you are saying.
I used the tutorial example as a base to buld this project:
Ref: https://docs.juce.com/master/tutorial_code_basic_plugin.html paragraph: Modify MIDI notes.
So if this example is not good could you point me to a more convenient one ?
Thanks.

PS: Remind that my little project must be a VST plugin.

Hi levioter,

The argument “midiMessages” doesn’t contain all the notes of your MIDI track, only a small chunk of them of a certain block size at a certain sample rate. This is not specific to JUCE, this is how real time audio processing works (which is the basis for audio plugins of any sort). I don’t have a specific reference in mind (I learned it a long time ago!), maybe somebody else can suggest a good modern introduction to real time audio/MIDI processing?

Just for clarification I am using a Midi Keyboard live and not a track or sequencer.
That’s why I need precide timestamping in order to try to filter this bug.
I guess I need to intercept the midi input and timestamp accurately with a high resolution timer before any timestamp manipulation.
Thanks I will dig a liitle bit more then.
Have a good day.
Cheers.