Are VBlankAttachment and Timer synchronised within message thread

Hello,

My main question is:
is it safe to fill buffers in timercallback() started in message thread, and then use those buffers in VBlankAttachment::callback? Or should I use any critical section?

And here some explanation:
As I remember (at the moment I can’t find explicit info in juce docs) timerCallback() is synchronised with message thread. But not sure how it is with new VBlankAttachment.

To be honest I am still on the begining of my way in programming world. And I am not even sure (I assume but not sure) if Component::paint() is syncronised with message thread. Of course I know it sounds stupid, but I discovered many times that Component::paint() is called from some systems methods. And repaint() also doesn’t call paint() synchronously. So the question in my mind is: Are they for sure synchronised?

I am after studying of those videos:
Fabian Renn-Giles & Dave Rowland - Real-time 101 - part I: Investigating the real-time problem space
Dave Rowland & Fabian Renn-Giles - Real-time 101 - Part II: The real-time audio developer’s toolbox

And I still have many doubts which solution should I use in my issues. I am working on visualisers in my plugin. I mean printing waveform and spectrum analyser. Actually they are both works now, even nice. But I’ve found out two issues:

  1. Spectrum analyser: I fill buffer in audio real-time thread. And then in message thread (specifically in timerCallback()) I call:
juce::ScopedLock lockedForReading (juceCriticalSection);
bufferForFFT.copyFrom(0, 0, bufferFilledInProcessBlock[i], 0, 0, juceFft.getSize()/2);

And I started worrying if juce::ScopedLock can block my audio real-time thread.
Of course I use some fifos (here specifically juce::AbstractFifo) which wait for new data etc. But that exact issue is not about Fifo but about blocking real-time thread when copying buffer filled by that thread.

  1. Audio waveform: this also works fine. But finally I’ve found out that in Logic Pro when user stop playback there is no more processBlock called (releaseResources() is also not called) so my wave form has no more new data so it freezes which I don’t like very much. In ocasion of repairing it I’ve also found out in my code there are also some lacks of synchronisation between threads. Or at least my solutions are not enaugh. But to solve freezed waveform I and after watching mentioned videos I decided the best way would be to fill buffer in audio thread, then in Timer copy that buffer, and zero it (to use zeroed buffer when processBlock stops filling it). And also in Timer shift (rotate ring buffer) to achieve moving waveform from right to left, and avoid freezing.
    And then in VBlankAttachment::callback use buffer filled in Timer to draw Path.

I know I can use VBlankAttachment::callback to do all which is done in Timer, and then remove Timer at all. But as far as I know let’s say new Macbooks can change in the flow the frequency of refreshing display. Of course I could measure interval from last call of ``VBlankAttachment::callback. But I am not exactly sure what exact frequency of refreshing screen I can expect, how to debug it and how to test what happen if intervals will suddenly be rapidly changed. So I prefer to make rotating buffer in fixed intervals in Timer. That's why I wonder if it is save to use shared buffer by TimerandVBlankAttachment::callback`.

To be honest I am affraid that my idea can take me to the point when I was not using VBlankAttachment. I mean the printing and shifting of waveform will be again not as fluid as VBlankAttachment provide if used without any Timer.

And I’ve also heard the Timer not guarantees the length of interval set by startTimer(myInterval). So I also wondered about using juce::Thread with Time::waitForMillisecondCounter(); in run, instead Timer. But then I probaly need to synch by myself that new thread with VBlankAttachment.

For any feedback great thanks in advance.

Best Regards

I don’t know, however, you can debug out this to find out:

juce::MessageManager::getInstance()->isThisTheMessageThread()

He he, thanks. I didn’t know that method.