1 /* Copyright (c) 1997-1999 Miller Puckette.
2 * For information on usage and redistribution, and for a DISCLAIMER OF ALL
3 * WARRANTIES, see the file, "LICENSE.txt," in this distribution. */
5 /* connective objects */
9 #include "../../pdbox.h"
21 /* -------------------------- int ------------------------------ */
22 static t_class
*pdint_class
;
30 static void *pdint_new(t_floatarg f
)
32 t_pdint
*x
= (t_pdint
*)pd_new(pdint_class
);
34 outlet_new(&x
->x_obj
, &s_float
);
35 floatinlet_new(&x
->x_obj
, &x
->x_f
);
39 static void pdint_bang(t_pdint
*x
)
41 outlet_float(x
->x_obj
.ob_outlet
, (t_float
)(int)(x
->x_f
));
44 static void pdint_float(t_pdint
*x
, t_float f
)
46 outlet_float(x
->x_obj
.ob_outlet
, (t_float
)(int)(x
->x_f
= f
));
49 void pdint_setup(void)
51 pdint_class
= class_new(gensym("int"), (t_newmethod
)pdint_new
, 0,
52 sizeof(t_pdint
), 0, A_DEFFLOAT
, 0);
53 class_addcreator((t_newmethod
)pdint_new
, gensym("i"), A_DEFFLOAT
, 0);
54 class_addbang(pdint_class
, pdint_bang
);
55 class_addfloat(pdint_class
, pdint_float
);
58 /* -------------------------- float ------------------------------ */
59 static t_class
*pdfloat_class
;
61 typedef struct _pdfloat
67 /* "float," "symbol," and "bang" are special because
68 they're created by short-circuited messages to the "new"
69 object which are handled specially in pd_typedmess(). */
71 static void *pdfloat_new(t_pd
*dummy
, t_float f
)
76 t_pdfloat
*x
= (t_pdfloat
*)pd_new(pdfloat_class
);
78 outlet_new(&x
->x_obj
, &s_float
);
79 floatinlet_new(&x
->x_obj
, &x
->x_f
);
80 newest
= &x
->x_obj
.ob_pd
;
84 static void *pdfloat_new2(t_floatarg f
)
86 return (pdfloat_new(0, f
));
89 static void pdfloat_bang(t_pdfloat
*x
)
91 outlet_float(x
->x_obj
.ob_outlet
, x
->x_f
);
94 static void pdfloat_float(t_pdfloat
*x
, t_float f
)
96 outlet_float(x
->x_obj
.ob_outlet
, x
->x_f
= f
);
99 void pdfloat_setup(void)
101 pdfloat_class
= class_new(gensym("float"), (t_newmethod
)pdfloat_new
, 0,
102 sizeof(t_pdfloat
), 0, A_FLOAT
, 0);
103 class_addcreator((t_newmethod
)pdfloat_new2
, gensym("f"), A_DEFFLOAT
, 0);
104 class_addbang(pdfloat_class
, pdfloat_bang
);
105 class_addfloat(pdfloat_class
, (t_method
)pdfloat_float
);
108 /* -------------------------- symbol ------------------------------ */
109 static t_class
*pdsymbol_class
;
111 typedef struct _pdsymbol
117 static void *pdsymbol_new(t_pd
*dummy
, t_symbol
*s
)
122 t_pdsymbol
*x
= (t_pdsymbol
*)pd_new(pdsymbol_class
);
124 outlet_new(&x
->x_obj
, &s_symbol
);
125 symbolinlet_new(&x
->x_obj
, &x
->x_s
);
126 newest
= &x
->x_obj
.ob_pd
;
130 static void pdsymbol_bang(t_pdsymbol
*x
)
132 outlet_symbol(x
->x_obj
.ob_outlet
, x
->x_s
);
135 static void pdsymbol_symbol(t_pdsymbol
*x
, t_symbol
*s
)
137 outlet_symbol(x
->x_obj
.ob_outlet
, x
->x_s
= s
);
140 static void pdsymbol_anything(t_pdsymbol
*x
, t_symbol
*s
, int ac
, t_atom
*av
)
146 outlet_symbol(x
->x_obj
.ob_outlet
, x
->x_s
= s
);
149 void pdsymbol_setup(void)
151 pdsymbol_class
= class_new(gensym("symbol"), (t_newmethod
)pdsymbol_new
, 0,
152 sizeof(t_pdsymbol
), 0, A_SYMBOL
, 0);
153 class_addbang(pdsymbol_class
, pdsymbol_bang
);
154 class_addsymbol(pdsymbol_class
, pdsymbol_symbol
);
155 class_addanything(pdsymbol_class
, pdsymbol_anything
);
158 /* -------------------------- bang ------------------------------ */
159 static t_class
*bang_class
;
166 static void *bang_new(t_pd
*dummy
)
171 t_bang
*x
= (t_bang
*)pd_new(bang_class
);
172 outlet_new(&x
->x_obj
, &s_bang
);
173 newest
= &x
->x_obj
.ob_pd
;
177 static void *bang_new2(t_bang f
)
182 return (bang_new(0));
185 static void bang_bang(t_bang
*x
)
187 outlet_bang(x
->x_obj
.ob_outlet
);
190 void bang_setup(void)
192 bang_class
= class_new(gensym("bang"), (t_newmethod
)bang_new
, 0,
193 sizeof(t_bang
), 0, 0);
194 class_addcreator((t_newmethod
)bang_new2
, gensym("b"), 0);
195 class_addbang(bang_class
, bang_bang
);
196 class_addfloat(bang_class
, bang_bang
);
197 class_addsymbol(bang_class
, bang_bang
);
198 class_addlist(bang_class
, bang_bang
);
199 class_addanything(bang_class
, bang_bang
);
202 /* -------------------- send ------------------------------ */
204 static t_class
*send_class
;
212 static void send_bang(t_send
*x
)
214 if (x
->x_sym
->s_thing
) pd_bang(x
->x_sym
->s_thing
);
217 static void send_float(t_send
*x
, t_float f
)
219 if (x
->x_sym
->s_thing
) pd_float(x
->x_sym
->s_thing
, f
);
222 static void send_symbol(t_send
*x
, t_symbol
*s
)
224 if (x
->x_sym
->s_thing
) pd_symbol(x
->x_sym
->s_thing
, s
);
227 static void send_pointer(t_send
*x
, t_gpointer
*gp
)
229 if (x
->x_sym
->s_thing
) pd_pointer(x
->x_sym
->s_thing
, gp
);
232 static void send_list(t_send
*x
, t_symbol
*s
, int argc
, t_atom
*argv
)
234 if (x
->x_sym
->s_thing
) pd_list(x
->x_sym
->s_thing
, s
, argc
, argv
);
237 static void send_anything(t_send
*x
, t_symbol
*s
, int argc
, t_atom
*argv
)
239 if (x
->x_sym
->s_thing
) typedmess(x
->x_sym
->s_thing
, s
, argc
, argv
);
242 static void *send_new(t_symbol
*s
)
244 t_send
*x
= (t_send
*)pd_new(send_class
);
249 static void send_setup(void)
251 send_class
= class_new(gensym("send"), (t_newmethod
)send_new
, 0,
252 sizeof(t_send
), 0, A_DEFSYM
, 0);
253 class_addcreator((t_newmethod
)send_new
, gensym("s"), A_DEFSYM
, 0);
254 class_addbang(send_class
, send_bang
);
255 class_addfloat(send_class
, send_float
);
256 class_addsymbol(send_class
, send_symbol
);
257 class_addpointer(send_class
, send_pointer
);
258 class_addlist(send_class
, send_list
);
259 class_addanything(send_class
, send_anything
);
261 /* -------------------- receive ------------------------------ */
263 static t_class
*receive_class
;
265 typedef struct _receive
271 static void receive_bang(t_receive
*x
)
273 outlet_bang(x
->x_obj
.ob_outlet
);
276 static void receive_float(t_receive
*x
, t_float f
)
278 outlet_float(x
->x_obj
.ob_outlet
, f
);
281 static void receive_symbol(t_receive
*x
, t_symbol
*s
)
283 outlet_symbol(x
->x_obj
.ob_outlet
, s
);
286 static void receive_pointer(t_receive
*x
, t_gpointer
*gp
)
288 outlet_pointer(x
->x_obj
.ob_outlet
, gp
);
291 static void receive_list(t_receive
*x
, t_symbol
*s
, int argc
, t_atom
*argv
)
293 outlet_list(x
->x_obj
.ob_outlet
, s
, argc
, argv
);
296 static void receive_anything(t_receive
*x
, t_symbol
*s
, int argc
, t_atom
*argv
)
298 outlet_anything(x
->x_obj
.ob_outlet
, s
, argc
, argv
);
301 static void *receive_new(t_symbol
*s
)
303 t_receive
*x
= (t_receive
*)pd_new(receive_class
);
305 pd_bind(&x
->x_obj
.ob_pd
, s
);
306 outlet_new(&x
->x_obj
, 0);
310 static void receive_free(t_receive
*x
)
312 pd_unbind(&x
->x_obj
.ob_pd
, x
->x_sym
);
315 static void receive_setup(void)
317 receive_class
= class_new(gensym("receive"), (t_newmethod
)receive_new
,
318 (t_method
)receive_free
, sizeof(t_receive
), CLASS_NOINLET
, A_DEFSYM
, 0);
319 class_addcreator((t_newmethod
)receive_new
, gensym("r"), A_DEFSYM
, 0);
320 class_addbang(receive_class
, receive_bang
);
321 class_addfloat(receive_class
, (t_method
)receive_float
);
322 class_addsymbol(receive_class
, receive_symbol
);
323 class_addpointer(receive_class
, receive_pointer
);
324 class_addlist(receive_class
, receive_list
);
325 class_addanything(receive_class
, receive_anything
);
328 /* -------------------------- select ------------------------------ */
330 static t_class
*sel1_class
;
340 static void sel1_float(t_sel1
*x
, t_float f
)
342 if (x
->x_atom
.a_type
== A_FLOAT
&& f
== x
->x_atom
.a_w
.w_float
)
343 outlet_bang(x
->x_outlet1
);
344 else outlet_float(x
->x_outlet2
, f
);
347 static void sel1_symbol(t_sel1
*x
, t_symbol
*s
)
349 if (x
->x_atom
.a_type
== A_SYMBOL
&& s
== x
->x_atom
.a_w
.w_symbol
)
350 outlet_bang(x
->x_outlet1
);
351 else outlet_symbol(x
->x_outlet2
, s
);
354 static t_class
*sel2_class
;
356 typedef struct _selectelement
367 t_selectelement
*x_vec
;
368 t_outlet
*x_rejectout
;
371 static void sel2_float(t_sel2
*x
, t_float f
)
375 if (x
->x_type
== A_FLOAT
)
377 for (nelement
= x
->x_nelement
, e
= x
->x_vec
; nelement
--; e
++)
378 if (e
->e_w
.w_float
== f
)
380 outlet_bang(e
->e_outlet
);
384 outlet_float(x
->x_rejectout
, f
);
387 static void sel2_symbol(t_sel2
*x
, t_symbol
*s
)
391 if (x
->x_type
== A_SYMBOL
)
393 for (nelement
= x
->x_nelement
, e
= x
->x_vec
; nelement
--; e
++)
394 if (e
->e_w
.w_symbol
== s
)
396 outlet_bang(e
->e_outlet
);
400 outlet_symbol(x
->x_rejectout
, s
);
403 static void sel2_free(t_sel2
*x
)
405 freebytes(x
->x_vec
, x
->x_nelement
* sizeof(*x
->x_vec
));
408 static void *select_new(t_symbol
*s
, int argc
, t_atom
*argv
)
422 t_sel1
*x
= (t_sel1
*)pd_new(sel1_class
);
424 x
->x_outlet1
= outlet_new(&x
->x_obj
, &s_bang
);
425 if (argv
->a_type
== A_FLOAT
)
427 floatinlet_new(&x
->x_obj
, &x
->x_atom
.a_w
.w_float
);
428 x
->x_outlet2
= outlet_new(&x
->x_obj
, &s_float
);
432 symbolinlet_new(&x
->x_obj
, &x
->x_atom
.a_w
.w_symbol
);
433 x
->x_outlet2
= outlet_new(&x
->x_obj
, &s_symbol
);
441 t_sel2
*x
= (t_sel2
*)pd_new(sel2_class
);
442 x
->x_nelement
= argc
;
443 x
->x_vec
= (t_selectelement
*)getbytes(argc
* sizeof(*x
->x_vec
));
444 x
->x_type
= argv
[0].a_type
;
445 for (n
= 0, e
= x
->x_vec
; n
< argc
; n
++, e
++)
447 e
->e_outlet
= outlet_new(&x
->x_obj
, &s_bang
);
448 if ((x
->x_type
= argv
->a_type
) == A_FLOAT
)
449 e
->e_w
.w_float
= atom_getfloatarg(n
, argc
, argv
);
450 else e
->e_w
.w_symbol
= atom_getsymbolarg(n
, argc
, argv
);
452 x
->x_rejectout
= outlet_new(&x
->x_obj
, &s_float
);
458 void select_setup(void)
460 sel1_class
= class_new(gensym("select"), 0, 0,
461 sizeof(t_sel1
), 0, 0);
462 class_addfloat(sel1_class
, sel1_float
);
463 class_addsymbol(sel1_class
, sel1_symbol
);
465 sel2_class
= class_new(gensym("select"), 0, (t_method
)sel2_free
,
466 sizeof(t_sel2
), 0, 0);
467 class_addfloat(sel2_class
, sel2_float
);
468 class_addsymbol(sel2_class
, sel2_symbol
);
470 class_addcreator((t_newmethod
)select_new
, gensym("select"), A_GIMME
, 0);
471 class_addcreator((t_newmethod
)select_new
, gensym("sel"), A_GIMME
, 0);
474 /* -------------------------- route ------------------------------ */
476 static t_class
*route_class
;
478 typedef struct _routeelement
484 typedef struct _route
489 t_routeelement
*x_vec
;
490 t_outlet
*x_rejectout
;
493 static void route_anything(t_route
*x
, t_symbol
*sel
, int argc
, t_atom
*argv
)
497 if (x
->x_type
== A_SYMBOL
)
499 for (nelement
= x
->x_nelement
, e
= x
->x_vec
; nelement
--; e
++)
500 if (e
->e_w
.w_symbol
== sel
)
502 if (argc
> 0 && argv
[0].a_type
== A_SYMBOL
)
503 outlet_anything(e
->e_outlet
, argv
[0].a_w
.w_symbol
,
505 else outlet_list(e
->e_outlet
, 0, argc
, argv
);
509 outlet_anything(x
->x_rejectout
, sel
, argc
, argv
);
512 static void route_list(t_route
*x
, t_symbol
*sel
, int argc
, t_atom
*argv
)
519 if (x
->x_type
== A_FLOAT
)
523 f
= atom_getfloat(argv
);
524 for (nelement
= x
->x_nelement
, e
= x
->x_vec
; nelement
--; e
++)
525 if (e
->e_w
.w_float
== f
)
527 if (argc
> 1 && argv
[1].a_type
== A_SYMBOL
)
528 outlet_anything(e
->e_outlet
, argv
[1].a_w
.w_symbol
,
530 else outlet_list(e
->e_outlet
, 0, argc
-1, argv
+1);
534 else /* symbol arguments */
536 if (argc
> 1) /* 2 or more args: treat as "list" */
538 for (nelement
= x
->x_nelement
, e
= x
->x_vec
; nelement
--; e
++)
540 if (e
->e_w
.w_symbol
== &s_list
)
542 if (argc
> 0 && argv
[0].a_type
== A_SYMBOL
)
543 outlet_anything(e
->e_outlet
, argv
[0].a_w
.w_symbol
,
545 else outlet_list(e
->e_outlet
, 0, argc
, argv
);
550 else if (argc
== 0) /* no args: treat as "bang" */
552 for (nelement
= x
->x_nelement
, e
= x
->x_vec
; nelement
--; e
++)
554 if (e
->e_w
.w_symbol
== &s_bang
)
556 outlet_bang(e
->e_outlet
);
561 else if (argv
[0].a_type
== A_FLOAT
) /* one float arg */
563 for (nelement
= x
->x_nelement
, e
= x
->x_vec
; nelement
--; e
++)
565 if (e
->e_w
.w_symbol
== &s_float
)
567 outlet_float(e
->e_outlet
, argv
[0].a_w
.w_float
);
574 for (nelement
= x
->x_nelement
, e
= x
->x_vec
; nelement
--; e
++)
576 if (e
->e_w
.w_symbol
== &s_symbol
)
578 outlet_symbol(e
->e_outlet
, argv
[0].a_w
.w_symbol
);
584 outlet_list(x
->x_rejectout
, 0, argc
, argv
);
588 static void route_free(t_route
*x
)
590 freebytes(x
->x_vec
, x
->x_nelement
* sizeof(*x
->x_vec
));
593 static void *route_new(t_symbol
*s
, int argc
, t_atom
*argv
)
600 t_route
*x
= (t_route
*)pd_new(route_class
);
608 x
->x_type
= argv
[0].a_type
;
609 x
->x_nelement
= argc
;
610 x
->x_vec
= (t_routeelement
*)getbytes(argc
* sizeof(*x
->x_vec
));
611 for (n
= 0, e
= x
->x_vec
; n
< argc
; n
++, e
++)
613 e
->e_outlet
= outlet_new(&x
->x_obj
, &s_list
);
614 if (x
->x_type
== A_FLOAT
)
615 e
->e_w
.w_float
= atom_getfloatarg(n
, argc
, argv
);
616 else e
->e_w
.w_symbol
= atom_getsymbolarg(n
, argc
, argv
);
618 x
->x_rejectout
= outlet_new(&x
->x_obj
, &s_list
);
622 void route_setup(void)
624 route_class
= class_new(gensym("route"), (t_newmethod
)route_new
,
625 (t_method
)route_free
, sizeof(t_route
), 0, A_GIMME
, 0);
626 class_addlist(route_class
, route_list
);
627 class_addanything(route_class
, route_anything
);
630 /* -------------------------- pack ------------------------------ */
632 static t_class
*pack_class
;
637 t_int x_n
; /* number of args */
638 t_atom
*x_vec
; /* input values */
639 t_int x_nptr
; /* number of pointers */
640 t_gpointer
*x_gpointer
; /* the pointers */
641 t_atom
*x_outvec
; /* space for output values */
644 static void *pack_new(t_symbol
*s
, int argc
, t_atom
*argv
)
649 t_pack
*x
= (t_pack
*)pd_new(pack_class
);
650 t_atom defarg
[2], *ap
, *vec
, *vp
;
658 SETFLOAT(&defarg
[0], 0);
659 SETFLOAT(&defarg
[1], 0);
663 vec
= x
->x_vec
= (t_atom
*)getbytes(argc
* sizeof(*x
->x_vec
));
664 x
->x_outvec
= (t_atom
*)getbytes(argc
* sizeof(*x
->x_outvec
));
666 for (i
= argc
, ap
= argv
; i
--; ap
++)
667 if (ap
->a_type
== A_SYMBOL
&& *ap
->a_w
.w_symbol
->s_name
== 'p')
670 gp
= x
->x_gpointer
= (t_gpointer
*)t_getbytes(nptr
* sizeof (*gp
));
673 for (i
= 0, vp
= x
->x_vec
, ap
= argv
; i
< argc
; i
++, ap
++, vp
++)
675 if (ap
->a_type
== A_FLOAT
)
678 if (i
) floatinlet_new(&x
->x_obj
, &vp
->a_w
.w_float
);
680 else if (ap
->a_type
== A_SYMBOL
)
682 char c
= *ap
->a_w
.w_symbol
->s_name
;
685 SETSYMBOL(vp
, &s_symbol
);
686 if (i
) symbolinlet_new(&x
->x_obj
, &vp
->a_w
.w_symbol
);
690 vp
->a_type
= A_POINTER
;
691 vp
->a_w
.w_gpointer
= gp
;
693 if (i
) pointerinlet_new(&x
->x_obj
, gp
);
698 if (c
!= 'f') pd_error(x
, "pack: %s: bad type",
699 ap
->a_w
.w_symbol
->s_name
);
701 if (i
) floatinlet_new(&x
->x_obj
, &vp
->a_w
.w_float
);
705 outlet_new(&x
->x_obj
, &s_list
);
709 static void pack_bang(t_pack
*x
)
711 int i
, reentered
= 0, size
= x
->x_n
* sizeof (t_atom
);
714 for (i
= x
->x_nptr
, gp
= x
->x_gpointer
; i
--; gp
++)
715 if (!gpointer_check(gp
, 1))
717 pd_error(x
, "pack: stale pointer");
720 /* reentrancy protection. The first time through use the pre-allocated
721 x_outvec; if we're reentered we have to allocate new memory. */
724 /* LATER figure out how to deal with reentrancy and pointers... */
726 post("pack_bang: warning: reentry with pointers unprotected");
727 outvec
= t_getbytes(size
);
732 outvec
= x
->x_outvec
;
735 memcpy(outvec
, x
->x_vec
, size
);
736 outlet_list(x
->x_obj
.ob_outlet
, &s_list
, x
->x_n
, outvec
);
738 t_freebytes(outvec
, size
);
739 else x
->x_outvec
= outvec
;
742 static void pack_pointer(t_pack
*x
, t_gpointer
*gp
)
744 if (x
->x_vec
->a_type
== A_POINTER
)
746 gpointer_unset(x
->x_gpointer
);
747 *x
->x_gpointer
= *gp
;
748 if (gp
->gp_stub
) gp
->gp_stub
->gs_refcount
++;
751 else pd_error(x
, "pack_pointer: wrong type");
754 static void pack_float(t_pack
*x
, t_float f
)
756 if (x
->x_vec
->a_type
== A_FLOAT
)
758 x
->x_vec
->a_w
.w_float
= f
;
761 else pd_error(x
, "pack_float: wrong type");
764 static void pack_symbol(t_pack
*x
, t_symbol
*s
)
766 if (x
->x_vec
->a_type
== A_SYMBOL
)
768 x
->x_vec
->a_w
.w_symbol
= s
;
771 else pd_error(x
, "pack_symbol: wrong type");
774 static void pack_list(t_pack
*x
, t_symbol
*s
, int ac
, t_atom
*av
)
779 obj_list(&x
->x_obj
, 0, ac
, av
);
782 static void pack_anything(t_pack
*x
, t_symbol
*s
, int ac
, t_atom
*av
)
784 t_atom
*av2
= (t_atom
*)getbytes((ac
+ 1) * sizeof(t_atom
));
786 for (i
= 0; i
< ac
; i
++)
789 obj_list(&x
->x_obj
, 0, ac
+1, av2
);
790 freebytes(av2
, (ac
+ 1) * sizeof(t_atom
));
793 static void pack_free(t_pack
*x
)
797 for (gp
= x
->x_gpointer
, i
= x
->x_nptr
; i
--; gp
++)
799 freebytes(x
->x_vec
, x
->x_n
* sizeof(*x
->x_vec
));
800 freebytes(x
->x_outvec
, x
->x_n
* sizeof(*x
->x_outvec
));
801 freebytes(x
->x_gpointer
, x
->x_nptr
* sizeof(*x
->x_gpointer
));
804 static void pack_setup(void)
806 pack_class
= class_new(gensym("pack"), (t_newmethod
)pack_new
,
807 (t_method
)pack_free
, sizeof(t_pack
), 0, A_GIMME
, 0);
808 class_addbang(pack_class
, pack_bang
);
809 class_addpointer(pack_class
, pack_pointer
);
810 class_addfloat(pack_class
, pack_float
);
811 class_addsymbol(pack_class
, pack_symbol
);
812 class_addlist(pack_class
, pack_list
);
813 class_addanything(pack_class
, pack_anything
);
816 /* -------------------------- unpack ------------------------------ */
818 static t_class
*unpack_class
;
820 typedef struct unpackout
826 typedef struct _unpack
833 static void *unpack_new(t_symbol
*s
, int argc
, t_atom
*argv
)
838 t_unpack
*x
= (t_unpack
*)pd_new(unpack_class
);
839 t_atom defarg
[2], *ap
;
846 SETFLOAT(&defarg
[0], 0);
847 SETFLOAT(&defarg
[1], 0);
850 x
->x_vec
= (t_unpackout
*)getbytes(argc
* sizeof(*x
->x_vec
));
851 for (i
= 0, ap
= argv
, u
= x
->x_vec
; i
< argc
; u
++, ap
++, i
++)
853 t_atomtype type
= ap
->a_type
;
854 if (type
== A_SYMBOL
)
856 char c
= *ap
->a_w
.w_symbol
->s_name
;
859 u
->u_type
= A_SYMBOL
;
860 u
->u_outlet
= outlet_new(&x
->x_obj
, &s_symbol
);
864 u
->u_type
= A_POINTER
;
865 u
->u_outlet
= outlet_new(&x
->x_obj
, &s_pointer
);
869 if (c
!= 'f') pd_error(x
, "unpack: %s: bad type",
870 ap
->a_w
.w_symbol
->s_name
);
872 u
->u_outlet
= outlet_new(&x
->x_obj
, &s_float
);
878 u
->u_outlet
= outlet_new(&x
->x_obj
, &s_float
);
884 static void unpack_list(t_unpack
*x
, t_symbol
*s
, int argc
, t_atom
*argv
)
892 if (argc
> x
->x_n
) argc
= x
->x_n
;
893 for (i
= argc
, u
= x
->x_vec
+ i
, ap
= argv
+ i
; u
--, ap
--, i
--;)
895 t_atomtype type
= u
->u_type
;
896 if (type
!= ap
->a_type
)
897 pd_error(x
, "unpack: type mismatch");
898 else if (type
== A_FLOAT
)
899 outlet_float(u
->u_outlet
, ap
->a_w
.w_float
);
900 else if (type
== A_SYMBOL
)
901 outlet_symbol(u
->u_outlet
, ap
->a_w
.w_symbol
);
902 else outlet_pointer(u
->u_outlet
, ap
->a_w
.w_gpointer
);
906 static void unpack_anything(t_unpack
*x
, t_symbol
*s
, int ac
, t_atom
*av
)
908 t_atom
*av2
= (t_atom
*)getbytes((ac
+ 1) * sizeof(t_atom
));
910 for (i
= 0; i
< ac
; i
++)
913 unpack_list(x
, 0, ac
+1, av2
);
914 freebytes(av2
, (ac
+ 1) * sizeof(t_atom
));
917 static void unpack_free(t_unpack
*x
)
919 freebytes(x
->x_vec
, x
->x_n
* sizeof(*x
->x_vec
));
922 static void unpack_setup(void)
924 unpack_class
= class_new(gensym("unpack"), (t_newmethod
)unpack_new
,
925 (t_method
)unpack_free
, sizeof(t_unpack
), 0, A_GIMME
, 0);
926 class_addlist(unpack_class
, unpack_list
);
927 class_addanything(unpack_class
, unpack_anything
);
930 /* -------------------------- trigger ------------------------------ */
932 static t_class
*trigger_class
;
938 #define TR_ANYTHING 5
940 typedef struct triggerout
942 int u_type
; /* outlet type from above */
946 typedef struct _trigger
953 static void *trigger_new(t_symbol
*s
, int argc
, t_atom
*argv
)
958 t_trigger
*x
= (t_trigger
*)pd_new(trigger_class
);
959 t_atom defarg
[2], *ap
;
966 SETSYMBOL(&defarg
[0], &s_bang
);
967 SETSYMBOL(&defarg
[1], &s_bang
);
970 x
->x_vec
= (t_triggerout
*)getbytes(argc
* sizeof(*x
->x_vec
));
971 for (i
= 0, ap
= argv
, u
= x
->x_vec
; i
< argc
; u
++, ap
++, i
++)
973 t_atomtype thistype
= ap
->a_type
;
975 if (thistype
== TR_SYMBOL
) c
= ap
->a_w
.w_symbol
->s_name
[0];
976 else if (thistype
== TR_FLOAT
) c
= 'f';
979 u
->u_type
= TR_POINTER
,
980 u
->u_outlet
= outlet_new(&x
->x_obj
, &s_pointer
);
982 u
->u_type
= TR_FLOAT
, u
->u_outlet
= outlet_new(&x
->x_obj
, &s_float
);
984 u
->u_type
= TR_BANG
, u
->u_outlet
= outlet_new(&x
->x_obj
, &s_bang
);
986 u
->u_type
= TR_LIST
, u
->u_outlet
= outlet_new(&x
->x_obj
, &s_list
);
988 u
->u_type
= TR_SYMBOL
,
989 u
->u_outlet
= outlet_new(&x
->x_obj
, &s_symbol
);
991 u
->u_type
= TR_ANYTHING
,
992 u
->u_outlet
= outlet_new(&x
->x_obj
, &s_symbol
);
995 pd_error(x
, "trigger: %s: bad type", ap
->a_w
.w_symbol
->s_name
);
996 u
->u_type
= TR_FLOAT
, u
->u_outlet
= outlet_new(&x
->x_obj
, &s_float
);
1002 static void trigger_list(t_trigger
*x
, t_symbol
*s
, int argc
, t_atom
*argv
)
1016 for (i
= x
->x_n
, u
= x
->x_vec
+ i
; u
--, i
--;)
1018 if (u
->u_type
== TR_FLOAT
)
1019 outlet_float(u
->u_outlet
, atom_getfloat(argv
));
1020 else if (u
->u_type
== TR_BANG
)
1021 outlet_bang(u
->u_outlet
);
1022 else if (u
->u_type
== TR_SYMBOL
)
1023 outlet_symbol(u
->u_outlet
, atom_getsymbol(argv
));
1024 else if (u
->u_type
== TR_POINTER
)
1026 if (argv
->a_type
!= TR_POINTER
)
1027 pd_error(x
, "unpack: bad pointer");
1028 else outlet_pointer(u
->u_outlet
, argv
->a_w
.w_gpointer
);
1030 else outlet_list(u
->u_outlet
, &s_list
, argc
, argv
);
1034 static void trigger_anything(t_trigger
*x
, t_symbol
*s
, int argc
, t_atom
*argv
)
1038 for (i
= x
->x_n
, u
= x
->x_vec
+ i
; u
--, i
--;)
1040 if (u
->u_type
== TR_BANG
)
1041 outlet_bang(u
->u_outlet
);
1042 else if (u
->u_type
== TR_ANYTHING
)
1043 outlet_anything(u
->u_outlet
, s
, argc
, argv
);
1044 else pd_error(x
, "trigger: can only convert 's' to 'b' or 'a'",
1049 static void trigger_bang(t_trigger
*x
)
1051 trigger_list(x
, 0, 0, 0);
1054 static void trigger_pointer(t_trigger
*x
, t_gpointer
*gp
)
1057 SETPOINTER(&at
, gp
);
1058 trigger_list(x
, 0, 1, &at
);
1061 static void trigger_float(t_trigger
*x
, t_float f
)
1065 trigger_list(x
, 0, 1, &at
);
1068 static void trigger_symbol(t_trigger
*x
, t_symbol
*s
)
1072 trigger_list(x
, 0, 1, &at
);
1075 static void trigger_free(t_trigger
*x
)
1077 freebytes(x
->x_vec
, x
->x_n
* sizeof(*x
->x_vec
));
1080 static void trigger_setup(void)
1082 trigger_class
= class_new(gensym("trigger"), (t_newmethod
)trigger_new
,
1083 (t_method
)trigger_free
, sizeof(t_trigger
), 0, A_GIMME
, 0);
1084 class_addcreator((t_newmethod
)trigger_new
, gensym("t"), A_GIMME
, 0);
1085 class_addlist(trigger_class
, trigger_list
);
1086 class_addbang(trigger_class
, trigger_bang
);
1087 class_addpointer(trigger_class
, trigger_pointer
);
1088 class_addfloat(trigger_class
, (t_method
)trigger_float
);
1089 class_addsymbol(trigger_class
, trigger_symbol
);
1090 class_addanything(trigger_class
, trigger_anything
);
1093 /* -------------------------- spigot ------------------------------ */
1094 static t_class
*spigot_class
;
1096 typedef struct _spigot
1102 static void *spigot_new(void)
1104 t_spigot
*x
= (t_spigot
*)pd_new(spigot_class
);
1105 floatinlet_new(&x
->x_obj
, &x
->x_state
);
1106 outlet_new(&x
->x_obj
, 0);
1111 static void spigot_bang(t_spigot
*x
)
1113 if (x
->x_state
!= 0) outlet_bang(x
->x_obj
.ob_outlet
);
1116 static void spigot_pointer(t_spigot
*x
, t_gpointer
*gp
)
1118 if (x
->x_state
!= 0) outlet_pointer(x
->x_obj
.ob_outlet
, gp
);
1121 static void spigot_float(t_spigot
*x
, t_float f
)
1123 if (x
->x_state
!= 0) outlet_float(x
->x_obj
.ob_outlet
, f
);
1126 static void spigot_symbol(t_spigot
*x
, t_symbol
*s
)
1128 if (x
->x_state
!= 0) outlet_symbol(x
->x_obj
.ob_outlet
, s
);
1131 static void spigot_list(t_spigot
*x
, t_symbol
*s
, int argc
, t_atom
*argv
)
1133 if (x
->x_state
!= 0) outlet_list(x
->x_obj
.ob_outlet
, s
, argc
, argv
);
1136 static void spigot_anything(t_spigot
*x
, t_symbol
*s
, int argc
, t_atom
*argv
)
1138 if (x
->x_state
!= 0) outlet_anything(x
->x_obj
.ob_outlet
, s
, argc
, argv
);
1141 static void spigot_setup(void)
1143 spigot_class
= class_new(gensym("spigot"), (t_newmethod
)spigot_new
, 0,
1144 sizeof(t_spigot
), 0, A_DEFSYM
, 0);
1145 class_addbang(spigot_class
, spigot_bang
);
1146 class_addpointer(spigot_class
, spigot_pointer
);
1147 class_addfloat(spigot_class
, spigot_float
);
1148 class_addsymbol(spigot_class
, spigot_symbol
);
1149 class_addlist(spigot_class
, spigot_list
);
1150 class_addanything(spigot_class
, spigot_anything
);
1153 /* --------------------------- moses ----------------------------- */
1154 static t_class
*moses_class
;
1156 typedef struct _moses
1163 static void *moses_new(t_floatarg f
)
1165 t_moses
*x
= (t_moses
*)pd_new(moses_class
);
1166 floatinlet_new(&x
->x_ob
, &x
->x_y
);
1167 outlet_new(&x
->x_ob
, &s_float
);
1168 x
->x_out2
= outlet_new(&x
->x_ob
, &s_float
);
1173 static void moses_float(t_moses
*x
, t_float f
)
1175 if (f
< x
->x_y
) outlet_float(x
->x_ob
.ob_outlet
, f
);
1176 else outlet_float(x
->x_out2
, f
);
1179 static void moses_setup(void)
1181 moses_class
= class_new(gensym("moses"), (t_newmethod
)moses_new
, 0,
1182 sizeof(t_moses
), 0, A_DEFFLOAT
, 0);
1183 class_addfloat(moses_class
, moses_float
);
1186 /* ----------------------- until --------------------- */
1188 static t_class
*until_class
;
1190 typedef struct _until
1197 static void *until_new(void)
1199 t_until
*x
= (t_until
*)pd_new(until_class
);
1200 inlet_new(&x
->x_obj
, &x
->x_obj
.ob_pd
, gensym("bang"), gensym("bang2"));
1201 outlet_new(&x
->x_obj
, &s_bang
);
1206 static void until_bang(t_until
*x
)
1210 while (x
->x_run
&& x
->x_count
)
1211 x
->x_count
--, outlet_bang(x
->x_obj
.ob_outlet
);
1214 static void until_float(t_until
*x
, t_float f
)
1218 while (x
->x_run
&& x
->x_count
)
1219 x
->x_count
--, outlet_bang(x
->x_obj
.ob_outlet
);
1222 static void until_bang2(t_until
*x
)
1227 static void until_setup(void)
1229 until_class
= class_new(gensym("until"), (t_newmethod
)until_new
, 0,
1230 sizeof(t_until
), 0, 0);
1231 class_addbang(until_class
, until_bang
);
1232 class_addfloat(until_class
, until_float
);
1233 class_addmethod(until_class
, (t_method
)until_bang2
, gensym("bang2"), 0);
1236 /* ----------------------- makefilename --------------------- */
1238 static t_class
*makefilename_class
;
1240 typedef struct _makefilename
1246 static void *makefilename_new(t_symbol
*s
)
1248 t_makefilename
*x
= (t_makefilename
*)pd_new(makefilename_class
);
1249 if (!s
->s_name
) s
= gensym("file.%d");
1250 outlet_new(&x
->x_obj
, &s_symbol
);
1255 static void makefilename_float(t_makefilename
*x
, t_floatarg f
)
1257 char buf
[MAXPDSTRING
];
1259 snprintf(buf
, sizeof(buf
), x
->x_format
->s_name
, (int)f
);
1261 sprintf(buf
, x
->x_format
->s_name
, (int)f
);
1263 outlet_symbol(x
->x_obj
.ob_outlet
, gensym(buf
));
1266 static void makefilename_symbol(t_makefilename
*x
, t_symbol
*s
)
1268 char buf
[MAXPDSTRING
];
1270 snprintf(buf
, sizeof(buf
), x
->x_format
->s_name
, s
->s_name
);
1272 sprintf(buf
, x
->x_format
->s_name
, s
->s_name
);
1274 outlet_symbol(x
->x_obj
.ob_outlet
, gensym(buf
));
1277 static void makefilename_setup(void)
1279 makefilename_class
= class_new(gensym("makefilename"),
1280 (t_newmethod
)makefilename_new
, 0,
1281 sizeof(t_makefilename
), 0, A_DEFSYM
, 0);
1282 class_addfloat(makefilename_class
, makefilename_float
);
1283 class_addsymbol(makefilename_class
, makefilename_symbol
);
1286 /* -------------------------- swap ------------------------------ */
1287 static t_class
*swap_class
;
1289 typedef struct _swap
1297 static void *swap_new(t_floatarg f
)
1299 t_swap
*x
= (t_swap
*)pd_new(swap_class
);
1302 outlet_new(&x
->x_obj
, &s_float
);
1303 x
->x_out2
= outlet_new(&x
->x_obj
, &s_float
);
1304 floatinlet_new(&x
->x_obj
, &x
->x_f2
);
1308 static void swap_bang(t_swap
*x
)
1310 outlet_float(x
->x_out2
, x
->x_f1
);
1311 outlet_float(x
->x_obj
.ob_outlet
, x
->x_f2
);
1314 static void swap_float(t_swap
*x
, t_float f
)
1320 void swap_setup(void)
1322 swap_class
= class_new(gensym("swap"), (t_newmethod
)swap_new
, 0,
1323 sizeof(t_swap
), 0, A_DEFFLOAT
, 0);
1324 class_addcreator((t_newmethod
)swap_new
, gensym("fswap"), A_DEFFLOAT
, 0);
1325 class_addbang(swap_class
, swap_bang
);
1326 class_addfloat(swap_class
, swap_float
);
1329 /* -------------------------- change ------------------------------ */
1330 static t_class
*change_class
;
1332 typedef struct _change
1338 static void *change_new(t_floatarg f
)
1340 t_change
*x
= (t_change
*)pd_new(change_class
);
1342 outlet_new(&x
->x_obj
, &s_float
);
1346 static void change_bang(t_change
*x
)
1348 outlet_float(x
->x_obj
.ob_outlet
, x
->x_f
);
1351 static void change_float(t_change
*x
, t_float f
)
1356 outlet_float(x
->x_obj
.ob_outlet
, x
->x_f
);
1360 static void change_set(t_change
*x
, t_float f
)
1365 void change_setup(void)
1367 change_class
= class_new(gensym("change"), (t_newmethod
)change_new
, 0,
1368 sizeof(t_change
), 0, A_DEFFLOAT
, 0);
1369 class_addbang(change_class
, change_bang
);
1370 class_addfloat(change_class
, change_float
);
1371 class_addmethod(change_class
, (t_method
)change_set
, gensym("set"),
1375 /* -------------------- value ------------------------------ */
1377 static t_class
*value_class
, *vcommon_class
;
1379 typedef struct vcommon
1386 typedef struct _value
1390 t_float
*x_floatstar
;
1393 /* get a pointer to a named floating-point variable. The variable
1394 belongs to a "vcommon" object, which is created if necessary. */
1395 t_float
*value_get(t_symbol
*s
)
1397 t_vcommon
*c
= (t_vcommon
*)pd_findbyclass(s
, vcommon_class
);
1400 c
= (t_vcommon
*)pd_new(vcommon_class
);
1403 pd_bind(&c
->c_pd
, s
);
1409 /* release a variable. This only frees the "vcommon" resource when the
1410 last interested party releases it. */
1411 void value_release(t_symbol
*s
)
1413 t_vcommon
*c
= (t_vcommon
*)pd_findbyclass(s
, vcommon_class
);
1416 if (!--c
->c_refcount
)
1418 pd_unbind(&c
->c_pd
, s
);
1422 else bug("value_release");
1426 * value_getfloat -- obtain the float value of a "value" object
1427 * return 0 on success, 1 otherwise
1430 value_getfloat(t_symbol
*s
, t_float
*f
)
1432 t_vcommon
*c
= (t_vcommon
*)pd_findbyclass(s
, vcommon_class
);
1440 * value_setfloat -- set the float value of a "value" object
1441 * return 0 on success, 1 otherwise
1444 value_setfloat(t_symbol
*s
, t_float f
)
1446 t_vcommon
*c
= (t_vcommon
*)pd_findbyclass(s
, vcommon_class
);
1453 static void *value_new(t_symbol
*s
)
1455 t_value
*x
= (t_value
*)pd_new(value_class
);
1457 x
->x_floatstar
= value_get(s
);
1458 outlet_new(&x
->x_obj
, &s_float
);
1462 static void value_bang(t_value
*x
)
1464 outlet_float(x
->x_obj
.ob_outlet
, *x
->x_floatstar
);
1467 static void value_float(t_value
*x
, t_float f
)
1469 *x
->x_floatstar
= f
;
1472 static void value_ff(t_value
*x
)
1474 value_release(x
->x_sym
);
1477 static void value_setup(void)
1479 value_class
= class_new(gensym("value"), (t_newmethod
)value_new
,
1481 sizeof(t_value
), 0, A_DEFSYM
, 0);
1482 class_addcreator((t_newmethod
)value_new
, gensym("v"), A_DEFSYM
, 0);
1483 class_addbang(value_class
, value_bang
);
1484 class_addfloat(value_class
, value_float
);
1485 vcommon_class
= class_new(gensym("value"), 0, 0,
1486 sizeof(t_vcommon
), CLASS_PD
, 0);
1489 /* -------------- overall setup routine for this file ----------------- */
1491 void x_connective_setup(void)
1507 makefilename_setup();