Well this is a kick in the nuts: VST2 plug-ins

DSP, Plugin and Host development discussion.
Post Reply New Topic
RELATED
PRODUCTS

Post

Hello,
I'd like to tell my story of how I stopped worrying and finally loved LV2. :)

Putting LV2 in our plugins (and supporting Linux) was the idea of Ethan Reker from Cut Though Recordings for his own plugins, we use the same framework for plug-ins. At first I was uninterested, it seems so ugly with the Turtle syntax and all the... strange things. It's stupid FOSS for Linux users only! They don't understand our commercial needs :x

Actually after the both of us implement it in 2019 (necessitates to generate TTL from inside the plugin at build to be practical) it striked both of us as being really well-made. The implementation time was measurably less than for the VST2/VST3/AAX plugin clients, and the implementation size was also less.

We went to the IRC to complain that (obviously!) arbitrary byte chunks were missing but actually it was all available in the state API, it's all a matter of understanding why things are the way they are.

Once you read Turtle/.ttl syntax it all appears as it is: a way to have the last plugin format for extensibility. There would be no need for "MTS" or "The ARA Spec" in LV2, as vendors would be able to create the "ARA" LV2 extension, host it online with a scheme, and that would be integrated it into the spec in a staged response. So it is a format uniquely positionned to being extended by multiple vendors and not break into a constellation of private specs, like VST2.4 was (NKS, ARA, MTS).

Schemas URL don't need to perform DNS look-up of course, those can be cached / builtin. LV2 comes with quite strong opinions (like: semantically charged, extensibility) but the more you dig, the more sensical it all becomes.

So I fear people are disregarding LV2 because of it's unfamiliarity/strangeness rather than on its merit. I guarantee that if you go through the experience of implementing the LV2 client (LV2 host is likely more difficult) you will discover a perfectly adequate format for effects and synths alike.

More over, it has an existing community, implementers, and stewardship. Did I mention the license?
http://drobilla.net/2019/11/11/lv2-the- ... -ugly.html
Checkout our plug-ins here.

Post

Urs wrote: Sun Apr 25, 2021 11:29 am I feel the complete opposite. A dispatcher requires everyone to maintain some kind of big enum that has to be in sync on all sides and thus requires quite a process & committee to get extensions adopted. It also means, the standard constantly grows, whereas the beauty of optional extensions is that the SDK itself remains small & steady. Extensions such as NKS, ARA or ODD MTS could be implemented inside the standard without pushing them onto those who don't need them.
yes, sure. when i was talking about extensibility, i was thinking about it from the interface maintainer's point of view, not the user. but i was actually comparing it to the suggested alternative of having specific callback functions for specific functionality. is that also what you are talking about here? how does this optional extensions stuff work? did NKS, ARA, etc. introduce new callbacks to an existing standard? the wikipedia page says: "Audio Random Access (commonly abbreviated to ARA) is an extension for audio plug-in interfaces, such as AU, VST and RTAS"

https://en.wikipedia.org/wiki/Audio_Random_Access

wouldn't that break backward compatibility? i mean, wouldn't a host just crash when it tries to call an ara-specific callback on a plugin that doesn't implement it? or can the host figure out beforehand if a particular vst-plugin is ara-enabled or something? how does that work? i've never worked with any of those mentioned interfaces - i had to google them to figure out what they are. for ARA, i found a link linking to some kvr thread, opened it:

viewtopic.php?f=33&t=356880

only to discover that i apparently did start it myself :hihi: i've totally forgotten that this is a thing
Last edited by Music Engineer on Sun Apr 25, 2021 1:00 pm, edited 1 time in total.
My website: rs-met.com, My presences on: YouTube, GitHub, Facebook

Post

