Midi event offsets always zero (live input)?

Hey everyone,

I do this:

    class MyClass : public AudioIODeviceCallback, public MidiInputCallback
        // .....
        MidiMessageCollector m_MidiMessageCollector;
        MidiBuffer m_MidiBuffer;

    void MyClass::handleIncomingMidiMessage(MidiInput* source, const MidiMessage& message)
        m_MidiMessageCollector.handleIncomingMidiMessage(source, message);

    void MyClass::audioDeviceIOCallback(const float** inputChannelData, int numInputChannels, float** outputChannelData, int numOutputChannels, int numSamples)
        m_MidiMessageCollector.removeNextBlockOfMessages(m_MidiBuffer, numSamples);

        MidiBuffer::Iterator midiBufferIterator(m_MidiBuffer);
        MidiMessage midiMessage;
        int samplePosition;

        while (midiBufferIterator.getNextEvent(midiMessage, samplePosition))
            // samplePosition is always zero!

The sampleposition found there, in the midi event loop processing is always zero. This is “ok” for small buffer sizes, but running my code with large (6000+ samples) buffersizes makes everything behave craaaaazy :slight_smile:

Am I missing something? Are realtime midi events really always timed at zero? Why not add a [buffersize] latency and at least have jitter which is less than a buffersize?

FYI, I’m using Juce standalone, so both the audio and midi are handled by Juce.

  • bram

Some further investigation leads me to: MidiMessageCollector::addMessageToQueue

    const int sampleNumber = (int) ((message.getTimeStamp() - 0.001 * lastCallbackTime) * sampleRate);
    DBG(sampleNumber); // I added this!

And at debug this tells me:


For just hitting some notes. I.e. all my events are coming in at negative timestamps! :o I tried this both with a real midi-cable-attached (my old fatar) device and a USB/midi device (akai mpk).

  • Bram

Rebooting my computer solved this issue… And then I got it again, rebooting fixed it yet again… It looks like a driver thing to me…

  • bram

Just a guess but the timestamp is relative to the beginning of the audio i/o block. For MIDI inputs, a positive value would mean a keyboard note was pressed in the future? I think the timestamp is more relevant for MIDI output rather than MIDI input. If you want to jitter your inputs for some reason then you can do it yourself.

But more importantly I think if you’re doing live processing, you want your buffer to be as small as possible without getting dropouts this way MIDI input events will have minimum latency.

Disclaimer: I have done very little with Juce MIDI.

This is not entirely correct: incoming midi should be timestamped to avoid midi jitter. And Juce does this, but I think my soundcard/midi input start misbehaving if I put breakpoints in the audio thread.

Imagine all midi events have timestamp zero, the most granular input you can then do is buffersize!

  • bram

And…what’s wrong with that? This is how most audio apps work…you can’t change a parameter in the middle of the audio i/o block. Thats why users want to make the buffer size as small as possible.

Errm…I thought the solution to midi input jitter is to make the buffer size smaller, not to modify the input data with random timestamps! Read this article


Huh? I’m confused… the best way is to add 1 buffersize of latency (or perhaps the input latency) to all the timestamps, as they come in, not add a random timestamp.
Again, just like Juce does I think! :slight_smile:
It timestamps the incoming midi timestamps with a timestamp relative to the current buffer time.

  • Bram

of course you can! :slight_smile: the VST standard doesn’t say anything of the timeing on which setParameter events enter the picture, actually, neither does Juce as far as I know!

aaaaaanyway, all of this is a void discussion as the original post from me is no longer valid.

  • bram