Cant get the Processor to talk to the Editor

Hey there.

I’m trying to get a simple plugin done, but since I’m a noob at C++ and Juce, I’m failing big time and could do with some help.

I managed to get a plugin up and running with Juicer in Xcode, testing in the JUCE AudioPluginHost which:
a) receives MIDI notes in the Processor thread and calculates the tempo from their distance, then write that to variable TempoProc and make it visible via DBG in the debug console. Check

b) has a scalable Editor window with a label that displays the variable TempoGUI. Check

c) has a Timer implemented which periodically checks if TempoGUI has changed and if so, refreshes the label with the correct value

However, I can’t seem to find a way to make TempoProc yell “Hey TempoGUI, yes, you, over in the other thread - I have changed to this new value, adjust yourself!”

What I have tried so far, to show you the scale of my ineptitude:

  • Tried to read up on the issue, but all I found was along the lines of “Oh, that’s easy, you just need to inflect a convoltation on the (mergoffled) backwibble in procrastic mode, but make sure you don’t overpledge the frobbleworth-constantation, its offlepoff conflictions can get nasty if you don’t frimbiffle them in time before the grenforth gramblination runs out. But no worries, you can fix this with an easy grek or two.” This, to be honest, makes my eyes glaze over, if anything.

  • Checked into Broadcasters and Listeners, however I guess these are designed to signal the change of GUI elements into the processor, not the other way round.

  • Created a function in the Editor, made it a friend of the Processor so it can access the Processor’s variables and tried to read Processor’s TempoProc from the Editor which ended in the compiler complaining about TempoProc not being declared in Editor. Of course it isn’t, Captain Obvious, it lives in the Processor thread, that’s the point of the exercise.

  • Created a function in the Processor to write TempoProc to TempoGUI which of course results in TempoGUI not being declared in the Processor. Well, I’m not surprised.

So how do I signal the new value of a variable in the processor thread to another variable in the Editor thread ?

Thanks

I think you might be mixing up two things here, which are the scope and lifetime of a class or variable and threads on the other hand.

A variable or class does not belong to one special thread. Neither do member functions of classes. So it is perfectly fine for a class that member functions are accessed by different threads even at the same time.

So an easy solution to your problem is to add a getTempo() member function to your processor which returns the current value of the probably private TempoProc variable.

Now your editor always has a reference to the processor, as you can be sure that there is a processor somewhere if an editor exists (you can’t be sure of it the other way round). You can use this reference to access public member functions and member variables of your processor from within the functions of your editor.

Now what you want to do in your editors Timer callback is to periodically check the return value of processor.getTempo() and update your label accordingly.

This should just work in most cases. However you can trigger one rare but unwanted situation if by chance the audio thread writes a new value to the processors TempoProc variable while the editors message thread calls getTempo and therefore reads the value of TempoProc at the very same moment. This way you could read a variable that is half-written or something like that, which could lead to completely unusable results. To work around this issue, so called atomic variables exist. Atomic variables are safe to write and read at the same time from different threads, as they guarantee that you’ll never read a half-written result from them. You can use the juce::Atomic or the std::atomic class to make an atomic variable.

Hope this gets you started in finding a solution and clearing up some confusion…

1 Like

A couple of things:

  • In a plugin, your processor always exists, but the editor may not.
  • The processor is usually doing something on the audio thread which is VERY time sensitive, but the editor is usually working on another thread which isn’t as time sensitive.

So, most of us never have the processor access the editor, but have the editor access the processor and it’s variables when it needs them.

Hope that helps.

1 Like

Hey pizzafilms.

Yes, I am aware of these rules, thanks for reminding me.

Hey PluginPenguin.

Well, this indeed does clear up some confusion. Especially the dot in processor.getTempo() is the elephant in the room that I could not see, as I always and only connected the dot (see what I did there?) to objects, not functions.

Now it works beautifully and I can go on to a) drill down on that atomic feature and b) make it more accurate. I’m using getMillisecondCounterHiRes to measure the distance between notes and that is mostly precise enough, although at 120bpm it swings between 119.8 and 120.2 (I’m rounding to 1 decimal to get a sensible readout).

Thank you so much for pointing me in the right direction.

you are forgetting the offline bounce. The only time that matters is from the audio clock, either count samples or use AudioPlayHead.

getMillisecondCounterHiRes() shows the wall clock, which is meaningless in an audio pipeline. Even if it appears “good enough” for the moment…

1 Like

Why not just use the time stamps of the MIDI messages and the host playhead position? (If the host provides no playhead or it can’t be used because you don’t want to have the host timeline playback running, you can also count time as samples yourself at each processBlock call.)

Also, as Daniel pointed out, things don’t really happen at wall clock time anyway. (It may seem so in some circumstances, but there is offline render and “render ahead” features to consider too in the hosts.)

Yes I am aware that wall clock is not the most precise representation of “now”, I was just using the next best “good enough” time I could find to get this going without disappearing in that rabbit hole, as there’s enough other stuff to sort out before.

This plugin’s single task is to display a drummer’s accuracy in a live environment.

Common scenario is, there’s a drumloop going to be triggered by the drummer 1 minute into the song. Traditionally, you start a click track and the drummer locks in to that so he hits the tempo bang on.
But what if he doesn’t want to follow a click just to hit one specific spot 1min later ? What if there’s a free flowing part in the middle which defeats use of a click track?

This plugin shows the drummer his current tempo so he can monitor and adjust properly and steer towards the hit point with full authority.

Therefore, the plugin is designed to be fully independent of host tempo and host transport state. It does not have to care of pre-rendering and bounces, as every MIDI event it receives is live and also there’s no audio involved

I will look into sample counting later, but it might turn out that an accuracy of 0,2bpm is indeed good enough.

Next task is to correctly detect and evaluate in-between ghost notes.

Thanks guys