Urs wrote: Sun Apr 25, 2021 11:29 am
Music Engineer wrote: Sun Apr 25, 2021 10:57 amthe dispatcher approach is clearly preferable due to easy extensibility and lean ABI.
I feel the complete opposite. A dispatcher requires everyone to maintain some kind of big enum that has to be in sync on all sides and thus requires quite a process & committee to get extensions adopted. It also means, the standard constantly grows, whereas the beauty of optional extensions is that the SDK itself remains small & steady. Extensions such as NKS, ARA or ODD MTS could be implemented inside the standard without pushing them onto those who don't need them.
While I don't have strong feelings for one design or another, there's at least a metric ton of different ways you can add optional extensions to whatever standard. The most obviously general one is to just add more library exports into the DLL the same way you can build a single binary that works as a VST2 and VST3 and AU and anything and everything else at the same time, but you can also have a base dispatcher opcode to query for additional ranges or secondary dispatchers or callback tables or whatever floats your boat.

Post

It's stupid FOSS for Linux users only!
i don't think FOSS is stupid at all! :-P
necessitates to generate TTL from inside the plugin at build to be practical
...yeah...that's for these static manifest files, right? i mean, i have nowadays only a single plugin to maintain (that acts as shell for all my actual plugins (which are therefore not actually plugins anymore but built directly into this thing)) - so i guess, i could just write the ttl manually once and for all. but is my interpretation correct, that when the plugin I/O configuration or the set of parameters changes, i have to generate a new ttl configuration file at runtime? is this what the "DynamicManifestGenerator" is about? that would seem a bit quirky to me - but if that's what it takes, then so be it. i've not yet looked very closely. in the talk, Filipe said, they are planning to switch to json at some point, which is certainly more readable. (he also seems to strongly dislike xml - why do so many people seem to hate xml? what's wrong with it?)
Last edited by Music Engineer on Sun Apr 25, 2021 4:15 pm, edited 1 time in total.
My website: rs-met.com, My presences on: YouTube, GitHub, Facebook

Post

Music Engineer wrote: Sun Apr 25, 2021 12:59 pm(he also seems to strongly dislike xml - why do so many people seem to hate xml? what's wrong with it?)
Because it takes about half a megabyte worth of code to try to parse is properly.

edit: Basically when you have a file-format that allows for this kinda of non-sense you have a problem.

Post

"The usage of function pointers was inspired by Reapers' Control Surface DLL interface and the way BASS (Unseen developments) handles DLL interfacing.
(And the rest of the world...)"
It certainly is different from old skool technologies like VST2 or error-prone COM C++ interfaces (almost not extensible to other Languages). :)

Post

mystran wrote: Sun Apr 25, 2021 1:08 pmBecause it takes about half a megabyte worth of code to try to parse is properly.

edit: Basically when you have a file-format that allows for this kinda of non-sense you have a problem.
ok - thanks, for the info. i've never tried to write my own xml parser. i'm just using juce's (for presets and pretty much anything). it's less then 1000 lines:
https://github.com/juce-framework/JUCE/ ... cument.cpp
so should i assume, it's not proper? so i guess, someone could bring down my plugins with a malicious preset? but then, who would do such a thing and why (...i don't really expect these questions to be answered - don't want to derail the thread)
My website: rs-met.com, My presences on: YouTube, GitHub, Facebook

Post

Music Engineer wrote: Sun Apr 25, 2021 12:40 pmwouldn't that break backward compatibility? i mean, wouldn't a host just crash when it tries to call an ara-specific callback on a plugin that doesn't implement it? or can the host figure out beforehand if a particular vst-plugin is ara-enabled or something? how does that work?
First off, ARA, NKS etc. are just examples of extensions that could have become part of an open standard, if there was an open standard that got widely adopted.

The idea is that there's a single callback that the host can pass a query with a well defined URI-style pattern and, if the extension is available, receives a pointer to an object that represents access to the plug-in's implementation of that extension. I guess that's pretty much what LV2 does in these ttl files, but wrapped into code rather than type-down-lists. The general idea is to avoid dozens of exports, possibly with various libraries to link to in favour of a consistent kind of interface. That's something I've seen the other day and I found it quite elegant compared to the things I knew.

Post

If a few big companies adopted LV2, there's no guarantee that it would catch on, but people would certainly notice. People have been interested in FL Studio adopting it in the past, though sadly they lost a main developer from what I understand. https://forum.image-line.com/viewtopic.php?t=189931

