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
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:
- 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.
- Audio waveform: this also works fine. But finally I’ve found out that in Logic Pro when user stop playback there is no more
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
Timercopy that buffer, and zero it (to use zeroed buffer when
processBlockstops filling it). And also in
Timershift (rotate ring buffer) to achieve moving waveform from right to left, and avoid freezing.
And then in
VBlankAttachment::callbackuse buffer filled in
Timerto 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 Timer
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
And I’ve also heard the
Timer not guarantees the length of interval set by
startTimer(myInterval). So I also wondered about using
Time::waitForMillisecondCounter(); in run, instead
Timer. But then I probaly need to synch by myself that new thread with
For any feedback great thanks in advance.