Converting plugin to Rack 2 issues

Just trying to compile my DanTModules plugin for Rack 2 and am seeing the following error:

src/wavulike.cpp: In member function 'virtual void Wavulike::onSampleRateChange()':
src/wavulike.cpp:212:61: error: 'appGet' is not a member of 'rack'
  212 |     dcOffsetFilter.setCutoff(dtm::dcOffsetFrequency / rack::appGet()->engine->getSampleRate());

Does the onSampleRateChange() get the sample rate as an arg?

Answering my own question… VCV Rack API: rack::engine::Module::SampleRateChangeEvent Struct Reference

Ok, I think this is a case of bad copy pasta, simple solution was switch rack::appGet()->engine->getSampleRate() for APP->engine->getSampleRate()

Ok new issue, difficult to describe (especially since its not open source) so I created a video to show the issue.

This works fine in V1, anyone have ideas about why this might be happening? It looks like the point params of the Wavulike module only update when they receive an interaction, rather when when the number of points param changes.

Edit: figured out this only happens when the module is in “param override” mode and there is no CV connected; ie. the CV input directly changes the param, rather than being added to the param value.

So effectively in the code I first get the active points param value and store it in a local variable, then because its in param override mode I then set the param value using that variable, which because there is no CV connected, is the same value.

Not sure why this would affect the code, because i then use the local variable in the rest of the code, for example a few lines later I set the brightness of each of the slider lights based on that variable. Logically I can’t see why this is not working.

Would you be able to give some pseudo code of just the parts that isn’t working like

global p_val

process():
   if port.isconnected()
      pval =  port.getval
   else
      pval =  slider.getval

I’m having a hard time comparing your expected behavior to the logic you’re describing with just the video and text description

Ok, rather than pseudo code, here is an attempt at a simplified version: My usual disclaimer applies, I am still a C++ novice, this might not be the best way of doing things, but this works exactly as I intend in Rack V1.


int getActivePoints()
  {
    int active = params[POINTS_ACTIVE_PARAM].getValue();
    if (inputs[ACTIVE_INPUT].isConnected())
    {
      active = int(inputs[ACTIVE_INPUT].getVoltage() + (CV_OVERRIDE_MODE ? 0 : params[POINTS_ACTIVE_PARAM].getValue()));
    }
    return active;
  }

void process(const ProcessArgs &args) override
  {

...

    int activeValue = getActivePoints();
    if (CV_OVERRIDE_MODE)
    {
      params[POINTS_ACTIVE_PARAM].setValue(activeValue);
    }

    // use variable activeValue to calculate outputs & module state
    // this is the part that doesn't seem to be working eg:
    lights[POINT_F_LIGHT].setBrightness(activeValue > 5 ? 1 : 0);

  }

void draw(const DrawArgs &args) override
  {

...

    int active = module->getActivePoints();
    // use variable active to draw the custom waveform widget
  }

hmmm, yeah, that is really weird. So far as I can tell you’re right and your logic is fine. Just for S&G’s, can you take the code out of getActivePoints() and inline it into process() and see if that matters? I’m wondering if maybe there’s something funky the new engine is doing with threading? Though that’s a long shot.

The function is now named rack::contextGet(), but it is recommended to use the APP macro for API stability.

However, I should have kept a deprecated appGet() function in the Rack API, so has been added to the source for the next development build.

1 Like

Ah ok, thanks Andrew. I do believe I originally didn’t use the macro as I had read on various “learn c++” websites that using macros was considered bad practice, but I am happy either way and glad I can help out in some small way, even if it is just pointing out issues with my own bad code :smiley:

Yep, I gave that a try, inlined the code in the process function and hard coded the value in the draw function, still same result. The param only updates after I interact with one of the other params.

Its really strange and I am totally out of my depth with this as far as my C++ knowledge goes. My thinking was going down the lines of, perhaps the new engine has some performance code whereby if you update a param to the same value it considers that as not requiring any processing and therefore bypasses it?

Its not super functionality breaking, so I could live with it for the time being and continue with converting the rest of the plugin.

I guess my only other hope would be letting someone else in to look at the source, or hoping @Vortico might be able to find some time to take a look at my repo at some point before I am ready to release V2…

Anyone know if it is possible to use configSwitch for a 3-way switch?

I am using the VCV Rack API: rack::componentlibrary::NKK Struct Reference switch on my TMNT module, but can only get the first two positions to have labels, the down position label is empty.

Edit: actually it seems it works fine for reasonable values like so:

configSwitch(MUTATE_TYPE_PARAM, 0.0f, 2.0f, 1.0f, "Mutation Type", {"Remove", "Toggle", "Insert"});

but for these values (ie. including a negative minimum) for example it doesnt work:

configSwitch(DIR_PARAM, -1.0f, 1.0f, 0.0f, "Direction", {"Backwards", "Stopped", "Forwards"});

Andrew showed an example here in case you missed it, and it seems to work with offsets, but perhaps it doesn’t work with negative offsets like you mentioned:

I did see that yes, but was slightly confused by it, in that Andrew mentions it is convenient to have an offset, but the configSwitch() method does not have an offset param, just min, max and default:

TSwitchQuantity * rack::engine::Module::configSwitch	(	int 	paramId,
float 	minValue,
float 	maxValue,
float 	defaultValue,
std::string 	name = "",
std::vector< std::string > 	labels = {} 
)	

By “offset” in this discussion I think what is meant is just to have a start at value different than 0, not really a separate offset parameter, but perhaps a look at the Rack code will reveal why starting at -1.0f doesn’t seem to work.

This new commit by Andrew might help with your switch issue:

1 Like