Cabbage Logo
Back to Cabbage Site

Best way to use variables

It could be very nice if the user could write something like:

<Cabbage>
 <group name="cpuDemandingGroup" enabled="false">
  somewidget_1 ...
  somewidget_2 ...
  ...
  somewidget_400 ...
 </group>
 <group name="lightGroup" enabled="true">
  somewidget_1 ...
  somewidget_2 ...
  somewidget_3 ...
 </group>
</Cabbage>

and then Cabbage would poll only the enabled=“true” groups. Then we should have some button to enable/disable a group… Maybe a special widget that is completely independent from the Csound code, so that it should be faster.

EDIT: after having rethought it, I think it could be useful to enable/disable the groups from the Csound code itself, so there should be a special widget to allow enabling/disabling of the groups from within Csound code.

First thoughts here are we already have group abstractions in the form of plants which have visible() identifier, which can be set from Csound.

So it would just be a matter of preventing any controls contained within a hidden plant from updated. With the one caveat that the plant itself will continue to be polled so that the user can enable and disable it as they wish.

It would all happen in here:

1 Like

That would be very nice (I didn’t know of plants).

They’re groovy :wink:

http://cabbageaudio.com/docs/plants/

It’s very interesting, but I don’t see a “visible” identifier in the plants documentation… And the “Custom plant imports” link in the webpage you posted is broken.

My bad, I need to fix the custom plant import. For a list of identifiers for plants check the groupbox and image widget entries as they are the only widget that can be parents. All identifiers are valid when they are used to create plants.

Well, the synth will have 4 oscillators, 4 enveloppes, 4 filters, 2 lfo, some FX

But they will be grouped in tabs (using groups, visible(1) to show the active tab) and these tabs buttons, oscillators selection button for the enveloppes for example are already like 16 controls, but the user will just see tabs he can click to display one of the four envelopes available

So in from of the user, there are way less controls !

Cool. Let me take a look at implementing some of things we discussed here. Should make things a little quicker.

1 Like

I just pushed through some changes there that might help. Child components of hidden plants will no longer be polled for channel data on each k-cycle. In my tests here this helped improve performance. Note this only works for child components as their visibility can be be enabling by the parent.

I’m having some issues with my Windows machine at the moment. And my automated builds are screwed up since Steinberg decided to remove the VST2 SDK from their servers. Please leave it with me. I should have a new Windows machine shortly.

p.s. I also added support for loading remote URLs with infobutton. Just pass the full URL with http://...

1 Like

Very nice! That could improve the GUI performance a lot if you use many widgets grouped in a few plants and, as a side effect, it makes you create better organized interfaces! :wink:

I’m still having issues with the full build but in the meantime you can try this one. You can simple swap the files in this zip with the ones in your Cabbage folder. Let me know if it works Ok.

@mauro this build is from the develop branch. I made a new branch to investiage some weirdness on Windows. I will merge to master once I get to test out a few things on different platforms. The dev branch uses the latest master release of JUCE.

Is the code bellow a “child component” ? Should I notice performance improvement ?

groupbox bounds(0, 20, 305, 110), visible(1), identchannel("GROUP_OSC1"), plant("GUI_OSC1"){ image bounds(0, 0, 305, 110), colour(20, 30, 40, 255), $bgtabstyle label bounds(245,4,50,20), text("OSC1") rslider bounds(6, 6, 45, 45), channel("osc1wave1"), range(0, 8, 0, 1, 1) , text("Wave1"), $rsliderstyle rslider bounds(48, 6, 45, 45), channel("osc1wave2"), range(0, 8, 0, 1, 1), text("Wave2"), $rsliderstyle rslider bounds(6, 56, 45, 45), channel("osc1morph"), range(0, 0.999, 0, 1, 0.001), text("Morph"), $rsliderstyle rslider bounds(86, 50, 50, 50), channel("osc1vol"), range(0, 1, 1, 0.5, 0.001), text("Vol"), $rsliderstyle rslider bounds(124, 50, 50, 50), channel("osc1det"), range(0.001, 0.5, 0, 0.5, 0.001), text("Detune"), $rsliderstyle rslider bounds(164, 50, 50, 50), channel("osc1wid"), range(0.001, 1, 1, 0.5, 0.001), text("Width"), $rsliderstyle rslider bounds(204, 50, 50, 50), channel("osc1phase"), range(0.001, 1, 0, 0.5, 0.001), text("Phase"), $rsliderstyle nslider bounds(50, 56, 40, 42), channel("osc1voice"), range(1, 8, 1, 1, 1), text("Voices"), $nsliderstyle nslider bounds(254, 30, 38, 35), channel("osc1octave"), range(-3, 3, 0, 1, 1), text("Octave"), $nsliderstyle nslider bounds(254, 65, 38, 35), channel("osc1semi"), range(-12, 12, 0, 0.5, 1), text("Semi"), $nsliderstyle rslider bounds(94, 8, 45, 40), channel("osc1cent"), range(-100, 100, 0, 1, 1)text("Cent"), $rsliderstyle label bounds(162, 32, 100, 13), text("Retrig.") checkbox bounds(170, 30, 15, 15), channel("osc1retrig"),text("Retrig"), , $checkboxstyle }