Post

Add Harrison Mixbus to that list of DAWs that support LV2.

Post


Post

...yeah...that's for these static manifest files, right? i mean, i have nowadays only a single plugin to maintain (that acts as shell for all my actual plugins) - so i guess, i could just write the ttl manually once and for all. but is my interpretation correct, that when the plugin I/O configuration or the set of parameters changes, i have to generate a new ttl configuration file at runtime?
You have to generate a new ttl if you parameters set, I/O, or presets change. But it doesn't have to be dynamic or at runtime, it can be static (written by hand or a tool who is fed metadata). For our use case, it is generated in an additional extern(C) callback, at build time. The build tool call into the plugin to generate the ttl data. Inside the plugin, a client is instantiated just for the sake of reading those presets, parameters data, etc. which aren't declarative.

is this what the "DynamicManifestGenerator" is about?
The dynamic manifest extension is something niche and I don't think it's needed. Not an expert.
Filipe said, they are planning to switch to json at some point, which is certainly more readable. (he also seems to strongly dislike xml - why do so many people seem to hate xml? what's wrong with it?)
(I like XML!) But in this case I hope they stick to their guns with Turtle/.ttl, else it's essentially another format. For sure, it would indeed be a tiny bit easier for adoption, just because of familiarity and existing parsers.
Turtle/RDF is just a list of triples.
Last edited by Guillaume Piolat on Sun Apr 25, 2021 3:06 pm, edited 2 times in total.
Checkout our plug-ins here.

Post

The Good the Bad and the Ugly from David Robillard.

http://drobilla.net/2019/11/11/lv2-the- ... -ugly.html

For hobbyists and beginners just looking for a casual tutorial about getting started, this might be helpful.

http://ll-plugins.nongnu.org/lv2pftci/

Post

Urs wrote: Sun Apr 25, 2021 2:01 pm The idea is that there's a single callback that the host can pass a query with a well defined URI-style pattern and, if the extension is available, receives a pointer to an object that represents access to the plug-in's implementation of that extension. I guess that's pretty much what LV2 does in these ttl files, but wrapped into code rather than type-down-lists. The general idea is to avoid dozens of exports...
i actually think, we are totally on the same page here. the dispatcher approach is also about avoiding dozens of exports and is actually compatible with such an extension system. you would just need some sort of "getExtension" opcode. what i was comparing it against was something like Eduur suggested and looks like dozens of exports indeed:
procedure SetEditor(form:TForm);
procedure AddParameters;
procedure Process(const Inputs,Outputs: TDAVArrayOfSingleFixedArray; const SampleFrames: Cardinal);
procedure SetSampleRate(rate:single);
procedure OnParameterChanged(Sender: TObject; const Index,Value: Integer);
function ParamCount:integer;
procedure Close;
procedure SetTempo(tempo:single);
procedure ProcessMidi(Sender: TObject; MidiEvent: TMidiEvent);
procedure LoadFromStream(stream: TMemoryStream; index: integer; isPreset: boolean);
procedure SaveToStream(stream: TMemoryStream; index: integer; isPreset: boolean);
function GetFormClass:TFormClass;
so, the primary API could use a single callback (the dispatcher) whose opcodes could define the officially supported primary functionality curated by the maintainer and third parties could still define their own extensions independently from that
My website: rs-met.com, My presences on: YouTube, GitHub, Facebook

Post

Guillaume Piolat wrote: Sun Apr 25, 2021 2:58 pm You have to generate a new ttl if you parameters set, I/O, or presets change. But it doesn't have to be dynamic or at runtime, it can be static
well, i mean, if those things change at runtime. for example, when the user adds a new eq-band and the plugin therefore gets a few more parameters. i think, it's a somewhat complicated way to communicate such changes to the host via a generated string in some weird format. but hey - at least, it's possible at all - which wasn't the case in vst2 (if i'm not mistaken)
My website: rs-met.com, My presences on: YouTube, GitHub, Facebook

Post Reply

Return to “DSP and Plugin Development”