Hi folks, I need help on an external. I wanna perform a task on an array of signal inputs. It's a multichannel object, and I define the number of channels with an argument.
Here's just the core of it, as an object named "mtx~", where I map the input to the output. And this is what happens.
[image: Imagem inline 1]
So you see I get a weird mirrored output, instead of something like "1 2 3 4 5 6".
The perform method in the code is just
static t_int *mtx_perform(t_int *w){
t_mtx *x = (t_mtx *)(w[1]);
int nblock = (int)(w[2]);
t_float **in_vectors = x->x_in_vectors;
t_float **out_vectors = x->x_out_vectors;
t_int i;
for(i = 0; i < x->x_ch; i++){
t_float *in = in_vectors[i];
t_float *out = out_vectors[i];
t_int n = nblock;
while(n--)
*out++ = *in++;
}
return (w + 3);
}
What am I doing wrong? How should this go? See attached the help test example and code.
Thanks
Check that the input addresses are different from the output ones - usually in a case like that Pd will re-use the memory from the inputs for the outputs, so your object needs to be able to operate in-place.
(hint: allocate a bunch of temporary signals on teh stack using alloca(), and put the outputs in them irst; then when you're through using the intputs for anything, you can copy the temporary outputs to the real ones.)
cheers Miller
On Thu, Feb 22, 2018 at 02:38:24PM -0300, Alexandre Torres Porres wrote:
Hi folks, I need help on an external. I wanna perform a task on an array of signal inputs. It's a multichannel object, and I define the number of channels with an argument.
Here's just the core of it, as an object named "mtx~", where I map the input to the output. And this is what happens.
[image: Imagem inline 1]
So you see I get a weird mirrored output, instead of something like "1 2 3 4 5 6".
The perform method in the code is just
static t_int *mtx_perform(t_int *w){
t_mtx *x = (t_mtx *)(w[1]); int nblock = (int)(w[2]); t_float **in_vectors = x->x_in_vectors; t_float **out_vectors = x->x_out_vectors; t_int i; for(i = 0; i < x->x_ch; i++){ t_float *in = in_vectors[i]; t_float *out = out_vectors[i]; t_int n = nblock; while(n--) *out++ = *in++; } return (w + 3);
}
What am I doing wrong? How should this go? See attached the help test example and code.
Thanks
#include "m_pd.h"
typedef struct _mtx{ t_object x_obj; t_int x_ch; t_float **x_in_vectors; t_float **x_out_vectors; }t_mtx;
static t_class *mtx_class;
static t_int *mtx_perform(t_int *w){ t_mtx *x = (t_mtx *)(w[1]); int nblock = (int)(w[2]); t_float **in_vectors = x->x_in_vectors; t_float **out_vectors = x->x_out_vectors; t_int i; for(i = 0; i < x->x_ch; i++){ t_float *in = in_vectors[i]; t_float *out = out_vectors[i]; t_int n = nblock; while(n--) *out++ = *in++; } return (w + 3); }
static void mtx_dsp(t_mtx *x, t_signal **sp){ t_int i, nblock = sp[0]->s_n; t_signal **sigp = sp; t_float **vecp = x->x_in_vectors; for(i = 0; i < x->x_ch; i++) *vecp++ = (*sigp++)->s_vec; // input vectors vecp = x->x_out_vectors; for(i = 0; i < x->x_ch; i++) *vecp++ = (*sigp++)->s_vec; // output vectors dsp_add(mtx_perform, 2, x, nblock); }
static void *mtx_free(t_mtx *x){ freebytes(x->x_in_vectors, x->x_ch * sizeof(*x->x_in_vectors)); freebytes(x->x_out_vectors, x->x_ch * sizeof(*x->x_out_vectors)); return(void *)x; }
static void *mtx_new(t_floatarg f){ t_mtx *x = (t_mtx *)pd_new(mtx_class); x->x_ch = (int)f < 1 ? 1 : (int)f > 64 ? 64 : (int)f; x->x_in_vectors = getbytes(x->x_ch * sizeof(*x->x_in_vectors)); x->x_out_vectors = getbytes(x->x_ch * sizeof(*x->x_out_vectors)); t_int i; for(i = 0; i < x->x_ch; i++) inlet_new(&x->x_obj, &x->x_obj.ob_pd, &s_signal, &s_signal); for(i = 0; i < x->x_ch; i++) outlet_new(&x->x_obj, gensym("signal")); return(x); }
void mtx_tilde_setup(void){ mtx_class = class_new(gensym("mtx~"), (t_newmethod)mtx_new, (t_method)mtx_free, sizeof(t_mtx), CLASS_NOINLET, A_DEFFLOAT, 0); class_addmethod(mtx_class, (t_method)mtx_dsp, gensym("dsp"), A_CANT, 0); }
Pd-dev mailing list Pd-dev@lists.iem.at https://lists.puredata.info/listinfo/pd-dev
Hi Alexandre,
You can also look at this thread on the forum.pdpatchrepo.info: https://forum.pdpatchrepo.info/topic/10466/matrices-and-reallocating-memory. And to this code : https://github.com/pierreguillot/pd.dummies/blob/master/src/leeloo_tilde.c
2018-02-22 18:41 GMT+01:00 Miller Puckette msp@ucsd.edu:
Check that the input addresses are different from the output ones - usually in a case like that Pd will re-use the memory from the inputs for the outputs, so your object needs to be able to operate in-place.
(hint: allocate a bunch of temporary signals on teh stack using alloca(), and put the outputs in them irst; then when you're through using the intputs for anything, you can copy the temporary outputs to the real ones.)
cheers Miller
On Thu, Feb 22, 2018 at 02:38:24PM -0300, Alexandre Torres Porres wrote:
Hi folks, I need help on an external. I wanna perform a task on an array
of
signal inputs. It's a multichannel object, and I define the number of channels with an argument.
Here's just the core of it, as an object named "mtx~", where I map the input to the output. And this is what happens.
[image: Imagem inline 1]
So you see I get a weird mirrored output, instead of something like "1 2
3
4 5 6".
The perform method in the code is just
static t_int *mtx_perform(t_int *w){
t_mtx *x = (t_mtx *)(w[1]); int nblock = (int)(w[2]); t_float **in_vectors = x->x_in_vectors; t_float **out_vectors = x->x_out_vectors; t_int i; for(i = 0; i < x->x_ch; i++){ t_float *in = in_vectors[i]; t_float *out = out_vectors[i]; t_int n = nblock; while(n--) *out++ = *in++; } return (w + 3);
}
What am I doing wrong? How should this go? See attached the help test example and code.
Thanks
#include "m_pd.h"
typedef struct _mtx{ t_object x_obj; t_int x_ch; t_float **x_in_vectors; t_float **x_out_vectors; }t_mtx;
static t_class *mtx_class;
static t_int *mtx_perform(t_int *w){ t_mtx *x = (t_mtx *)(w[1]); int nblock = (int)(w[2]); t_float **in_vectors = x->x_in_vectors; t_float **out_vectors = x->x_out_vectors; t_int i; for(i = 0; i < x->x_ch; i++){ t_float *in = in_vectors[i]; t_float *out = out_vectors[i]; t_int n = nblock; while(n--) *out++ = *in++; } return (w + 3); }
static void mtx_dsp(t_mtx *x, t_signal **sp){ t_int i, nblock = sp[0]->s_n; t_signal **sigp = sp; t_float **vecp = x->x_in_vectors; for(i = 0; i < x->x_ch; i++) *vecp++ = (*sigp++)->s_vec; // input vectors vecp = x->x_out_vectors; for(i = 0; i < x->x_ch; i++) *vecp++ = (*sigp++)->s_vec; // output vectors dsp_add(mtx_perform, 2, x, nblock); }
static void *mtx_free(t_mtx *x){ freebytes(x->x_in_vectors, x->x_ch * sizeof(*x->x_in_vectors)); freebytes(x->x_out_vectors, x->x_ch * sizeof(*x->x_out_vectors)); return(void *)x; }
static void *mtx_new(t_floatarg f){ t_mtx *x = (t_mtx *)pd_new(mtx_class); x->x_ch = (int)f < 1 ? 1 : (int)f > 64 ? 64 : (int)f; x->x_in_vectors = getbytes(x->x_ch * sizeof(*x->x_in_vectors)); x->x_out_vectors = getbytes(x->x_ch * sizeof(*x->x_out_vectors)); t_int i; for(i = 0; i < x->x_ch; i++) inlet_new(&x->x_obj, &x->x_obj.ob_pd, &s_signal, &s_signal); for(i = 0; i < x->x_ch; i++) outlet_new(&x->x_obj, gensym("signal")); return(x); }
void mtx_tilde_setup(void){ mtx_class = class_new(gensym("mtx~"), (t_newmethod)mtx_new,
(t_method)mtx_free,
sizeof(t_mtx), CLASS_NOINLET, A_DEFFLOAT, 0); class_addmethod(mtx_class, (t_method)mtx_dsp, gensym("dsp"), A_CANT,
0);
}
Pd-dev mailing list Pd-dev@lists.iem.at https://lists.puredata.info/listinfo/pd-dev
Pd-dev mailing list Pd-dev@lists.iem.at https://lists.puredata.info/listinfo/pd-dev
2018-02-23 10:59 GMT-03:00 Pierre Guillot guillotpierre6@gmail.com:
(...) And to this code : https://github.com/pierreguillot/pd.dummies/blob/ master/src/leeloo_tilde.c
Wow, that's *exactly* what I needed :) it couldn't be easier than that for me, haha, thanks!
Pierre, That is really helpful! So, do we not know the vector size until the *_dsp method then? There is EXTERN int sys_getblksize(void); in m_pd.h, it would probably be useful if we added comments indicating the usage of that if it isn't giving us the block size that we should expect in _perform Another thing I wasn't sure about is if you need to explicitly free symbols after you gensym if they're being used for variables etc [like to get a "value"]. would be nice to add into the header docs. Maybe these questions are answered "how to make an external" doc but I didn't see it. It could be useful to create an updated doc.
On Fri, Feb 23, 2018 at 8:02 AM, Alexandre Torres Porres porres@gmail.com wrote:
2018-02-23 10:59 GMT-03:00 Pierre Guillot guillotpierre6@gmail.com:
(...) And to this code : https://github.com/pierregui llot/pd.dummies/blob/master/src/leeloo_tilde.c
Wow, that's *exactly* what I needed :) it couldn't be easier than that for me, haha, thanks!
Pd-dev mailing list Pd-dev@lists.iem.at https://lists.puredata.info/listinfo/pd-dev
2018-02-23 13:02 GMT-03:00 Alexandre Torres Porres porres@gmail.com:
Wow, that's *exactly* what I needed :) it couldn't be easier than that for me, haha, thanks!
Well, it got hard again. I actually needed an extra main signal inlet, so, when I added it, I managed to make it work and build and stuff... but now, if I change the number of channels (that is, if I recreate the object with a different argument), Pd can freeze or blow up... so I screwed it somehow. Here's the code: https://github.com/porres/pd-else/blob/master/classes/mtx~.c - I don't know if it's something to do with the "free" method, or something inside the "dsp" method, that's all I can think but I've also already done all I could take a wild guess on.
On the other hand, I made progress with my previous way of trying to do this. Instead of a split and mirrored output, say 1 2 3 | 3 2 1, I'm now able to get an exact copy of the input, but reversed. Say the input is "1 2 3 4 5 6", I get "6 5 4 3 2 1".
Ok, so I see a way around would be to have a temporary array and rearrange things over. Well, I tried all possible combinations to not have that inverted result, nothing worked... so either I missed something or it's just that I really need a temporary array to rearrange things. Now, I also tried that in every way I could take a guess, but failed miserably, here's the blunt truth, I can't really code, so I need a pretty straightforward example for me to work on and develop on it, like: https://github.com/pierreguillot/pd.dummies/blob/master/src/leeloo_tilde.c - or also some fix to this code on my repository: here's the issue and link to the code: https://github.com/porres/pd-else/issues/161
Yeah, I know, if only one could give me a hint and I'd fix it myself, but sorry, I'm not there yet. So I hope someone can give me a fix in either of the two attempts.
By the way, the end goal is not to have this silly multi channel gate object, but more of an automatic fade in/out for multi-channel files. I got all the rest worked out, but I need to get over this obstacle... yeah, I would know how to do this as a patch, but, well, I'm trying to learn how to make externals ;)
thanks