COCKOS
CONFEDERATED FORUMS
Cockos : REAPER : NINJAM : Forums
Forum Home : Register : FAQ : Members List : Search :

Go Back   Cockos Incorporated Forums > Other Software Discussion > WDL users forum

Reply
 
Thread Tools Display Modes
Old 05-22-2017, 06:51 AM   #1
Nowhk
Human being with feelings
 
Join Date: Mar 2016
Posts: 234
Default Is there the equivalent "ProcessDoubleReplacing" for the GUI thread?

Hi all,

ProcessDoubleReplacing is called for each buffer (sent by DAW) within the audio thread. Is there the same "general/misc" function called by the GUI thread?

Where for example I can sync some IControl display with "audio" variables processed by audio thread (such as refresh Meter by the current output level).

I'd like to avoid calling method/function (such as SetDirty) within audio thread, which run DSP and I'd like to keep it as optimized as possible. Such calling a general function RefreshAdvancedParametersGUI(); which browse all my AdvancedParameters and keep value from IParam to the linked IControl.

Thanks.
Nowhk is offline   Reply With Quote
Old 05-22-2017, 07:07 AM   #2
Xenakios
Human being with feelings
 
Xenakios's Avatar
 
Join Date: Feb 2007
Location: Oulu, Finland
Posts: 8,062
Default

Quote:
Originally Posted by Nowhk View Post

I'd like to avoid calling method/function (such as SetDirty) within audio thread,
SetDirty is supposed to just set a boolean flag or such, so calling it from the audio thread shouldn't be harmful. (The flag is then later supposed to be checked by the GUI thread from a timer callback or such to see if the graphics needs to be redrawn etc. The implementation of SetDirty in IControl pretty much just does the flag setting if the pushParamToPlug is set to false when calling.)
__________________
I am no longer part of the REAPER community. Please don't contact me with any REAPER-related issues.
Xenakios is offline   Reply With Quote
Old 05-22-2017, 07:18 AM   #3
Nowhk
Human being with feelings
 
Join Date: Mar 2016
Posts: 234
Default

Quote:
Originally Posted by Xenakios View Post
SetDirty is supposed to just set a boolean flag or such, so calling it from the audio thread shouldn't be harmful. (The flag is then later supposed to be checked by the GUI thread from a timer callback or such to see if the graphics needs to be redrawn etc. The implementation of SetDirty in IControl pretty much just does the flag setting if the pushParamToPlug is set to false when calling.)
Ok, but where can I manage the whole logic of GUI? SetDirty is alongside a fixed IControl. What if I'd like to manage the whole graphic? Is there a common function or I need to create a sort of "MasterGUIIControl" a call the SetDirty of that?
Nowhk is offline   Reply With Quote
Old 05-22-2017, 11:45 PM   #4
earlevel
Human being with feelings
 
Join Date: Dec 2015
Posts: 331
Default

Quote:
Originally Posted by Nowhk View Post
ProcessDoubleReplacing is called for each buffer (sent by DAW) within the audio thread. Is there the same "general/misc" function called by the GUI thread?

Where for example I can sync some IControl display with "audio" variables processed by audio thread (such as refresh Meter by the current output level).
Sure, OnGUIIdle is the generic GUI processing method. Override it in any control that needs idle processing.
earlevel is offline   Reply With Quote
Old 05-22-2017, 11:59 PM   #5
Nowhk
Human being with feelings
 
Join Date: Mar 2016
Posts: 234
Default

Hi man

Quote:
Originally Posted by earlevel View Post
Sure, OnGUIIdle is the generic GUI processing method. Override it in any control that needs idle processing.
So:

1. I make a generic IControl (such as MainGUIController);
2. I override that OnGUIIdle function;
3. I call SetDirty() of MainGUIController (which will call OnGUIIdle);

That's the way?

