HighResolutionTimer Deadlock

I tried to find the juce-way solution for my problem in my brain, the forum and the whole internet, but I couldn't.

 

I want to use a HighResolutionTimer in my application for updating the GUI in realtime. (Normal Timer is too slow.)

For updating the GUI I need to get a MessageManagerLock. (Or is there another way?)

But when I want to stop the timer from a button of the GUI, this creates a deadlock since the GUI gets the MessageManagerLock and waits in the stopTimer() call for left hiResTimerCallbacks() to finish, but these are waiting for the MessageManagerLock as well. (I hope I understood it right.)

So I tried:

void myTimer::hiResTimerCallback()
{
    MessageManagerLock CLock(Thread::getCurrentThread());     
    if (CLock.lockWasGained())
    {         
        update();
    }
}

From the MessageManagerLock constructor:

Optionally, you can pass a thread object here, and while waiting to obtain the lock, this method will keep checking whether the thread has been given the Thread::signalThreadShouldExit() signal. If this happens, then it will return without gaining the lock. If you pass a thread, you must check whether the lock was successful by calling lockWasGained(). If this is false, your thread is being told to die, so you should take evasive action.

But getCurrentThread() returns a nullpointer!? (Because the hiResTimerCallbacks() gets called from a non-juce thread?)

What can I do?
 

Any help is appreciated. Thank you very much!

It's a very bad idea to update your GUI in realtime! This should always happen on the message thread. GUI updates faster than something around 50 Hz are not perceivable by the eye anyway, so I'm not sure what you try to accomplish here?

I am metering things in processBlock() and want to have a realtime graph plot of the values while playing the audio.

If I use a normal Timer, it is okay in the beginning. But after some time the graph falls behind the audio. So for example the audio track is at second 50 but the graph at second 25.

I can't throw values away because I want to keep the history.

Thank you.

What you probably want to do is to stick your audio values into a Buffer in the realtime thread, and then render the contents of the most current Buffer (or some other function of the buffer content) on the normal GUI thread.

Check out how the AudioVisualiserComponent works as a start.

Remember, the GUI is updating much less frequently than the audio callback is happening, and it has to be that way. You simply can't render all the audio samples graphically as they happen (and I don't see why you would want this in the first place?). If you need to keep a history of all the audio data, you could for example write them to disk... (also buffered of course)

 

You've clearly never played modern PC video games. There's absolutely a perceivable difference when running vsync'd on 60Hz vs 144Hz monitors.

OK, maybe the number 50 Hz as the perceivable limit is not correct, and it's more like 60 Hz (where Hz = fps). Sorry for that, but in any case the GUI should not be rendered on a high-resolution realtime thread in the way inkeye described, at least not in JUCE, as far as I know

I guess that modern PC games have more sophisticated ways of doing things than JUCE's message/GUI thread, but I don't see how this is relevant here.

And by the way, I like games and I have played some, in fact I have a PlayStation at home... and I am annoyed by laggy framerates just like everyone else.

1 Like

Your comparison to consoles is probably unfair since most games have difficulty getting above 30fps for various reasons, so they tend to lock their update/draw loop to 30fps. Also, consoles don't support output beyond 60fps/1080p (ie: HDTV).

DirectX and OpenGL are designed for performance rendering - JUCE supports the latter, so why not use that?

Yes, this seems like a good idea. Actually it fits really well into the rest of my design!

Sorry, I am not that experienced with GUI-programming. Thank you very much, timur!