Welcome to %s forums

BrainModular Users Forum

Login Register

Moving GUI to poly object

I need help on a Patch
Post Reply
woodslanding
Member
Posts: 1327
Contact:

Moving GUI to poly object

Unread post by woodslanding » 28 Oct 2024, 18:48

In previous versions of my wkp, I have tried using a single poly object for most of the interface, since my paradigm is a mixer with a set of functionally identical channels.

The advantage is that if I make an architectural change to a channel, I can just reset polyphony and the whole UI is rebuilt with the new features on every channel. The disadvantage has been a huge number of busses, and too much CPU required. Plus in V3 and V4 there were issues that would cause crashes with extremely complex poly objects. Never tried in V5, but haven't had a poly issue for a while.

I have tried scripting a process to remove all but one channel, and then copy that channel across to all the other tracks. But that has been buggy for me. Some copies were not perfect. Again, haven't tried since V4.

Wondering if the new global arrays would make this approach less CPU expensive and more reliable. What do you think? Any thoughts about pitfalls in re-architecting this way?

Things I know how to do:
dynamically name UI control busses based on channel number. Dynamically change layout object position/color based on channel number. Make sure all audio and midi keyboard input for a particular track goes straight through without busses, so there is not added latency. A block of latency on data coming from the UI is okay. I run the GUI slow anyway, as I am near CPU capacity. But maybe global arrays would reduce this latency?

Things I am not sure of:
Latency and CPU of global arrays.
Currently I'm sending vst parameters via traditional array sends from track to track. Some of these arrays are pretty big. Wondering if using global arrays would save CPU/reduce latency here?

Any thoughts or resources welcome. I will go re-read up on global arrays now.

cheers!
-eric

EDIT: It's been more than a year since I last did any major development on my WKP (although I use it every day!) and I had forgotten about Usine Objects. Is this a possible approach for a poly UI? It definitely cleans up the patching space. I use it to save and load control settings from files, but I don't know if it is fast enough for live performace.
Custom Ryzen 5900x MATX build, Win10, Fireface UFX, touchscreen
Custom 2 manual midi keyboard
Usine, Kontakt, Reaktor, Synthmaster, Byome, Arturia, Soundtoys, Unify

SylvainT
Site Admin
Posts: 494
Contact:

Unread post by SylvainT » 30 Oct 2024, 08:55

Hi Woodslanding,

It is not an easy task to answer to your message. There are many ways to adapt CPU load, but depend on every configuration.
And yours seems pretty big.
Can you share your work ? In a private message. Then I can see how you handle this and give you appropriate answers.
You have dynamic load, you have Global Arrays, you have Usine Objects, you have multithreading on poly-patches, you have Procedures ..... so many solutions.

Sylvain

User avatar
oli_lab
Member
Posts: 1261
Location: Brittany, France
Contact:

Unread post by oli_lab » 30 Oct 2024, 13:32

Hi !
For sure, to have a better CPU usage you should have each channel of your mixer having its own rack.
then for each channel, you could set a global array that will update each parameter, the name of the global array get the number of the rack (channel1 for example)

then on another rack, you will design your gui that will adress, the global arrays alternatively

my two cents

Olivar
http://oli-lab.org

Win11 Ryzen9/32GB RAM - RME MADIFACE - SSL alpha link 4-16 - OSC capable interfaces

follow OLI_LAB adventures on Mastodon
@olivar_premier@mastodon.social

woodslanding
Member
Posts: 1327
Contact:

Unread post by woodslanding » 30 Oct 2024, 22:30

Thanks Oli.... yeah, that was the basic idea...

currently each rack is
ins-> InputProcessing->GUI->VstHosting->outputProcessing->outs.

But the midi is just passed through the gui block, as it doesn't get directly modified there anyway. However, most of the busses are scope RACK, which will change. Now they need to be WKP scope, and be renamed by channel. But maybe instead of a bunch of busses, I can use the global arrays. Maybe an array of length RACK_COUNT for each parameter, where the position is the value for that parameter in that rack? Then instead of renaming busses, I'm just writing to different positions in the array for each channel...

Here's the data I store for each channel:
CHANNEL=3,inst=Kontakt,bank=Pianos,preset=HW Rhodes,ns1=RH4Bass,ns2=KEY2,enable=1,fxsel=14,oct=0,semi=0,hands=0,nssolo=0,exp=0,ped2=0,wheel=0,breath=0,pressure=0,nosus=0,nssel=1,controls=0,drawbars=0,audioout=0,volume=0.341460049152374,fxlevel=0.807017266750336,pan=1,macro.1.value=0,macro.2.value=0,macro.3.value=0,macro.4.value=0