But do I need point 3. or it will automatically called when GUI thread run?
Not sure about that. I see USE_IDLE_CALLS, which seems I can uncomment it and I don't need SetDirty?
Nowhk is offline   Reply With Quote
Old 05-23-2017, 12:37 AM   #6
Nowhk
Human being with feelings
 
Join Date: Mar 2016
Posts: 234
Default

Anyway, I've tried both, uncommenting USE_IDLE_CALLS and call SetDirty() to that IControl... but nothing happens...

Code:
#ifndef MISC_PANEL_H
#define MISC_PANEL_H

#define MISC_PANEL_WIDTH 640
#define MISC_PANEL_HEIGHT 54

class MainIPlug;

class MiscPanel : public IControl
{
public:
	MiscPanel(MainIPlug *plug, int x, int y);
	~MiscPanel() { }

	void OnGUIIdle() {
		DBGMSG("Hello World");
	}
	bool Draw(IGraphics *pGraphics);

private:
	MainIPlug *pPlug;
	IRECT mRectHelpText;
};

#endif // !MISC_PANEL_H
I never see that "Hello World" in console...

But it seems that if it finds "any" dirty control, it won't call that idle function: https://github.com/olilarkin/wdl-ol/...phics.cpp#L745
Since I've some other controls which are always dirty (i.e. inline bool IsDirty() { return true; }), that OnGUIIdle won't never be called.

What's the purpose of that so? :O

Last edited by Nowhk; 05-23-2017 at 12:48 AM.
Nowhk is offline   Reply With Quote
Old 05-23-2017, 04:25 AM   #7
Xenakios
Human being with feelings
 
Xenakios's Avatar
 
Join Date: Feb 2007
Location: Oulu, Finland
Posts: 8,062
Default

edit : Maybe not...
__________________
I am no longer part of the REAPER community. Please don't contact me with any REAPER-related issues.

Last edited by Xenakios; 05-23-2017 at 04:38 AM.
Xenakios is offline   Reply With Quote
Old 05-23-2017, 05:00 AM   #8
Nowhk
Human being with feelings
 
Join Date: Mar 2016
Posts: 234
Default

Quote:
Originally Posted by Xenakios View Post
edit : Maybe not...
Lol that OnIdle seems to be the right place, but I don't know how to deal with it. Maybe should I edit IPlug and call OnGUIIdle even if dirty? Not sure...
Nowhk is offline   Reply With Quote
Old 05-23-2017, 06:28 AM   #9
Youlean
Human being with feelings
 
Youlean's Avatar
 
Join Date: May 2015
Location: Serbia
Posts: 654
Default

Of you want to use this inside IControl class use this:

IsDirty()
{
// Your code

return mDirty;
}
Youlean is offline   Reply With Quote
Old 05-23-2017, 11:53 AM   #10
earlevel
Human being with feelings
 
Join Date: Dec 2015
Posts: 331
Default

Quote:
Originally Posted by Nowhk View Post
I see USE_IDLE_CALLS, which seems I can uncomment it and I don't need SetDirty?
You do need to define USE_IDLE_CALLS. The suggesting, in the code, to uncomment the line in IPlugBase.h isn't a very good one—you might not want it on every plugin, so modifying the framework doesn't make sense. Define it in the project, in Xcode and VS.

My old comment (may no longer be true) in my own code says that only VST and RTAS supported idle calls in the original wdl-ol I downloaded. I added that capability to my own version for AAX. So AU may not have it. All the calls are there, but if there is no mechanism to call it in place, nothing will happen.
earlevel is offline   Reply With Quote
Old 05-24-2017, 01:10 AM   #11
Nowhk
Human being with feelings
 
Join Date: Mar 2016
Posts: 234
Default

Quote:
Originally Posted by earlevel View Post
You do need to define USE_IDLE_CALLS. The suggesting, in the code, to uncomment the line in IPlugBase.h isn't a very good one—you might not want it on every plugin, so modifying the framework doesn't make sense. Define it in the project, in Xcode and VS.