And thanks a lot ! HTML files, and direct URL request work perfectly :slight_smile:

I forgot to add the same thing to images, but will do. Yes, when you hide this plant, none of the child components will be queried for values. Note in my test I was using some profiling tools, which makes it easier to see a different in performance. If this doesn’t help at all, PM me your file and I can run it through a profiler here. although it won’t be until Monday before I get a chance to look at it.

1 Like

Btw, you not calling chnset for any channels at each k-boundary by any chance? That wouldn’t be good. All your identchannel chnset calls should be done once when needed. I always wrap them in an if statement:

kTrigButton chnget "button2"
if changed(kTrigButton))==1 then
    chnget "visible(1)", "plant1"
endif
1 Like

Yes I do the same as you, they are only called when the user click on a tab button

[quote=“rorywalsh, post:20, topic:1236”]
@mauro this build is from the develop branch. I made a new branch to investiage some weirdness on Windows.
[/quote]What weirdness? Maybe I can help you investigate? I use Cabbage mainly on a Windows 10 PC. On a Linux PC I tried Cabbage inside a Win7 virtual machine and, apart some graphical glitches that I think are dependent from the software emulated vga, it works quite well.

[quote=“rorywalsh, post:20, topic:1236”]
in the meantime you can try this one
[/quote]I will try it when I get home. :slight_smile:

Btw, the performance improvement won’t be all that notable, as Cabbage still needs to check each widget’s visibility. But it’s incurs less overhead than checking for the existence of strings on channels. in my test I saw a clear improvement, although you may need to optimise the instrument in other ways too.

1 Like

Hey Rory, actually, I’m having some trouble with the new version you provide above :

This example works with the older Cabbage version (the current official version)
When you click on PITCH or FILTER button, a Rotary Slider is supposed to appear.

With the test version you gave above, nothing happens

testdebug.csd (1.4 KB)

And also, sometimes Cabbage exits when I save/run, but I can’t tell how to reproduce, it’s really random.

Thanks. I had to make some changes to other parts of the code base which might be the problem here. I’ll take a look. Probably best to revert to the previous version for now…

[edit] Hmm. Looks like my visible change fails one very important test when the widgets themselves are made invisible regardless of containing plants! Just preparing a new build for you now…

1 Like

My naive implementation makes me realise that for this to work we need to be able to able to control widget visibility through other means. One possible solution would be to have a reserved channel that holds a list of widgets that are to be polled. This wouldn’t break any existing code, and could easily be added to earlier instruments. We just have to come up with a possible syntax. Maybe something like:

chnget "widget_channel1:widget_channel2: ...", "REMOVE_WIDGET_POLLING"
chnget "widget_channel1:widget_channel2: ...", "ADD_WIDGET_POLLING"

Or a way to enable or disable in single go:

chnget "widget_channel1:1 widget_channel2:0 ...", "WIDGET_POLLING"

where widget_channel is the channel given to a particular widget. 0 or 1 will enable/disable the widget. Note it would only apply to widgets that use channels as they are the only ones queried on each k-cycle. It should be relatively simple to maintain a list of widgets in Csound and update accordingly. Let me know what you think. The performance gains might not be that much as we will still need to check the polling channel on each k-cycle. But it might be worth a shot.