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 /* send~, receive~, throw~, catch~ */
9 #include "../../pdbox.h"
18 #define DEFSENDVS 64 /* LATER get send to get this from canvas */
20 /* ----------------------------- send~ ----------------------------- */
21 static t_class
*sigsend_class
;
23 typedef struct _sigsend
32 static void *sigsend_new(t_symbol
*s
)
34 t_sigsend
*x
= (t_sigsend
*)pd_new(sigsend_class
);
35 pd_bind(&x
->x_obj
.ob_pd
, s
);
38 x
->x_vec
= (t_sample
*)getbytes(DEFSENDVS
* sizeof(t_sample
));
39 memset((char *)(x
->x_vec
), 0, DEFSENDVS
* sizeof(t_sample
));
44 static t_int
*sigsend_perform(t_int
*w
)
46 t_sample
*in
= (t_sample
*)(w
[1]);
47 t_sample
*out
= (t_sample
*)(w
[2]);
51 *out
= (PD_BIGORSMALL(*in
) ? 0 : *in
);
58 static void sigsend_dsp(t_sigsend
*x
, t_signal
**sp
)
60 if (x
->x_n
== sp
[0]->s_n
)
61 dsp_add(sigsend_perform
, 3, sp
[0]->s_vec
, x
->x_vec
, sp
[0]->s_n
);
62 else error("sigsend %s: unexpected vector size", x
->x_sym
->s_name
);
65 static void sigsend_free(t_sigsend
*x
)
67 pd_unbind(&x
->x_obj
.ob_pd
, x
->x_sym
);
68 freebytes(x
->x_vec
, x
->x_n
* sizeof(float));
71 static void sigsend_setup(void)
73 sigsend_class
= class_new(gensym("send~"), (t_newmethod
)sigsend_new
,
74 (t_method
)sigsend_free
, sizeof(t_sigsend
), 0, A_DEFSYM
, 0);
75 class_addcreator((t_newmethod
)sigsend_new
, gensym("s~"), A_DEFSYM
, 0);
76 CLASS_MAINSIGNALIN(sigsend_class
, t_sigsend
, x_f
);
77 class_addmethod(sigsend_class
, (t_method
)sigsend_dsp
, gensym("dsp"), 0);
80 /* ----------------------------- receive~ ----------------------------- */
81 static t_class
*sigreceive_class
;
83 typedef struct _sigreceive
87 t_sample
*x_wherefrom
;
91 static void *sigreceive_new(t_symbol
*s
)
93 t_sigreceive
*x
= (t_sigreceive
*)pd_new(sigreceive_class
);
94 x
->x_n
= DEFSENDVS
; /* LATER find our vector size correctly */
97 outlet_new(&x
->x_obj
, &s_signal
);
101 static t_int
*sigreceive_perform(t_int
*w
)
103 t_sigreceive
*x
= (t_sigreceive
*)(w
[1]);
104 t_sample
*out
= (t_sample
*)(w
[2]);
106 t_sample
*in
= x
->x_wherefrom
;
120 static void sigreceive_set(t_sigreceive
*x
, t_symbol
*s
)
122 t_sigsend
*sender
= (t_sigsend
*)pd_findbyclass((x
->x_sym
= s
),
126 if (sender
->x_n
== x
->x_n
)
127 x
->x_wherefrom
= sender
->x_vec
;
130 pd_error(x
, "receive~ %s: vector size mismatch", x
->x_sym
->s_name
);
136 pd_error(x
, "receive~ %s: no matching send", x
->x_sym
->s_name
);
141 static void sigreceive_dsp(t_sigreceive
*x
, t_signal
**sp
)
143 if (sp
[0]->s_n
!= x
->x_n
)
145 pd_error(x
, "receive~ %s: vector size mismatch", x
->x_sym
->s_name
);
149 sigreceive_set(x
, x
->x_sym
);
150 dsp_add(sigreceive_perform
, 3,
151 x
, sp
[0]->s_vec
, sp
[0]->s_n
);
155 static void sigreceive_setup(void)
157 sigreceive_class
= class_new(gensym("receive~"),
158 (t_newmethod
)sigreceive_new
, 0,
159 sizeof(t_sigreceive
), 0, A_DEFSYM
, 0);
160 class_addcreator((t_newmethod
)sigreceive_new
, gensym("r~"), A_DEFSYM
, 0);
161 class_addmethod(sigreceive_class
, (t_method
)sigreceive_set
, gensym("set"),
163 class_addmethod(sigreceive_class
, (t_method
)sigreceive_dsp
, gensym("dsp"),
165 class_sethelpsymbol(sigreceive_class
, gensym("send~"));
168 /* ----------------------------- catch~ ----------------------------- */
169 static t_class
*sigcatch_class
;
171 typedef struct _sigcatch
179 static void *sigcatch_new(t_symbol
*s
)
181 t_sigcatch
*x
= (t_sigcatch
*)pd_new(sigcatch_class
);
182 pd_bind(&x
->x_obj
.ob_pd
, s
);
185 x
->x_vec
= (t_sample
*)getbytes(DEFSENDVS
* sizeof(t_sample
));
186 memset((char *)(x
->x_vec
), 0, DEFSENDVS
* sizeof(t_sample
));
187 outlet_new(&x
->x_obj
, &s_signal
);
191 static t_int
*sigcatch_perform(t_int
*w
)
193 t_sample
*in
= (t_sample
*)(w
[1]);
194 t_sample
*out
= (t_sample
*)(w
[2]);
196 while (n
--) *out
++ = *in
, *in
++ = 0;
200 static void sigcatch_dsp(t_sigcatch
*x
, t_signal
**sp
)
202 if (x
->x_n
== sp
[0]->s_n
)
203 dsp_add(sigcatch_perform
, 3, x
->x_vec
, sp
[0]->s_vec
, sp
[0]->s_n
);
204 else error("sigcatch %s: unexpected vector size", x
->x_sym
->s_name
);
207 static void sigcatch_free(t_sigcatch
*x
)
209 pd_unbind(&x
->x_obj
.ob_pd
, x
->x_sym
);
210 freebytes(x
->x_vec
, x
->x_n
* sizeof(float));
213 static void sigcatch_setup(void)
215 sigcatch_class
= class_new(gensym("catch~"), (t_newmethod
)sigcatch_new
,
216 (t_method
)sigcatch_free
, sizeof(t_sigcatch
), CLASS_NOINLET
, A_DEFSYM
, 0);
217 class_addmethod(sigcatch_class
, (t_method
)sigcatch_dsp
, gensym("dsp"), 0);
218 class_sethelpsymbol(sigcatch_class
, gensym("throw~"));
221 /* ----------------------------- throw~ ----------------------------- */
222 static t_class
*sigthrow_class
;
224 typedef struct _sigthrow
233 static void *sigthrow_new(t_symbol
*s
)
235 t_sigthrow
*x
= (t_sigthrow
*)pd_new(sigthrow_class
);
243 static t_int
*sigthrow_perform(t_int
*w
)
245 t_sigthrow
*x
= (t_sigthrow
*)(w
[1]);
246 t_sample
*in
= (t_sample
*)(w
[2]);
248 t_sample
*out
= x
->x_whereto
;
253 *out
+= (PD_BIGORSMALL(*in
) ? 0 : *in
);
261 static void sigthrow_set(t_sigthrow
*x
, t_symbol
*s
)
263 t_sigcatch
*catcher
= (t_sigcatch
*)pd_findbyclass((x
->x_sym
= s
),
267 if (catcher
->x_n
== x
->x_n
)
268 x
->x_whereto
= catcher
->x_vec
;
271 pd_error(x
, "throw~ %s: vector size mismatch", x
->x_sym
->s_name
);
277 pd_error(x
, "throw~ %s: no matching catch", x
->x_sym
->s_name
);
282 static void sigthrow_dsp(t_sigthrow
*x
, t_signal
**sp
)
284 if (sp
[0]->s_n
!= x
->x_n
)
286 pd_error(x
, "throw~ %s: vector size mismatch", x
->x_sym
->s_name
);
290 sigthrow_set(x
, x
->x_sym
);
291 dsp_add(sigthrow_perform
, 3,
292 x
, sp
[0]->s_vec
, sp
[0]->s_n
);
296 static void sigthrow_setup(void)
298 sigthrow_class
= class_new(gensym("throw~"), (t_newmethod
)sigthrow_new
, 0,
299 sizeof(t_sigthrow
), 0, A_DEFSYM
, 0);
300 class_addcreator((t_newmethod
)sigthrow_new
, gensym("r~"), A_DEFSYM
, 0);
301 class_addmethod(sigthrow_class
, (t_method
)sigthrow_set
, gensym("set"),
303 CLASS_MAINSIGNALIN(sigthrow_class
, t_sigthrow
, x_f
);
304 class_addmethod(sigthrow_class
, (t_method
)sigthrow_dsp
, gensym("dsp"), 0);
307 /* ----------------------- global setup routine ---------------- */
309 void d_global_setup(void)