matrix that adds up data?

xaf's icon

hi,

i'm looking for a simple way to add up numerical values from different inputs from a matrix that are routed to the same output, just like matrix~ does with signals. panaiotis' matrix object unfortunately seem to be able to do this, it just outputs the last changed value. any ideas?

grtz,
xaf

Luke Hall's icon

You could try converting to and from a signal and then using [matrix~]. Something like this will work, however you will need the DSP turned on to use it.

lh

Max Patch
Copy patch and select New From Clipboard in Max.

xaf's icon

that was my first thought too, but i was hoping there'd be a way without having to convert everything into signals, and then back into data again. since i need a rather large matrix that would be not very cpu efficient.

ps: i'm still in version 4.6

Luke Hall's icon

I had a go at coding something in javascript to do this because I'm trying to improve my js chops. It should do what you're after but I'm not sure it's the most efficient way, I'm still quite new to this. It requires two arguments: the number of inlets and outlets respectively. Connect a [matrixctrl] to the first inlet to create/remove connections, or send it similary formatted lists. You can also send this inlet the message "changemode" followed by a 1 or 0. This causes the object to act as though it has a [change] object hooked up after every outlet, it is on by default. I hope it helps.

lh

// lh.addrouter.js

inlets = jsarguments[1];
outlets = jsarguments[2];

var sums;
sumsinit();
var prevsums = sums.slice();
var change = 1;