My old comment (may no longer be true) in my own code says that only VST and RTAS supported idle calls in the original wdl-ol I downloaded. I added that capability to my own version for AAX. So AU may not have it. All the calls are there, but if there is no mechanism to call it in place, nothing will happen.
Here OnGUIIdle is never called, neither if I use USE_IDLE_CALLS.

I think the right way is just to override that IsDirty(), as Youlean suggested. It doesn't "sound" like the appropriate/suitable function, but it seems its always called when the GUI Thread run (few lines of code above OnGUIIdle).

Thanks
Nowhk is offline   Reply With Quote
Old 05-24-2017, 03:50 AM   #12
Youlean
Human being with feelings
 
Youlean's Avatar
 
Join Date: May 2015
Location: Serbia
Posts: 654
Default

You should use OnGUIIdle inside your plugin class, not control class.
Youlean is offline   Reply With Quote
Old 05-24-2017, 05:38 AM   #13
Nowhk
Human being with feelings
 
Join Date: Mar 2016
Posts: 234
Default

Quote:
Originally Posted by Youlean View Post
You should use OnGUIIdle inside your plugin class, not control class.
Uhm... why? I'll use it for things related to the GUI thread, not the audio one. It says:

Code:
// Uncomment to enable IPlug::OnIdle() and IGraphics::OnGUIIdle().
So I guess it should works for both audio end gui thread. But it doesn't at all (due to that "dirty" that (for some other IControl) will always result in at least 1 true... (not sure at all why that behaviour).
Nowhk is offline   Reply With Quote
Old 05-24-2017, 05:53 PM   #14
earlevel
Human being with feelings
 
Join Date: Dec 2015
Posts: 331
Default

Quote:
Originally Posted by Nowhk View Post
Here OnGUIIdle is never called, neither if I use USE_IDLE_CALLS.

I think the right way is just to override that IsDirty(), as Youlean suggested. It doesn't "sound" like the appropriate/suitable function, but it seems its always called when the GUI Thread run (few lines of code above OnGUIIdle).

Thanks
You have the source code, look at it.

OnGUIIdle is a method of IControl. Look at what calls it. It's IGraphics::IsDirty. Look at what calls IGraphics::IsDirty. It's a timer driven event loop.

In other words, IPlug regularly—when it's doing nothing else (idle)—checks the controls to see if anything is dirty, and returns the if and where info, to take further action. But IGraphics::IsDirty also has this interesting code:

Code:
#ifdef USE_IDLE_CALLS
  if (dirty)
  {
    mIdleTicks = 0;
  }
  else if (++mIdleTicks > IDLE_TICKS)
  {
    OnGUIIdle();
    mIdleTicks = 0;
  }
#endif
That is, if something is dirty, IGraphics::OnGUIIdle is called—but only after a little time elapses, to limit the rate.

What does IGraphics::OnGUIIdle do? If calls OnGUIIdle for each control:

Code:
void IGraphics::OnGUIIdle()
{
  int i, n = mControls.GetSize();
  IControl** ppControl = mControls.GetList();
  for (i = 0; i < n; ++i, ++ppControl)
  {
    IControl* pControl = *ppControl;
    pControl->OnGUIIdle();
  }
}
There you have it. OnGUIIdle is called if USE_IDLE_CALLS is defined, and while a control is not dirty (it's not idle if something is dirty), but not more often than IDLE_TICKS.

Overriding OnGUIIdle for your control is what you want if you want a control to do something while idle. If it's not working, you will have to set breakpoints or other methods to see what's really happening.
earlevel is offline   Reply With Quote
Old 05-25-2017, 12:12 AM   #15
Nowhk
Human being with feelings
 
Join Date: Mar 2016
Posts: 234
Default

Quote:
Originally Posted by earlevel View Post
That is, if something is dirty, IGraphics::OnGUIIdle is called—but only after a little time elapses, to limit the rate.
Nope As I said above, if any of the controls I have is always dirty (on some IControl I have inline bool IsDirty() { return true; });) that function OnGUIIdle will never be called.

