1
0
Fork 0
forked from len0rd/rockbox
foxbox/apps/plugins/pdbox/PDa/src/x_connective.c
Andree Buschmann f7808c1fe5 Fix several 'variable set but not used' warnings reported by GCC 6.4.1.
git-svn-id: svn://svn.rockbox.org/rockbox/trunk@29871 a1c6a512-1295-4272-9138-f99709370657
2011-05-13 18:47:42 +00:00

1512 lines
36 KiB
C

/* Copyright (c) 1997-1999 Miller Puckette.
* For information on usage and redistribution, and for a DISCLAIMER OF ALL
* WARRANTIES, see the file, "LICENSE.txt," in this distribution. */
/* connective objects */
#ifdef ROCKBOX
#include "plugin.h"
#include "../../pdbox.h"
#endif
#include "m_pd.h"
#ifndef ROCKBOX
#include <string.h>
#include <stdio.h>
#endif
extern t_pd *newest;
/* -------------------------- int ------------------------------ */
static t_class *pdint_class;
typedef struct _pdint
{
t_object x_obj;
t_float x_f;
} t_pdint;
static void *pdint_new(t_floatarg f)
{
t_pdint *x = (t_pdint *)pd_new(pdint_class);
x->x_f = f;
outlet_new(&x->x_obj, &s_float);
floatinlet_new(&x->x_obj, &x->x_f);
return (x);
}
static void pdint_bang(t_pdint *x)
{
outlet_float(x->x_obj.ob_outlet, (t_float)(int)(x->x_f));
}
static void pdint_float(t_pdint *x, t_float f)
{
outlet_float(x->x_obj.ob_outlet, (t_float)(int)(x->x_f = f));
}
void pdint_setup(void)
{
pdint_class = class_new(gensym("int"), (t_newmethod)pdint_new, 0,
sizeof(t_pdint), 0, A_DEFFLOAT, 0);
class_addcreator((t_newmethod)pdint_new, gensym("i"), A_DEFFLOAT, 0);
class_addbang(pdint_class, pdint_bang);
class_addfloat(pdint_class, pdint_float);
}
/* -------------------------- float ------------------------------ */
static t_class *pdfloat_class;
typedef struct _pdfloat
{
t_object x_obj;
t_float x_f;
} t_pdfloat;
/* "float," "symbol," and "bang" are special because
they're created by short-circuited messages to the "new"
object which are handled specially in pd_typedmess(). */
static void *pdfloat_new(t_pd *dummy, t_float f)
{
#ifdef ROCKBOX
(void) dummy;
#endif
t_pdfloat *x = (t_pdfloat *)pd_new(pdfloat_class);
x->x_f = f;
outlet_new(&x->x_obj, &s_float);
floatinlet_new(&x->x_obj, &x->x_f);
newest = &x->x_obj.ob_pd;
return (x);
}
static void *pdfloat_new2(t_floatarg f)
{
return (pdfloat_new(0, f));
}
static void pdfloat_bang(t_pdfloat *x)
{
outlet_float(x->x_obj.ob_outlet, x->x_f);
}
static void pdfloat_float(t_pdfloat *x, t_float f)
{
outlet_float(x->x_obj.ob_outlet, x->x_f = f);
}
void pdfloat_setup(void)
{
pdfloat_class = class_new(gensym("float"), (t_newmethod)pdfloat_new, 0,
sizeof(t_pdfloat), 0, A_FLOAT, 0);
class_addcreator((t_newmethod)pdfloat_new2, gensym("f"), A_DEFFLOAT, 0);
class_addbang(pdfloat_class, pdfloat_bang);
class_addfloat(pdfloat_class, (t_method)pdfloat_float);
}
/* -------------------------- symbol ------------------------------ */
static t_class *pdsymbol_class;
typedef struct _pdsymbol
{
t_object x_obj;
t_symbol *x_s;
} t_pdsymbol;
static void *pdsymbol_new(t_pd *dummy, t_symbol *s)
{
#ifdef ROCKBOX
(void) dummy;
#endif
t_pdsymbol *x = (t_pdsymbol *)pd_new(pdsymbol_class);
x->x_s = s;
outlet_new(&x->x_obj, &s_symbol);
symbolinlet_new(&x->x_obj, &x->x_s);
newest = &x->x_obj.ob_pd;
return (x);
}
static void pdsymbol_bang(t_pdsymbol *x)
{
outlet_symbol(x->x_obj.ob_outlet, x->x_s);
}
static void pdsymbol_symbol(t_pdsymbol *x, t_symbol *s)
{
outlet_symbol(x->x_obj.ob_outlet, x->x_s = s);
}
static void pdsymbol_anything(t_pdsymbol *x, t_symbol *s, int ac, t_atom *av)
{
#ifdef ROCKBOX
(void) ac;
(void) av;
#endif
outlet_symbol(x->x_obj.ob_outlet, x->x_s = s);
}
void pdsymbol_setup(void)
{
pdsymbol_class = class_new(gensym("symbol"), (t_newmethod)pdsymbol_new, 0,
sizeof(t_pdsymbol), 0, A_SYMBOL, 0);
class_addbang(pdsymbol_class, pdsymbol_bang);
class_addsymbol(pdsymbol_class, pdsymbol_symbol);
class_addanything(pdsymbol_class, pdsymbol_anything);
}
/* -------------------------- bang ------------------------------ */
static t_class *bang_class;
typedef struct _bang
{
t_object x_obj;
} t_bang;
static void *bang_new(t_pd *dummy)
{
#ifdef ROCKBOX
(void) dummy;
#endif
t_bang *x = (t_bang *)pd_new(bang_class);
outlet_new(&x->x_obj, &s_bang);
newest = &x->x_obj.ob_pd;
return (x);
}
static void *bang_new2(t_bang f)
{
#ifdef ROCKBOX
(void) f;
#endif
return (bang_new(0));
}
static void bang_bang(t_bang *x)
{
outlet_bang(x->x_obj.ob_outlet);
}
void bang_setup(void)
{
bang_class = class_new(gensym("bang"), (t_newmethod)bang_new, 0,
sizeof(t_bang), 0, 0);
class_addcreator((t_newmethod)bang_new2, gensym("b"), 0);
class_addbang(bang_class, bang_bang);
class_addfloat(bang_class, bang_bang);
class_addsymbol(bang_class, bang_bang);
class_addlist(bang_class, bang_bang);
class_addanything(bang_class, bang_bang);
}
/* -------------------- send ------------------------------ */
static t_class *send_class;
typedef struct _send
{
t_object x_obj;
t_symbol *x_sym;
} t_send;
static void send_bang(t_send *x)
{
if (x->x_sym->s_thing) pd_bang(x->x_sym->s_thing);
}
static void send_float(t_send *x, t_float f)
{
if (x->x_sym->s_thing) pd_float(x->x_sym->s_thing, f);
}
static void send_symbol(t_send *x, t_symbol *s)
{
if (x->x_sym->s_thing) pd_symbol(x->x_sym->s_thing, s);
}
static void send_pointer(t_send *x, t_gpointer *gp)
{
if (x->x_sym->s_thing) pd_pointer(x->x_sym->s_thing, gp);
}
static void send_list(t_send *x, t_symbol *s, int argc, t_atom *argv)
{
if (x->x_sym->s_thing) pd_list(x->x_sym->s_thing, s, argc, argv);
}
static void send_anything(t_send *x, t_symbol *s, int argc, t_atom *argv)
{
if (x->x_sym->s_thing) typedmess(x->x_sym->s_thing, s, argc, argv);
}
static void *send_new(t_symbol *s)
{
t_send *x = (t_send *)pd_new(send_class);
x->x_sym = s;
return (x);
}
static void send_setup(void)
{
send_class = class_new(gensym("send"), (t_newmethod)send_new, 0,
sizeof(t_send), 0, A_DEFSYM, 0);
class_addcreator((t_newmethod)send_new, gensym("s"), A_DEFSYM, 0);
class_addbang(send_class, send_bang);
class_addfloat(send_class, send_float);
class_addsymbol(send_class, send_symbol);
class_addpointer(send_class, send_pointer);
class_addlist(send_class, send_list);
class_addanything(send_class, send_anything);
}
/* -------------------- receive ------------------------------ */
static t_class *receive_class;
typedef struct _receive
{
t_object x_obj;
t_symbol *x_sym;
} t_receive;
static void receive_bang(t_receive *x)
{
outlet_bang(x->x_obj.ob_outlet);
}
static void receive_float(t_receive *x, t_float f)
{
outlet_float(x->x_obj.ob_outlet, f);
}
static void receive_symbol(t_receive *x, t_symbol *s)
{
outlet_symbol(x->x_obj.ob_outlet, s);
}
static void receive_pointer(t_receive *x, t_gpointer *gp)
{
outlet_pointer(x->x_obj.ob_outlet, gp);
}
static void receive_list(t_receive *x, t_symbol *s, int argc, t_atom *argv)
{
outlet_list(x->x_obj.ob_outlet, s, argc, argv);
}
static void receive_anything(t_receive *x, t_symbol *s, int argc, t_atom *argv)
{
outlet_anything(x->x_obj.ob_outlet, s, argc, argv);
}
static void *receive_new(t_symbol *s)
{
t_receive *x = (t_receive *)pd_new(receive_class);
x->x_sym = s;
pd_bind(&x->x_obj.ob_pd, s);
outlet_new(&x->x_obj, 0);
return (x);
}
static void receive_free(t_receive *x)
{
pd_unbind(&x->x_obj.ob_pd, x->x_sym);
}
static void receive_setup(void)
{
receive_class = class_new(gensym("receive"), (t_newmethod)receive_new,
(t_method)receive_free, sizeof(t_receive), CLASS_NOINLET, A_DEFSYM, 0);
class_addcreator((t_newmethod)receive_new, gensym("r"), A_DEFSYM, 0);
class_addbang(receive_class, receive_bang);
class_addfloat(receive_class, (t_method)receive_float);
class_addsymbol(receive_class, receive_symbol);
class_addpointer(receive_class, receive_pointer);
class_addlist(receive_class, receive_list);
class_addanything(receive_class, receive_anything);
}
/* -------------------------- select ------------------------------ */
static t_class *sel1_class;
typedef struct _sel1
{
t_object x_obj;
t_atom x_atom;
t_outlet *x_outlet1;
t_outlet *x_outlet2;
} t_sel1;
static void sel1_float(t_sel1 *x, t_float f)
{
if (x->x_atom.a_type == A_FLOAT && f == x->x_atom.a_w.w_float)
outlet_bang(x->x_outlet1);
else outlet_float(x->x_outlet2, f);
}
static void sel1_symbol(t_sel1 *x, t_symbol *s)
{
if (x->x_atom.a_type == A_SYMBOL && s == x->x_atom.a_w.w_symbol)
outlet_bang(x->x_outlet1);
else outlet_symbol(x->x_outlet2, s);
}
static t_class *sel2_class;
typedef struct _selectelement
{
t_word e_w;
t_outlet *e_outlet;
} t_selectelement;
typedef struct _sel2
{
t_object x_obj;
t_atomtype x_type;
t_int x_nelement;
t_selectelement *x_vec;
t_outlet *x_rejectout;
} t_sel2;
static void sel2_float(t_sel2 *x, t_float f)
{
t_selectelement *e;
int nelement;
if (x->x_type == A_FLOAT)
{
for (nelement = x->x_nelement, e = x->x_vec; nelement--; e++)
if (e->e_w.w_float == f)
{
outlet_bang(e->e_outlet);
return;
}
}
outlet_float(x->x_rejectout, f);
}
static void sel2_symbol(t_sel2 *x, t_symbol *s)
{
t_selectelement *e;
int nelement;
if (x->x_type == A_SYMBOL)
{
for (nelement = x->x_nelement, e = x->x_vec; nelement--; e++)
if (e->e_w.w_symbol == s)
{
outlet_bang(e->e_outlet);
return;
}
}
outlet_symbol(x->x_rejectout, s);
}
static void sel2_free(t_sel2 *x)
{
freebytes(x->x_vec, x->x_nelement * sizeof(*x->x_vec));
}
static void *select_new(t_symbol *s, int argc, t_atom *argv)
{
#ifdef ROCKBOX
(void) s;
#endif
t_atom a;
if (argc == 0)
{
argc = 1;
SETFLOAT(&a, 0);
argv = &a;
}
if (argc == 1)
{
t_sel1 *x = (t_sel1 *)pd_new(sel1_class);
x->x_atom = *argv;
x->x_outlet1 = outlet_new(&x->x_obj, &s_bang);
if (argv->a_type == A_FLOAT)
{
floatinlet_new(&x->x_obj, &x->x_atom.a_w.w_float);
x->x_outlet2 = outlet_new(&x->x_obj, &s_float);
}
else
{
symbolinlet_new(&x->x_obj, &x->x_atom.a_w.w_symbol);
x->x_outlet2 = outlet_new(&x->x_obj, &s_symbol);
}
return (x);
}
else
{
int n;
t_selectelement *e;
t_sel2 *x = (t_sel2 *)pd_new(sel2_class);
x->x_nelement = argc;
x->x_vec = (t_selectelement *)getbytes(argc * sizeof(*x->x_vec));
x->x_type = argv[0].a_type;
for (n = 0, e = x->x_vec; n < argc; n++, e++)
{
e->e_outlet = outlet_new(&x->x_obj, &s_bang);
if ((x->x_type = argv->a_type) == A_FLOAT)
e->e_w.w_float = atom_getfloatarg(n, argc, argv);
else e->e_w.w_symbol = atom_getsymbolarg(n, argc, argv);
}
x->x_rejectout = outlet_new(&x->x_obj, &s_float);
return (x);
}
}
void select_setup(void)
{
sel1_class = class_new(gensym("select"), 0, 0,
sizeof(t_sel1), 0, 0);
class_addfloat(sel1_class, sel1_float);
class_addsymbol(sel1_class, sel1_symbol);
sel2_class = class_new(gensym("select"), 0, (t_method)sel2_free,
sizeof(t_sel2), 0, 0);
class_addfloat(sel2_class, sel2_float);
class_addsymbol(sel2_class, sel2_symbol);
class_addcreator((t_newmethod)select_new, gensym("select"), A_GIMME, 0);
class_addcreator((t_newmethod)select_new, gensym("sel"), A_GIMME, 0);
}
/* -------------------------- route ------------------------------ */
static t_class *route_class;
typedef struct _routeelement
{
t_word e_w;
t_outlet *e_outlet;
} t_routeelement;
typedef struct _route
{
t_object x_obj;
t_atomtype x_type;
t_int x_nelement;
t_routeelement *x_vec;
t_outlet *x_rejectout;
} t_route;
static void route_anything(t_route *x, t_symbol *sel, int argc, t_atom *argv)
{
t_routeelement *e;
int nelement;
if (x->x_type == A_SYMBOL)
{
for (nelement = x->x_nelement, e = x->x_vec; nelement--; e++)
if (e->e_w.w_symbol == sel)
{
if (argc > 0 && argv[0].a_type == A_SYMBOL)
outlet_anything(e->e_outlet, argv[0].a_w.w_symbol,
argc-1, argv+1);
else outlet_list(e->e_outlet, 0, argc, argv);
return;
}
}
outlet_anything(x->x_rejectout, sel, argc, argv);
}
static void route_list(t_route *x, t_symbol *sel, int argc, t_atom *argv)
{
#ifdef ROCKBOX
(void) sel;
#endif
t_routeelement *e;
int nelement;
if (x->x_type == A_FLOAT)
{
float f;
if (!argc) return;
f = atom_getfloat(argv);
for (nelement = x->x_nelement, e = x->x_vec; nelement--; e++)
if (e->e_w.w_float == f)
{
if (argc > 1 && argv[1].a_type == A_SYMBOL)
outlet_anything(e->e_outlet, argv[1].a_w.w_symbol,
argc-2, argv+2);
else outlet_list(e->e_outlet, 0, argc-1, argv+1);
return;
}
}
else /* symbol arguments */
{
if (argc > 1) /* 2 or more args: treat as "list" */
{
for (nelement = x->x_nelement, e = x->x_vec; nelement--; e++)
{
if (e->e_w.w_symbol == &s_list)
{
if (argc > 0 && argv[0].a_type == A_SYMBOL)
outlet_anything(e->e_outlet, argv[0].a_w.w_symbol,
argc-1, argv+1);
else outlet_list(e->e_outlet, 0, argc, argv);
return;
}
}
}
else if (argc == 0) /* no args: treat as "bang" */
{
for (nelement = x->x_nelement, e = x->x_vec; nelement--; e++)
{
if (e->e_w.w_symbol == &s_bang)
{
outlet_bang(e->e_outlet);
return;
}
}
}
else if (argv[0].a_type == A_FLOAT) /* one float arg */
{
for (nelement = x->x_nelement, e = x->x_vec; nelement--; e++)
{
if (e->e_w.w_symbol == &s_float)
{
outlet_float(e->e_outlet, argv[0].a_w.w_float);
return;
}
}
}
else
{
for (nelement = x->x_nelement, e = x->x_vec; nelement--; e++)
{
if (e->e_w.w_symbol == &s_symbol)
{
outlet_symbol(e->e_outlet, argv[0].a_w.w_symbol);
return;
}
}
}
}
outlet_list(x->x_rejectout, 0, argc, argv);
}
static void route_free(t_route *x)
{
freebytes(x->x_vec, x->x_nelement * sizeof(*x->x_vec));
}
static void *route_new(t_symbol *s, int argc, t_atom *argv)
{
#ifdef ROCKBOX
(void) s;
#endif
int n;
t_routeelement *e;
t_route *x = (t_route *)pd_new(route_class);
t_atom a;
if (argc == 0)
{
argc = 1;
SETFLOAT(&a, 0);
argv = &a;
}
x->x_type = argv[0].a_type;
x->x_nelement = argc;
x->x_vec = (t_routeelement *)getbytes(argc * sizeof(*x->x_vec));
for (n = 0, e = x->x_vec; n < argc; n++, e++)
{
e->e_outlet = outlet_new(&x->x_obj, &s_list);
if (x->x_type == A_FLOAT)
e->e_w.w_float = atom_getfloatarg(n, argc, argv);
else e->e_w.w_symbol = atom_getsymbolarg(n, argc, argv);
}
x->x_rejectout = outlet_new(&x->x_obj, &s_list);
return (x);
}
void route_setup(void)
{
route_class = class_new(gensym("route"), (t_newmethod)route_new,
(t_method)route_free, sizeof(t_route), 0, A_GIMME, 0);
class_addlist(route_class, route_list);
class_addanything(route_class, route_anything);
}
/* -------------------------- pack ------------------------------ */
static t_class *pack_class;
typedef struct _pack
{
t_object x_obj;
t_int x_n; /* number of args */
t_atom *x_vec; /* input values */
t_int x_nptr; /* number of pointers */
t_gpointer *x_gpointer; /* the pointers */
t_atom *x_outvec; /* space for output values */
} t_pack;
static void *pack_new(t_symbol *s, int argc, t_atom *argv)
{
#ifdef ROCKBOX
(void) s;
#endif
t_pack *x = (t_pack *)pd_new(pack_class);
t_atom defarg[2], *ap, /* *vec, */ *vp;
t_gpointer *gp;
int nptr = 0;
int i;
if (!argc)
{
argv = defarg;
argc = 2;
SETFLOAT(&defarg[0], 0);
SETFLOAT(&defarg[1], 0);
}
x->x_n = argc;
/* vec = */ x->x_vec = (t_atom *)getbytes(argc * sizeof(*x->x_vec));
x->x_outvec = (t_atom *)getbytes(argc * sizeof(*x->x_outvec));
for (i = argc, ap = argv; i--; ap++)
if (ap->a_type == A_SYMBOL && *ap->a_w.w_symbol->s_name == 'p')
nptr++;
gp = x->x_gpointer = (t_gpointer *)t_getbytes(nptr * sizeof (*gp));
x->x_nptr = nptr;
for (i = 0, vp = x->x_vec, ap = argv; i < argc; i++, ap++, vp++)
{
if (ap->a_type == A_FLOAT)
{
*vp = *ap;
if (i) floatinlet_new(&x->x_obj, &vp->a_w.w_float);
}
else if (ap->a_type == A_SYMBOL)
{
char c = *ap->a_w.w_symbol->s_name;
if (c == 's')
{
SETSYMBOL(vp, &s_symbol);
if (i) symbolinlet_new(&x->x_obj, &vp->a_w.w_symbol);
}
else if (c == 'p')
{
vp->a_type = A_POINTER;
vp->a_w.w_gpointer = gp;
gpointer_init(gp);
if (i) pointerinlet_new(&x->x_obj, gp);
gp++;
}
else
{
if (c != 'f') pd_error(x, "pack: %s: bad type",
ap->a_w.w_symbol->s_name);
SETFLOAT(vp, 0);
if (i) floatinlet_new(&x->x_obj, &vp->a_w.w_float);
}
}
}
outlet_new(&x->x_obj, &s_list);
return (x);
}
static void pack_bang(t_pack *x)
{
int i, reentered = 0, size = x->x_n * sizeof (t_atom);
t_gpointer *gp;
t_atom *outvec;
for (i = x->x_nptr, gp = x->x_gpointer; i--; gp++)
if (!gpointer_check(gp, 1))
{
pd_error(x, "pack: stale pointer");
return;
}
/* reentrancy protection. The first time through use the pre-allocated
x_outvec; if we're reentered we have to allocate new memory. */
if (!x->x_outvec)
{
/* LATER figure out how to deal with reentrancy and pointers... */
if (x->x_nptr)
post("pack_bang: warning: reentry with pointers unprotected");
outvec = t_getbytes(size);
reentered = 1;
}
else
{
outvec = x->x_outvec;
x->x_outvec = 0;
}
memcpy(outvec, x->x_vec, size);
outlet_list(x->x_obj.ob_outlet, &s_list, x->x_n, outvec);
if (reentered)
t_freebytes(outvec, size);
else x->x_outvec = outvec;
}
static void pack_pointer(t_pack *x, t_gpointer *gp)
{
if (x->x_vec->a_type == A_POINTER)
{
gpointer_unset(x->x_gpointer);
*x->x_gpointer = *gp;
if (gp->gp_stub) gp->gp_stub->gs_refcount++;
pack_bang(x);
}
else pd_error(x, "pack_pointer: wrong type");
}
static void pack_float(t_pack *x, t_float f)
{
if (x->x_vec->a_type == A_FLOAT)
{
x->x_vec->a_w.w_float = f;
pack_bang(x);
}
else pd_error(x, "pack_float: wrong type");
}
static void pack_symbol(t_pack *x, t_symbol *s)
{
if (x->x_vec->a_type == A_SYMBOL)
{
x->x_vec->a_w.w_symbol = s;
pack_bang(x);
}
else pd_error(x, "pack_symbol: wrong type");
}
static void pack_list(t_pack *x, t_symbol *s, int ac, t_atom *av)
{
#ifdef ROCKBOX
(void) s;
#endif
obj_list(&x->x_obj, 0, ac, av);
}
static void pack_anything(t_pack *x, t_symbol *s, int ac, t_atom *av)
{
t_atom *av2 = (t_atom *)getbytes((ac + 1) * sizeof(t_atom));
int i;
for (i = 0; i < ac; i++)
av2[i + 1] = av[i];
SETSYMBOL(av2, s);
obj_list(&x->x_obj, 0, ac+1, av2);
freebytes(av2, (ac + 1) * sizeof(t_atom));
}
static void pack_free(t_pack *x)
{
t_gpointer *gp;
int i;
for (gp = x->x_gpointer, i = x->x_nptr; i--; gp++)
gpointer_unset(gp);
freebytes(x->x_vec, x->x_n * sizeof(*x->x_vec));
freebytes(x->x_outvec, x->x_n * sizeof(*x->x_outvec));
freebytes(x->x_gpointer, x->x_nptr * sizeof(*x->x_gpointer));
}
static void pack_setup(void)
{
pack_class = class_new(gensym("pack"), (t_newmethod)pack_new,
(t_method)pack_free, sizeof(t_pack), 0, A_GIMME, 0);
class_addbang(pack_class, pack_bang);
class_addpointer(pack_class, pack_pointer);
class_addfloat(pack_class, pack_float);
class_addsymbol(pack_class, pack_symbol);
class_addlist(pack_class, pack_list);
class_addanything(pack_class, pack_anything);
}
/* -------------------------- unpack ------------------------------ */
static t_class *unpack_class;
typedef struct unpackout
{
t_atomtype u_type;
t_outlet *u_outlet;
} t_unpackout;
typedef struct _unpack
{
t_object x_obj;
t_int x_n;
t_unpackout *x_vec;
} t_unpack;
static void *unpack_new(t_symbol *s, int argc, t_atom *argv)
{
#ifdef ROCKBOX
(void) s;
#endif
t_unpack *x = (t_unpack *)pd_new(unpack_class);
t_atom defarg[2], *ap;
t_unpackout *u;
int i;
if (!argc)
{
argv = defarg;
argc = 2;
SETFLOAT(&defarg[0], 0);
SETFLOAT(&defarg[1], 0);
}
x->x_n = argc;
x->x_vec = (t_unpackout *)getbytes(argc * sizeof(*x->x_vec));
for (i = 0, ap = argv, u = x->x_vec; i < argc; u++, ap++, i++)
{
t_atomtype type = ap->a_type;
if (type == A_SYMBOL)
{
char c = *ap->a_w.w_symbol->s_name;
if (c == 's')
{
u->u_type = A_SYMBOL;
u->u_outlet = outlet_new(&x->x_obj, &s_symbol);
}
else if (c == 'p')
{
u->u_type = A_POINTER;
u->u_outlet = outlet_new(&x->x_obj, &s_pointer);
}
else
{
if (c != 'f') pd_error(x, "unpack: %s: bad type",
ap->a_w.w_symbol->s_name);
u->u_type = A_FLOAT;
u->u_outlet = outlet_new(&x->x_obj, &s_float);
}
}
else
{
u->u_type = A_FLOAT;
u->u_outlet = outlet_new(&x->x_obj, &s_float);
}
}
return (x);
}
static void unpack_list(t_unpack *x, t_symbol *s, int argc, t_atom *argv)
{
#ifdef ROCKBOX
(void) s;
#endif
t_atom *ap;
t_unpackout *u;
int i;
if (argc > x->x_n) argc = x->x_n;
for (i = argc, u = x->x_vec + i, ap = argv + i; u--, ap--, i--;)
{
t_atomtype type = u->u_type;
if (type != ap->a_type)
pd_error(x, "unpack: type mismatch");
else if (type == A_FLOAT)
outlet_float(u->u_outlet, ap->a_w.w_float);
else if (type == A_SYMBOL)
outlet_symbol(u->u_outlet, ap->a_w.w_symbol);
else outlet_pointer(u->u_outlet, ap->a_w.w_gpointer);
}
}
static void unpack_anything(t_unpack *x, t_symbol *s, int ac, t_atom *av)
{
t_atom *av2 = (t_atom *)getbytes((ac + 1) * sizeof(t_atom));
int i;
for (i = 0; i < ac; i++)
av2[i + 1] = av[i];
SETSYMBOL(av2, s);
unpack_list(x, 0, ac+1, av2);
freebytes(av2, (ac + 1) * sizeof(t_atom));
}
static void unpack_free(t_unpack *x)
{
freebytes(x->x_vec, x->x_n * sizeof(*x->x_vec));
}
static void unpack_setup(void)
{
unpack_class = class_new(gensym("unpack"), (t_newmethod)unpack_new,
(t_method)unpack_free, sizeof(t_unpack), 0, A_GIMME, 0);
class_addlist(unpack_class, unpack_list);
class_addanything(unpack_class, unpack_anything);
}
/* -------------------------- trigger ------------------------------ */
static t_class *trigger_class;
#define TR_BANG 0
#define TR_FLOAT 1
#define TR_SYMBOL 2
#define TR_POINTER 3
#define TR_LIST 4
#define TR_ANYTHING 5
typedef struct triggerout
{
int u_type; /* outlet type from above */
t_outlet *u_outlet;
} t_triggerout;
typedef struct _trigger
{
t_object x_obj;
t_int x_n;
t_triggerout *x_vec;
} t_trigger;
static void *trigger_new(t_symbol *s, int argc, t_atom *argv)
{
#ifdef ROCKBOX
(void) s;
#endif
t_trigger *x = (t_trigger *)pd_new(trigger_class);
t_atom defarg[2], *ap;
t_triggerout *u;
int i;
if (!argc)
{
argv = defarg;
argc = 2;
SETSYMBOL(&defarg[0], &s_bang);
SETSYMBOL(&defarg[1], &s_bang);
}
x->x_n = argc;
x->x_vec = (t_triggerout *)getbytes(argc * sizeof(*x->x_vec));
for (i = 0, ap = argv, u = x->x_vec; i < argc; u++, ap++, i++)
{
t_atomtype thistype = ap->a_type;
char c;
if (thistype == TR_SYMBOL) c = ap->a_w.w_symbol->s_name[0];
else if (thistype == TR_FLOAT) c = 'f';
else c = 0;
if (c == 'p')
u->u_type = TR_POINTER,
u->u_outlet = outlet_new(&x->x_obj, &s_pointer);
else if (c == 'f')
u->u_type = TR_FLOAT, u->u_outlet = outlet_new(&x->x_obj, &s_float);
else if (c == 'b')
u->u_type = TR_BANG, u->u_outlet = outlet_new(&x->x_obj, &s_bang);
else if (c == 'l')
u->u_type = TR_LIST, u->u_outlet = outlet_new(&x->x_obj, &s_list);
else if (c == 's')
u->u_type = TR_SYMBOL,
u->u_outlet = outlet_new(&x->x_obj, &s_symbol);
else if (c == 'a')
u->u_type = TR_ANYTHING,
u->u_outlet = outlet_new(&x->x_obj, &s_symbol);
else
{
pd_error(x, "trigger: %s: bad type", ap->a_w.w_symbol->s_name);
u->u_type = TR_FLOAT, u->u_outlet = outlet_new(&x->x_obj, &s_float);
}
}
return (x);
}
static void trigger_list(t_trigger *x, t_symbol *s, int argc, t_atom *argv)
{
#ifdef ROCKBOX
(void) s;
#endif
t_triggerout *u;
int i;
t_atom at;
if (!argc)
{
argc = 1;
SETFLOAT(&at, 0);
argv = &at;
}
for (i = x->x_n, u = x->x_vec + i; u--, i--;)
{
if (u->u_type == TR_FLOAT)
outlet_float(u->u_outlet, atom_getfloat(argv));
else if (u->u_type == TR_BANG)
outlet_bang(u->u_outlet);
else if (u->u_type == TR_SYMBOL)
outlet_symbol(u->u_outlet, atom_getsymbol(argv));
else if (u->u_type == TR_POINTER)
{
if (argv->a_type != TR_POINTER)
pd_error(x, "unpack: bad pointer");
else outlet_pointer(u->u_outlet, argv->a_w.w_gpointer);
}
else outlet_list(u->u_outlet, &s_list, argc, argv);
}
}
static void trigger_anything(t_trigger *x, t_symbol *s, int argc, t_atom *argv)
{
t_triggerout *u;
int i;
for (i = x->x_n, u = x->x_vec + i; u--, i--;)
{
if (u->u_type == TR_BANG)
outlet_bang(u->u_outlet);
else if (u->u_type == TR_ANYTHING)
outlet_anything(u->u_outlet, s, argc, argv);
else pd_error(x, "trigger: can only convert 's' to 'b' or 'a'",
s->s_name);
}
}
static void trigger_bang(t_trigger *x)
{
trigger_list(x, 0, 0, 0);
}
static void trigger_pointer(t_trigger *x, t_gpointer *gp)
{
t_atom at;
SETPOINTER(&at, gp);
trigger_list(x, 0, 1, &at);
}
static void trigger_float(t_trigger *x, t_float f)
{
t_atom at;
SETFLOAT(&at, f);
trigger_list(x, 0, 1, &at);
}
static void trigger_symbol(t_trigger *x, t_symbol *s)
{
t_atom at;
SETSYMBOL(&at, s);
trigger_list(x, 0, 1, &at);
}
static void trigger_free(t_trigger *x)
{
freebytes(x->x_vec, x->x_n * sizeof(*x->x_vec));
}
static void trigger_setup(void)
{
trigger_class = class_new(gensym("trigger"), (t_newmethod)trigger_new,
(t_method)trigger_free, sizeof(t_trigger), 0, A_GIMME, 0);
class_addcreator((t_newmethod)trigger_new, gensym("t"), A_GIMME, 0);
class_addlist(trigger_class, trigger_list);
class_addbang(trigger_class, trigger_bang);
class_addpointer(trigger_class, trigger_pointer);
class_addfloat(trigger_class, (t_method)trigger_float);
class_addsymbol(trigger_class, trigger_symbol);
class_addanything(trigger_class, trigger_anything);
}
/* -------------------------- spigot ------------------------------ */
static t_class *spigot_class;
typedef struct _spigot
{
t_object x_obj;
float x_state;
} t_spigot;
static void *spigot_new(void)
{
t_spigot *x = (t_spigot *)pd_new(spigot_class);
floatinlet_new(&x->x_obj, &x->x_state);
outlet_new(&x->x_obj, 0);
x->x_state = 0;
return (x);
}
static void spigot_bang(t_spigot *x)
{
if (x->x_state != 0) outlet_bang(x->x_obj.ob_outlet);
}
static void spigot_pointer(t_spigot *x, t_gpointer *gp)
{
if (x->x_state != 0) outlet_pointer(x->x_obj.ob_outlet, gp);
}
static void spigot_float(t_spigot *x, t_float f)
{
if (x->x_state != 0) outlet_float(x->x_obj.ob_outlet, f);
}
static void spigot_symbol(t_spigot *x, t_symbol *s)
{
if (x->x_state != 0) outlet_symbol(x->x_obj.ob_outlet, s);
}
static void spigot_list(t_spigot *x, t_symbol *s, int argc, t_atom *argv)
{
if (x->x_state != 0) outlet_list(x->x_obj.ob_outlet, s, argc, argv);
}
static void spigot_anything(t_spigot *x, t_symbol *s, int argc, t_atom *argv)
{
if (x->x_state != 0) outlet_anything(x->x_obj.ob_outlet, s, argc, argv);
}
static void spigot_setup(void)
{
spigot_class = class_new(gensym("spigot"), (t_newmethod)spigot_new, 0,
sizeof(t_spigot), 0, A_DEFSYM, 0);
class_addbang(spigot_class, spigot_bang);
class_addpointer(spigot_class, spigot_pointer);
class_addfloat(spigot_class, spigot_float);
class_addsymbol(spigot_class, spigot_symbol);
class_addlist(spigot_class, spigot_list);
class_addanything(spigot_class, spigot_anything);
}
/* --------------------------- moses ----------------------------- */
static t_class *moses_class;
typedef struct _moses
{
t_object x_ob;
t_outlet *x_out2;
float x_y;
} t_moses;
static void *moses_new(t_floatarg f)
{
t_moses *x = (t_moses *)pd_new(moses_class);
floatinlet_new(&x->x_ob, &x->x_y);
outlet_new(&x->x_ob, &s_float);
x->x_out2 = outlet_new(&x->x_ob, &s_float);
x->x_y = f;
return (x);
}
static void moses_float(t_moses *x, t_float f)
{
if (f < x->x_y) outlet_float(x->x_ob.ob_outlet, f);
else outlet_float(x->x_out2, f);
}
static void moses_setup(void)
{
moses_class = class_new(gensym("moses"), (t_newmethod)moses_new, 0,
sizeof(t_moses), 0, A_DEFFLOAT, 0);
class_addfloat(moses_class, moses_float);
}
/* ----------------------- until --------------------- */
static t_class *until_class;
typedef struct _until
{
t_object x_obj;
int x_run;
int x_count;
} t_until;
static void *until_new(void)
{
t_until *x = (t_until *)pd_new(until_class);
inlet_new(&x->x_obj, &x->x_obj.ob_pd, gensym("bang"), gensym("bang2"));
outlet_new(&x->x_obj, &s_bang);
x->x_run = 0;
return (x);
}
static void until_bang(t_until *x)
{
x->x_run = 1;
x->x_count = -1;
while (x->x_run && x->x_count)
x->x_count--, outlet_bang(x->x_obj.ob_outlet);
}
static void until_float(t_until *x, t_float f)
{
x->x_run = 1;
x->x_count = f;
while (x->x_run && x->x_count)
x->x_count--, outlet_bang(x->x_obj.ob_outlet);
}
static void until_bang2(t_until *x)
{
x->x_run = 0;
}
static void until_setup(void)
{
until_class = class_new(gensym("until"), (t_newmethod)until_new, 0,
sizeof(t_until), 0, 0);
class_addbang(until_class, until_bang);
class_addfloat(until_class, until_float);
class_addmethod(until_class, (t_method)until_bang2, gensym("bang2"), 0);
}
/* ----------------------- makefilename --------------------- */
static t_class *makefilename_class;
typedef struct _makefilename
{
t_object x_obj;
t_symbol *x_format;
} t_makefilename;
static void *makefilename_new(t_symbol *s)
{
t_makefilename *x = (t_makefilename *)pd_new(makefilename_class);
if (!s->s_name) s = gensym("file.%d");
outlet_new(&x->x_obj, &s_symbol);
x->x_format = s;
return (x);
}
static void makefilename_float(t_makefilename *x, t_floatarg f)
{
char buf[MAXPDSTRING];
#ifdef ROCKBOX
snprintf(buf, sizeof(buf), x->x_format->s_name, (int)f);
#else
sprintf(buf, x->x_format->s_name, (int)f);
#endif
outlet_symbol(x->x_obj.ob_outlet, gensym(buf));
}
static void makefilename_symbol(t_makefilename *x, t_symbol *s)
{
char buf[MAXPDSTRING];
#ifdef ROCKBOX
snprintf(buf, sizeof(buf), x->x_format->s_name, s->s_name);
#else
sprintf(buf, x->x_format->s_name, s->s_name);
#endif
outlet_symbol(x->x_obj.ob_outlet, gensym(buf));
}
static void makefilename_setup(void)
{
makefilename_class = class_new(gensym("makefilename"),
(t_newmethod)makefilename_new, 0,
sizeof(t_makefilename), 0, A_DEFSYM, 0);
class_addfloat(makefilename_class, makefilename_float);
class_addsymbol(makefilename_class, makefilename_symbol);
}
/* -------------------------- swap ------------------------------ */
static t_class *swap_class;
typedef struct _swap
{
t_object x_obj;
t_outlet *x_out2;
t_float x_f1;
t_float x_f2;
} t_swap;
static void *swap_new(t_floatarg f)
{
t_swap *x = (t_swap *)pd_new(swap_class);
x->x_f2 = f;
x->x_f1 = 0;
outlet_new(&x->x_obj, &s_float);
x->x_out2 = outlet_new(&x->x_obj, &s_float);
floatinlet_new(&x->x_obj, &x->x_f2);
return (x);
}
static void swap_bang(t_swap *x)
{
outlet_float(x->x_out2, x->x_f1);
outlet_float(x->x_obj.ob_outlet, x->x_f2);
}
static void swap_float(t_swap *x, t_float f)
{
x->x_f1 = f;
swap_bang(x);
}
void swap_setup(void)
{
swap_class = class_new(gensym("swap"), (t_newmethod)swap_new, 0,
sizeof(t_swap), 0, A_DEFFLOAT, 0);
class_addcreator((t_newmethod)swap_new, gensym("fswap"), A_DEFFLOAT, 0);
class_addbang(swap_class, swap_bang);
class_addfloat(swap_class, swap_float);
}
/* -------------------------- change ------------------------------ */
static t_class *change_class;
typedef struct _change
{
t_object x_obj;
t_float x_f;
} t_change;
static void *change_new(t_floatarg f)
{
t_change *x = (t_change *)pd_new(change_class);
x->x_f = f;
outlet_new(&x->x_obj, &s_float);
return (x);
}
static void change_bang(t_change *x)
{
outlet_float(x->x_obj.ob_outlet, x->x_f);
}
static void change_float(t_change *x, t_float f)
{
if (f != x->x_f)
{
x->x_f = f;
outlet_float(x->x_obj.ob_outlet, x->x_f);
}
}
static void change_set(t_change *x, t_float f)
{
x->x_f = f;
}
void change_setup(void)
{
change_class = class_new(gensym("change"), (t_newmethod)change_new, 0,
sizeof(t_change), 0, A_DEFFLOAT, 0);
class_addbang(change_class, change_bang);
class_addfloat(change_class, change_float);
class_addmethod(change_class, (t_method)change_set, gensym("set"),
A_DEFFLOAT, 0);
}
/* -------------------- value ------------------------------ */
static t_class *value_class, *vcommon_class;
typedef struct vcommon
{
t_pd c_pd;
int c_refcount;
t_float c_f;
} t_vcommon;
typedef struct _value
{
t_object x_obj;
t_symbol *x_sym;
t_float *x_floatstar;
} t_value;
/* get a pointer to a named floating-point variable. The variable
belongs to a "vcommon" object, which is created if necessary. */
t_float *value_get(t_symbol *s)
{
t_vcommon *c = (t_vcommon *)pd_findbyclass(s, vcommon_class);
if (!c)
{
c = (t_vcommon *)pd_new(vcommon_class);
c->c_f = 0;
c->c_refcount = 0;
pd_bind(&c->c_pd, s);
}
c->c_refcount++;
return (&c->c_f);
}
/* release a variable. This only frees the "vcommon" resource when the
last interested party releases it. */
void value_release(t_symbol *s)
{
t_vcommon *c = (t_vcommon *)pd_findbyclass(s, vcommon_class);
if (c)
{
if (!--c->c_refcount)
{
pd_unbind(&c->c_pd, s);
pd_free(&c->c_pd);
}
}
else bug("value_release");
}
/*
* value_getfloat -- obtain the float value of a "value" object
* return 0 on success, 1 otherwise
*/
int
value_getfloat(t_symbol *s, t_float *f)
{
t_vcommon *c = (t_vcommon *)pd_findbyclass(s, vcommon_class);
if (!c)
return (1);
*f = c->c_f;
return (0);
}
/*
* value_setfloat -- set the float value of a "value" object
* return 0 on success, 1 otherwise
*/
int
value_setfloat(t_symbol *s, t_float f)
{
t_vcommon *c = (t_vcommon *)pd_findbyclass(s, vcommon_class);
if (!c)
return (1);
c->c_f = f;
return (0);
}
static void *value_new(t_symbol *s)
{
t_value *x = (t_value *)pd_new(value_class);
x->x_sym = s;
x->x_floatstar = value_get(s);
outlet_new(&x->x_obj, &s_float);
return (x);
}
static void value_bang(t_value *x)
{
outlet_float(x->x_obj.ob_outlet, *x->x_floatstar);
}
static void value_float(t_value *x, t_float f)
{
*x->x_floatstar = f;
}
static void value_ff(t_value *x)
{
value_release(x->x_sym);
}
static void value_setup(void)
{
value_class = class_new(gensym("value"), (t_newmethod)value_new,
(t_method)value_ff,
sizeof(t_value), 0, A_DEFSYM, 0);
class_addcreator((t_newmethod)value_new, gensym("v"), A_DEFSYM, 0);
class_addbang(value_class, value_bang);
class_addfloat(value_class, value_float);
vcommon_class = class_new(gensym("value"), 0, 0,
sizeof(t_vcommon), CLASS_PD, 0);
}
/* -------------- overall setup routine for this file ----------------- */
void x_connective_setup(void)
{
pdint_setup();
pdfloat_setup();
pdsymbol_setup();
bang_setup();
send_setup();
receive_setup();
select_setup();
route_setup();
pack_setup();
unpack_setup();
trigger_setup();
spigot_setup();
moses_setup();
until_setup();
makefilename_setup();
swap_setup();
change_setup();
value_setup();
}