Tremus / CPLUG

C wrapper for VST3, AUv2, CLAP audio plugin formats
Other
98 stars 8 forks source link

Changing latency and parameters dynamically #3

Open Photosounder opened 4 months ago

Photosounder commented 4 months ago

Is there a way to change things that aren't typically changed dynamically? I have two things in mind:

Now that I think about it I also can't make CPLUG_NUM_PARAMS a global variable because different instances of the same host plugin would host different modules with different numbers of parameters, so the number of parameters would have to come from a cplug_... callback that provides the instance pointer, for instance we could replace CPLUG_NUM_PARAMS with something like cplug_getParamCount(vst3->userPlugin), which could actually even be done as a macro for each plugin format but that would be unwieldy.

Tremus commented 4 months ago

cplug_getParamCount

Good idea. This works well for finding the number of params on the fly.

I'm thinking in order to notify the host of a change in latency, tail time, number of busses, and number of parameters I could pass something like this into createPlugin()

...
enum // property types
{
    CPLUG_CHANGED_LATENCY,
    CPLUG_CHANGED_TAIL_TIME,
    CPLUG_CHANGED_NUM_INPUT_BUSSES,
    CPLUG_CHANGED_NUM_OUTPUT_BUSSES,
    CPLUG_CHANGED_NUM_PARAMS,
};

struct CplugHostContext
{
    void (*propertyChanged)(struct CplugHostContext* ctx, uint32_t changedProperty);
    // ...
    // some other feature?
};

void* createPlugin(struct CplugHostContext*);
...
uint32_t cplug_getParamCount();
...

For the user, they simply save the context struct somewhere in their plugin and call the function with a property type. For the wrapper, this context struct above could be saved within the wrapper struct, and I could use offsetof to shift the pointer back to the start of the struct and recast it.

Something like this should work perfectly well in AUv2 and CLAP (so long as hosts support it)

Thoughts?

Photosounder commented 4 months ago

Sounds good. I think you mean that void *cplug_createPlugin() would become void *cplug_createPlugin(struct CplugHostContext *host_context) and we'd be free to store this pointer in our instance structure and then use that pointer to actively call wrapper functions such as propertyChanged(), correct? And this host context would be what is currently the VST3Plugin, AUv2Plugin, and CLAPPlugin, but with a new unified type name, right?

Tremus commented 4 months ago

Yep, that's right