Cabbage Logo
Back to Cabbage Site

One or many instruments?

I was wondering about the best solution for managing widgets.
I have a lot of widget spread over multiple groupbox, of which, only one is visible at a time, the other being deactivated.
My question :
Should it be a good idea to make one instrument per groupbox ; this instrument would beturnon when the groupbox is visible andturnoff when it is hidden ?
Would this save some CPU ( the widget not being checked during that time)

Somehow, I have my answer but I would very much appreciate if someone could confirm :
After a little test using the Morpheur synth, and not playing any note : here are the result:

Whole interface managed within 1 instrument, cabbage consumes about 1% CPU
Management of each groupbox done by a separate instrument : cabbage consumes about 0.2% CPU !

I think I will split the management into several instruments.

It really depends on how you write your instruments. For example, the following instrument is effectively off when kEnable is set to 0:

instr 1
if kEnable == 1 then
...lot of complex processing algorithms..
endif
endin

Even with this instrument running, I don’t ink it will use up much CPU if none of the code is being hit. I have to say however that this is just something I’ve always assumed. It’s not based on any research or experimentation!

Thank you !! You gave me the right idea… I was looking for something too much complex, turning on and off instruments

Instead of splitting the management of groupboxes into several instruments, it is better to make a flag and to brace the code of one groupboxto be executed within a test of that flag. In clear,

instr Manage_Menu 
 ; Based on the button which is clicked then set the flag for each groupbox
if chnget:k("But1")==1 then 
  ; set Groupbox visible
        chnset "visible(0)","GB_1"
        chnset "visible(1)", "GB_2"
 ;set a global Flag
       gkFlag_GB1_is_active =1
       gkFlag_GB2_is_active =0
endif
endin 

inst manage_GroupBox
 if gkFlag_GB1_is_active==1 then 
      ; do all the complex business relatively to that groupbox "GB_1"
elseif  gkFlag_GB2_is_active ==1 then
      ; do all the complex business relatively to that groupbox "GB_2"
endif
endin

Of course both instruments must run for ever.

I know it’s just thinking out loud, but if you have if-elseif-endif in manage_Groupbox that would mean that if GB1 is active, GB2 won’t be processed no matter the state of its flag. If that’s what you’re looking for just have one gkFlag and assign the GB number to it.

(I might be talking rubbish!)

Cheers.

Hi Guillermo, @gsenna

Thank you for your comment. I managed to decrease the CPU usage with that very simple trick.
One group box is a master and contains buttons. When one button is clicked, it popup a group box.
One instrument contains the management of all these buttons.
Another instrument contains the management of all groupboxes
In the management of each button, it also set the flag for the relative groupbox to 1 and set the flag of the others to 0.
Skeleton for such a use is thereafter

instr Manage_Menu 
 ; Based on the button which is clicked then set the flag for each groupbox
if chnget:k("But1")==1 then 
  ; set Groupbox visible
        chnset "visible(0)","GB_1"
        chnset "visible(1)", "GB_2"
 ;set a global Flag
       gkFlag_GB1_is_active =1
       gkFlag_GB2_is_active =0
endif
if chnget:k("But2")==1 then 
  ; set Groupbox visible
        chnset "visible(1)","GB_1"
        chnset "visible(0)", "GB_2"
 ;set a global Flag
       gkFlag_GB1_is_active =0
       gkFlag_GB2_is_active =1
endif

; … one button for groupbox
endin

inst manage_GroupBox
 if gkFlag_GB1_is_active==1 then 
      ; do all the complex business relatively to that groupbox "GB_1"
endif

if  gkFlag_GB2_is_active ==1 then
      ; do all the complex business relatively to that groupbox "GB_2"
endif

if  gkFlag_GB3_is_active ==1 then
;blabla do stuff for GB3 
endif

endin

Can a GB be active while it’s invisible? If No, then you can just use one global variable and maybe sprintfk the strings “visible(%d)” and “GB_%d”. It would make the code less repetitive.

Hummm I think only Rory can answer that question.
But the trouble is really to check the state of all widgets ( even if they are hidden )
Let’s imagine an instrument with 10 GBox containing 10 widgets each ( sliders, buttons,etc…) = 100 widgets.
One Gbox is visible at a time.

Then for checking the status of the only 10 visible widgets, we need to go through a loop checking the 100 of them.

Should you have 5 minutes, have a look at my new version of the Morpheur Synth … The code is a little less readable than before ( less commented… but you will see).

I’ll have a look at it.

I was thinking about something like this. I haven’t run it, but maybe you can get an idea from it.

instr Manage_Menu 
  kBut_Call_MainOsc chnget "But_Call_MainOsc"
  kBut_Call_Filters chnget "But_Call_Filters"
  kBut_Call_Filter chnget "But_Call_Filter"
  kBut_Call_Effects chnget "But_Call_Effects"
  
  if changed:k(kBut_Call_MainOsc, kBut_Call_Filters, kBut_Call_Filter, kBut_Call_Effects) == 1 then   
     chnset sprintfk ("visible(%d)", kBut_Call_MainOsc), "GB_MainOsc"
     chnset sprintfk ("visible(%d)", kBut_Call_Filters), "GB_Filters"
     chnset sprintfk ("visible(%d)", kBut_Call_Filter), "GB_Filter"
     chnset sprintfk ("visible(%d)", kBut_Call_Effects), "GB_Effects"
     gkFl = kBut1 << 0 | kBut2 << 1 | kBut3 << 2 | kBut4 << 3
  endif
endin

and then:

instr manage_GroupBox  
  if gkFl == 1 then
    ; proccess MainOsc
  elseif gkFl == 2 then
    ; proccess Filters
  elseif gkFl == 4 then
    ; proccess Filter
  elseif gkFl == 8 then
    ; proccess Effects
  endif
endin

@Karamel1 - This is a very interesting discussion for optimization as a standalone cabbage instrument. But keep in mind that if your goal is to use this a a vst plugin, this approach means that any DAW automation sent to the controls will be disabled if the proper screen isn’t active within the synth’s windows. You could always state this as a caveat and work around it by automating the selection of the synth screen as well, tho that will limit you to only automating widgets from one screen at a time (a little confusing, hopefully that made sense).

Or it could be limited it to certain types of controls that have no function if the window or setting isn’t active anyway. I see this method as perfect for things like selectable on|off features like the delay or chorus effects.

I saw the new Morpheus version posted by the way. Haven’t gotten to try it out yet, but I will soon and send you some any feedback about it from OSX

Indeed, I did not think about this… (being totally noob, I am not familiar with automation in VST).
However, in the morpheur synth, I still can use the controls sent by an external midi keyboard to the DAW, even if the window is not visible. The trick relies on the fact that controllers messages are received in the “ever active” window (Menu Buttons) and the gkvariables and the channel of the widget are updated there.
Maybe this is not the best way because it requires the controller to be explicitly hard coded into the CSD but it works. Switching back to the window where a widget has been updated while it was hidden shows an updated widget.
For instance, the controller N°31 in charge of the main gain,in the morpheur synth, respond to changes triggered by the midi kbd knob whenever the “effect” window is visible or not.

Please let me know if this brings some explanation and if this is an acceptable way of doing the things.