sendChangeMessage() from Audio Callback- really a good idea?


#1

Is it really a good idea to inform the GUI about updates via sendChangeMessage() from the audio callback, since it uses the Win32 function PostMessage?
I know that MSDN says that PostMessage returns immediately - but I’ve read in other forums that this is not always true, and that would ofcourse lead to audio drops. It’s a must that PostMessage returns immediately, otherwise using sendChangeMessage() in the audio callback is a no-go!
I would like to hear your opinions about this!

Wouldn’t it be possible to just implement the messaging system in JUCE via an own FIFO instead of using OS functions such as PostMessage?


#2

I have my own thread queue (similar to the one from DspFilters). Normally I use a WaitableEvent to signal when the queue goes from empty to non-empty but for the GUI, I use an AsyncUpdater. My handleAsyncUpdate() override processes the GUI thread queue. So I am still using a PostMessage implicitly (due to the implementation of AsyncUpdater built on top of CallbackMessage) but there is only one of them for all queued changes, not one per change.

I don’t think there is any other solution, you need at minimum one call to PostMessage(), since that is the only way to break out of the message loop and execute stuff (on Windows).

To recap, building your own thread queue / FIFO and using AsyncUpdater to notify the GUI when it needs to process the queue is a workable solution and probably the only solution.

Here’s my ThreadQueue:

ThreadQueue.h ThreadQueue.cpp

To use this ThreadQueue with an AsyncUpdater:

struct GuiThreadQueue : public ThreadQueue, public AsyncUpdater
{
  void signal () { triggerAsyncUpdate(); }
  void handleAsyncUpdate () { process (); }
};

Example of posting messages to the queue from the audio I/O callback:

GuiThreadQueue& queue;
queue.call (boost::bind (&Listener::onParamChanged, listener, paramThatChanged, newValue));
queue.call (boost::bind (&Listener::onPlayPosition, listener, playPosition));

#3

Why don’t you just use a Timer and poll instead of using postMessage()?


#4

Polling is yucky!

Anyway… an instance of a thread function queue that works seamlessly with the message thread is in VFLib, it’s called GuiCallQueue and it uses the techniques described here: