solo-ing?
Trying to make a DAW mixer-esq patch that allows soloing of any of the channels. For some reason I can't seem to get my head around how to have multiple channels soloed at once.
It will make more sense when looking at the patch. I think it needs some if.... objects, but I've not managed to make that way work either.
Cheers for any suggestions
have a look at the matrix~ object
I'm experimenting with matrix~, still can't figure out how to get it to work fully. It also seems that the panning doesn't work when going through the matrix~. I may be using the connect/disconnect messages incorrectly
(hold r and click to reset pan/gain on the bpatchers).
I don't think I'm fully getting the hang of the [if] object either.
I need something like :
[ if $i1 && $i2 && $i3 == 0 then bang out1 ]
but that didn't work when I tried it, presumably because $i1/2/3 are not reaching the object at the same time. I tried to use buddy bondo and pak to sort that out, but wasn't successful.
Any more suggestions still very appreciated!
thanks, heres the point I'm stuck at, I don't think the gates opened by if are neccesary, its just how I was tinkering at the time
I was thinking about your problem at work yesterday and jotted down some pseudo-code. I put this together last night hopefully it should do what you want. If you get your abstraction to send mute and solo messages to an outlet you should just need to connect that to the relevant [toggle].
It could be easier to accept 2 element lists formatted as " " for both the mute and solo inlets. This would mean you could set up one [receive] and multiple [sends] in your abstraction so long as they know the instance number. It would also make the "endsolo" message work properly because at the moment the [pak] remembers the last state and the [toggles] aren't turned off.
If any part of it doesn't make sense to you or you'd like it tweaked a little bit feel free to ask.
lh
// lh.mutesolo
// mute and solo channel strips using [matrix~]
inlets = 2;
var tracks = jsarguments[1];
var ramp = 20;
var mutes = new Array(tracks);
var solos = new Array(tracks);
for (i=0; i
mutes[i] = 0;
solos[i] = 0;
}
function list() {
all = arrayfromargs(messagename,arguments);
all.splice(tracks);
if (inlet == 0) {
mutes = all.map(clip);
} else {
solos = all.map(clip);
}
if (sigma(solos) > 0) {
for (i=0; i
outlet (0, i, i, solos[i], ramp);
}
} else {
for (i=0; i
outlet (0, i, i, 1-mutes[i], ramp);
}
}
}
function msg_int(x) {
onoff = Math.min(Math.max(0,x),1);
for (i=0; i
outlet (0, i, i, onoff, ramp);
}
}
function endsolo() {
for (i=0; i
solos[i] = 0;
}
list()
}
function setramp(x) {
ramp = Math.max(0,x);
}
function clip(x) {
return Math.min(Math.max(0,x),1);
}
function sigma(arrname) {
count = 0;
for (i=0; i
count += arrname[i];
}
return count;
}
//EOF
soloing and muting is a little tricky. you probably want to mute independently, which isn't hard. But when you click any track to solo, everything else gets muted, yet the "secondary mute states" preserve when you go out of solo mode. Also, if you want multiple soloing tracks, that's not hard in itself, it's mute in reverse... but if you turn off the last soloing track, then all the other tracks get "unmuted", yet still preserve their secondary mutes. yes, it's a bit of a challenge.
I use matrix~ with presets and this works well, it handles muting only though (the way I use it, anyway). Using presets, uzi, and some zl functions may not get you soloing, at least in the traditional way, but they can offer a lot of new ways to work with muting that other apps usually don't have (rotating lists, set-every-other, randomize on/off with weighted probabilities, etc).
For a standard setup, and this is just brainstorming, you could use one matrixctrl into matrix~ for muting and one for soloing, so the muting one isn't affected by the soloing. First "gate-check" is the soloing matrixctrl: if a track is soloed, it goes through and bypasses the track's mute setting (and therefore the second gate). If a track isn't soloed, it may or may not go through... this depends on whether ANY tracks are soloed. So always evaluate the solo list as a whole, and if there are no solos (the matrixctrl reads all 0's), then you send them ALL to try and get through the muting list (which is a second set of gates that the tracks are now affected by). Otherwise, if ANY tracks are soloed, let them through and bypass the muting gates, but in this case, you don't let any 0's through even the first set.
If you only want one track soloed at a time, this is a lot easier---just set the soloing matrixctrl to "one cell per matrix" (see attribute in Inspector) and read the list of values every time you click. That single track bypasses its mute gate and heads out to make sound, but no other tracks go anywhere.
With [key] and [keyup] you can assign a hotkey that sets the matrixctrl into this mode while it's pressed. so for example, if you're holding "s" and you click the soloing matrixctrl, it highlights only that channel, clearing all the others. Release "s" and you can add or remove individual channels as usual.
Hi thanks for the help! I didn't quite get what the patch was doing, but I added some objects which make it function nearly as I need it to.
At the moment, multiple channels can be solo-ed, and when all soloing if off, the previous mute states are recalled, which works really well.
However, It needs some sort of hierarchy where the states of the mute toggles cannot override the states of the solo toggles, if that makes sense. Its easy to see the problem if you solo a channel first and then mute something.
Would you be able to try and explain what the js file is actually doing, and how I would go about modifying the it if I wanted more than 4 channels? I have no experience with javascript, but would love to learn some things.
I didn't think it would be so tricky when I started doing this!
Actually, I just loaded your patch again and it works well.
For some reason the first time I loaded it the js object only had 1 inlet.
Seeing as that works, would you be able to try and explain how the js is handling the lists? Would it not be possible with max objects?
The rest of my library is super buggy but I believe the solo object works great.
otherwise use this logic table
Column 1: something is soloed
Column 2: mute button is lit
Column 3: solo button is lit
OUTCOME: 0 = muted 1 = thru
0 0 0 --> 1
0 0 1 --> 1 //not possible
0 1 0 --> 0
0 1 1 --> 0
1 0 0 --> 0
1 0 1 --> 1
1 1 0 --> 0
1 1 1 --> 0
I've quickly commented the code, if there are any specific bits you want be to explain more clearly then reply here or drop me an email.
lh
inlets = 2; //set 2 inlets
var tracks = jsarguments[1]; //use the argument to [js] to specify number of channels
var ramp = 20; //set a default ramp time
var mutes = new Array(tracks); //create arrays for storing mute and solo toggles
var solos = new Array(tracks);
for (i=0; i
mutes[i] = 0; //set them all to default to 0
solos[i] = 0;
}
function list() {
all = arrayfromargs(messagename,arguments); //don't think this is needed, I'm too used to using function anything()
all.splice(tracks); //chop the list down to the number of tracks we have, ignore any extras
if (inlet == 0) { //first inlet sets mute states
mutes = all.map(clip); //call clip function on each value in the list
} else { //second inlet is for solos
solos = all.map(clip); //same as above
}
if (sigma(solos) > 0) { //if the sigma() function returns greater than 0 we must have some tracks soloed so...
for (i=0; i
outlet (0, i, i, solos[i], ramp); // output messages formatted for [matrix~]
}
} else { //no tracks are soloed, we only need the mute data
for (i=0; i
outlet (0, i, i, 1-mutes[i], ramp); //output messages formatted for [matrix~]
}
}
}
function msg_int(x) {
onoff = Math.min(Math.max(0,x),1); // an integer > 0 will turn all tracks on,
for (i=0; i
outlet (0, i, i, onoff, ramp);
}
}
function endsolo() { //set all solos off
for (i=0; i
solos[i] = 0;
}
list()
}
function setramp(x) {
ramp = Math.max(0,x); //set a different ramp time
}
function clip(x) {
return Math.min(Math.max(0,x),1); //clip lists to being 0 or 1
}
function sigma(arrname) { //sum all the values in a numerical array and return the value
count = 0;
for (i=0; i
count += arrname[i];
}
return count;
}
Hey again, thanks for commenting the js, still confuses me, but I'll get there eventually.
If you're interested I've attached a knock-up of how I'll use your js as part of a mixer.
I'll add parametric eq and clean up the keyboard controls, and build back in the grouping function I had before, to use when dealing with more channels.
Thanks for the help!
I'm basically doing the same thing (but emulating a large hardware digital console). I did it without JS (I think). Basically, a solo goes on and I use [switcher~] to switch monitoring from whatever it is to the Solo bus (which is fed from channels using [route] and [matrix~]). I then devised a system where it will count the number of channels on which solo is engaged, and then count when they are disengaged, and revert back to the previous monitor source when that number is 0 (which means no solos are on). I also setup a PFL/AFL switch. I haven't tested extensively, but it seems to work thus far. If you're interested I can break-out pieces and attach, it's fairly large just to paste in here. I'm still new, so it may not be the best way (I'd love to know what that is), but seems like it will do the job and not be too kludgy.
I achieved a similar thing for my drum machine.
What I did was this:
For each channel there was a mute and solo button.
when you muted a channel - it muted (duh!) with the mute button value sent via a send (i.e. [s chan1mute])
when you solo'ed a channel - it mutes everything else.
Now, You want to mute everything else EXCEPT any channels that are also solo'ed.
So... to do this you only need to rely on the mute button values, like so.
When mute button is off, mute value = 1
When mute button is on, mute value = 0
When solo button is on, mute value = 12
So only channels whose mute values are below 12 will be muted.
seems a bit complicated now i type it... so heres a pic of how i achieved it (i couldn't work out how to save as text)

Hope this helps
a bit convoluted i know, but... it works.