What the World Needs: a New Plug-in Format!

DSP, Plugin and Host development discussion.

Does the World Need a New Plug-in Standard?

Poll ended at Sun Jan 25, 2009 7:38 pm

No! There are too many already!
62
40%
Yes! VST 3 isn't the answer!
41
26%
That's the wrong question.
26
17%
That's the wrong question.
26
17%
 
Total votes: 155

RELATED
PRODUCTS

Post

My suggestions..

Dont use COM. Dont use a specific binary layout because you can kludge it into a C++ class/vtable or interface. A kludge is always a kludge, and shouldnt be part of a public API.

Use structs of function pointers for the API.

Have the first field in the struct be a pointer for the local object.

Have the first function return the size of the struct. This means the struct / API can expand without causing problems. The win32 api does this, it often has the first field of the struct as the size of the struct. That means you can copy it without losing information.

Have explicit calling conventions.

Don't have unnecessary limitations, like limited string lengths, or block sizes.

Dont worry about function call overhead on anything but audio / event functions. For GUI, or general API matters, it's completely irelevant because the cost of a wrapper function will be insignificant in comparision to the memory copys / allocations, string processing, gui redraws.. ect.. that will be going on.

Post

Stupid American Pig wrote:I vehemently oppose this standard as it is an unauthorized use of the initials S.A.P... :tantrum:
Did I miss anything? Are you a bodysnatcher or did you just steal Bones' footer?

:shock:

Post

nollock wrote:My suggestions..

Dont use COM. .... A kludge is always a kludge, and shouldnt be part of a public API.

Use structs of function pointers for the API.

Have the first field in the struct be a pointer for the local object.
You just described the basic COM structure perfectly. :-) , like VST3, like Firefox, like many plugin APIs.

Like I said, the problem with proposing an unfamiliar technique like COM, is that people knee-jerk reject it (then go on to re-invent something dam near identical).

Best Regards, :-)
jeff

Post

plugins are written in C++,
If that is *actually* true, then the proper API would be returning a pointer to a pure virtual (abstract) base class. I've done that before, but the problem is that other languages will have to be separately wrapped (maybe not so big a problem), and you're also locked to the ABI of the host compiler. On Windows, where some people insist on using MinGW, that would cause confusion, because MSVC and GCC are not binary compatible for Vtable layout.

Believe me, it would be a lot simpler and neater to specify the plug-in as:

Code: Select all

class I_Plugin {
  public:
    virutal void Suspend() = 0;
    virutal void Resume = 0;
    virtual void Process( args go here ) = 0;
};

