# Managing plugin parameters in AudioPluginInstance

**URL:** <https://forum.juce.com/t/managing-plugin-parameters-in-audioplugininstance/30013>\
**Category:** Audio Plugins\
**Created:** [October 24, 2018, 2:22pm UTC](https://forum.juce.com/t/managing-plugin-parameters-in-audioplugininstance/30013 "2018-10-24T14:22:22Z")\
**Posts on this page:** 20\
**Page:** 1

<div class="post-metadata">

**Author:** ![jacosol](https://sea2.discourse-cdn.com/flex026/user_avatar/forum.juce.com/jacosol/32/5080_2.png) [@jacosol](https://forum.juce.com/u/jacosol)\
**Post date:** [October 24, 2018, 2:22pm UTC](https://forum.juce.com/t/managing-plugin-parameters-in-audioplugininstance/30013/1 "2018-10-24T14:22:22Z")

</div>

I am creating a plugin instance of the TAL-Noisemaker synth (which is available for free and should not have protection for debuggers), following the recipe that @t0m gave in this thread [Connect to a VST plugin](https://forum.juce.com/t/connect-to-a-vst-plugin/20929).

Everything works fine til now: for example I can get the parameters (in an `AudioPluginParameter` form) via `AudioPluginInstance::getParameters()` , I can get their names and their default values via the `getName()` and `getValue()` methods of `AudioPluginParameter.`

Nevertheless I found out that the discrete parameters of the synth, e.g. waveform of oscillator1 (name I get from `getName()` : “osc1waveform”) that can assume 3 values, are mapped in a non linear way to the 0 -1 continuous range that the `AudioPluginParameter` supports:

My questions are the following:

1. **is it possible to change the way discrete parameters are mapped to the 0 - 1 continuous range in an `AudioPluginInstance` instantiated by loading a 3rd party plugin?**
2. Is the above possible just using the `AudioProcessorParameter` array returned by `AudioPluginInstance::getParameters()`?
3. Is it possible to delete and add parameters to a 3rd party plugin loaded as an `AudioPluginInstance`?

Any help/clarification/suggestion/link-to-docs is deeply appreciated.

---

<div class="post-metadata">

**Author:** ![t0m](https://sea2.discourse-cdn.com/flex026/user_avatar/forum.juce.com/t0m/32/16413_2.png) [@t0m](https://forum.juce.com/u/t0m)\
**Post date:** [October 25, 2018, 8:52am UTC](https://forum.juce.com/t/managing-plugin-parameters-in-audioplugininstance/30013/2 "2018-10-25T08:52:03Z")

</div>

The answer to all of those is no…

A better question is: what are you trying to achieve? Have a look at how the `GenericAudioProcessorEditor` does things.

If you load a VST there is no way (unless you parse an accompanying VSTXML file, which is rare and, as of recently, undocumented) to determine if a parameter is discrete or not. AUs and VST3 do provide this information.

---

<div class="post-metadata">

**Author:** ![jacosol](https://sea2.discourse-cdn.com/flex026/user_avatar/forum.juce.com/jacosol/32/5080_2.png) [@jacosol](https://forum.juce.com/u/jacosol)\
**Post date:** [October 25, 2018, 9:42am UTC](https://forum.juce.com/t/managing-plugin-parameters-in-audioplugininstance/30013/3 "2018-10-25T09:42:13Z")

</div>

Thanks for your reply it already helps a lot.

> A better question is: what are you trying to achieve?

I am trying to generate a big dataset of sounds (for research purposes) produced by 3rd party plugins (synths) by calling the `processBlock` function of an `AudioPluginInstance`. A very important feature of the dataset is that every sound need to be accompanied by the list of parameters the plugin used to produce a particular sound.  
For discrete parameters like (e.g. “waveform” that could be {“sine”, “square”, “noise”}) I have a problem. I need to find an automated way of knowing exactly which waveform (and the same goes for the other discrete parameters) was employed to produce a given sound in the dataset.

The root of the problem is that I am not aware of the exact way the float values, that I have to pass to the AudioPluginInstance processor for discrete parameters as well, are mapped to the different “choices” of that discrete parameter.

_After some reading around I was thinking that maybe modifying the `NormalisableRange` class and adapt it for this purpose could help (but I am unsure whether and how the VST processor utilises that class)._  
_Alternatively, I was wondering is there a way to read (for example) which waveform was used to produce a sound?  
when loading the plugin in a DAW that parameter comes with a drop-down menu with {“sine”, “square”, “noise”} so I guess that information is stored somewhere…_

Thanks for your patience and I hope in your understanding if I am missing something basic. I am relatively noob but I am attempting to dive deeper into JUCE and its logic atm.

---

<div class="post-metadata">

**Author:** ![t0m](https://sea2.discourse-cdn.com/flex026/user_avatar/forum.juce.com/t0m/32/16413_2.png) [@t0m](https://forum.juce.com/u/t0m)\
**Post date:** [October 25, 2018, 9:59am UTC](https://forum.juce.com/t/managing-plugin-parameters-in-audioplugininstance/30013/4 "2018-10-25T09:59:46Z")

</div>

The `GenericAudioProcessorEditor` handles discrete parameters in the way you want, presenting a drop-down of the available values - take the code from there.

---

<div class="post-metadata">

**Author:** ![jacosol](https://sea2.discourse-cdn.com/flex026/user_avatar/forum.juce.com/jacosol/32/5080_2.png) [@jacosol](https://forum.juce.com/u/jacosol)\
**Post date:** [October 25, 2018, 2:56pm UTC](https://forum.juce.com/t/managing-plugin-parameters-in-audioplugininstance/30013/5 "2018-10-25T14:56:32Z")

</div>

Thanks t0m for your prompt answer, the `GenericAudioProcessorEditor` has indeed some inspirational snippets.  
I have been doing some trials with no luck so far. I feel my problem is a bit upstream because I don’t have a way (and I am wondering if there is one) to read the actual available values (e.g. {“sine”, “square”, “noise”} for a waveform discrete parameter) from the `AudioPluginInstance`. After I load a 3rd party plugin into an `AudioPluginInstance`, I can only read the 0 - 1 value of each parameter via `AudioPluginInstance::getParams()`.  
Also, I would really love to understand where/when the actual conversion from 0 -1 to the available discrete parameter value exactly takes place in the case of an AudioPluginInstance (loaded with a 3rd party VST).

any suggestions?

---

<div class="post-metadata">

**Author:** ![alibarker](https://avatars.discourse-cdn.com/v4/letter/a/ed8c4c/32.png) [@alibarker](https://forum.juce.com/u/alibarker)\
**Post date:** [October 25, 2018, 3:11pm UTC](https://forum.juce.com/t/managing-plugin-parameters-in-audioplugininstance/30013/6 "2018-10-25T15:11:19Z")

</div>

Can you not call the `getText (float normValue, int)` function on each of the parameters returned from `getParameters ()`?. You’ll need to pass in the normalised value you already have.

---

<div class="post-metadata">

**Author:** ![t0m](https://sea2.discourse-cdn.com/flex026/user_avatar/forum.juce.com/t0m/32/16413_2.png) [@t0m](https://forum.juce.com/u/t0m)\
**Post date:** [October 25, 2018, 3:50pm UTC](https://forum.juce.com/t/managing-plugin-parameters-in-audioplugininstance/30013/7 "2018-10-25T15:50:41Z")

</div>

Get labels for the values a parameter can take:

> <https://github.com/WeAreROLI/JUCE/blob/06c3674e510f991d88f881203aedd85a60fbced9/modules/juce_audio_processors/processors/juce_GenericAudioProcessorEditor.cpp#L264>

Handling a new parameter value and mapping it to a label:

> <https://github.com/WeAreROLI/JUCE/blob/06c3674e510f991d88f881203aedd85a60fbced9/modules/juce_audio_processors/processors/juce_GenericAudioProcessorEditor.cpp#L285>

---

<div class="post-metadata">

**Author:** ![jacosol](https://sea2.discourse-cdn.com/flex026/user_avatar/forum.juce.com/jacosol/32/5080_2.png) [@jacosol](https://forum.juce.com/u/jacosol)\
**Post date:** [October 25, 2018, 6:07pm UTC](https://forum.juce.com/t/managing-plugin-parameters-in-audioplugininstance/30013/8 "2018-10-25T18:07:50Z")

</div>

Thanks a lot @alibarker for your suggestion.  
I have tried that, but in my case returns only the value back as a string. I guess it happens when the `getParameters ()` is called from an `AudioPluginInstance` loaded with a 3rd party plugin? (see previous answer from t0m below).

> If you load a VST there is no way (unless you parse an accompanying VSTXML file, which is rare and, as of recently, undocumented) to determine if a parameter is discrete or not. AUs and VST3 do provide this information.

Did you mean I should somehow implement my own version of `getText (float normValue, int)`?

---

<div class="post-metadata">

**Author:** ![t0m](https://sea2.discourse-cdn.com/flex026/user_avatar/forum.juce.com/t0m/32/16413_2.png) [@t0m](https://forum.juce.com/u/t0m)\
**Post date:** [October 26, 2018, 9:16am UTC](https://forum.juce.com/t/managing-plugin-parameters-in-audioplugininstance/30013/9 "2018-10-26T09:16:42Z")

</div>

The `GenericAudioProcessorEditor` attempts to extract the maximum amount of information about the parameters possible. Since VST2s cannot provide information about the number of steps they have (it’s not available via the VST2 API) the best you can do is to look at the text value provided by the plug-in for each parameter value. You can see this text displayed in the Slider boxes in the GUI. If, however, the plug-in chooses not to provide any meaningful text there is nothing you can do.

---

<div class="post-metadata">

**Author:** ![jacosol](https://sea2.discourse-cdn.com/flex026/user_avatar/forum.juce.com/jacosol/32/5080_2.png) [@jacosol](https://forum.juce.com/u/jacosol)\
**Post date:** [October 26, 2018, 10:27am UTC](https://forum.juce.com/t/managing-plugin-parameters-in-audioplugininstance/30013/10 "2018-10-26T10:27:33Z")

</div>

Thanks for your answer t0m, but I am still struggling with this issue.

I think if I post a bit of code it can help you helping me. I am doing some trials in a command line application. As you can see, I am not using any editor and indeed the flag I tried to put in the `GenericAudioProcessorEditor` constructor does not fire. Though I’ve noticed that some parameters’ attributes are initialized by the VSTPluginInstance constructor. To play around a bit I hardcoded a parameter to be boolean and have 2 steps .I commented the outputs I get form cout.

```
#include "../JuceLibraryCode/JuceHeader.h"
#include <array>
using namespace std;
typedef std::vector<std::pair<int, float>> PluginPatch;

int main ()
{
	MessageManager::getInstance(); //to avoid leaks

AudioPluginInstance* plugin;
PluginPatch params;
PluginPatch overridenParameters;
OwnedArray<PluginDescription> pluginDescriptions;
KnownPluginList pluginList;
AudioPluginFormatManager pluginFormatManager;
String path = "/path/to/my/VST/TAL-NoiseMaker.vst";

pluginFormatManager.addDefaultFormats();
for (int i = pluginFormatManager.getNumFormats(); --i >= 0;)
{
	pluginList.scanAndAddFile (String (path),
							   true,
							   pluginDescriptions,
							   *pluginFormatManager.getFormat(i)); //fill in plugin description
}
String errorMessage;
plugin = pluginFormatManager.createPluginInstance (*pluginDescriptions[0],
												   44100,
												   512,
												   errorMessage); //load TAL-NoiseMaker.vst into my AudioPluginInstance

jassert (pluginDescriptions.size() > 0);

//At this point I only have the AudioPluginInstance of TAL-NoiseMaker.vst.
//I have no editor, as I want to process the audio and save each sound offline (by calling the prepareToPlay and processBlock functions later with a given MIDI information).

//some flags and printing trials
if (plugin != nullptr)
{
	const OwnedArray<AudioProcessorParameter>& processorParams = plugin->getParameters();//get the parameters as an AudioProcessorParameter array
	for (int i=0 ; i< plugin->juce::AudioProcessor::getNumParameters() ; i++){

		juce::StringArray pstring = processorParams[i]->getAllValueStrings();
		
		//i = 45 correspond to lfosync1, a boolean parameter of Tal-Noisemaker.vst.
		//I modified the constructor of VSTPluginInstance in juce_VSTPluginFormat.cpp hardcoding the isBoolean and numSteps attributes to 1 for i = 45
		if (i ==45) {
			processorParams[i]->setValue(0.51);
			cout << processorParams[i]->getName(100) << " = " << processorParams[i]->getText(processorParams[i]->getValue(), 100) << endl; //prints "lfo1sync = On"
		}
		if (i ==45) {
			processorParams[i]->setValue(0.49);
			cout << processorParams[i]->getName(100) << " = " << processorParams[i]->getText(processorParams[i]->getValue(), 100) << endl; //prints "lfo1sync = Off"
		} //without modifying the constructor of VSTPluginInstance it would print the float value.
		if (i ==1) {
			processorParams[i]->setValue(0.51);
			cout << processorParams[i]->getName(100) << " = " << processorParams[i]->getText(processorParams[i]->getValue(), 100) << endl; //prints "volume = 0.51"
		}
		if (i ==45) {
			cout << processorParams[i]->getName(100) << " getAllValueString() k = " << pstring.size()<< endl; //prints 0
		}
	}
}

delete plugin;
DeletedAtShutdown::deleteAll();
MessageManager::deleteInstance();

return 0;

```

}

Maybe I could hardcode the parameters’ attributes I know to be discrete/boolean and their number of steps in the `VSTPluginInstance` constructor, it does not seem a very neat solution. In addition, I am not sure whether those hardcoded parameter will be correctly interpreted/mapped by the `AudioProcessor` of the TAL-Noisemaker.vst plugin (loaded as `AudioPluginInstance`).

Hopes this helps in helping me, I am stuck on these since 3 days already 😕

---

<div class="post-metadata">

**Author:** ![t0m](https://sea2.discourse-cdn.com/flex026/user_avatar/forum.juce.com/t0m/32/16413_2.png) [@t0m](https://forum.juce.com/u/t0m)\
**Post date:** [October 26, 2018, 11:02am UTC](https://forum.juce.com/t/managing-plugin-parameters-in-audioplugininstance/30013/11 "2018-10-26T11:02:17Z")

</div>

If you get values like “lfo1sync = 0.49” then I’m afraid there is no alternative approach you can use to determine the number of steps; the only mechanism available to the plug-in to communicate labels for specific parameter values is via getText. As for how the plug-in interprets different floating point values - it’s up to the plug-in!

The plug-in’s own GUI will obviously feed in the right numbers when you interact with it. You could try playing with the GUI and recording the parameter changes to get a feel for what values are appropriate.

---

<div class="post-metadata">

**Author:** ![kunz](https://avatars.discourse-cdn.com/v4/letter/k/f19dbf/32.png) [@kunz](https://forum.juce.com/u/kunz)\
**Post date:** [October 26, 2018, 12:59pm UTC](https://forum.juce.com/t/managing-plugin-parameters-in-audioplugininstance/30013/12 "2018-10-26T12:59:02Z")

</div>

It’s a long time ago when i wrote the plugin. All values are in the range from 0…1 and divided to the number of discrete steps. Booleans or switches maybe are true when \> 0. You maybe find out more if you switch to the generic parameter view in your favourite host.

---

<div class="post-metadata">

**Author:** ![jacosol](https://sea2.discourse-cdn.com/flex026/user_avatar/forum.juce.com/jacosol/32/5080_2.png) [@jacosol](https://forum.juce.com/u/jacosol)\
**Post date:** [October 26, 2018, 1:29pm UTC](https://forum.juce.com/t/managing-plugin-parameters-in-audioplugininstance/30013/13 "2018-10-26T13:29:10Z")

</div>

Thanks t0m for your help.  
Your answer clarifies a lot. So the interpretation of the floating point values (mapping them to a discrete set of choice) happens inside the processor of the VST and I cannot do anything about it (not even with the AudioProcessor I get with the AudioPluginInstance after loading), correct?

Then I guess there is nothing I can do other than “measure” when the change happens via the GUI. I thought maybe JUCE was taking care of this “mapping” so I could edit the mapping function but it’s not the case. It happens internally in the 3rd party VST processor (correct?).

I tested in logic for the values of the discrete parameter “osc2waveform” (5 values in the GUI) and indeed it changes at non-equally spaced intervals of the float value (see image below).

 ![image](https://us1.discourse-cdn.com/flex026/uploads/juce/original/2X/6/66533f45b3b6786a321699d8236139dfb70721a9.jpeg)

It looks like I’d better switch to a VST3 plug-in, which indeed provides a much richer rose of information when using `getText()` (see image below for the output of `getText()` after loading a VST3 plug-in in the `AudioPluginInstance`)  
 ![image](https://us1.discourse-cdn.com/flex026/uploads/juce/original/2X/2/292908ee6388ed47516d7130943371009cafec63.png)

I will check whether there is a VST3 version of the plugin available, I really like the Noisemaker synth!

---

<div class="post-metadata">

**Author:** ![jacosol](https://sea2.discourse-cdn.com/flex026/user_avatar/forum.juce.com/jacosol/32/5080_2.png) [@jacosol](https://forum.juce.com/u/jacosol)\
**Post date:** [October 26, 2018, 1:46pm UTC](https://forum.juce.com/t/managing-plugin-parameters-in-audioplugininstance/30013/14 "2018-10-26T13:46:49Z")

</div>

Oh wow, great to hear from the creator himself!

> [@kunz](#):
>
> All values are in the range from 0…1 and divided to the number of discrete steps.

I was indeed expecting that (seemed to me the most logical design) but I am afraid something different is happening, both when loading Noisemaker with JUCE and in LogicX…please check the results of a test I did in LogicX in this reply in this thread (look at the attached image).

> [@Managing plugin parameters in AudioPluginInstance](https://forum.juce.com/t/managing-plugin-parameters-in-audioplugininstance/30013/13):
>
> Thanks t0m for your help. Your answer clarifies a lot. So the interpretation of the floating point values (mapping them to a discrete set of choice) happens inside the processor of the VST and I cannot do anything about it (not even with the AudioProcessor I get with the AudioPluginInstance after loading), correct? Then I guess there is nothing I can do other than “measure” when the change happens via the GUI. I thought maybe JUCE was taking care of this “mapping” so I could edit the mapping f…

The issue illustrated by the image in the post above is the reason why I was wondering if there was a way using JUCE to edit the float mapping. Or at least to read the actual parameters as they are displayed in the GUI (like “saw” “sine” etc… for waveform parameters) but it looks that is not possible and I can only get/set the float value.

> [@kunz](#):
>
> You maybe find out more if you switch to the generic parameter view in your favourite host.

Interesting, are you maybe aware of such an option in LogicX?

Last but not least, I really like Noisemaker such “big” sounds for a digital synth. Great work!  
I hope I can solve this issue to keep using it in this project.

---

<div class="post-metadata">

**Author:** ![jacosol](https://sea2.discourse-cdn.com/flex026/user_avatar/forum.juce.com/jacosol/32/5080_2.png) [@jacosol](https://forum.juce.com/u/jacosol)\
**Post date:** [October 29, 2018, 4:07pm UTC](https://forum.juce.com/t/managing-plugin-parameters-in-audioplugininstance/30013/15 "2018-10-29T16:07:20Z")

</div>

A small update: I could reproduce the behaviour reported [here](https://forum.juce.com/t/managing-plugin-parameters-in-audioplugininstance/30013/13?u=jacosol) for the mapping between floating point values of a plugin parameter, to a set of discrete choices (e.g. waveforms) for other synthesizer plugins. Does someone have any idea of why the 0-1 range is not divided by the number of discrete steps?What is going on?

---

<div class="post-metadata">

**Author:** ![t0m](https://sea2.discourse-cdn.com/flex026/user_avatar/forum.juce.com/t0m/32/16413_2.png) [@t0m](https://forum.juce.com/u/t0m)\
**Post date:** [October 29, 2018, 4:24pm UTC](https://forum.juce.com/t/managing-plugin-parameters-in-audioplugininstance/30013/16 "2018-10-29T16:24:02Z")

</div>

```auto
a | b | c | d | e
0 | 0.25 | 0.5 | 0.75 | 1.0
    0.125 0.375 0.625 0.875
```

---

<div class="post-metadata">

**Author:** ![kunz](https://avatars.discourse-cdn.com/v4/letter/k/f19dbf/32.png) [@kunz](https://forum.juce.com/u/kunz)\
**Post date:** [October 31, 2018, 9:14am UTC](https://forum.juce.com/t/managing-plugin-parameters-in-audioplugininstance/30013/17 "2018-10-31T09:14:46Z")

</div>

This maybe helps:

```
int calcComboBoxValue(float value, int param)
{
    int numItems = this->getNumComboBoxItems(param);
    return (int)floorf(value * (numItems - 1.0f) + 1.0f + 0.5f);
}

float calcComboBoxValueNormalized(float value, int param)
{
    int numItems = this->getNumComboBoxItems(param);
    return (value - 1.0f) / (numItems - 1.0f);
}

int getNumComboBoxItems(int param)
{
    int numItems = 1;

    switch(param)
    {
    case VOICES: numItems = 6; break;
    case PORTAMENTOMODE: numItems = 3; break;
    case LFO1DESTINATION: numItems = 8; break;
    case LFO2DESTINATION: numItems = 8; break;
    case FREEADDESTINATION: numItems = 6; break;
    case FILTERTYPE: numItems = 12; break;
    case OSC1WAVEFORM: numItems = 3; break;
    case OSC2WAVEFORM: numItems = 5; break;
    case ENVELOPEEDITORDEST1: numItems = 8; break;
    case ENVELOPEEDITORSPEED: numItems = 6; break;
    }

    return numItems;
}
```

---

<div class="post-metadata">

**Author:** ![jacosol](https://sea2.discourse-cdn.com/flex026/user_avatar/forum.juce.com/jacosol/32/5080_2.png) [@jacosol](https://forum.juce.com/u/jacosol)\
**Post date:** [October 31, 2018, 2:03pm UTC](https://forum.juce.com/t/managing-plugin-parameters-in-audioplugininstance/30013/18 "2018-10-31T14:03:45Z")

</div>

Thanks t0m for this answer, I indeed also noticed that pattern shortly after posting my previous message but I was afraid I had to then to check manually whether all the parameters were also mapped with the same criterion. But @kunz 's [answer](https://forum.juce.com/t/managing-plugin-parameters-in-audioplugininstance/30013/17?u=jacosol) solves all my problems!  
Thanks A LOT for your help.

---

<div class="post-metadata">

**Author:** ![jacosol](https://sea2.discourse-cdn.com/flex026/user_avatar/forum.juce.com/jacosol/32/5080_2.png) [@jacosol](https://forum.juce.com/u/jacosol)\
**Post date:** [October 31, 2018, 2:12pm UTC](https://forum.juce.com/t/managing-plugin-parameters-in-audioplugininstance/30013/19 "2018-10-31T14:12:29Z")

</div>

Great @kunz thank you so much for sharing this!It clarifies everything in detail.

Just a curiosity, is it common practice in plugin development to use this parameter mapping?I see that this way you can map N parameters with only N-1 threshold values for the switch in the combobox but is that why you used this mapping instead of equally spaced intervals?or is there some other reason I am missing?  
thanks a lot, bottom line is I am glad I can now keep using Noisemaker

---

<div class="post-metadata">

**Author:** ![kunz](https://avatars.discourse-cdn.com/v4/letter/k/f19dbf/32.png) [@kunz](https://forum.juce.com/u/kunz)\
**Post date:** [October 31, 2018, 2:32pm UTC](https://forum.juce.com/t/managing-plugin-parameters-in-audioplugininstance/30013/20 "2018-10-31T14:32:34Z")

</div>

I’m not sure why i did this that way. It just happened. Never thought that someone will come up with this about 9 years later 🙂

[Next page](https://forum.juce.com/t/managing-plugin-parameters-in-audioplugininstance/30013.md?page=2)
