Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

VST plugin Program presets not accessible #257

Open
petrikaj opened this issue Oct 5, 2023 · 3 comments
Open

VST plugin Program presets not accessible #257

petrikaj opened this issue Oct 5, 2023 · 3 comments

Comments

@petrikaj
Copy link

petrikaj commented Oct 5, 2023

I have tried to access and change iZotope's VST plugins' Program presets but it seems they are not exposed.

Parameters work ok.

Here's what MrsWatson prints out from plugin —display-info

mrswatson

Notice it's not part of the parameters.

Using plugin.show_editor() allows to access those presets and changing them will change the parameters accordingly after quitting the showeditor(/).

MrsWatson allows to change it while loading the plugin:
"mrswatson64 --plugin 'plugin_name,preset_name’ -i input.wav -o output.wav"

@0xdevalias
Copy link

0xdevalias commented Nov 8, 2023

Looking at the MrsWatson source code, this seems to be where the 'Programs' is being printed:

It reads from:

  • data->pluginHandle->numPrograms
  • data->pluginHandle effGetProgramNameIndexed nameBuffer->data
  • data->pluginHandle effGetProgramName nameBuffer->data

Googling for effGetProgramNameIndexed, it seems to be part of the VST2 SDK or similar.

Eg. Here's a go package that implements bindings for it:

  • https://github.com/pipelined/vst2
    • Build vst2 plugins and hosts with Go

    • vst2 implements VST2 SDK API. It provides capabilities to build both VST2 hosts and plugins.

    • https://pkg.go.dev/github.com/pipelined/vst2
      • // EffGetProgramNameIndexed passed to get program name by index.
        // Index: program index.
        // Ptr: *[maxProgNameLen]uint8 buffer for program name.
        // Return: true for success.
        EffGetProgramNameIndexed

Pedalboard doesn't seem to support VST2, but not sure if there is an equivalent function in VST3. We can start by looking at the VST3 SDK:

Searching for effGetProgramNameIndexed doesn't seem to turn up any results there (neither does GetProgramName / ProgramName)

Clicking through from that repo lead me to:

And searching that repo for GetProgramName lead me to this definition:

IUnitInfo describes the internal structure of the plug-in.
- The root unit is the component itself, so getUnitCount must return 1 at least.
- The root unit id has to be 0 (kRootUnitId).
- Each unit can reference one program list - this reference must not change.
- Each unit, using a program list, references one program of the list.
    /** Component intern program structure. */
	/** Gets the count of Program List. */
	virtual int32 PLUGIN_API getProgramListCount () = 0;

	/** Gets for a given index the Program List Info. */
	virtual tresult PLUGIN_API getProgramListInfo (int32 listIndex, ProgramListInfo& info /*out*/) = 0;

	/** Gets for a given program list ID and program index its program name. */
	virtual tresult PLUGIN_API getProgramName (ProgramListID listId, int32 programIndex, String128 name /*out*/) = 0;

	/** Gets for a given program list ID, program index and attributeId the associated attribute value. */
	virtual tresult PLUGIN_API getProgramInfo (ProgramListID listId, int32 programIndex,
		CString attributeId /*in*/, String128 attributeValue /*out*/) = 0;
/** Basic Program List Description.
\see IUnitInfo
*/
struct ProgramListInfo
{
	ProgramListID id;				///< program list identifier
	String128 name;					///< name of program list
	int32 programCount;				///< number of programs in this list
};

Then we can find the definition for ProgramListID in the following:

typedef int32 ProgramListID;	///< program list identifier

So it definitely seems like the concept of 'programs' still exists in the VST3 SDK.


Looking at an example CLI app for using the vst-rs Rust bindings for VST2, they don't seem to print the 'programs' details either; but they do have a section called 'presets':

    // Get the plugin information
    let info = instance.get_info();

    println!(
        "Loaded '{}':\n\t\
         Vendor: {}\n\t\
         Presets: {}\n\t\
         Parameters: {}\n\t\
         VST ID: {}\n\t\
         Version: {}\n\t\
         Initial Delay: {} samples",
        info.name, info.vendor, info.presets, info.parameters, info.unique_id, info.version, info.initial_delay
    );

Tracing through the code a bit, I found the definition for Info, which again doesn't mention 'program', but does mention 'presets':

Tracing through the code a bit more I found this implementation of PluginInstance, which seems to equate presets with programs:

plug.info = Info {
  // ..snip..
  presets: effect.numPrograms,
  // ..snip..
  preset_chunks: flags.intersects(PluginFlags::PROGRAM_CHUNKS),
}

Looking at the vst3-sys Rust bindings for VST3:

@petrikaj
Copy link
Author

petrikaj commented Nov 8, 2023

Here's less technical explanation on the github docs:

https://steinbergmedia.github.io/vst3_dev_portal/pages/Technical+Documentation/Presets+Program+Lists/Index.html

@0xdevalias
Copy link

0xdevalias commented May 20, 2024

Just wanted to note that #297 just got merged, which may provide one potential angle of a solution here:

Apologies that this took so long - I've just made a couple changes and merged this, and it should be available as of v0.9.6 (released later today).

I did rename this property to raw_state instead of just state, as the state data is often (but not always) encoded in a format that I hope we can parse and expose as a .state parameter later. (i.e.: if the state of a VST3 is valid XML, Pedalboard could unwrap and parse that XML directly to make the client code simpler.)

Originally posted by @psobot in #297 (comment)

Docs:

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants