MIDI Plugins - VST Module Architecture vs. VSTi v2.4

DSP, Plugin and Host development discussion.
RELATED
PRODUCTS

Post

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?

Post

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:

Code: Select all

 double secondsSinceStart = samplesSinceStart / sampleRateSinceStart;
 double qnPerBeat = 4.0 / (double) timeSigDenominator;
 double qnPerSecond = bpm / 60.0;
 ppqPosition = secondsSinceStart * qnPerSecond;
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.
tonespace / hypercyclic
Image

Post

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.

Post

cool - the more midi plugin devs out there the merrier :-)

btw scrap my remark about going back to VST2.3. Just found out that Ableton Live does not like anything lower than 2.4 on MacIntel
tonespace / hypercyclic
Image

Post

mucoder wrote:Just found out that Ableton Live does not like anything lower than 2.4 on MacIntel
This is very good to know!

Thanks for the headsup (and wonderful MIDI plugins) :)
Image
stay juicy!

Post

mucoder wrote:cool - the more midi plugin devs out there the merrier :-)
Thanks. :)

I just finished an arpeggiator. Here's a sneak peak:

Image

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. :D

Post

Very nice! Is the attack variation based on the gate param?

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..
Image
stay juicy!

Post

wow, nice stuff indeed! Worthy addition to the midi plug universe :tu:
tonespace / hypercyclic
Image

Post

That sequence demo is really awesome, congrats Leslie.

Post

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

Post

Optomadic wrote:Very nice! Is the attack variation based on the gate param?
I was just messing around with Cobalt's attack as the arp was playing. :)
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..
I'm thinking $25. Thanks for your offer to test it out. I may have that covered, but will let you know. :)

Post

Sounds like a plan Leslie :tu:.
Image
stay juicy!

Post

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.

Post

Is there a guide somewhere on getting VSTi MIDI effects to work in various hosts?
for some hosts tried by yours truly pls see appendix in this manual

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
it's very strange that my plugin performs with dead on timing in some hosts and not others
here is some speculation...

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
tonespace / hypercyclic
Image

Post

mucoder wrote:for some hosts tried by yours truly pls see appendix in this manual
Thanks! I will check it out.
are you sending midi back via loopback adapter? That might cause latency and midi jitter
I don't know what a loopback adapter is. :oops: I just call sendVstEventsToHost to send MIDI messages.
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've tried to makes sure my events are timestamped correctly.

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;
My Advance method looks like this:

Code: Select all

inline bool Clock::Advance()
{
    position += positionIncrement;

    unsigned int oldTickCount = tickCount;

    tickCount = static_cast<unsigned int>(position * ppqn);

    return (oldTickCount != tickCount);
}
It returns true when the tick count has changed.

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...
        }
    }
}
count is the number of sample frames for this (sub)buffer. offset is the offset into the current position of the parent buffer. That is to say, I sometimes break up a buffer into sub-buffers, usually at the boundary of MIDI messages received via processEvents. "i + offset" gives me the deltaFrames value relateve to the overall parent buffer.

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.
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
Good point. I made FL's buffer much smaller than I originally had it. Didn't make a difference.

Post Reply

Return to “DSP and Plugin Development”