Handling output of many sliders/dials

Aug 4, 2008 at 3:29am

Handling output of many sliders/dials

I need 108 sliders which send there values to a [ctrlout] with CC 1-108 on channel 1 and 108 dials which do the same on channel 2. To make the value/number pair I have a [pack] after each slider/dial. Means, I would need 216 [pack]s. And I need more of this kind later. There is certainly a better way than using a ton of [pack] objects?

Here is a small patch to illustrate it:

– Pasted Max Patch, click to expand. –
#39126
Aug 4, 2008 at 5:18am

#137357
Aug 4, 2008 at 5:54am

I had alot of fun figuring out this one. Here you can encapsulate and then use thispatcher with an uzi to auto-generate all your UI objects.

1. I created a single dialmodule.maxpat which has your dial attached to a pack with argument placeholders like this:

and then i send the output of the pack to a master send object named

2. I created a single slidermodule.maxpat which has your slider attached to a pack with argument placeholders and the same send object as in dialmodule.maxpat.

3. I created a Master UI patch called MAINUI.maxpat where these modules will be auto-generated as many times as you select them to be. I script the auto-generation of them within bpatchers and set positioning and arguments according to calculations which are automatically incremented appropriately for each instance triggered from one single object.

That’s only 3 patches you need to create, very easily, and then one huge-ass bang you hit to auto-generate everything you need.

I may have gotten the arrangement of your numbering wrong or something but hopefully you can tweak out the scripts to your liking. Let me know if you have further questions about it or if I’ve failed to understand your needs completely.
I’ve attached the folder here. Open MAINUI.maxpat to see the main thing first.
Hope you like.

#137358
Aug 4, 2008 at 6:01am

I’d be more inclined to make something more generic and easily reusable, like:

[slider]–>[messagebox]–>[s sliderout]

plus a [js] to grab the instance number from the parent patcher object name, ie myobject[5] would yield 5. At load, the js would set the content of that message box to [$1 5], so your output list is [slidervalue 5] for that instance.

Save that as an abstraction, load it into an appropriately sized bpatcher, give the bpatcher a name: slider[1]. Duplicate 107 times and you will get different message output from each one, without needing to set bpatcher arguments or make connections.

Connect a [r sliderout] to your ctlout, of which you only need one for the whole patch.

#137359
Aug 4, 2008 at 6:06am

Nice, I knew there had to be a js way of doing this, but you say “duplicate 107 times”, isn’t that much more work than simply clicking one bang in the main patch I have made which can automatically generate 108 elements with just one click?

#137360
Aug 4, 2008 at 7:00am

On Aug 3, 2008, at 8:29 PM, Peter Ostry wrote:
> I need 108 sliders which send there values to a [ctrlout] with CC
> 1-108 on channel 1 and 108 dials which do the same on channel 2.

Here’s a list-based approach:

– Pasted Max Patch, click to expand. –

Chris Muir
cbm@well.com

http://www.xfade.com

#137361
Aug 4, 2008 at 11:06am

Peter Ostry schrieb:
> I need 108 sliders which send there values to a [ctrlout] with CC
> 1-108 on channel 1 and 108 dials which do the same on channel 2. To
> make the value/number pair I have a [pack] after each slider/dial.
> Means, I would need 216 [pack]s. And I need more of this kind later.
> There is certainly a better way than using a ton of [pack] objects?

Beside the answers, which had been given already, I just wonder how you
want to place 216 controllers on a screen without confusing any user?

Another option would be to encapsulate it completely into a poly~…
(You could create some kind of link to a visible part in the main
patcher which could give you a visual feedback of the setting of faders
and dials…)

Stefan


Stefan Tiedje————x——-
–_____———–|————–
–(_|_ —-|—–|—–()——-
– _|_)—-|—–()————–
———-()——–www.ccmix.com

#137362
Aug 4, 2008 at 1:56pm

Quote: Stefan Tiedje wrote on Mon, 04 August 2008 13:06
—————————————————-
> Beside the answers, which had been given already, I just wonder how you
> want to place 216 controllers on a screen without confusing any user?
—————————————————-

These interface elements represent the volume faders and pan knobs of 108 Logic channels. Finally they will not be shown to the user but rather be hidden number boxes. I used sliders and dials to make the example more clear.

According to a user chosen preset I need to tell Logic “pull volume 4, 34 and 38 smoothly down, pan 3, 34 and 61 slowly from left to center, set volume 18, 19, 24 and 27 to unity gain and center their pans”. The user gets only the audible result of his choice.

