MIDI Plugins - VST Module Architecture vs. VSTi v2.4
-
Leslie Sanford Leslie Sanford https://www.kvraudio.com/forum/memberlist.php?mode=viewprofile&u=131095
- KVRAF
- 1640 posts since 4 Dec, 2006
I'm thinking about doing some MIDI fx plugins. I did some searching here and the consensus seems to be:
1) VST Module Architecture is supported by very few hosts
2) VST Module Architecture is buggy (?)
3) Go with VSTi v2.4, make it a synth with a dummy audio output (Cubase seems to need this)
Is that about right?
In a standard VSTi, how would you set up MIDI timing events? Perhaps have your own MIDI clock? Update it every time processReplacing is called and you retrieve the tempo and ppqn values?
Anything else?
1) VST Module Architecture is supported by very few hosts
2) VST Module Architecture is buggy (?)
3) Go with VSTi v2.4, make it a synth with a dummy audio output (Cubase seems to need this)
Is that about right?
In a standard VSTi, how would you set up MIDI timing events? Perhaps have your own MIDI clock? Update it every time processReplacing is called and you retrieve the tempo and ppqn values?
Anything else?
-
- KVRist
- 277 posts since 19 Aug, 2006 from Leuven, Belgium
I'd go for (3), albeit nowadays compiling to v2.3 for compatibility with some picky hosts (you can use 2.4 SDK but disable 2.4 extensions)
timing :
-when host transport is started you can piggyback on host song position in ppq
-when host transport is not started and you want your plug to generate midi output anyway you need to calc your own song position based on count of samples since start of plugin. Something along these lines:
I'd also consider to offer the option of midi out from plug to OS midi loopback devices. Some hosts don't accept midi out directly from a plugin - loopback is a workaround in that case
from the anything else dept: make sure your midi generating algorithm is fully deterministic and is a function of time (ie of songposition). So given the exact time (with sample accuracy) you should know which notes are playing and which ones ain't. With deterministic I mean the outcome of that function should always be the same, given the same input time.
timing :
-when host transport is started you can piggyback on host song position in ppq
-when host transport is not started and you want your plug to generate midi output anyway you need to calc your own song position based on count of samples since start of plugin. Something along these lines:
Code: Select all
double secondsSinceStart = samplesSinceStart / sampleRateSinceStart;
double qnPerBeat = 4.0 / (double) timeSigDenominator;
double qnPerSecond = bpm / 60.0;
ppqPosition = secondsSinceStart * qnPerSecond;from the anything else dept: make sure your midi generating algorithm is fully deterministic and is a function of time (ie of songposition). So given the exact time (with sample accuracy) you should know which notes are playing and which ones ain't. With deterministic I mean the outcome of that function should always be the same, given the same input time.
-
Leslie Sanford Leslie Sanford https://www.kvraudio.com/forum/memberlist.php?mode=viewprofile&u=131095
- KVRAF
- Topic Starter
- 1640 posts since 4 Dec, 2006
Thanks for your reply, mucoder. I've managed to get a very primitive VST v2.4 MIDI metronome built.
So I'm confident I'm on the right track.
-
- KVRist
- 277 posts since 19 Aug, 2006 from Leuven, Belgium
-
- KVRAF
- 6111 posts since 18 Oct, 2007
-
Leslie Sanford Leslie Sanford https://www.kvraudio.com/forum/memberlist.php?mode=viewprofile&u=131095
- KVRAF
- Topic Starter
- 1640 posts since 4 Dec, 2006
Thanks.mucoder wrote:cool - the more midi plugin devs out there the merrier
I just finished an arpeggiator. Here's a sneak peak:
Here's me testing it with Cobalt using Cantabile:
Arp Test
I'm excited by the results. This is a whole new arena to play in.
-
- KVRAF
- 6111 posts since 18 Oct, 2007
-
- KVRist
- 277 posts since 19 Aug, 2006 from Leuven, Belgium
-
Leslie Sanford Leslie Sanford https://www.kvraudio.com/forum/memberlist.php?mode=viewprofile&u=131095
- KVRAF
- Topic Starter
- 1640 posts since 4 Dec, 2006
Still playing around with the arpeggiator by running it through Cobalt. I'm amazed all over again at the job Atomsplitter did for me in creating some of Cobalt's factory presets. This is one of his:
Falling Stars
Falling Stars
-
Leslie Sanford Leslie Sanford https://www.kvraudio.com/forum/memberlist.php?mode=viewprofile&u=131095
- KVRAF
- Topic Starter
- 1640 posts since 4 Dec, 2006
I was just messing around with Cobalt's attack as the arp was playing.Optomadic wrote:Very nice! Is the attack variation based on the gate param?
I'm thinking $25. Thanks for your offer to test it out. I may have that covered, but will let you know.Whats the pricing going to be for this? Do you need testers? I would be happy to try it out in several hosts/setups. Let me know..
-
Leslie Sanford Leslie Sanford https://www.kvraudio.com/forum/memberlist.php?mode=viewprofile&u=131095
- KVRAF
- Topic Starter
- 1640 posts since 4 Dec, 2006
Is there a guide somewhere on getting VSTi MIDI effects to work in various hosts?
For example, it took me maybe 2 minutes to figure out how to set up my arp to feed Cobalt in Reaper. And the timing and performance is rock solid.
It took me quite a bit longer to figure out how to create the same set up in FL Studio, and the timing is all over the place. By that I mean that the arpeggiated patterns aren't played back with the correct timing. I've not been able to zero in on why yet.
Ditto with Sonar. I think I got things working in Sonar by accident, but there, too, the timing is off.
On the other hand, ext, like Reaper, is rock solid. Cantabile is solid, too.
So I'm looking for any advice from folks who have been down this road. I guess I have two questions: What steps do you need to take to get a VSTi MIDI effect working in various hosts (with each host having a different set of steps)? What I'd like to do is include a guide in my arp's manual detailing how to get it running in various hosts. And what could be the source of my timing problems in some hosts?
It's possible that there's a bug in my algorithms, but if so, it's very strange that my plugin performs with dead on timing in some hosts and not others.
For example, it took me maybe 2 minutes to figure out how to set up my arp to feed Cobalt in Reaper. And the timing and performance is rock solid.
It took me quite a bit longer to figure out how to create the same set up in FL Studio, and the timing is all over the place. By that I mean that the arpeggiated patterns aren't played back with the correct timing. I've not been able to zero in on why yet.
Ditto with Sonar. I think I got things working in Sonar by accident, but there, too, the timing is off.
On the other hand, ext, like Reaper, is rock solid. Cantabile is solid, too.
So I'm looking for any advice from folks who have been down this road. I guess I have two questions: What steps do you need to take to get a VSTi MIDI effect working in various hosts (with each host having a different set of steps)? What I'd like to do is include a guide in my arp's manual detailing how to get it running in various hosts. And what could be the source of my timing problems in some hosts?
It's possible that there's a bug in my algorithms, but if so, it's very strange that my plugin performs with dead on timing in some hosts and not others.
-
- KVRist
- 277 posts since 19 Aug, 2006 from Leuven, Belgium
for some hosts tried by yours truly pls see appendix in this manualIs there a guide somewhere on getting VSTi MIDI effects to work in various hosts?
however, would be really useful to have a wiki with a compendium of such stuff for any host under the sun. Am willing to contribute the little I know if someone would host the wiki...
as to
here is some speculation...it's very strange that my plugin performs with dead on timing in some hosts and not others
are you sending midi back via loopback adapter? That might cause latency and midi jitter
if sending midi directly to host, do you make sure your midi-out events are properly timestamped with sample pos of the ProcessReplacing samplebuffer that they are supposed to fire at?
btw not all hosts use same buffer size for ProcessReplacing() so if timestamps are off, this might make a bigger difference in hosts with larger buffers
-
Leslie Sanford Leslie Sanford https://www.kvraudio.com/forum/memberlist.php?mode=viewprofile&u=131095
- KVRAF
- Topic Starter
- 1640 posts since 4 Dec, 2006
Thanks! I will check it out.mucoder wrote:for some hosts tried by yours truly pls see appendix in this manual
I don't know what a loopback adapter is.are you sending midi back via loopback adapter? That might cause latency and midi jitter
I've tried to makes sure my events are timestamped correctly.if sending midi directly to host, do you make sure your midi-out events are properly timestamped with sample pos of the ProcessReplacing samplebuffer that they are supposed to fire at?
I have a MidiClock class. This class has a PPQN resolution. Currently I'm using 96. What I do is calculate an increment variable (of type double) that increments the PPQN position each time the clock's Advance method is called. I calculate this increment value any time the sample rate or tempo changes:
Code: Select all
positionIncrement = tempo / 60.0 / sampleRate;
Code: Select all
inline bool Clock::Advance()
{
position += positionIncrement;
unsigned int oldTickCount = tickCount;
tickCount = static_cast<unsigned int>(position * ppqn);
return (oldTickCount != tickCount);
}
Inside my arp's processReplacing method, I have a loop that looks something like this:
Code: Select all
for(unsigned int i = 0; i < count; i++)
{
if(clock.Advance())
{
unsigned int deltaFrames = i + offset;
if(clock.GetTickCount() % ppn)
{
// Do stuff...
}
}
}
ppn is the length in MIDI ticks of whatever note length I'm interested in. For example, if my arp is outputing 1/8 notes, ppn would be 48, assuming a PPQN resolution of 96.
I update my MidiClock when the position changes. I ask the host per-buffer what the PPQN position is. I then pass that along to my MidiClock. This is to ensure that its position is locked into that of the host.
In practise, I've found when this update occurs that the difference between my clock's position value and that of the host is very, very small. Infintesimally small. But not in FL Studio. The difference is still small, but perhaps large enough to cause a problem.
However, when I use my arp in FL, it doesn't just sound like it's off by a little, it sounds flat out sluggish, like something more serious is wrong besides missing a tick here or there.
Good point. I made FL's buffer much smaller than I originally had it. Didn't make a difference.btw not all hosts use same buffer size for ProcessReplacing() so if timestamps are off, this might make a bigger difference in hosts with larger buffers


