I'm trying to create a signal external with a variable number of inlets and outlets. As a test, I have written an object that copies its input to the respective output. When I put the object in a subpatch and use [block~] to change the block size, it crashes. Loading Pd with gdb gives the following output, which to me doesn't seem very helpful:
``` Program received signal SIGSEGV, Segmentation fault. 0x0000000000000000 in ?? () ```
Here's the code of the object (the var_io_tilde_process function is there as a test to see if I can process the output in a routine other than the perform one):
```
#include <m_pd.h>
static t_class *var_io_tilde_class;
typedef struct _var_io_tilde { t_object obj; t_sample f; t_sample **in; t_sample **out; t_sample *buf; int chnls; int blksize; int bufbytes; } t_var_io_tilde;
static void var_io_tilde_process(t_var_io_tilde *x, int n) { int i, j; t_sample **out = x->out; t_sample *buf = x->buf; for (i = 0; i < x->chnls; i++) { for (j = 0; j < n; j++) { out[i][j] = buf[i*n+j]; } } }
t_int *var_io_tilde_perform(t_int *w) { int i, j, n; t_var_io_tilde *x = (t_var_io_tilde *)(w[1]); n = (int)(w[2]); t_sample **in = x->in; //t_sample **out = x->out; t_sample *buf = x->buf;
for (i = 0; i < x->chnls; i++) { for (j = 0; j < n; j++) { buf[i*n+j] = in[i][j]; } } var_io_tilde_process(x, n); return (w+3); }
void var_io_tilde_dsp(t_var_io_tilde *x, t_signal **sp) { int i; int bufbytes = x->bufbytes; t_sample **dummy = x->in; for (i=0; i<x->chnls; i++) *dummy++ = sp[i]->s_vec; dummy = x->out; for (i=x->chnls; i<x->chnls*2; i++) *dummy++ = sp[i]->s_vec;
if (x->blksize != sp[0]->s_n) { x->blksize = sp[0]->s_n; x->bufbytes = x->chnls*2*sp[0]->s_n; x->buf = (t_sample *)resizebytes((void *)x->buf, bufbytes, x->bufbytes); if (x->buf == NULL) { pd_error(x, "cannot realloc %d bytes of memory", x->bufbytes); return; } } dsp_add(var_io_tilde_perform, 2, x, sp[0]->s_n); }
void *var_io_tilde_new(t_floatarg f) { int i; t_var_io_tilde *x = (t_var_io_tilde *)pd_new(var_io_tilde_class); x->chnls = (f) ? f : 2; x->blksize = sys_getblksize();
/* create signal inlets (first is done in var_io_tilde_setup) */ for (i=1; i<x->chnls; i++) inlet_new(&x->obj, &x->obj.ob_pd, &s_signal, &s_signal); /* create signal outlets */ for (i=0; i<x->chnls; i++) outlet_new(&x->obj, &s_signal);
x->in = (t_sample **)getbytes(x->chnls * sizeof(t_sample **)); x->out = (t_sample **)getbytes(x->chnls * sizeof(t_sample **));
for (i=0; i<x->chnls; i++) x->in[i] = x->out[i] = 0;
x->bufbytes = x->chnls*2*x->blksize; x->buf = (t_sample *)getbytes(x->bufbytes * sizeof(t_sample *)); return (void *)x; }
void var_io_tilde_free(t_var_io_tilde *x) { freebytes(x->in, sizeof(x->in)); freebytes(x->out, sizeof(x->out)); }
void var_io_tilde_setup(void) { var_io_tilde_class = class_new(gensym("var_io~"), (t_newmethod)var_io_tilde_new, (t_method)var_io_tilde_free, sizeof(t_var_io_tilde), CLASS_DEFAULT, A_DEFFLOAT, 0); class_addmethod(var_io_tilde_class, (t_method)var_io_tilde_dsp, gensym("dsp"), 0); CLASS_MAINSIGNALIN(var_io_tilde_class, t_var_io_tilde, f); }
```
What am I doing wrong? And, if this is not the way, how can I create an object with a variable number of inlets and outlets (preferably independent of one another).