Way to make params 'hidden' in rack pro


The new Surge XT modules (coming to beta later this week! Stay tuned) have a lot of parameters because of our modulation matrix, which is super cool. This works great.

But it means I burn a lot of the VST parameters when I instantiate a module in rack pro plugin

Some of my parameters definitely make sense for automation but others less so. The VST AU CLAP etc… specs have a way to mark a parameter as ‘expert’ or ‘hidden’ often. is there any way to do that with a rack::ParamQuantity? I don’t see it in the API?

Appreciate any help

1 Like

If a parameter is hidden, how could it be accessed?

I think, ‘expert’ params should go into an expander module.

through the ui gesture which edits it in the module.

It’s the equivalent of a non-automatable parameter in VST3, CLAP, AU, etc…

I don’t see anything in the API either.

You could always not store the data in a parameter and instead store it as a field on the module. I could walk through what that would look like if that is a new concept for you.

yeah i know how to do that (but thank you!)

but these are parameters. They bind to a knob.

(Basically you can think of the surge mod matrix as having an attenuverter for each CV control to each knob, so for 4 cv controls and 8 knobs you pick up an extra 4 * 8 attenuverters which are useful to edit but not useful to automate. These belong as parameters since i want to use al that looking of config, knob, etc… but there’s no reason to expose them at the edge of rack pro)

Looking at the API, this is the cleanest way I can think to achieve what you are looking for. Note I have not tested this. And obviously this is just the relevant lines in the module.

struct MyModule : Module {
	enum HiddenParamId {
	std::vector<Param> hiddenParams;
	std::vector<ParamQuantity*> hiddenParamQuantities;


	///Copied from Module.cpp in VCV Rack. Modified to add to hiddenParams
	template <class TParamQuantity = HiddenParamQuantity >
	TParamQuantity* configHiddenParam(int paramId, float minValue, float maxValue, float defaultValue, std::string name = "", std::string unit = "", float displayBase = 0.f, float displayMultiplier = 1.f, float displayOffset = 0.f) {
		assert(paramId < (int) hiddenParams.size() && paramId < (int) hiddenParamQuantities.size());
		if (hiddenParamQuantities[paramId])
			delete hiddenParamQuantities[paramId];

		TParamQuantity* q = new TParamQuantity;
		q->ParamQuantity::module = this;
		q->ParamQuantity::paramId = paramId;
		q->ParamQuantity::minValue = minValue;
		q->ParamQuantity::maxValue = maxValue;
		q->ParamQuantity::defaultValue = defaultValue;
		q->ParamQuantity::name = name;
		q->ParamQuantity::unit = unit;
		q->ParamQuantity::displayBase = displayBase;
		q->ParamQuantity::displayMultiplier = displayMultiplier;
		q->ParamQuantity::displayOffset = displayOffset;
		hiddenParamQuantities[paramId] = q;

		Param* p = &hiddenParams[paramId];
		p->value = q->getDefaultValue();
		return q;

struct HiddenParamQuantity : ParamQuantity   {
	float getValue() override {
		MyModule* module = dynamic_cast<MyModule*>(this->module);
		return module->hiddenParams[paramId].value;
	void setValue(float v) override {
		MyModule* module = dynamic_cast<MyModule*>(this->module);
		module->hiddenParams[paramId].value = v;

yeah i was thinking about mocking up non-listed param quantities would be a solution indeed. And then you can bind them to the knob by overwriting param widget init param quantities.

but also don’t forget in the to/from json you have to stream them otherwise that would be a real bummer for users.

i have a base class where i could do that but wanted to avoid it for a variety of reasons, as I’m sure you can imagine.

1 Like

The primary risk here, of course, is making sure you catch all the implicit plumbing that a param quantity participates in; for me this approach where param quantities are in one of two places would be a really sweeping change from where I am today since - of course - my matrix assumes index offsets into a params array and so on…

Yeah, this is definitely pushing VCV rack past what it was designed to do, and updating all the places seems like it might take a good amount of work. Unfortunately I don’t see a better option. There is nothing in the VCV Rack codebase hinting at this, and the VCV VST plugin is proprietary so we can’t see what it does, and even if we could it likely never imagined this case.


I was just wondering how many places does ParamWidget assume paramQuantity points to this->module->params[this->paramId] for instance? Maybe none. but if it is even one …

OK I’ll just leave the modules as param heavy. I’ll also DM you a preview if you want before we launch the beta this week :slight_smile:

Thanks for the help. I guess the answer is “no”. I’, mark this as a solution.

I wouldn’t say no to a preview :slight_smile:

1 Like

I think I DMed one to you now. If I didn’t uhhh message me and I’ll reply with the link again.

1 Like

Just to wrap this up: I sent a FR to the rack support email for a way to do this, since there isn’t one today. Thanks for the help all.

You can always do like voxglitch and not use params at all. Not for the faint of heart.

Yeah I know but it’s a lot of tooling to reconstruct especially in the ui layer with tooltips typeins and so forth

I do it in a couple of places but params are convenient

1 Like