# How do I get this SliderAttachment set up properly... I'm halfway there...?

**URL:** <https://forum.juce.com/t/how-do-i-get-this-sliderattachment-set-up-properly-im-halfway-there/54624>\
**Category:** General JUCE discussion\
**Created:** [January 20, 2023, 7:23pm UTC](https://forum.juce.com/t/how-do-i-get-this-sliderattachment-set-up-properly-im-halfway-there/54624 "2023-01-20T19:23:54Z")\
**Posts on this page:** 17\
**Page:** 1

<div class="post-metadata">

**Author:** ![Ian-SAfc](https://sea2.discourse-cdn.com/flex026/user_avatar/forum.juce.com/ian-safc/32/17877_2.png) [@Ian-SAfc](https://forum.juce.com/u/Ian-SAfc)\
**Post date:** [January 20, 2023, 7:23pm UTC](https://forum.juce.com/t/how-do-i-get-this-sliderattachment-set-up-properly-im-halfway-there/54624/1 "2023-01-20T19:23:54Z")

</div>

I had been using the `sliderValueChanged()` method to update my parameters, but apparently its better to use `ParameterAttachement()` or `SliderAttachment()` so the PluginProcessor can update the parameters, and pick up, for example, any automation of that parameter in track envelopes etc.

I’m fairly new to JUCE, I’ve been looking for example code etc., there’s very little out there on `ParameterAttachement` especially.

Anyway, here’s what I’ve got so far. How can I implement this properly in PluginProcessor?

In PluginEditor.h

```auto
juce::Slider myGain_slider;
juce::AudioProcessorValueTreeState::SliderAttachment myGain_sliderAttachment;

```

In PluginEditor.cpp

```auto
myGain_slider.setTextBoxStyle(juce::Slider::TextBoxBelow, true, 40, 20);
myGain_slider.setRange(0.0f, 1.0f, 0.01f);
myGain_slider.setValue(0.0f);
addAndMakeVisible(myGain_slider);

```

(constructor):

```auto
mypluginnameEditor::mypluginnameEditor (mypluginnameProcessor& p)
    : AudioProcessorEditor (&p), audioProcessor (p),

myGain_sliderAttachment(audioProcessor.apvts, "Gain", myGain_slider)

```

In `PluginProcessor.cpp` and `PluginProcessor.h`…  
this is where things get cloudy for me. How do I implement a simple `apvts` ?  
Or I’d be open to advice on how to use `ParameterAttachment()`.

---

<div class="post-metadata">

**Author:** ![stefhen](https://avatars.discourse-cdn.com/v4/letter/s/7ab992/32.png) [@stefhen](https://forum.juce.com/u/stefhen)\
**Post date:** [January 20, 2023, 11:47pm UTC](https://forum.juce.com/t/how-do-i-get-this-sliderattachment-set-up-properly-im-halfway-there/54624/2 "2023-01-20T23:47:37Z")

</div>

This tutorial covers a simple apvts.  
[https://docs.juce.com/master/tutorial\_audio\_processor\_value\_tree\_state.html](https://docs.juce.com/master/tutorial_audio_processor_value_tree_state.html)

If you scroll down to ‘Adding Parameters Programatically’ they outline a more convenient approach using the createParameterLayout() function.

---

<div class="post-metadata">

**Author:** ![Ian-SAfc](https://sea2.discourse-cdn.com/flex026/user_avatar/forum.juce.com/ian-safc/32/17877_2.png) [@Ian-SAfc](https://forum.juce.com/u/Ian-SAfc)\
**Post date:** [January 21, 2023, 7:21pm UTC](https://forum.juce.com/t/how-do-i-get-this-sliderattachment-set-up-properly-im-halfway-there/54624/3 "2023-01-21T19:21:12Z")

</div>

Got it working, thanks… I’m working now on how to change those default horizontal sliders to rotary ones and position them. 👍

---

<div class="post-metadata">

**Author:** ![Mrugalla](https://sea2.discourse-cdn.com/flex026/user_avatar/forum.juce.com/mrugalla/32/13092_2.png) [@Mrugalla](https://forum.juce.com/u/Mrugalla)\
**Post date:** [January 22, 2023, 9:48am UTC](https://forum.juce.com/t/how-do-i-get-this-sliderattachment-set-up-properly-im-halfway-there/54624/4 "2023-01-22T09:48:31Z")

</div>

that tutorial is a nice starting point, but not well executed. first of all it doesn’t even show that one should use a method call to create the parameter layout, and 2ndly it uses unique\_ptr for the attachments instead of just explaining what an initializer list is good for, even though one was used for apvts itself.

creating parameters with a free function is not required, but just best practice, so that the constructor of the processor doesn’t look so cluttered and in case some intermediate variables need to be constructed before being passed on at parameter creation. generally a much more pleasant experience.

and unique\_ptr is just overkill for that situation. even considering that it automatically handles its scope it’s slightly more of a burdon than something that is just normally instantiated on the stack and has you use the → operator all the time.  
watch this tut and you hopefully know what i mean. don’t worry. it’s easy peasy: [Member Initializer Lists in C++ (Constructor Initializer List) - YouTube](https://youtu.be/1nfuYMXjZsA)

---

<div class="post-metadata">

**Author:** ![Ian-SAfc](https://sea2.discourse-cdn.com/flex026/user_avatar/forum.juce.com/ian-safc/32/17877_2.png) [@Ian-SAfc](https://forum.juce.com/u/Ian-SAfc)\
**Post date:** [January 23, 2023, 3:42pm UTC](https://forum.juce.com/t/how-do-i-get-this-sliderattachment-set-up-properly-im-halfway-there/54624/5 "2023-01-23T15:42:34Z")

</div>

thanks 👍 I did look at the Juce tutorial, but found a video online which helped me through the process too.  
Here’s what I went for  
in PluginProcessor.h:

```auto
static juce::AudioProcessorValueTreeState::ParameterLayout createParameterLayout();
juce::AudioProcessorValueTreeState apvts{ *this, nullptr, "Parameters", createParameterLayout() };

```

In PluginProcessor.cpp:

```auto
juce::AudioProcessorEditor* mypluginname::createEditor()
{
    //return new mypluginnameAudioProcessorEditor (*this);
    return new juce::GenericAudioProcessorEditor(*this);
}

```

```auto
juce::AudioProcessorValueTreeState::ParameterLayout mypluginnameAudioProcessor::createParameterLayout()
{
    juce::AudioProcessorValueTreeState::ParameterLayout layout;
    layout.add(std::make_unique<juce::AudioParameterFloat>("mGain", "Gain",
        juce::NormalisableRange<float>(0.0, 1.0, 0.1, 1.f), 0.0));
... etc...
    return layout; }

```

and to access the values: `gain_value = apvts.getRawParameterValue("mGain")->load();`

---

<div class="post-metadata">

**Author:** ![Mrugalla](https://sea2.discourse-cdn.com/flex026/user_avatar/forum.juce.com/mrugalla/32/13092_2.png) [@Mrugalla](https://forum.juce.com/u/Mrugalla)\
**Post date:** [January 23, 2023, 7:11pm UTC](https://forum.juce.com/t/how-do-i-get-this-sliderattachment-set-up-properly-im-halfway-there/54624/6 "2023-01-23T19:11:47Z")

</div>

nice. you probably want to find a better way to access the parameter though. a string compare is expensive. i personally like to make an enum with all the parameters so i can index them with their names, but without having to use a string. some people prefer to just give each parameter its own member variable in the processor. all has their pros and cons

---

<div class="post-metadata">

**Author:** ![aamf](https://sea2.discourse-cdn.com/flex026/user_avatar/forum.juce.com/aamf/32/19941_2.png) [@aamf](https://forum.juce.com/u/aamf)\
**Post date:** [January 23, 2023, 10:39pm UTC](https://forum.juce.com/t/how-do-i-get-this-sliderattachment-set-up-properly-im-halfway-there/54624/7 "2023-01-23T22:39:29Z")

</div>

Hey, I found this interesting and looked under the hood. `getRawParameterValue` takes a `StringRef` and uses it to look up the pointer to the corresponding `ParameterAdapter` in a `std::map` (adapterTable). So it’s just performing a table look-up. Shouldn’t it be fast enough?

---

<div class="post-metadata">

**Author:** ![xenakios](https://sea2.discourse-cdn.com/flex026/user_avatar/forum.juce.com/xenakios/32/4047_2.png) [@xenakios](https://forum.juce.com/u/xenakios)\
**Post date:** [January 23, 2023, 10:42pm UTC](https://forum.juce.com/t/how-do-i-get-this-sliderattachment-set-up-properly-im-halfway-there/54624/8 "2023-01-23T22:42:58Z")

</div>

> [@aamf](#):
>
> Shouldn’t it be fast enough?

It’s still unnecessary overhead, you might not want to have if you have, say, hundreds of parameters in your plugin. I am currently working on a plugin with about 20 parameters and using getRawParameterValue, but I might look into changing that at some point. (The plugin seems to be one that is going to need a ton more parameters in the future…)

---

<div class="post-metadata">

**Author:** ![aamf](https://sea2.discourse-cdn.com/flex026/user_avatar/forum.juce.com/aamf/32/19941_2.png) [@aamf](https://forum.juce.com/u/aamf)\
**Post date:** [January 30, 2023, 12:47pm UTC](https://forum.juce.com/t/how-do-i-get-this-sliderattachment-set-up-properly-im-halfway-there/54624/9 "2023-01-30T12:47:28Z")

</div>

Would you say there’s something wrong in using getRawParameterValue as described in the tutorial mentioned above, that is, using it just to get a pointer to the value, and thereafter dereferencing that pointer?

---

<div class="post-metadata">

**Author:** ![Mrugalla](https://sea2.discourse-cdn.com/flex026/user_avatar/forum.juce.com/mrugalla/32/13092_2.png) [@Mrugalla](https://forum.juce.com/u/Mrugalla)\
**Post date:** [January 30, 2023, 2:46pm UTC](https://forum.juce.com/t/how-do-i-get-this-sliderattachment-set-up-properly-im-halfway-there/54624/10 "2023-01-30T14:46:30Z")

</div>

one option that is pretty good is this. at initialisation you make a vector with all the RangedAudioParameter\*

[https://docs.juce.com/master/classAudioProcessorValueTreeState.html#a1f4daee2af4de07db54d53ada539b7f9](https://docs.juce.com/master/classAudioProcessorValueTreeState.html#a1f4daee2af4de07db54d53ada539b7f9)

because if you look at the docs of RangedAudioParameter

[https://docs.juce.com/master/classRangedAudioParameter.html](https://docs.juce.com/master/classRangedAudioParameter.html)

you see it has both the normalisation and denormalisation functions so you can freely decide which value to use in your dsp processing. its base class is AudioProcessorParameter so you also have all the methods of this class available then:

[https://docs.juce.com/master/classAudioProcessorParameter.html](https://docs.juce.com/master/classAudioProcessorParameter.html)

---

<div class="post-metadata">

**Author:** ![daniel](https://sea2.discourse-cdn.com/flex026/user_avatar/forum.juce.com/daniel/32/790_2.png) [@daniel](https://forum.juce.com/u/daniel)\
**Post date:** [January 30, 2023, 2:55pm UTC](https://forum.juce.com/t/how-do-i-get-this-sliderattachment-set-up-properly-im-halfway-there/54624/11 "2023-01-30T14:55:48Z")

</div>

I would advice against that. The reason is, that if you already upcast to RangedBasedAudioParameter, you might as well go the whole nine yards and store it in the actual type wherever you need it.

The reason is that the AudioParameterFloat has a get() method, that returns the parameter as float in the correct range. The AudioParameterInt get() method returns an int in the correct range etc. Don’t do this by hand. Also every type conversion is a potential mistake, just as well as range conversions.

A vector requires maintenance in different places: you need to memorize which parameter is what (by index), and if the vector contents changes all your code is messed up.

For me keeping a pointer to the parameter wherever you need it is the most readable and future proof way:

```auto
// member
juce::AudioParameterFloat* gain = nullptr;

// in the constructor once in a lifetime
gain = dynamic_cast<juce::AudioParameterFloat*>(apvts.getParameter ("gain"));
jassert (gain); // double check the parameter exists and has the correct type

```

---

<div class="post-metadata">

**Author:** ![aamf](https://sea2.discourse-cdn.com/flex026/user_avatar/forum.juce.com/aamf/32/19941_2.png) [@aamf](https://forum.juce.com/u/aamf)\
**Post date:** [January 30, 2023, 4:08pm UTC](https://forum.juce.com/t/how-do-i-get-this-sliderattachment-set-up-properly-im-halfway-there/54624/12 "2023-01-30T16:08:11Z")

</div>

According to the documentation, `getRawParameterValue` returns a pointer to a floating point representation of a particular parameter (a `std::atomic<float>*`) which “a realtime process can read”.

Can a j`uce::AudioParameterFloat*` likewise be read by a realtime process?

---

<div class="post-metadata">

**Author:** ![daniel](https://sea2.discourse-cdn.com/flex026/user_avatar/forum.juce.com/daniel/32/790_2.png) [@daniel](https://forum.juce.com/u/daniel)\
**Post date:** [January 30, 2023, 4:20pm UTC](https://forum.juce.com/t/how-do-i-get-this-sliderattachment-set-up-properly-im-halfway-there/54624/13 "2023-01-30T16:20:59Z")

</div>

If in doubt have a look into the sources. The get() method returns the same atomic value that represents the parameter value:

> <https://github.com/juce-framework/JUCE/blob/master/modules/juce_audio_processors/utilities/juce_AudioParameterFloat.h#L121>

A bit further down you find:

```cpp
std::atomic<float> value;

```

Even without the dodgy raw pointer…

---

<div class="post-metadata">

**Author:** ![aamf](https://sea2.discourse-cdn.com/flex026/user_avatar/forum.juce.com/aamf/32/19941_2.png) [@aamf](https://forum.juce.com/u/aamf)\
**Post date:** [January 30, 2023, 4:25pm UTC](https://forum.juce.com/t/how-do-i-get-this-sliderattachment-set-up-properly-im-halfway-there/54624/14 "2023-01-30T16:25:45Z")

</div>

Ah perfect.

---

<div class="post-metadata">

**Author:** ![Mrugalla](https://sea2.discourse-cdn.com/flex026/user_avatar/forum.juce.com/mrugalla/32/13092_2.png) [@Mrugalla](https://forum.juce.com/u/Mrugalla)\
**Post date:** [January 30, 2023, 9:29pm UTC](https://forum.juce.com/t/how-do-i-get-this-sliderattachment-set-up-properly-im-halfway-there/54624/15 "2023-01-30T21:29:46Z")

</div>

i still really dislike this approach, because it means you can’t just have one big vector with the parameters, except with some ugly casting in processBlock. and who cares if some parameters are float that could also be bool? if you check for a bool being false or true or a float being smaller or greater than .5 doesn’t make a difference. most parameters, even int or bool are being used in some way where they have to be converted into a float type parameter anyway, for example if you wanna smoothen their value or when combining them with the output of other parameters. so actually having an advantage of parameters not being float all the time doesn’t happen very often.

edit: in fact checking for a float being greater than .5 is even better than checking for a bool being true or false, because true is everything except 0, so if you have something like FL studio’s parameter randomizer randomizing the bypass parameter you just completely knock out the entire plugin. a switch should always be a 50:50 thing

---

<div class="post-metadata">

**Author:** ![daniel](https://sea2.discourse-cdn.com/flex026/user_avatar/forum.juce.com/daniel/32/790_2.png) [@daniel](https://forum.juce.com/u/daniel)\
**Post date:** [January 30, 2023, 9:34pm UTC](https://forum.juce.com/t/how-do-i-get-this-sliderattachment-set-up-properly-im-halfway-there/54624/16 "2023-01-30T21:34:22Z")

</div>

> [@Mrugalla](#):
>
> edit: in fact checking for a float being greater than .5 is even better than checking for a bool being true or false

That is exactly my point, you don’t do it yourself, you use the framework and it’s potential. And fact-checking… yes, juce does the right thing, I don’t have to spend a thought

> <https://github.com/juce-framework/JUCE/blob/master/modules/juce_audio_processors/utilities/juce_AudioParameterBool.h#L101>

---

<div class="post-metadata">

**Author:** ![Mrugalla](https://sea2.discourse-cdn.com/flex026/user_avatar/forum.juce.com/mrugalla/32/13092_2.png) [@Mrugalla](https://forum.juce.com/u/Mrugalla)\
**Post date:** [January 30, 2023, 11:35pm UTC](https://forum.juce.com/t/how-do-i-get-this-sliderattachment-set-up-properly-im-halfway-there/54624/17 "2023-01-30T23:35:06Z")

</div>

ok nice. but isn’t it kinda one conditional too much then?

let’s say i have a parameterBool for a polarity switch. so while getting the parameter value there is the value \> .5 conditional returning to bool. then in processBlock i check if that bool is true and then multiply all audio with -1.  
whereas when the parameter always just returns its float you can check for bigger than .5 yourself in processBlock and only have 1 conditional.

to me it just seems like wrapping a parameter around something that pretends like a parameter’s heart is not an atomic float doesn’t really help
