I’m trying to make sense of the timeStamp value in MidiMessages and the sampleNumber in MidiBuffer::addEvent().
What do these represent? The time since the track started? The time after the event is queued that it should be triggered? The time since the buffer was last filled? Or something else?
In the plugin I’m writing, the user triggers events in the UI, and I really want them to be sent out to other synths as soon as possible after that.
Does this mean I should timeStamp the MidiMessage as 0? Can I also put sampleNumber as 0?
//==============================================================================
/** Returns the timestamp associated with this message.
The exact meaning of this time and its units will vary, as messages are used in
a variety of different contexts.
If you're getting the message from a midi file, this could be a time in seconds, or
a number of ticks - see MidiFile::convertTimestampTicksToSeconds().
If the message is being used in a MidiBuffer, it might indicate the number of
audio samples from the start of the buffer.
If the message was created by a MidiInput, see MidiInputCallback::handleIncomingMidiMessage()
for details of the way that it initialises this value.
@see setTimeStamp, addToTimeStamp
*/
double getTimeStamp() const noexcept { return timeStamp; }
It’s for holding any double value you want to put there. The meaning of that double is up to you, or the code that created the MidiMessage.
But MidiBuffer is completely different - it doesn’t hold MidiMessage objects, it’s a packed format with an integer sample offset for each of its messages. It’s analogous to an AudioBuffer.
OK. So, as to the other part of my question. What about the sampleNumber?
What I really want to know is, when trying to send out Midi messages from my plugin, what should I put in both timeStamp and sampleNumber to ensure that the midi message gets sent out as quickly as possible.
But what does it mean to say “offset from start of sample buffer”? Does it mean “wait this many sample points before sending the message out”?
Because I’d like all the messages to be sent immediately. Which would suggest putting a 0 there. But elsewhere the documentation seems to tell me that sampleNumber defines the ordering and if I try to put two events at the same samplePoint the second will overwrite the first.
So basically there shouldn’t be any problem having both the timeStamp in the MidiMessage I create and the samplePoint be zero when I use midiBuffer::addEvent(myMsg, 0);
Be aware though, that you discretise your midi events by doing so in bufferSize fragments. So it will not sound very musical.
If the midi is captured by the host, it already has a number here, that you should preserve, if not, you should calculate the proper positions of the beat.
The latency of one buffer, that cannot be avoided, is less noticeable than the misplacements of the individual notes to the grid.
One processBlock call is basically: “I’ll tell you what is happening in the next bufferSize samples, and when it happens…”
When you say “not very musical” you mean not quantized to a grid?
That’s OK, I’m not trying to sync. anything to any other pattern (at least not yet). I may add that later. But for now it’s OK if when the event happens, the midi signal gets sent.
No, I mean quantized to a random grid, that is different to anything sensible. Events can only occur every bufferSize samples, if you ignore the sample position inside the block.
Sure, but the buffer is 200ms long, you’d be sending out sudden bursts of messages every 200ms, which is going to sound pretty crappy depending on what these messages are.
If your messages are generated then you should be able to work out their timing correctly. If they’re coming in from a live source you can juce::MidiMessageCollector to help to reschedule them evenly.
Is the buffer not the same as the buffer you set the size of in the DAW then? I though it was something you could choose the length (and therefore frequency) of.
You’re saying you basically get 5 processBlocks per second?