__declspec(dllexport) I_Plugin *MakePlugin(I_Host *host);
But my current feeling is that this causes too much consternation. Am I mistaken? Is this a better approach than C-struct-with-function-pointers? (Note that you'd have to define the ABI for each host OS -- MSVC for Windows, GCC 4.x for MacOS X and Linux)

I oppose putting plug-in information separate from the plug-in binary itself. If you really want that information in a host, you can build that information the first time you scan the plug-in. Separting information makes it quite easy to shoot yourself in the foot, where you describe some pin differently from how it's implemented. Also, I think that stereo audio (or 7.1 audio) should go into ONE pin if it's a coherent trunk of channels. I like separation between "pins" and "busses," because understanding what is processing, what is side-chain etc is easier.

GMPI doesn't just bind you to an ABI, it also doesn't properly describe the inputs and outputs even enough to do stereo coherence from the host (at least not without guessing). The "gain" plug-in can't be used with any number of channels in that model (or that of LV2). The range of "gain" isn't documented. The host can't create any kind of usable GUI for the plug-in, unless you define that all parameters are in the range 0..1 (and then how do you display a value that makes sense to the user, like dB?)
Apparently, there are some legal, mostly non-controverisal subjects you can't talk about on KVR, or even mention in your sig. Unfortunately, the guidelines don't actually talk about them, so the only way to find out is trial and error.

Post

So, who would prefer an API such as the following?

Code: Select all

class Vocoder : BaseEffect
{
  public:
    Vocoder(Host *host) : BaseEffect(host, L"My Cool Vocoder")
    {
      AddInputBus(L"Carrier", carrier_);
      AddInputBus(L"Modulator", modulator_);
      AddOutputBus(L"Vocoder", vocoder_);
      AddInputBus(L"MIDI In", midiIn_);
    }

    void Process(unsigned int count)
    {
      for (unsigned int i = 0; i < count; ++i)
      {
        //  this does ring modulation, not vocoding, but you get the idea
        vocoder_[0][i] = carrier_[0][i] * modulator_[0][i];
        vocoder_[1][i] = carrier_[1][i] * modulator_[0][i];
      }
    }

    float *carrier_[2];
    float *modulator_[1];
    float *vocoder_[2];
    MidiEvent *midiIn_[1];
 }
Apparently, there are some legal, mostly non-controverisal subjects you can't talk about on KVR, or even mention in your sig. Unfortunately, the guidelines don't actually talk about them, so the only way to find out is trial and error.

Post

a c++ interface is more efficient in some ways, but also suffers from it's own problems.

i'd imagine such an interface would work fine in most cases - gcc (mingw) actually does have a msvc compatible vtable.

Post

Believe me, it would be a lot simpler and neater to specify the plug-in as:

Code: Select all

class I_Plugin {
  public:
    virutal void Suspend() = 0;
    virutal void Resume = 0;
    virtual void Process( args go here ) = 0;
};
It is nice... (actual GMPI API)

Code: Select all

class IMpPlugin : public IMpUnknown
{
public:
   virtual int32_t open() = 0;
   virtual int32_t setBuffer( int32_t pinId, float* buffer ) = 0;
   virtual void process( int32_t count, MpEvent* events ) = 0;
   virtual int32_t recieveMessageFromGui( int32_t id, int32_t size, void* messageData ) = 0;
};
and you're also locked to the ABI of the host compiler.... because MSVC and GCC are not binary compatible for Vtable layout.
True in general, the exception is - pure virtual functions using standard calling convention. Like I said, Firefox and many other big, cross platform, purist-driven projects use that technique. The Above code works on GCC, MS VCC, Borland, Wattcom, Windows, Linux... everything.
But my current feeling is that this causes too much consternation.
Tell me about it ;-)

So forget C++. It's better mayby to use the C version of the same thing...

Code: Select all

typedef struct {
  void* functionTable;
} Plugin;
i.e. The plugin is a struct, the first member is a list of function pointers, (plain C standard calling convention).

The function list looks like...
1 - Provides the API version (so you can safely figure out what the other pointers represent.
2 - creates plugin instances.
3 - destroys the plugin.
next are...
4 - Suspend( Plugin* p, ... )
5 - Resume( Plugin* p, ... )
6 - Process( Plugin* p, ... )
..etc.
GMPI doesn't doesn't properly describe the inputs and outputs even enough to do stereo coherence from the host .
True, easy enough to add though.
The range of "gain" isn't documented... how do you display a value that makes sense to the user, like dB?)
The default is 0->1, but you can specify e.g. RangeMinimum="5" RangeMaximum="10".

Your requirements may vary from mine of course, That's cool. I'm just suggesting some (hopefully) useful ideas.
So, who would prefer an API such as the following? (snipped)
That's nice because:
-it's compact
-it's clear

One disadvantage:
-Strings are entered directly in source code. Bit difficult to manage other languages. GMPI and LV2 using XML-type syntax in a seperate file for such stuff. Makes translation easy (even for end-users).

Best Regards, looking good!
Jeff

Post

The plugin is a struct, the first member is a list of function pointers
Which is almost exactly what I initially proposed in SAPS_plugin.h in the download file :-)
http://www.enchantedage.com/saps

The next question is then: Does it matter much if the interface between plug-in and host is C structs or pure abstract base classes? A simple wrapper that you include (similar to the VST SDK) could easily be made to map the last C++ class to whatever mechanism is used by the host, so selecting based on language compatibility and performance seems to be the main goal?


