GUI text output from Audio Plugin

#1

I’m extending DSPModulePluginDemo.h and would like to print out to its GUI some realtime values as they occur in the dsp section. I’ve created a Label and added it to the GUI. I understand that I can’t call myLabel.setText() from within the Audio Processor’s thread.

My question is how & where to make the call to myLabel.setText()?

Thank you.

0 Likes

#2

There are several options.

Either you use a timer in your editor (GUI), that say every 30msecs checks the realtime value, and updates the label as needed.

Alternatively you use a broadcaster/listener model: in your processor you broadcast a message every time the value is changed; in your editor you use a listener that catches these update messages and subsequently updates the label.

Or use a FIFO if your editor is the only component that needs to be made aware of these value changes.

Frankly, if these values change in realtime as often as samples do (which I suspect in your case), I would advise NOT to reflect that in real time. You do not want your GUI to change a label 44100 times per second.

0 Likes

#3

Yes I’m thinking of updating the labels about once per second, and don’t require much time accuracy. I think I like the timer idea. Seems like with broadcaster/listener or FIFO I’d anyways have to either keep track of time, or else count audio blocks, to know when to broadcast or push to the FIFO?

Could you please provide any examples of creating and using a timer in the context of the demo file I mentioned? I’m new to JUCE and suck at C++.

0 Likes

#4

It is a tricky one…
The challenge is to get the string populated from the audio thread, so it is readable from the message thread. That is already a problem independently of the gui. The proposed solution of running a timer and fetching the string from the processor, is good, but there is no atomic way, the audio thread can set the string.

If you can reduce the string from a free form to a number of alternatives, it will make your life much easier. In this case you have an std::atomic<int> that you can set from the processBlock, and the int will help your GUI to select the right string.

Or if it is about levels, you can have an std::atomic<float> level and a

String getLevelLabel() const
{
    return String (Decibels::gainToDecibels (level.load()), 2) + " dB";
}

which would be safe.

But you cannot write a string and read it from another thread without a lock. To solve that, it takes some trickery, like a FIFO.

0 Likes

#5

Thank you daniel and tomto66. I’m trying to get a timer and callback working. Any help is appreciated. The code below prints out the constructor message and not the callback message. And tomto66 yes the Editor is the only consumer of the values to be output.

class myTimerClass : public Timer
{
public:
    Label *labelPtr;  // [1] This feels wrong. What's right?
    myTimerClass(Label *labelPtr)
    {
        printConstructorMessage(labelPtr);
        startTimerHz(1);  // [2]  2nd attempt at starting timer
    }
    ~myTimerClass() {}
    void timerCallback() override
    {
        printCallbackMessage (labelPtr);
    }
    void printCallbackMessage (Label *myLabelPtr)
    {
        myLabelPtr->setText ("myTimer Callback", dontSendNotification);  // [3] This does not print out
    }
    void printConstructorMessage (Label *myLabelPtr)
    {
        myLabelPtr->setText ("myTimer Constructor", dontSendNotification);  // [4] This does print out
    }
    // startTimerHz(1);  // [5] 1st attempt at starting timer. Doesn't compile
};

	// Within DspModulePluginDemoAudioProcessorEditor:
    myTimerClass myTimer (&timeLabel);
    myTimer.startTimer (1000);  // [6] 3rd attempt at starting timer
0 Likes