setCurrentProgram not called on VST3 plugin

Hello,

It seems that “setCurrentProgram” is never called on my VST3 plugin. I’m running on Linux with Reaper 6.27

I can see on the Debugger that all other preset-related functions are called. Reaper is showing the list of built-in programs correctly and calling “getNumPrograms()”, “getCurrentProgram()” and “getProgramName()” but I never get “setCurrentProgram()” called.

I just have a preset array of structs with one “name” and one “xml” member as in the code below. Nothing fancy. Then I have a working APVTS

  //----------------------------------------------------------------------------
  int getNumPrograms() override { return sizeof presets / sizeof (preset); }
  //----------------------------------------------------------------------------
  int getCurrentProgram() override { return _program; }
  //----------------------------------------------------------------------------
  void setCurrentProgram (int index) override
  {
    assert (index >= 0 && index < getNumPrograms());
    _program = index;
    set_apvts_state (juce::parseXML (presets[_program].xml));
  }
  //----------------------------------------------------------------------------
  const juce::String getProgramName (int index) override
  {
    assert (index >= 0 && index < getNumPrograms());
    return presets[index].name;
  }

Is this a bug? Something VST3 specific? Do I need some #define?

I just tried modifying the DSPModulePluginDemo example so that the program-related functions are implemented like this:

    int program = 0;

    int getNumPrograms()    override { return 10; }
    int getCurrentProgram() override { return program; }
    void setCurrentProgram (int i) override { program = i; }
    const String getProgramName (int i) override { return "hello " + String (i); }

Then, I stuck a breakpoint on setCurrentProgram. When I select a new preset from the dropdown in REAPER, the breakpoint is hit and the function parameter has the expected value. I’m using JUCE develop, and I tested with REAPER 6.26 and 6.29.

If you’re not using a recent copy of JUCE, try updating to the current develop branch and testing again. If the problem persists, please try testing with a blank plugin project with only the program-related functions overridden as above. If the problem persists in the ‘blank’ plugin, then this is probably a REAPER or JUCE bug. Otherwise, if the problem is only present in your existing plugin, then it is probably caused by some configuration specific to that plugin.

Weird. I updatedfrom 6.0.8 to the tip of the development branch and it keeps happening. I tested on Windows to be sure and it happens too, so this is not a Linux issue.

The methods contain no typos, as they are marked “override”, so it looks like a configuration issue.

Unfortunately I don’t see anything that could be relevant on my configuration. The only thing affecting VST3 should be JUCE_VST3_CAN_REPLACE_VST2, which is 0.

Did you test whether a new fresh project also exhibits the same problem?

How is presets defined? If it’s a pointer, then sizeof will give you the size of the pointer, not the array it points to. Instead of dividing the total size by the size of an element, why not just use the constant or value that was used to allocate the array? If it’s a JUCE Array or Owned array, then you can use .size() to get the number of elements.

This is defined as.

struct preset {
  char const* name;
  char const* xml;
};

static constexpr preset presets[] = {{.name = "x", .xml = "y" }, ...};

test.cpp (7.0 KB)
CMakeLists.txt (1.2 KB)

This is weird. Stripping down my code it seems that things work as it should.

For C-style arrays, you can find the size using juce::numElementsInArray, which is a bit friendlier (and safer!) than using sizeof.

Are you saying that the code you posted works as expected, or is this an example of a plugin which exhibits the bug?

If the plugin works correctly after removing some parts of your code, you should be able to work out which part of the code is causing the problem by gradually adding parts back into the project.

Please let us know if you discover the cause of the issue, as it will help us to diagnose similar issues in the future.

It did work, but it was only related to the number of presets. It is a JUCE bug.

On:
modules/juce_audio_plugin_client/VST3/juce_VST3_Wrapper.cpp:816

Function:
bool setNormalized (Vst::ParamValue v) override

If there are only two presets, when changing to the second preset, the “v” function parameter comes as 0.5, then the result of “programValue” on the line below becomes 0:

auto programValue = roundToInt (toPlain (v));

“toPlain” just does “v * info.stepCount”. When there are two parameters “info.stepCount” becomes 1, so the result of the above becomes “(int) 0.5f * 1.f = 0”

As I was planning on adding more presets this is no problem for me, just doing what I had planned works as workaround. Thanks for the support!

Can you reproduce?

Thanks, I can reproduce the issue. I’ll update this thread when I’ve pushed a fix.

I’ve pushed a fix here:

Please let us know if you run into any further problems with this change.

Thanks!