Page 3 of 3
Re: Beginner's guide to MIDI coding in VM
Posted: Mon Jun 19, 2023 8:11 am
by Waverley Instruments
Centripidity wrote: ↑Mon Jun 19, 2023 2:18 am
I'm pretty sure that's true. When I started VM development I made the mistake of trying to time events using calls to system timing methods like System.nanoTime()
In ProcessSample() if you base your timing calculations on counters and
sample time using Values.MsPerSample, I've found timing calculations to be spot-on. But they would be, right?
Re: Beginner's guide to MIDI coding in VM
Posted: Mon Jun 19, 2023 8:17 am
by Waverley Instruments
ColinP wrote: ↑Sun Jun 18, 2023 11:32 pmHowever, EXTERNAL MIDI signals don't exist in sample-time they exist in something closer to real-time so there's potential for jitter there unless there's some timestamping of incoming and outgoing MIDI messages going on behind the scenes to compensate.
My bet would be that the behind the scenes thing is the MidiMessageCollector in JUCE:
https://docs.juce.com/master/classMidiM ... ector.html
I think it's pretty cool the good folks at CA decided to protect VM developers from dealing with buffers and their inherent complexity, so we can focus purely on processing at the sample level. I for one, thank them for it! :
Re: Beginner's guide to MIDI coding in VM
Posted: Mon Jun 19, 2023 9:20 am
by ColinP
Yup, that's the one.
Cheers Rob that makes a lot of sense as CA did once indicate that VM is indeed written on top of JUCE.
So it's safe to assume that incoming MIDI uses timestamp compensation so that there's no incoming MIDI jitter. I'm not fully awake at the moment but I think that means that incoming MIDI latency will exactly match outgoing audio latency. So the gap between a note being played on a keyboard and the note being output by your DAC will be twice the latency set in audio/MIDI settings. I need coffee to be sure.
The only question then is does the same thing happen with MIDI output? Hopefully the answer is yes and MIDI messages are timestamped on their way out too - so that if say we send a ShortMessage.TIMING_CLOCK via a VoltageMIDIJack's AddMessage() in sample 37 of the current audio buffer it actually gets ouput by the MIDI driver at exactly the same time as sample 37 in the audio buffer is output by the audio driver.
Presumably this does happen so any timing discrepencies seen in external MIDI kit must be caused by something other than VM.
Re: Beginner's guide to MIDI coding in VM
Posted: Mon Jun 19, 2023 9:33 am
by utdgrant
ColinP wrote: ↑Mon Jun 19, 2023 7:07 am
I doesn't need to be that complicated, each module output just has a single value buffer. This value might actually be stored inside cable or bus objects but effectively VM remembers the state of every output from the previoue sample.
So the main thread does something like this...
Code: Select all
while audio buffer is not full
for each module in patch
for each input in module
inputValue = 0
for each cable connected to input
inputValue += value from cable (the value being the output of the previous sample calculation)
run ProcessSample() in module
store values of any cables attached to the audio output sockets in the audio buffer
sleep until audio driver empties the audio buffer by making a copy of it
In the case of Poly cables, if you have multiple cables going into a single input jack, then the addition loop ("inputValue += value" above) takes place for each individual 'voice' channel in turn. So, there's an extra "for each voice channel" loop inside the "for each cable" loop in the code block above.
By contrast, multiple MIDI cables going into a single MIDI input jack will merely
concatenate the message lists from all connected MIDI sources during that sample period. VM will
not sum the data values of individual MIDI events. Nor is there any form of intelligent 'merging' of the MIDI data. You could
potentially (but unlikely) end up with unbalanced interlacing of note-on and note-off messages, leading to hung notes, etc.
So that is a situation you may have to think about and account for when developing MIDI modules.
CAVEAT: I'm not able to use VM / VMD at the moment, so the stuff I wrote above about multiple MIDI cables going to a single MIDI Input jack is from my (failing) memory. I'll double-check tonight.
Re: Beginner's guide to MIDI coding in VM
Posted: Mon Jun 19, 2023 9:39 am
by ColinP
Yeah, that makes sense Grant.
Also AFAIK hardware MIDI mergers work the same way so one always has to cope with interleaved MIDI messages.
Re: Beginner's guide to MIDI coding in VM
Posted: Mon Jun 19, 2023 3:06 pm
by ColinP
Hang on a minute. I've had some coffee...
If there really is timestamp compensation for MIDI output then how come so many people have bought the Adroit MIDI Compensator? Including one person just yesterday.
If there was compensation then when you hook up MIDI Compensator's MIDI OUT to an external Synth, wire the module's AUDIO BEEPS OUT to VM's audio out and engage the TEST button then the external synth would only sound at the same time as the test beep (even if you used a ridiculouly large audio buffer) when the delay setting was zero - making the module completely pointless.
This module is a MIDI delay line and its whole purpose is to compensate for the fact that VM's MIDI output isn't timestamp compensated. Basically it delays VM's MIDI output by a tunable number of milliseconds in order to allow VM's audio sufficient time to catch up with the faster response of hardware synths, especially analog synths which have practically no latency (other than the tiny MIDI transmission overhead).
My hardware synths are in storage at the moment so I can't test it again but there's a 7 day demo period on MIDI Compensator so anyone can test whether it works or not. Nobody who has paid for the module has ever complained and I'm sure it worked last time I used it. Allowing me to exactly sync the attack of a VM generated sound with the attack of an externally generated one by applying a delay to VM's MIDI output in order to slooow down the external synth's response time.
Re: Beginner's guide to MIDI coding in VM
Posted: Mon Jun 19, 2023 8:41 pm
by utdgrant
utdgrant wrote: ↑Mon Jun 19, 2023 9:33 am
By contrast, multiple MIDI cables going into a single MIDI input jack will merely
concatenate the message lists from all connected MIDI sources during that sample period. VM will
not sum the data values of individual MIDI events. Nor is there any form of intelligent 'merging' of the MIDI data. You could
potentially (but
unlikely) end up with unbalanced interlacing of note-on and note-off messages, leading to hung notes, etc.
Actually, it's an awful lot
more likely than I had imagined. Even this simple patch can generate hung notes all too easily:
- HungMIDINotes.jpg (85.39 KiB) Viewed 9421 times
Re: Beginner's guide to MIDI coding in VM
Posted: Mon Jun 19, 2023 8:55 pm
by ColinP
Yeah it's very easy to trip MIDI up (or any state based system - another reason I adopted V/Bar for LSSP rather than clocks). The most common cause of hanging notes is just repatching cables because if you unplug a cable going to a module that has a note on state it won't get the note off.
It was why I released MIDI Panic for free.
Re: Beginner's guide to MIDI coding in VM
Posted: Mon Jun 19, 2023 9:03 pm
by ColinP
By the way when coding MIDI modules that have state you should always handle All Notes Off MIDI messages by reseting your data.
Re: Beginner's guide to MIDI coding in VM
Posted: Tue Jun 20, 2023 2:36 pm
by Steve W
Thanks to everyone here for sharing some of the nuances of what VM does (and doesn't do) with regard to midi data!