Each instrument bank also stores some data:
midi-in-ch=1
transpose=12
audio-in=0
cc-to-pitch=0
mw-midi=0
at-midi=0
params-on=1
input-trim=7.62097120285034
output-trim=8.22580432891846
hue=0.0859375
saturation=0.3671875
details=
renaming.1.param=49
renaming.2.param=50
renaming.3.param=51
renaming.4.param=53
renaming.5.param=127
renaming.6.param=52
renaming.1.text=Perc Off, Perc On
renaming.2.text=Perc Loud,Perc Soft
renaming.3.text=Perc Slow,Perc Fast
renaming.4.text=Vibrato 1,Chorus 1,Vibrato 2,Chorus 2,Vibrato 3,Chorus 3
renaming.5.text=Overdrive
renaming.6.text=Perc Oct,Perc 5th
macros.1.param=4
macros.2.param=4
macros.3.param=4
macros.4.param=4
macros.1.step=10
macros.2.step=10
macros.3.step=10
macros.4.step=10
controls.1.param=0
controls.2.param=0
controls.3.param=0
controls.4.param=0
controls.1.range.maxpos=0.698412716388702
controls.2.range.maxpos=0.698412716388702
controls.3.range.maxpos=0.698412716388702
controls.4.range.maxpos=0.698412716388702
controls.1.range.minpos=0.253968268632889
controls.2.range.minpos=0.253968268632889
controls.3.range.minpos=0.253968268632889
controls.4.range.minpos=0.253968268632889

And here's the global data, mostly for parameter control:

tempo.1.noteval=0
tempo.1.tempo=78
tempo.1.dotted=78 <<<Hmm bug, should be a 1 or 0
tempo.1.triplet=1
presets.1.panel.1.details=Some Details
encoders.1.value=0.503937005996704
encoders.1.index=50
encoders.1.chan=1
encoders.1.step=64
encoders.2.value=0.50892835855484
encoders.2.index=101
encoders.2.chan=1
encoders.2.step=64
encoders.3.value=0.187710911035538
encoders.3.index=3
encoders.3.chan=1
encoders.3.step=64
encoders.4.value=0.551181077957153
encoders.4.index=1
encoders.4.chan=1
encoders.4.step=64
encoders.5.value=0.991071403026581
encoders.5.index=1
encoders.5.chan=15
encoders.5.step=12
encoders.6.value=0.133858278393745
encoders.6.index=3
encoders.6.chan=15
encoders.6.step=14
encoders.7.value=0.45454528927803
encoders.7.index=4
encoders.7.chan=15
encoders.7.step=12
encoders.8.value=0.181818187236786
encoders.8.index=7
encoders.8.chan=15
encoders.8.step=12
switches.1.value=0
switches.1.index=44
switches.1.chan=1
switches.2.value=1
switches.2.index=46
switches.2.chan=1
switches.3.value=0
switches.3.index=48
switches.3.chan=1
switches.4.value=0
switches.4.index=18
switches.4.chan=15
switches.5.value=0
switches.5.index=45
switches.5.chan=1
switches.6.value=1
switches.6.index=47
switches.6.chan=1
switches.7.value=0
switches.7.index=49
switches.7.chan=1
switches.8.value=1
switches.8.index=23
switches.8.chan=15
incdecsw.1.value=1
incdecsw.1.index=43
incdecsw.1.chan=1
incdecsw.1.step=6
incdecsw.2.value=0.503937065601349
incdecsw.2.index=0
incdecsw.2.chan=11
incdecsw.2.step=26
incdecsw.3.value=0
incdecsw.3.index=5
incdecsw.3.chan=15
incdecsw.3.step=6
incdecsw.4.value=0.43636366724968
incdecsw.4.index=6
incdecsw.4.chan=15
incdecsw.4.step=11
drawbars.1.value=0.0319148898124695
drawbars.1.index=13
drawbars.2.value=0.506701290607452
drawbars.2.index=14
drawbars.3.value=1
drawbars.3.index=15
drawbars.4.value=1
drawbars.4.index=16
drawbars.5.value=1
drawbars.5.index=17
drawbars.6.value=1
drawbars.6.index=18
drawbars.7.value=1
drawbars.7.index=19
drawbars.8.value=1
drawbars.8.index=20
drawbars.9.value=1
drawbars.9.index=21

Everything can be represented as either a text array or a float array, although I also have integer values--don't know if the global arrays care about float vs. integer.

Anyway, it doesn't seem like a huge amount of data to keep in global arrays, and hopefully not expensive to send and receive.

we'll see how it likes running it in poly. wish me luck ;)
Custom Ryzen 5900x MATX build, Win10, Fireface UFX, touchscreen
Custom 2 manual midi keyboard
Usine, Kontakt, Reaktor, Synthmaster, Byome, Arturia, Soundtoys, Unify

woodslanding
Member
Posts: 1327
Contact:

Unread post by woodslanding » 31 Oct 2024, 02:30

Okay, well, I have about 100 quick links in each channel, and they don't work in poly. Not sure how much CPU that saves, but it's going to be a lot of work to replace them, there are so many nested deep in subpatches. So maybe I'll backburner this for now.

I guess many of them could get/send values from the global arrays.... I'll think on it. But it's not seeming as simple as it did.
Custom Ryzen 5900x MATX build, Win10, Fireface UFX, touchscreen
Custom 2 manual midi keyboard
Usine, Kontakt, Reaktor, Synthmaster, Byome, Arturia, Soundtoys, Unify

Post Reply

Who is online

Users browsing this forum: No registered users and 13 guests