Hi, I'm creating new fun objects that are tools to deal with multichannel signals to include in the next update of ELSE.
I have a working "pick~" object that picks a single channel from a multichannel connection. Of course you can set which channel with a message.
I'm now expanding this concept to remap or reorder a multichannel signal, much like how you can reorder a list message in Pd with dollar symbols ($1, $2, etc). It is called "remap~" for now and takes floats or lists. A "0" means "none", so no channel is picked and we get zeros. With a float input or argument it is just like "pick~".
It is working well depending on the list I am sending, but somehow it doesn't work for other lists.
here's the "dsp" code.
*static* *void* remap_dsp(t_remap *x, t_signal **sp){
signal_setmultiout(&sp[1], x->x_n);
*int* length = sp[0]->s_length;
*for*(*int* i = 0; i < x->x_n; i++){
*int* ch = x->x_vec[i].a_w.w_float;
*if*(ch > sp[0]->s_nchans)
ch = sp[0]->s_nchans;
*if*(ch >= 0)
dsp_add_copy(sp[0]->s_vec + ch*length, sp[1]->s_vec + i*length, length);
*else*
dsp_add_zero(sp[1]->s_vec + i*length, length);
}
}
If I print the "ch" values and ch*length or i_lenght I get the expected values, so I can't understand what goes wrong.
For instance, if I have a 4 channel connection input with values "1 2 3 4" and send it the list "1 2 3 2 1" I get the correct expected output of "1 2 3 2 1". If I send it "2 1", output is the same! Single float values also work as mentioned, now for some bugged outputs...
"3 2 1" gives me "3 2 *3*" "1 1 2" gives me "1 1 *1*" "1 2 2 3" gives me "1 2 2 *2*"
funny enough, something like "1 2 2 2 3" gives me the same correct output.
I can't see a pattern here. I need help from the wizards to please save me. Test patch attached. Code lives here https://github.com/porres/pd-else/blob/master/Code_source/Compiled/signal/re...
thanks
ps. While we're at it, I don't get why we have both sp[0]->s_length and sp[0]->s_n, aren't both the same?
Hi,
if the input and output signals have the same channel count, they will alias each other, just like in regular single-channel objects. In that case, your code may accidentally overwrite parts of the input before it is read. You first need to copy the whole input signal to a temporary buffer (probably allocated in your object) and then copy the corresponding channels to the output signal.
ps. While we're at it, I don't get why we have both sp[0]->s_length and sp[0]->s_n, aren't both the same?
s_length is just a more descriptive alias for s_n.
Christof
On 22.07.2023 20:52, Alexandre Torres Porres wrote:
Hi, I'm creating new fun objects that are tools to deal with multichannel signals to include in the next update of ELSE.
I have a working "pick~" object that picks a single channel from a multichannel connection. Of course you can set which channel with a message.
I'm now expanding this concept to remap or reorder a multichannel signal, much like how you can reorder a list message in Pd with dollar symbols ($1, $2, etc). It is called "remap~" for now and takes floats or lists. A "0" means "none", so no channel is picked and we get zeros. With a float input or argument it is just like "pick~".
It is working well depending on the list I am sending, but somehow it doesn't work for other lists.
here's the "dsp" code.
*static* *void* remap_dsp(t_remap *x, t_signal **sp){
signal_setmultiout(&sp[1], x->x_n);
*int* length = sp[0]->s_length;
*for*(*int* i = 0; i < x->x_n; i++){
*int* ch = x->x_vec[i].a_w.w_float;
*if*(ch > sp[0]->s_nchans)
ch = sp[0]->s_nchans;
*if*(ch >= 0)
dsp_add_copy(sp[0]->s_vec + ch*length, sp[1]->s_vec + i*length, length);
*else*
dsp_add_zero(sp[1]->s_vec + i*length, length);
}
}
If I print the "ch" values and ch*length or i_lenght I get the expected values, so I can't understand what goes wrong.
For instance, if I have a 4 channel connection input with values "1 2 3 4" and send it the list "1 2 3 2 1" I get the correct expected output of "1 2 3 2 1". If I send it "2 1", output is the same! Single float values also work as mentioned, now for some bugged outputs...
"3 2 1" gives me "3 2 *3*" "1 1 2" gives me "1 1 *1*" "1 2 2 3" gives me "1 2 2 *2*"
funny enough, something like "1 2 2 2 3" gives me the same correct output.
I can't see a pattern here. I need help from the wizards to please save me. Test patch attached. Code lives here https://github.com/porres/pd-else/blob/master/Code_source/Compiled/signal/re...
thanks
ps. While we're at it, I don't get why we have both sp[0]->s_length and sp[0]->s_n, aren't both the same?
Pd-dev mailing list Pd-dev@lists.iem.at https://lists.puredata.info/listinfo/pd-dev
Em sáb., 22 de jul. de 2023 às 18:39, Christof Ressi info@christofressi.com escreveu:
if the input and output signals have the same channel count, they will alias each other, just like in regular single-channel objects.
actually, funny stuff happens for 4 multichannel input and 3 multichannel output, but I've seen that issue with single channel objects and I tried copying stuff from other objects in ELSE into this multichannel idea and failed.
You first need to copy the whole input signal to a temporary buffer (probably allocated in your object) and then copy the corresponding channels to the output signal.
I wonder if you can give me a better detailed strategy/steps.
thanks
ok, I was able to compile a version that does not blow pd up
obviously I have no idea of what I am doing and I did some things based on warnings I was getting, but then, I do copy the input first and then reorder the channels but I do get the exact same result as before, so it was all for nothing.
here's my new attempt, hopefully not too far from getting things right https://github.com/porres/pd-else/blob/master/Code_source/Compiled/signal/re...
cheers
Em sáb., 22 de jul. de 2023 às 21:02, Alexandre Torres Porres < porres@gmail.com> escreveu:
Em sáb., 22 de jul. de 2023 às 18:39, Christof Ressi < info@christofressi.com> escreveu:
if the input and output signals have the same channel count, they will alias each other, just like in regular single-channel objects.
actually, funny stuff happens for 4 multichannel input and 3 multichannel output, but I've seen that issue with single channel objects and I tried copying stuff from other objects in ELSE into this multichannel idea and failed.
You first need to copy the whole input signal to a temporary buffer (probably allocated in your object) and then copy the corresponding channels to the output signal.
I wonder if you can give me a better detailed strategy/steps.
thanks
I see now I was just doing something silly thinking I was trying to copy some sophisticated trick that would sove things.
I can't remember now which object I had to deal with something like this.
anyway, in this last version, I have my own "perform" method that fails equally as before in some cases, but it is not as weird as before...
let me just copy it instead of linking to a github code that might change, here's the code section
*static* t_int *remap_perform(t_int *w){
t_remap *x = (t_remap *)(w[1]);
t_int n = (t_int)(w[2]);
t_int nchans = (t_int)(w[3]);
t_sample *in = (t_sample *)(w[4]);
t_sample *out = (t_sample *)(w[5]);
*for*(*int* i = 0; i < x->x_n; i++){ // channels to copy
*int* ch = x->x_vec[i].a_w.w_float - 1; // get channel number
*if*(ch >= nchans)
ch = nchans - 1;
*for*(*int* j = 0; j < n; j++){ // j is sample number of each channel
*if*(ch >= 0)
*out++ = in[ch*n + j];
*else*
*out++ = 0;
}
}
*return*(w+6);
}
Em sáb., 22 de jul. de 2023 às 21:22, Alexandre Torres Porres < porres@gmail.com> escreveu:
ok, I was able to compile a version that does not blow pd up
obviously I have no idea of what I am doing and I did some things based on warnings I was getting, but then, I do copy the input first and then reorder the channels but I do get the exact same result as before, so it was all for nothing.
here's my new attempt, hopefully not too far from getting things right https://github.com/porres/pd-else/blob/master/Code_source/Compiled/signal/re...
cheers
Em sáb., 22 de jul. de 2023 às 21:02, Alexandre Torres Porres < porres@gmail.com> escreveu:
Em sáb., 22 de jul. de 2023 às 18:39, Christof Ressi < info@christofressi.com> escreveu:
if the input and output signals have the same channel count, they will alias each other, just like in regular single-channel objects.
actually, funny stuff happens for 4 multichannel input and 3 multichannel output, but I've seen that issue with single channel objects and I tried copying stuff from other objects in ELSE into this multichannel idea and failed.
You first need to copy the whole input signal to a temporary buffer (probably allocated in your object) and then copy the corresponding channels to the output signal.
I wonder if you can give me a better detailed strategy/steps.
thanks
On Sun, 23 Jul 2023 at 00:10 Alexandre Torres Porres porres@gmail.com wrote:
I see now I was just doing something silly thinking I was trying to copy some sophisticated trick that would sove things.
I can't remember now which object I had to deal with something like this.
Found one, copied the structure, it works! I still have no good idea on how things work, but hey, I got it working and I can sleep
Thanks
anyway, in this last version, I have my own "perform" method that fails equally as before in some cases, but it is not as weird as before...
let me just copy it instead of linking to a github code that might change, here's the code section
*static* t_int *remap_perform(t_int *w){
t_remap *x = (t_remap *)(w[1]); t_int n = (t_int)(w[2]); t_int nchans = (t_int)(w[3]); t_sample *in = (t_sample *)(w[4]); t_sample *out = (t_sample *)(w[5]); *for*(*int* i = 0; i < x->x_n; i++){ // channels to copy *int* ch = x->x_vec[i].a_w.w_float - 1; // get channel number *if*(ch >= nchans) ch = nchans - 1; *for*(*int* j = 0; j < n; j++){ // j is sample number of each
channel
*if*(ch >= 0) *out++ = in[ch*n + j]; *else* *out++ = 0; } } *return*(w+6);
}
Em sáb., 22 de jul. de 2023 às 21:22, Alexandre Torres Porres < porres@gmail.com> escreveu:
ok, I was able to compile a version that does not blow pd up
obviously I have no idea of what I am doing and I did some things based on warnings I was getting, but then, I do copy the input first and then reorder the channels but I do get the exact same result as before, so it was all for nothing.
here's my new attempt, hopefully not too far from getting things right https://github.com/porres/pd-else/blob/master/Code_source/Compiled/signal/re...
cheers
Em sáb., 22 de jul. de 2023 às 21:02, Alexandre Torres Porres < porres@gmail.com> escreveu:
Em sáb., 22 de jul. de 2023 às 18:39, Christof Ressi < info@christofressi.com> escreveu:
if the input and output signals have the same channel count, they will alias each other, just like in regular single-channel objects.
actually, funny stuff happens for 4 multichannel input and 3 multichannel output, but I've seen that issue with single channel objects and I tried copying stuff from other objects in ELSE into this multichannel idea and failed.
You first need to copy the whole input signal to a temporary buffer (probably allocated in your object) and then copy the corresponding channels to the output signal.
I wonder if you can give me a better detailed strategy/steps.
thanks