var memory = new Array(jsarguments[1]);
for (i=0; i
memory[i] = 0;

var cons = new Array(jsarguments[1])
for (i=0; i
{
cons[i] = new Array(jsarguments[2])
for (j=0; j
cons[i][j] = 0;
}

function sumsinit()
{
sums = new Array(jsarguments[2]);
for (i=0; i
sums[i] = 0;
}
sumsinit.local = 1;

function msg_float(x)
{
memory[inlet] = x;
process();
}

function list(x,y,z)
{
if (inlet==0 && x
cons[x][y] = Math.min(Math.max(z,0),1);
process();
}

function process()
{
sumsinit();
for (i=jsarguments[2]-1; i>=0; i--)
{
for (j=0; j
if (cons[j][i] == 1)
sums[i] += memory[j];
if (change == 1)
if (sums[i] != prevsums[i])
outlet (i, sums[i]);
if (change == 0)
outlet (i, sums[i]);
}
prevsums = sums.slice();
}
process.local = 1;

function changemode(x)
{
if (inlet == 0)
change = Math.min(Math.max(x,0),1);
}

// EOF

xaf's icon

that sounds very interesting, but when it comes to javascript i personally never got any further then staring at the example patches in a state of deep confusion...
anyway, about time to give it a try.

so what i just did was:
create an object "js lh.addrouter.js"
double clicked it,
pasted the code,
closed the txt editor,
saved it as lh.addrouter.js
added the arguments.

but i must be doing something terribly wrong because if i double click the object again the code is gone and the max window says: "can't find file lh.addrouter.js"

xaf's icon

saved the patch as well and then restarted max, now it works.
i did save the js code in the search path though...
how is this supposed to be done?

anyway... excellent work, thanks a lot!

is there any maximum of in/outputs?

Luke Hall's icon

You can either keep the javascript in the same place as the patch file or add it to the max search path. I have a directory dedicated just to javascripts that I've written, so I know where they are all the time.

It doesn't have any maximums programmed in so if you give it too many it might slow down a bit. Each input causes it to cycle through a lot of stuff so if you're rapidly changing many inputs it might cause trouble. If this is the case try using a [mousefilter] or [speedlim] on each inlet.

lh

xaf's icon

great, thanks again!

i'll post any problems i might run into but for the moment it works like a charm, 0% cpu. it will get a lot hotter for sure though once the whole patch is up and running...

in the mean time, if i may be so bold, would it be very complicated to modify the code in such a way that it works with lists as well? that would save a lot of patchcables (and calculations perhaps?)

Luke Hall's icon

How do you want it to work? Should each item in the list be summed with the other list items like [zl sum]? Or each item in each list be summed with the corresponding item in the other list. I'll have a look at what I can do but for now just using multiple instances of the javascript will do the trick. What exactly are you using it for? There might be other ways around it.

lh

xaf's icon

what i meant is to have just one list as an input and one list as an output, instead of an x number of in/outputs. that way, i could use multisliders instead of a single sliders or number box for every in/output.

what i mainly want to use it for is to route midi controller data to ableton live. by creating a template set in live i only have to assign midi controllers once and then i can easily change the routing in max, add lfo's and envelopes, use curves, control multiple parameters with a single slider etc etc.

i'm aware that this method has it's limitations, but actually that's exactly what i need. i've been experimenting with live and max for a while now and what i mainly found out is that i need to restrict my possibilities or i end up endlessly tweaking everything.

max for live will probably make all this a lot easier, but i just can't wait and i doubt if i'll have the money to buy it once it finally comes out...

ideally speaking, i'd also be able to create a whole set of midi assignments as let's say a text file and import that into live at once. that would really make me happy, since i'm now facing the task of assigning all those controllers one by one (but i'd least i'd have to do it only once to create the template). i did find something like that a while ago, but for some reason i never went deeper into it. probably i should...

xaf's icon

i'm starting to remember something about opening package contents and then editting midi remote scripts in the resources folder... but there must have been a reason why i didn't continue along those lines... terrible memory, must upgrade my brain...

xaf's icon

ah yes, the reason was that i could only assign volume, pan, sends1 & 2, track arm and transport buttons that way. which still leaves me with assigning all effect params manually.

Luke Hall's icon

Here's some updated code, it seems to work fine but it's late so errors might have crept in somewhere along the way. Link a [matrixctrl] to the first inlet and your list of input values to the second inlet. The output is now a list too. If you have any problems let me know and I'll have another look into it. Still not entirely sure why you want the addition going on, anyway, I hope it helps.

lh

// lh.addrouter.js

inlets = 2;

var memory = [];
var sums;
sumsinit();

var cons = new Array(jsarguments[1])
for (i=0; i
{
cons[i] = new Array(jsarguments[2])
for (j=0; j
cons[i][j] = 0;
}

function sumsinit()
{
sums = new Array(jsarguments[2]);
for (i=0; i
sums[i] = 0;
}
sumsinit.local = 1;

function list()
{
all = arrayfromargs(arguments);
if (inlet==0 && all[0]
cons[all[0]][all[1]] = Math.min(Math.max(all[2],0),1);
if (inlet==1)
memory = arrayfromargs(arguments);
sumsinit();
for (i=jsarguments[2]-1; i>=0; i--)
for (j=0; j
if (cons[j][i] == 1)
sums[i] += memory[j];
outlet (0, sums);
}

//EOF

xaf's icon

wow, that's it!
thanks a million!!!

why i need the addition is because i want to be able to send for example both a slider, an lfo, an envelope and a stepsequencer to the same parameter in live. obviously i'll need to scale the values so i don't have my parameter stuck on 127 most of the time. i can easily do this with lmult.

as i said before, i need limitations so i don't want to make an abstraction that can do all that for every parameter separately, i'd rather have only a few modulators that i can dynamically assign to any parameter.

as the outputs of the matrix will be fixed to certain parameters in live, and the inputs will be fixed to a bunch of controllers and modulators, adding up the values in the matrix seemed like the only solution.

when i was a student my favorite synth was the vcs3. they had 2 of them in school. greatest synth ever. i've been hooked on matrixes ever since...

Tj Shredder's icon

I am confused, doesn't [router] from the standard distribution do what you want?

xaf's icon

router does handle lists, but it still has separate input.
the point was not having to connect all in and outputs separately, not to have a list for each separate in/output

also, router doesn't add up values that are sent to the same output.

lh's java thingy does exactly what i need.
.