I think, regardless if the controlling elements are sliders, number boxes or direct messages, the situation will be the same: parameter p of channelstrip s must get values on channel c with CC number n.

#137363
Aug 4, 2008 at 2:05pm

Quote: Chris Muir wrote on Mon, 04 August 2008 09:00
—————————————————-
> Here’s a list-based approach:
> …
—————————————————-

Wow, great. I believe I don’t even need to pack the interface elements. The lower patch with the multislider seems to do what I need. Thanks!

I will check the other suggestions either but like the preset-readout from the other thread I will need some time to get my head around all this methods.

#137364
Aug 4, 2008 at 10:21pm

Don’t forget that pattr works with multislider… so you’ll have all kinds of ways to manipulate/interpolate between your settings. I find multislider generally more intuitive than single sliders, as you can “paint” with it, plus hold shift if you want to only move one at a time. Maybe if your controllers are in logically-separated banks based on function, you can split up the 108 into many multis (then use a zl join to collect them back together, or whatever you need).

To query single sliders use the fetch $1 and the value comes out the right outlet, rather than parsing a list (though the list might work better, not sure). Sometimes I use a speedlim 40 or 50 on the multislider list out to ease up on the data load, since the list is then setting other parameters which might not react that quickly. Besides, it’s overkill (generally) to have things moving faster than 30-50 ms, when it’s something like an audio fade. Most people stop hearing and seeing audio/visual “steps” at around 40 ms (25 fps).

–CJ

#137365
Aug 4, 2008 at 11:22pm

Quote: RabidRaja wrote on Mon, 04 August 2008 18:06
—————————————————-
> Nice, I knew there had to be a js way of doing this, but you say “duplicate 107 times”, isn’t that much more work than simply clicking one bang in the main patch I have made which can automatically generate 108 elements with just one click?
—————————————————-

Indeed – the duplicate ability is more useful while you are inventing a patch, or for re-using the slider abstraction elsewhere, whereas building it all from a uzi or such is great when it’s all done and ready to deploy. You could still have the uzi generate 108 instances of the abstraction of course, and this is what I often do with auto-numbering stuff.

#137366
Aug 4, 2008 at 11:29pm

Quote: Peter Ostry wrote on Tue, 05 August 2008 01:56
—————————————————-
> These interface elements represent the volume faders and pan knobs of 108 Logic channels. Finally they will not be shown to the user but rather be hidden number boxes.
—————————————————-

If they will not be presented to the user or manipulated with the mouse, avoid using lots of UI elements like number boxes – these consume more CPU whether they are hidden or not. With dense MIDI streams, the impact can become significant if you are also running a CPU-heavy “main” app like Logic under heavy load.

I suggest you use multiple int objects instead, or something more integrated like multislider as suggested, or an object that stores many numbers like funbuff.

#137367
Aug 4, 2008 at 11:38pm

john wrote:
>You could still have the uzi generate 108 instances of the
>abstraction of course, and this is what I often do with
>auto-numbering stuff.

ah, that is a good idea. i’ll have to look more into js uses, i like editing code more than i like editing patches after all.

#137368
Aug 5, 2008 at 2:31am

Quote: seejayjames wrote on Tue, 05 August 2008 00:21
—————————————————-
> Besides, it’s overkill (generally) to have things moving faster than 30-50 ms, when it’s something like an audio fade.
—————————————————-

1)
Do you probably know how many steps per 6 dB or 12 dB are audible for the average ear? I don’t mean a studio reference but a stage performance with slow volume changes on delicate sounds.

2)
My automatic fades go always from 0-90 or 90-0 (these are MIDI values) which means in Logic a range from 0 dB down to infinity. For the slowest fades with 10 and 5 seconds I send all 90 values. But the next fade is 2 seconds. 2000 ms divided by 90 steps is about 22 ms per step. This is a bit fast for several parallel MIDI streams and according to your “30-50 ms” suggestion I can settle on 40 ms and keep this time for the faster fades either. Did I understand you right?

#137369
Aug 5, 2008 at 3:04am

Well, there are caveats. Wildly changing MIDI notes or other sounds can definitely be discerned at faster rates, and some elements of video can too—again, the more “contrast” (whether audio or visual) there is, the better we are at mentally “slicing it up” and hearing/seeing things as discrete events. Things like audio or visual fades, though, become more tricky to tell, since the underlying material isn’t changing things like timbre or visual color as much as it could be. Really, the more it changes overall (and the more contrasting elements there are at once), the more we have (mentally) to discern the “event steps”. This is a generalization, of course, but we’re best at perceiving sharp changes rather than smooth, so when you go from abstract number values to sound or visual parameters, the way you use them can matter quite a bit.