How about some other design choices, such as:
- plug-ins are represented by bitmaps and names (mainly useful when managing plug-ins, such as enabling/disabling)
- effects, exposed by plug-ins, are represented by bitmaps and names (typically what the user sees when interacting with effect palettes or whatnot)
- busses, exposed by effects, are only represented by names (most DAW-like hosts won't have a place to put these, anyway)

- floating point for audio transport
- busses are not interleaved (this seems to be what everyone does)

- buffer alignment rules -- could there be a rule that all blocks have the same number of sample frames?
- The main reason to not do the same number of samples in each process call is DirectSound-style interfaces, but those are really slow on Windows Vista. All the high-performance interfaces (ASIO, KS, WAVE_RT) are fixed block size.
- Are the current Mac buffers fixed size (like ASIO) or variable size (like DirectSound)?


Finally: I don't want to separate the functionality of the pins from the pin implementation, because doing that will lead to all kinds of gotchas. Indirecting strings to do localization is quite easy, no matter what the plug-in API is, and can likely be solved outside of a plug-in API.
Apparently, there are some legal, mostly non-controverisal subjects you can't talk about on KVR, or even mention in your sig. Unfortunately, the guidelines don't actually talk about them, so the only way to find out is trial and error.

Post

you don't need to worry about buffer sizes, just do triple-buffering.

Post

Honestly I won't try to do a plugin format
if I've never done some serious plugin, both instrument and effect with stuff like surround capabilities, internal sequencer and other advanced stuff.
No offense, but it's trying to do a compiler when you don't know all the language requirements.

VST 3 looks good as soon as they fixed the CC thing.
The main issue is that dev don't want to support yet another format.
As soon as they do a VST 3 that automatically is being wrapped as a 2.4 plugin, people will begin to support it.

I'm sure they can come up with some very easy default FX and instrument class so people can do very quickly VST 3 stuff.

my 2 cents.
Olivier Tristan
Developer - UVI Team
http://www.uvi.net

Post

I agree with otristan. I don't care so much about the surround stuff etc., but there are many others that do.
Anyway imagine you are a host/plugin developer - would you really give a minute checking out a new plugin format. I am and I won't :-). I would mean lots of work and nothing good coming from it. You would need to find some very common host developer that would say "ok, I'll remove support for VST and DXi and use your plugin interface only!" :D. And that is riddiculous.
I agree that VST is archaic and sucks, DXi is overcomplicated and COM dependent (which I think is suicide)... But that's how it is :-(. Too late to do something about it.
Well maybe you can develop your own format (which however must be competitive and, from what I have read here, it is very not) and also adapters to all existing formats and debug it for all existing hosts :-). So be prepared to 2-3 years of work, buying every existing hosts, and of course no income :-D.

Sad world...
Vojtech
MeldaProduction MSoundFactory MDrummer MCompleteBundle The best plugins in the world :D

Post

There are already lots of plugin formats around and I doubt if this makes much chance of getting adopted. I think the biggest problems with VST are lack of documentation and stability as all plugins run in the same address space and can crasht the host and one another. My thoughts are about a plugin format in which each plugin runs in its own separate process.

//Daniel

Post

Sorry but thanks but no thanks.

We have VST 2.x, VST 3.x, VST (Mac), RTAS, TDM, DX, AU... we don't need another standard. Maybe all those folks would finally decide to go for ONE standard, this'd be something. But this is highly unlikely within the next decade.
[ Mix Challenge ] | [ Studio Page / Twitter ] | [ KVRmarks (see: metering tools) ]

Post

O.K. i finally voted. i voted for 'That's the wrong question' and i think the right question would be something like: What could be done to make the industry agree on one common standard? i think it is non-controversy that the existence of so many standards is a hassle for all involved parties: host-devs, plugin-devs and users. so, one single common standard would be indeed desirable. and that should be public domain. it's probably indeed not realistic to expect that to happen within the next decade - but if there's development into that direction, i'd be all for it
My website: rs-met.com, My presences on: YouTube, GitHub, Facebook

Post

As good as the author's intentions no doubt are, I also don't think any major host vendors will adopt the new plugin format no matter how good or innovative or whatever it may be. It's hardly a coincidence that Steinberg hosts support only VST, ProTools recognizes nothing but RTAS and TDM, and for Logic it's AU or no go. In marketing terms this is probably called "establishing a customer base".

As much as I'd love for the forces that be to join up and make things easier for both developers and end users, none of them are going to make a switch anytime soon. And unless all (or at the very least most) hosts support the new format, all you'll be doing is adding to the confusion.

$.02,

-- dj!

Post Reply

Return to “DSP and Plugin Development”