Because there's always "dirty", so OnGUIIdle never reach the call...
Nowhk is offline   Reply With Quote
Old 05-25-2017, 12:14 AM   #16
Youlean
Human being with feelings
 
Youlean's Avatar
 
Join Date: May 2015
Location: Serbia
Posts: 654
Default

Quote:
Originally Posted by Nowhk View Post
Uhm... why? I'll use it for things related to the GUI thread, not the audio one.
Sorry my mistake. Earlevel has explained this very well.
Youlean is offline   Reply With Quote
Old 05-25-2017, 10:16 AM   #17
earlevel
Human being with feelings
 
Join Date: Dec 2015
Posts: 331
Default

Quote:
Originally Posted by Nowhk View Post
Nope As I said above, if any of the controls I have is always dirty (on some IControl I have inline bool IsDirty() { return true; });) that function OnGUIIdle will never be called.

Because there's always "dirty", so OnGUIIdle never reach the call...
You now know how IPlug works, for OnGUIIdle, you now know that you need a design change.
earlevel is offline   Reply With Quote
Old 05-25-2017, 11:41 PM   #18
Nowhk
Human being with feelings
 
Join Date: Mar 2016
Posts: 234
Default

Quote:
Originally Posted by earlevel View Post
You now know how IPlug works, for OnGUIIdle, you now know that you need a design change.
I've learned that some stuff (made by experienced people) are as they are for some reasons

I wouldn't change a design that will create other problems elsewhere.
For the moment I keep IsDirty as function

Thanks
Nowhk is offline   Reply With Quote
Old 05-26-2017, 12:52 AM   #19
earlevel
Human being with feelings
 
Join Date: Dec 2015
Posts: 331
Default

Quote:
Originally Posted by Nowhk View Post
I wouldn't change a design that will create other problems elsewhere.
For the moment I keep IsDirty as function
By all means, do as you wish. But then you must understand, if you keep the interface busy permanently, then it's never idle, and no use looking at OnGUIIdle.

I don't understand the part about "will create other problems elsewhere." You're basically handling it in the same place (part of the code flow) as you would via OnGUIIdle, except that the latter is moderated by a frame rate limit. That means your code handling it is called far more often than is likely necessary. If it takes a significant amount of time to process, it could hold up other things that may need to be more responsive. Since visual feedback does quite well limited to 25-30 fps, it's usually a good idea to limit it and make more time available to other things.
earlevel is offline   Reply With Quote
Old 05-26-2017, 01:41 AM   #20
Nowhk
Human being with feelings
 
Join Date: Mar 2016
Posts: 234
Default

Quote:
Originally Posted by earlevel View Post
By all means, do as you wish. But then you must understand, if you keep the interface busy permanently, then it's never idle, and no use looking at OnGUIIdle.

I don't understand the part about "will create other problems elsewhere." You're basically handling it in the same place (part of the code flow) as you would via OnGUIIdle, except that the latter is moderated by a frame rate limit. That means your code handling it is called far more often than is likely necessary. If it takes a significant amount of time to process, it could hold up other things that may need to be more responsive. Since visual feedback does quite well limited to 25-30 fps, it's usually a good idea to limit it and make more time available to other things.
I see Thanks!

Anyway, I feel "fluid" in IPlug using FPS of 100:

Code:
IGraphics *pGraphics = MakeGraphics(this, GUI_WIDTH, GUI_HEIGHT, 100);
It seems 60 is (sometimes) steppy, with ASIO 256.
Nowhk is offline   Reply With Quote
Reply

Thread Tools
Display Modes

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off

Forum Jump


All times are GMT -7. The time now is 01:58 AM.


Powered by vBulletin® Version 3.8.11
Copyright ©2000 - 2024, vBulletin Solutions Inc.