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.
Moving GUI to poly object
-
woodslanding
- Member
- Posts: 1327
- Contact:
Moving GUI to poly object
Custom Ryzen 5900x MATX build, Win10, Fireface UFX, touchscreen
Custom 2 manual midi keyboard
Usine, Kontakt, Reaktor, Synthmaster, Byome, Arturia, Soundtoys, Unify
Custom 2 manual midi keyboard
Usine, Kontakt, Reaktor, Synthmaster, Byome, Arturia, Soundtoys, Unify
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
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
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
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
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:
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
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
Custom 2 manual midi keyboard
Usine, Kontakt, Reaktor, Synthmaster, Byome, Arturia, Soundtoys, Unify
-
woodslanding
- Member
- Posts: 1327
- Contact:
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.
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
Custom 2 manual midi keyboard
Usine, Kontakt, Reaktor, Synthmaster, Byome, Arturia, Soundtoys, Unify
Who is online
Users browsing this forum: Bing [Bot] and 81 guests
