What is the best way to update GUI from AudioProcessor

Hello,
I want to have some audio processor parameters that is not automatable.

And I read many threads about that subject. But can’t find simply solution.
Some people say the solution is to create own class inherited from AudioProcessorValueTreeState::Parameter and override method iaAutomatable() to make it return always false. But other people say isAutomatable() is not supported by some hosts.

So for my non automatable parameters I tried to avoid using AudioProcessorValueTreeState::Parameter and instead I use just simply variables for example float.

But then the problem is how to update slider value from setStateInformation() when I want to recall saved parameters. Or from other methods. Of course I can create pointer to my slider and then update that slider by that pointer. But then the next problem is when I open let’s say Logic Pro X project and my plugin is loaded but by default it’s closed, then my pointer to slider would be null.

So I need also create in editor some reference to my parameter, which allows me to update slider properly always I open the editor.

But now it starts to look like some mess. I feel it’s not smart solution. So I want to ask for advice how you solve such issues?

For any help thanks in advance.
Best Regards

In the ValueTree of your AudioProcessorValueTreeState you can add a childnode for your additional properties. In this node you expose a property as Value. Now in your Slider you call referTo on that value:

Value MyProcessor::getMyValue()
{
    auto child = treeState.state.getOrCreateChildWithName ("private", nullptr);
    return child.getPropertyAsValue ("foo", nullptr);
}

MyEditor::MyEditor (MyProcessor& p) : AudioProcessor (p), processor (p)
{
    slider.setRange (0, 10);
    slider.referTo (processor.getMyValue()); // will always reflect the property in state and update it
    addAndMakeVisible (slider);
}

And you can use the value like

auto v = double (getMyValue().getValue());

EDIT: this doesn’t care about thread safety! Reading the value from the audio thread would not be thread safe. Would be cool to have some kind of atomic var…

And watch Dave’s talk from yesterdays meetup roughly about that topic:
Dave Rowland - Real-time Tradeoffs in Audio Programming

2 Likes

Hello,
great thanks for your support, but:

  1. I think you’ve made some small mistake. You’ve wrote:
    slider.referTo (processor.getMyValue());
    But shouldn’t it be:
    slider.getValueObject().referTo (processor.getMyValue());

  2. as I understand Value is created inside the scope of getMyValue(), so how can I change that value from other method. I tried that:
    getMyValue().setValue(newValue);

But that doesn’t update my slider. I suppose I do something wrong.

  1. To what refer the strings "private" and "foo". Shouldn’t it be the same string in both cases?

This is the tutorial I used to wrap my head around this concept. However, I am not using the AudioProcessorValueTreeState because I am also importing plugins, so the AudioProcessorParameter is what I am focused on, which you can subclass. For threading, using an atomic variable (like in the tutorial) I think should make it easy to access from GUI without interference.
So I recommend subclassing AudioProcessorParameter, so you can use all the setStateInformation() type methods. But as you say the AudioProcessorValueTreeState is useful, maybe subcalssing AudioProcessorValueTreeState::Parameter would be more appropriate - but I think you should find a single (sub-)class solution that will deal with non-automatable parameters as well. How come you can’t just return false on those and true on the automatable ones?

  1. yes you are correct. Sorry :slight_smile:
  2. Ok, then it seems we need to return the Value object by reference. I was lately under the impression, that the ValueSource would stay intact at copy, but seems not.
    Lets change to that and see if it works:
Value& MyProcessor::getMyValue()
{
    auto child = treeState.state.getOrCreateChildWithName ("private", nullptr);
    return child.getPropertyAsValue ("foo", nullptr);
}
  1. That string “private” is a sub node I introduced to stay away from the stuff the parameters save in the ValueTree. Inside this childnode we put now an arbitrary amount of properties, one is called foo.
    Since we always access via getMyValue(), the name doesn’t matter at all, unless it clashes with other properties.

That is not necessary, since the setStateInformation() will store our properties, that we put into the public state ValueTree alongside with no limitation.

1 Like

Hello,
now when I changed getMyValue() to return Value& I get such exception when I call getMyValue().setValue(_aheadTime); :

Exception thrown: read access violation.
this->value.referencedObject-> was 0xFFFFFFFFFFFFFFEF.

I’ve found out that calling
slider.getValueObject().referTo(processor.getMyValue());
also throw the exception like that:

Exception thrown at 0x00007FFE874F15D5 (vcruntime140d.dll) in AudioPluginHost.exe: 0xC0000005: Access violation writing location 0x00007FFE6030EE30.

So it looks like child.getPropertyAsValue ("foo", nullptr); return just temporaty value that doesn’t exist anymore out of getMyValue()

OK, I will try to just instance the Value myValue as a member of AudioProcessor. Let’s check if it would solve the problem

OK, so with Value as a member of AudioProcessor works ALMOST perfect. Thanks for your great help.

But why almost? Because now my slider’s text box is not updating. I suppose I need to call in someway the mySliderListener.sliderValueChanged() or in someway synchronise it.

Unfortunately, the Value::setValue() doesn’t support enum NotificationType. So I need to figure it out.

Great you got this far. Sorry I am too busy to do tests myself. In my experience referTo did send notifications, so I had the opposite problem stopping it from notifying… very weird…

1 Like