Creating an "Invisible" Slider or Parameter

Greetings All!

In short, I am attempting to calculate values from the user’s screenshot (a juce::Image object, which is a matrix of juce::Colour objects) and pass those calculations to the AudioProcessor. The screenshot is taken and displayed inside the AudioProcessorEditor.

This link takes you to the example I used to learn how to use the juce::CameraDevice class in order to capture and display the screenshot inside your AudioProcessorEditor: https://github.com/juce-framework/JUCE/blob/master/examples/GUI/CameraDemo.h

The first problem I ran into was how would I pass these calculations from the AudioProcessorEditor to the AudioProcessor if I don’t plan on having any juce::Sliders?

My answer was to still create the juce::Sliders and SliderAttachments WITHOUT calling “addAndMakeVisible()” in the AudioProcessorEditor.

So I set up the AudioProcessorValueTreeState in the AudioProcessor as normal, connected with the SliderAttachments and prayed calling juce::Slider.setValue() from inside the AudioProcessorEditor would update the parameters calculated from the juce::Image each time a new screenshot was taken.

Unfortunately that wasn’t the case. The behavior I am experiencing can be described as this:

  • Upon initial plugin load, audio flows through the VST plugin with no additional processing (as expected because user has not taken a screenshot)

  • When the user takes their first screenshot; the parameters are calculated and the audio effect starts being applied to the input audio signal (again as expected)

  • When the user takes the next (second, third, etc.) screenshot, however, there isn’t an update to the parameters and the resulting audio effect does not change as expected.

My next answer was to instead, pass the screenshot (juce::Image) into the AudioProcessor to calculate and update the “invisible” sliders using the AudioProcessorValueTreeState. I created a function that would accept the screenshot from the AudioProcessorEditor. To no avail; even caclulating and updating the parameters inside the AudioProcessor led to no change in effect upon the second screenshot taken.

The latest thing I tried was using the Gesture API for juce::RangedAudioParameters (aka our slider attachments in the tree state) since “addAndMakeVisible()” was never called for the Sliders in the AudioProcessorEditor.

Even after this addition, I am still not able to calculate a new effect after the first screenshot is taken.

I know this question is pretty involved. A can of worms if you will.
But any insight/feedback is tremendously appreciated! Thank you for your time (ahead of time)!

(some extra reference: I am normalizing the parameters calculated from the image pixels, and also clamping them so they do not exceed a specified normalized range)

I didn’t follow all of the intricacies of what you are asking, but if you don’t add the component to your main component, likely nothing will update it.

You could try addChildComponent() which adds the component, but keeps it invisible. Or hiding the component after addAndMakeVisible() with setVisible(false).

1 Like

I’m not sure you need a slider, AudioProcessorValueTreeState allows you to get a parameter, and that parameter has its set/getValue methods.

1 Like

No worries. And thank you for bringing this up… I forgot to add I was calling addChildComponent() so my apologies for not including that detail.

I’m going to try the second method you suggested to see if that produces a different build.

Its dawning on me that this is likely related to the apvts and the fact I am using sliders when not necessary as another commenter suggested.

Still I greatly appreciate your comment!

I think this is what I need to try. How would you define the apvts parameters in the AudioProcessor then?

For example, the way I usually define those parameters is something like sample below; would this still be the correct way to create the params without sliders & attachments?

(createParams() defined in PluginProcessor.h; this snippet is from PluginProcessor.cpp)

juce::AudioProcessorValueTreeState::ParameterLayout AudioProcessor::createParams() {

std::vector<std::unique_ptr<juce::RangedAudioParameter>> params;

auto paramOne = std::make_unique<juce::AudioParameterFloat>("ID1", "NAME1", ....);
auto paramTwo = std::make_unique<juce::AudioParameterFloat>("ID2", "NAME2", ....);
params.push_back(std::move(paramOne));
params.push_back(std::move(paramTwo));
return { params.begin(), params.end() };

}

Thank you for your help again!

I just define an AudioProcessorValueTreeState and add parameters using apvts.createAndAddParameter. You can access those parameters and their value through the ID. it is also possible to get a pointer to the value using apvts.getRawParameterValue although I’m not sure how and when it should be used, I use it in the audioProcessor

1 Like

Thank you for the insight. I am just getting around to trying this now. I’ll continue commenting on the post if I have more questions. But seriously thank you for the help.

The one question I have now is that, I am also trying to update the values in the apvts without a slider/slider attachment. Could I just dereference the pointer from apvts.getRawParameterValue and set it to a new value? I am having trouble finding a method in the apvts class to set/update the parameters.

Also, on this topic; I see that apvts.getRawParameterValue returns a juce::Atomic; do you think wrapping the values as a juce::Atomic in the AudioProcessor would help?

I use the raw parameter to read, with atomic float pointers. I’m not sure if it’s a good idea to use it to update the value directly.

In any case you also have the option to get the parameter with getParameter, or get the value with getParameterAsValue. I think one of these options should work for you.

https://docs.juce.com/master/classAudioProcessorValueTreeState.html

1 Like