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.