I don't succeed to send Midi messages with TimeStamp

Hello,
i am using JUCE on MacOs for a StandAlone version of an Audio/Midi Plugin.
The ProcessBlock function is writing a list of 10 midi messages with different TimeStamps: i tried to put a time difference of +1 (up to +10) between each, using:
midiMessages.addEvent (message, time);
time ++;

Just before the end of the ProcessBlock function i check that the TimeStamp are correctly recorded.
The StandAlone send midi messages on output to the virtual IAC Bus 1 and i capture the midi messages with Midi Monitor (an external software on MacOs):

StandAlone → Virtual Midi port IAC Bus 1 → Midi Monitor

However in Midi Monitor, i observe that the messages are sent at the same time (or with a tiny shift of few nanoseconds only), so the time shift of TimeStamp shift that i tried to impose has not been done.
Do you have an idea how to solve or to understand this problem please?
(for my project i need a specific ordering of the midi messages)
Thanks,
Frédéric.

You say you’re writing a plug-in, but Midi Monitor is a separate app. So what MIDI output is being captured by Midi Monitor, and how are you capturing it?

I am sorry that i was not clear. I have corrected the first message above as follows:
In fact i am using the StandAlone version of the plugin (created by JUCE). The StandAlone sends output midi messages on the virtual Midi port IAC Bus 1. Then Midi Monitor shows these messages coming from IAC Bus 1, in summary:

StandAlone → Virtual port IAC Bus 1 → Midi Monitor.

I’m not 100% sure but I believe the MIDI messages in the midiBuffer in processBlock are meant to be consumed by the DAW, or at least the next plug-in on the same track.

To send out MIDI messages to another process using timing information, you’ll have to construct a MidiOutput object and do midiOutput.sendBlockOfMessages(midiBuffer, juce::Time::getMillisecondCounterHiRes(), sampleRate);

Thanks for this information.

Does JUCE do this for the StandAlone version of a Plugin? I mean that we could expect that in the standAlone version of the Plugin, JUCE read the timestamps and send messages according to them. Do you think that JUCE has an option to do this or not?
It seems strang that i need to implement another MidiOutput object, since JUCE has already created one somehow for the standAlone version of the Plugin?

So you are creating 10 midimessages inside the process block. Then you add each of them to the midibuffer using the addEvent member function of the midibuffer-class, passing 10 successive integer values to the function (0-9)?

addEvent takes as second argument an int named ‘time’. The unit of time in this context is the number of samples that this processblock/ audiocallback takes. So time in this context schedules the message inside/ relative to this current callback (obviously it must be >= 0 and < bufferSize).
A sample rate of 44100hz means that one sample has a ‘duration’ of 1 divided by 44.100 seconds or 1000 / 44100 milliseconds, so the timing-offets of your messages are indeed tiny if you just increment by 1 sample.
They should also be output repeatedly and very frequently: every single time processblock is called ( = samplerate / buffersize times per second).

Apart from the “time”-argument in the addEvent member function of midibuffer, there is the “timestamp” argument you supply to construct a midimessage. This is a double and it is independent from the time value above. This confused me a lot at first.
It could denote musical time in a sense of its position in a bar. 0, 1/4, 2/4, 3/4 = the four ‘pulses’ of a bar, or something completely different. Thats completely up to you.
The relation to the time-as-sample-value from above needs to be established by yourself, if needed.
So in order to schedule a midimessage according to the timestamp you have given to it (upon construction), you first need to translate this into 1) finding the specific audiocallback in which it is due (count buffer.getNumSamples()…) and then 2) find its position ‘inside’ this callback/buffer ( = calculate sample number).

Im a juce-beginner myself so i hope what i said is correct and makes sense. Please correct me if im wrong.

Regarding the question about the midi IO-stuff…
If you chose to build a plugin in the projucer, but also chose to build (compile as) a standalone version (for testing etc) all the basic IO-stuff should be taken care of allready (even in standalone build). At least it is like this in my case.

In case someone is watching… i would also be interested to know more about midi in juce, for example,

  • is it necessary to do the midi-processing in a dedicated thread or can it stay in the audio-thread (im only doing midi, no audio)
  • if so… is juce::midimessagesequence a sensible choice as container to store the midi-data for a midisequencer?