Along those lines, we hear and see logarithmically, not linearly. (Anyone know about smell or touch? :) So linear steps from 0-255 in the brightness of a grayscale pixel will appear to “ramp” … there’s more apparent change early on per step, then not as much towards fully bright. Similar idea with audio, from the quietest sounds (or silence) to the maximum volume you’re working with. So the best bet may be to chop up the low levels finer than the high ones, so there’s more variation down low rather than up high. This is the “perceived variation”, not “actual”, though is there a difference? :) a question for the philosophy thread, perhaps…

I’m by no means an expert on this, but I do know the blending of biology/hearing/seeing senses and the digital/audio/visual material works in this logarithmic way. And I know that anywhere you can safely and easily eliminate excess data flow, without compromising what you want artistically, is a good thing. So just experiment with the full range of parameters and find a good balance. If you can hear steps at 40 ms and they’re annoying, speed it up if possible. But then if you run into processing or communication overloads, back off. And so on. Mostly it depends on what the numbers are actually changing, since the numbers themselves can change wicked fast… but changing something like audio levels or the brightness of a video may *appear* to be just as smooth, but have many values dropped.

One easy way to experiment with nonlinear mappings is to use an itable or table with some presets or pattrs, sort of like velocity curves do on keyboards. Then send in your linear values (from controllers, interface elements, or with counters) to map to nonlinear outputs. You’ll probably find that certain curves (or even jagged ones) give you what you want for simple audio, different ones for complex audio (frequencies also have an “optimal hearing range” within the 20-20000 spectrum), different ones for visuals (again, we see greens the best out of the rainbow), etc. Several itables with a bunch of preset curves will add a lot to your parameter control, and give new ideas on how best to work with your material. You can always have the default preset #1 be a straight line from lower left to top right, so that the numbers aren’t changed. Then tweak from there.

–CJ

#137370
Aug 5, 2008 at 3:07am

Quote: RabidRaja wrote on Tue, 05 August 2008 11:38
—————————————————-
> ah, that is a good idea. i’ll have to look more into js uses, i like editing code more than i like editing patches after all.
—————————————————-

Here’s the relevant parentinfo.js code for a js object that accepts two input messages: “name” and “instance”, and outputs that info for its parent patcher (the patcher the js object is in):

function name() {
if(this.patcher.box) outlet(0, this.patcher.box.varname);
}

function instance() {
var i = 0, s = null;
if(this.patcher.box && this.patcher.box.varname) {
s = this.patcher.box.varname.split(‘[');
i = parseInt(s[s.length - 1].split(‘]’)[0]);
if(isNaN(i)) i = 0;
}
outlet(0, i);
}

#137371
Aug 5, 2008 at 4:03am

Perfect starting point for me. Thanks!

Quote: johnpitcairn wrote on Mon, 04 August 2008 21:07
—————————————————-
> Here’s the relevant parentinfo.js code for a js object that accepts two input messages: “name” and “instance”, and outputs that info for its parent patcher (the patcher the js object is in):
>
> function name() {
> if(this.patcher.box) outlet(0, this.patcher.box.varname);
> }
>
> function instance() {
> var i = 0, s = null;
> if(this.patcher.box && this.patcher.box.varname) {
> s = this.patcher.box.varname.split(‘[');
> i = parseInt(s[s.length - 1].split(‘]’)[0]);
> if(isNaN(i)) i = 0;
> }
> outlet(0, i);
> }
>
—————————————————-

#137372
Sep 29, 2008 at 5:19am

Quote: RabidRaja wrote on Mon, 04 August 2008 18:06
—————————————————-
> the main patch I have made which can automatically generate 108 elements with just one click?
—————————————————-

I like the way you generate those elements, cool. Very helpful. Thx.

But is there a way to delete them, without opening the patch?

and is there a way to automatically include theme in presentation mode? Preferably on different pre-arranged spots. Something like;
If there is a slider 12 it will be in position 50 30.

In that way the user can change the interface to fit his setup. By adding or deleting controls or tracks or whatever else you can think of.

My patchers always have a lot of controls and it would be nice too control what you see…..

THX already

Tijn

#137373

You must be logged in to reply to this topic.