Add FS #10214. Initial commit of the original PDa code for the GSoC Pure Data plugin...
[kugel-rb.git] / apps / plugins / pdbox / PDa / src / d_arithmetic.c
blob72404ba50d43171dc17f995f6ed389cedfd5ede1
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 /* arithmetic binops (+, -, *, /).
6 If no creation argument is given, there are two signal inlets for vector/vector
7 operation; otherwise it's vector/scalar and the second inlet takes a float
8 to reset the value.
9 */
11 #include "m_pd.h"
13 /* ----------------------------- plus ----------------------------- */
14 static t_class *plus_class, *scalarplus_class;
16 typedef struct _plus
18 t_object x_obj;
19 float x_f;
20 } t_plus;
22 typedef struct _scalarplus
24 t_object x_obj;
25 float x_f;
26 t_float x_g; /* inlet value */
27 } t_scalarplus;
29 static void *plus_new(t_symbol *s, int argc, t_atom *argv)
31 if (argc > 1) post("+~: extra arguments ignored");
32 if (argc)
34 t_scalarplus *x = (t_scalarplus *)pd_new(scalarplus_class);
35 floatinlet_new(&x->x_obj, &x->x_g);
36 x->x_g = atom_getfloatarg(0, argc, argv);
37 outlet_new(&x->x_obj, &s_signal);
38 x->x_f = 0;
39 return (x);
41 else
43 t_plus *x = (t_plus *)pd_new(plus_class);
44 inlet_new(&x->x_obj, &x->x_obj.ob_pd, &s_signal, &s_signal);
45 outlet_new(&x->x_obj, &s_signal);
46 x->x_f = 0;
47 return (x);
51 t_int *plus_perform(t_int *w)
53 t_sample *in1 = (t_sample *)(w[1]);
54 t_sample *in2 = (t_sample *)(w[2]);
55 t_sample *out = (t_sample *)(w[3]);
56 int n = (int)(w[4]);
57 while (n--) *out++ = *in1++ + *in2++;
58 return (w+5);
61 t_int *plus_perf8(t_int *w)
63 t_sample *in1 = (t_sample *)(w[1]);
64 t_sample *in2 = (t_sample *)(w[2]);
65 t_sample *out = (t_sample *)(w[3]);
66 int n = (int)(w[4]);
67 for (; n; n -= 8, in1 += 8, in2 += 8, out += 8)
69 t_sample f0 = in1[0], f1 = in1[1], f2 = in1[2], f3 = in1[3];
70 t_sample f4 = in1[4], f5 = in1[5], f6 = in1[6], f7 = in1[7];
72 t_sample g0 = in2[0], g1 = in2[1], g2 = in2[2], g3 = in2[3];
73 t_sample g4 = in2[4], g5 = in2[5], g6 = in2[6], g7 = in2[7];
75 out[0] = f0 + g0; out[1] = f1 + g1; out[2] = f2 + g2; out[3] = f3 + g3;
76 out[4] = f4 + g4; out[5] = f5 + g5; out[6] = f6 + g6; out[7] = f7 + g7;
78 return (w+5);
81 t_int *scalarplus_perform(t_int *w)
83 t_sample *in = (t_sample *)(w[1]);
84 t_sample f = ftofix(*(t_float *)(w[2]));
85 t_sample *out = (t_sample *)(w[3]);
86 int n = (int)(w[4]);
87 while (n--) *out++ = *in++ + f;
88 return (w+5);
91 t_int *scalarplus_perf8(t_int *w)
93 t_sample *in = (t_sample *)(w[1]);
94 t_sample g = ftofix(*(t_float *)(w[2]));
95 t_sample *out = (t_sample *)(w[3]);
96 int n = (int)(w[4]);
97 for (; n; n -= 8, in += 8, out += 8)
99 t_sample f0 = in[0], f1 = in[1], f2 = in[2], f3 = in[3];
100 t_sample f4 = in[4], f5 = in[5], f6 = in[6], f7 = in[7];
102 out[0] = f0 + g; out[1] = f1 + g; out[2] = f2 + g; out[3] = f3 + g;
103 out[4] = f4 + g; out[5] = f5 + g; out[6] = f6 + g; out[7] = f7 + g;
105 return (w+5);
108 void dsp_add_plus(t_sample *in1, t_sample *in2, t_sample *out, int n)
110 if (n&7)
111 dsp_add(plus_perform, 4, in1, in2, out, n);
112 else
113 dsp_add(plus_perf8, 4, in1, in2, out, n);
116 static void plus_dsp(t_plus *x, t_signal **sp)
118 dsp_add_plus(sp[0]->s_vec, sp[1]->s_vec, sp[2]->s_vec, sp[0]->s_n);
121 static void scalarplus_dsp(t_scalarplus *x, t_signal **sp)
123 if (sp[0]->s_n&7)
124 dsp_add(scalarplus_perform, 4, sp[0]->s_vec, &x->x_g,
125 sp[1]->s_vec, sp[0]->s_n);
126 else
127 dsp_add(scalarplus_perf8, 4, sp[0]->s_vec, &x->x_g,
128 sp[1]->s_vec, sp[0]->s_n);
131 static void plus_setup(void)
133 plus_class = class_new(gensym("+~"), (t_newmethod)plus_new, 0,
134 sizeof(t_plus), 0, A_GIMME, 0);
135 class_addmethod(plus_class, (t_method)plus_dsp, gensym("dsp"), 0);
136 CLASS_MAINSIGNALIN(plus_class, t_plus, x_f);
137 class_sethelpsymbol(plus_class, gensym("sigbinops"));
138 scalarplus_class = class_new(gensym("+~"), 0, 0,
139 sizeof(t_scalarplus), 0, 0);
140 CLASS_MAINSIGNALIN(scalarplus_class, t_scalarplus, x_f);
141 class_addmethod(scalarplus_class, (t_method)scalarplus_dsp, gensym("dsp"),
143 class_sethelpsymbol(scalarplus_class, gensym("sigbinops"));
146 /* ----------------------------- minus ----------------------------- */
147 static t_class *minus_class, *scalarminus_class;
149 typedef struct _minus
151 t_object x_obj;
152 float x_f;
153 } t_minus;
155 typedef struct _scalarminus
157 t_object x_obj;
158 float x_f;
159 t_float x_g;
160 } t_scalarminus;
162 static void *minus_new(t_symbol *s, int argc, t_atom *argv)
164 if (argc > 1) post("-~: extra arguments ignored");
165 if (argc)
167 t_scalarminus *x = (t_scalarminus *)pd_new(scalarminus_class);
168 floatinlet_new(&x->x_obj, &x->x_g);
169 x->x_g = atom_getfloatarg(0, argc, argv);
170 outlet_new(&x->x_obj, &s_signal);
171 x->x_f = 0;
172 return (x);
174 else
176 t_minus *x = (t_minus *)pd_new(minus_class);
177 inlet_new(&x->x_obj, &x->x_obj.ob_pd, &s_signal, &s_signal);
178 outlet_new(&x->x_obj, &s_signal);
179 x->x_f = 0;
180 return (x);
184 t_int *minus_perform(t_int *w)
186 t_sample *in1 = (t_sample *)(w[1]);
187 t_sample *in2 = (t_sample *)(w[2]);
188 t_sample *out = (t_sample *)(w[3]);
189 int n = (int)(w[4]);
190 while (n--) *out++ = *in1++ - *in2++;
191 return (w+5);
194 t_int *minus_perf8(t_int *w)
196 t_sample *in1 = (t_sample *)(w[1]);
197 t_sample *in2 = (t_sample *)(w[2]);
198 t_sample *out = (t_sample *)(w[3]);
199 int n = (int)(w[4]);
200 for (; n; n -= 8, in1 += 8, in2 += 8, out += 8)
202 t_sample f0 = in1[0], f1 = in1[1], f2 = in1[2], f3 = in1[3];
203 t_sample f4 = in1[4], f5 = in1[5], f6 = in1[6], f7 = in1[7];
205 t_sample g0 = in2[0], g1 = in2[1], g2 = in2[2], g3 = in2[3];
206 t_sample g4 = in2[4], g5 = in2[5], g6 = in2[6], g7 = in2[7];
208 out[0] = f0 - g0; out[1] = f1 - g1; out[2] = f2 - g2; out[3] = f3 - g3;
209 out[4] = f4 - g4; out[5] = f5 - g5; out[6] = f6 - g6; out[7] = f7 - g7;
211 return (w+5);
214 t_int *scalarminus_perform(t_int *w)
216 t_sample *in = (t_sample *)(w[1]);
217 t_sample f = ftofix(*(t_float *)(w[2]));
218 t_sample *out = (t_sample *)(w[3]);
219 int n = (int)(w[4]);
220 while (n--) *out++ = *in++ - f;
221 return (w+5);
224 t_int *scalarminus_perf8(t_int *w)
226 t_sample *in = (t_sample *)(w[1]);
227 t_sample g = ftofix(*(t_float *)(w[2]));
228 t_sample *out = (t_sample *)(w[3]);
229 int n = (int)(w[4]);
230 for (; n; n -= 8, in += 8, out += 8)
232 t_sample f0 = in[0], f1 = in[1], f2 = in[2], f3 = in[3];
233 t_sample f4 = in[4], f5 = in[5], f6 = in[6], f7 = in[7];
235 out[0] = f0 - g; out[1] = f1 - g; out[2] = f2 - g; out[3] = f3 - g;
236 out[4] = f4 - g; out[5] = f5 - g; out[6] = f6 - g; out[7] = f7 - g;
238 return (w+5);
241 static void minus_dsp(t_minus *x, t_signal **sp)
243 if (sp[0]->s_n&7)
244 dsp_add(minus_perform, 4,
245 sp[0]->s_vec, sp[1]->s_vec, sp[2]->s_vec, sp[0]->s_n);
246 else
247 dsp_add(minus_perf8, 4,
248 sp[0]->s_vec, sp[1]->s_vec, sp[2]->s_vec, sp[0]->s_n);
251 static void scalarminus_dsp(t_scalarminus *x, t_signal **sp)
253 if (sp[0]->s_n&7)
254 dsp_add(scalarminus_perform, 4, sp[0]->s_vec, &x->x_g,
255 sp[1]->s_vec, sp[0]->s_n);
256 else
257 dsp_add(scalarminus_perf8, 4, sp[0]->s_vec, &x->x_g,
258 sp[1]->s_vec, sp[0]->s_n);
261 static void minus_setup(void)
263 minus_class = class_new(gensym("-~"), (t_newmethod)minus_new, 0,
264 sizeof(t_minus), 0, A_GIMME, 0);
265 CLASS_MAINSIGNALIN(minus_class, t_minus, x_f);
266 class_addmethod(minus_class, (t_method)minus_dsp, gensym("dsp"), 0);
267 class_sethelpsymbol(minus_class, gensym("sigbinops"));
268 scalarminus_class = class_new(gensym("-~"), 0, 0,
269 sizeof(t_scalarminus), 0, 0);
270 CLASS_MAINSIGNALIN(scalarminus_class, t_scalarminus, x_f);
271 class_addmethod(scalarminus_class, (t_method)scalarminus_dsp, gensym("dsp"),
273 class_sethelpsymbol(scalarminus_class, gensym("sigbinops"));
276 /* ----------------------------- times ----------------------------- */
278 static t_class *times_class, *scalartimes_class;
280 typedef struct _times
282 t_object x_obj;
283 float x_f;
284 } t_times;
286 typedef struct _scalartimes
288 t_object x_obj;
289 float x_f;
290 t_float x_g;
291 } t_scalartimes;
293 static void *times_new(t_symbol *s, int argc, t_atom *argv)
295 if (argc > 1) post("*~: extra arguments ignored");
296 if (argc)
298 t_scalartimes *x = (t_scalartimes *)pd_new(scalartimes_class);
299 floatinlet_new(&x->x_obj, &x->x_g);
300 x->x_g = atom_getfloatarg(0, argc, argv);
301 outlet_new(&x->x_obj, &s_signal);
302 x->x_f = 0;
303 return (x);
305 else
307 t_times *x = (t_times *)pd_new(times_class);
308 inlet_new(&x->x_obj, &x->x_obj.ob_pd, &s_signal, &s_signal);
309 outlet_new(&x->x_obj, &s_signal);
310 x->x_f = 0;
311 return (x);
315 t_int *times_perform(t_int *w)
317 t_sample *in1 = (t_sample *)(w[1]);
318 t_sample *in2 = (t_sample *)(w[2]);
319 t_sample *out = (t_sample *)(w[3]);
320 int n = (int)(w[4]);
321 while (n--) *out++ = mult(*in1++,*in2++);
322 return (w+5);
325 t_int *times_perf8(t_int *w)
327 t_sample *in1 = (t_sample *)(w[1]);
328 t_sample *in2 = (t_sample *)(w[2]);
329 t_sample *out = (t_sample *)(w[3]);
330 int n = (int)(w[4]);
331 for (; n; n -= 8, in1 += 8, in2 += 8, out += 8)
333 t_sample f0 = in1[0], f1 = in1[1], f2 = in1[2], f3 = in1[3];
334 t_sample f4 = in1[4], f5 = in1[5], f6 = in1[6], f7 = in1[7];
336 t_sample g0 = in2[0], g1 = in2[1], g2 = in2[2], g3 = in2[3];
337 t_sample g4 = in2[4], g5 = in2[5], g6 = in2[6], g7 = in2[7];
339 out[0] = mult(f0,g0); out[1] = mult(f1,g1); out[2] = mult(f2,g2); out[3] = mult(f3,g3);
340 out[4] = mult(f4,g4); out[5] = mult(f5,g5); out[6] = mult(f6,g6); out[7] = mult(f7,g7);
342 return (w+5);
345 t_int *scalartimes_perform(t_int *w)
347 t_sample *in = (t_sample *)(w[1]);
348 t_sample f = ftofix(*(t_float *)(w[2]));
349 t_sample *out = (t_sample *)(w[3]);
350 int n = (int)(w[4]);
351 while (n--) *out++ = mult(*in++,f);
352 return (w+5);
355 t_int *scalartimes_perf8(t_int *w)
357 t_sample *in = (t_sample *)(w[1]);
358 t_sample g = ftofix(*(t_float *)(w[2]));
359 t_sample *out = (t_sample *)(w[3]);
360 int n = (int)(w[4]);
361 for (; n; n -= 8, in += 8, out += 8)
363 t_sample f0 = in[0], f1 = in[1], f2 = in[2], f3 = in[3];
364 t_sample f4 = in[4], f5 = in[5], f6 = in[6], f7 = in[7];
366 out[0] = mult(f0,g); out[1] = mult(f1,g); out[2] = mult(f2,g); out[3] = mult(f3,g);
367 out[4] = mult(f4,g); out[5] = mult(f5,g); out[6] = mult(f6,g); out[7] = mult(f7,g);
369 return (w+5);
372 static void times_dsp(t_times *x, t_signal **sp)
374 if (sp[0]->s_n&7)
375 dsp_add(times_perform, 4,
376 sp[0]->s_vec, sp[1]->s_vec, sp[2]->s_vec, sp[0]->s_n);
377 else
378 dsp_add(times_perf8, 4,
379 sp[0]->s_vec, sp[1]->s_vec, sp[2]->s_vec, sp[0]->s_n);
382 static void scalartimes_dsp(t_scalartimes *x, t_signal **sp)
384 if (sp[0]->s_n&7)
385 dsp_add(scalartimes_perform, 4, sp[0]->s_vec, &x->x_g,
386 sp[1]->s_vec, sp[0]->s_n);
387 else
388 dsp_add(scalartimes_perf8, 4, sp[0]->s_vec, &x->x_g,
389 sp[1]->s_vec, sp[0]->s_n);
392 static void times_setup(void)
394 times_class = class_new(gensym("*~"), (t_newmethod)times_new, 0,
395 sizeof(t_times), 0, A_GIMME, 0);
396 CLASS_MAINSIGNALIN(times_class, t_times, x_f);
397 class_addmethod(times_class, (t_method)times_dsp, gensym("dsp"), 0);
398 class_sethelpsymbol(times_class, gensym("sigbinops"));
399 scalartimes_class = class_new(gensym("*~"), 0, 0,
400 sizeof(t_scalartimes), 0, 0);
401 CLASS_MAINSIGNALIN(scalartimes_class, t_scalartimes, x_f);
402 class_addmethod(scalartimes_class, (t_method)scalartimes_dsp, gensym("dsp"),
404 class_sethelpsymbol(scalartimes_class, gensym("sigbinops"));
407 /* ----------------------------- over ----------------------------- */
408 static t_class *over_class, *scalarover_class;
410 typedef struct _over
412 t_object x_obj;
413 float x_f;
414 } t_over;
416 typedef struct _scalarover
418 t_object x_obj;
419 float x_f;
420 t_float x_g;
421 } t_scalarover;
423 static void *over_new(t_symbol *s, int argc, t_atom *argv)
425 if (argc > 1) post("/~: extra arguments ignored");
426 if (argc)
428 t_scalarover *x = (t_scalarover *)pd_new(scalarover_class);
429 floatinlet_new(&x->x_obj, &x->x_g);
430 x->x_g = atom_getfloatarg(0, argc, argv);
431 outlet_new(&x->x_obj, &s_signal);
432 x->x_f = 0;
433 return (x);
435 else
437 t_over *x = (t_over *)pd_new(over_class);
438 inlet_new(&x->x_obj, &x->x_obj.ob_pd, &s_signal, &s_signal);
439 outlet_new(&x->x_obj, &s_signal);
440 x->x_f = 0;
441 return (x);
445 t_int *over_perform(t_int *w)
447 t_sample *in1 = (t_sample *)(w[1]);
448 t_sample *in2 = (t_sample *)(w[2]);
449 t_sample *out = (t_sample *)(w[3]);
450 int n = (int)(w[4]);
451 while (n--)
453 float g = *in2++;
454 *out++ = (g ? *in1++ / g : 0);
456 return (w+5);
459 t_int *over_perf8(t_int *w)
461 t_sample *in1 = (t_sample *)(w[1]);
462 t_sample *in2 = (t_sample *)(w[2]);
463 t_sample *out = (t_sample *)(w[3]);
464 int n = (int)(w[4]);
465 for (; n; n -= 8, in1 += 8, in2 += 8, out += 8)
467 t_sample f0 = in1[0], f1 = in1[1], f2 = in1[2], f3 = in1[3];
468 t_sample f4 = in1[4], f5 = in1[5], f6 = in1[6], f7 = in1[7];
470 t_sample g0 = in2[0], g1 = in2[1], g2 = in2[2], g3 = in2[3];
471 t_sample g4 = in2[4], g5 = in2[5], g6 = in2[6], g7 = in2[7];
473 out[0] = (g0? idiv(f0,g0) : 0);
474 out[1] = (g1? idiv(f1,g1) : 0);
475 out[2] = (g2? idiv(f2,g2) : 0);
476 out[3] = (g3? idiv(f3,g3) : 0);
477 out[4] = (g4? idiv(f4,g4) : 0);
478 out[5] = (g5? idiv(f5,g5) : 0);
479 out[6] = (g6? idiv(f6,g6) : 0);
480 out[7] = (g7? idiv(f7,g7) : 0);
482 return (w+5);
485 t_int *scalarover_perform(t_int *w)
487 t_sample *in = (t_sample *)(w[1]);
488 t_sample f = idiv(ftofix(1.),ftofix(*(t_float *)(w[2])));
489 t_sample *out = (t_sample *)(w[3]);
490 int n = (int)(w[4]);
491 while (n--) *out++ = mult(*in++,f);
492 return (w+5);
495 t_int *scalarover_perf8(t_int *w)
497 t_sample *in = (t_sample *)(w[1]);
498 t_sample g = ftofix(*(t_float *)(w[2]));
499 t_sample *out = (t_sample *)(w[3]);
500 int n = (int)(w[4]);
501 if (g) g = idiv(ftofix(1.f),g);
502 for (; n; n -= 8, in += 8, out += 8)
504 t_sample f0 = in[0], f1 = in[1], f2 = in[2], f3 = in[3];
505 t_sample f4 = in[4], f5 = in[5], f6 = in[6], f7 = in[7];
507 out[0] = mult(f0,g); out[1] = mult(f1,g); out[2] = mult(f2,g); out[3] = mult(f3,g);
508 out[4] = mult(f4,g); out[5] = mult(f5,g); out[6] = mult(f6,g); out[7] = mult(f7,g);
510 return (w+5);
513 static void over_dsp(t_over *x, t_signal **sp)
515 if (sp[0]->s_n&7)
516 dsp_add(over_perform, 4,
517 sp[0]->s_vec, sp[1]->s_vec, sp[2]->s_vec, sp[0]->s_n);
518 else
519 dsp_add(over_perf8, 4,
520 sp[0]->s_vec, sp[1]->s_vec, sp[2]->s_vec, sp[0]->s_n);
523 static void scalarover_dsp(t_scalarover *x, t_signal **sp)
525 if (sp[0]->s_n&7)
526 dsp_add(scalarover_perform, 4, sp[0]->s_vec, &x->x_g,
527 sp[1]->s_vec, sp[0]->s_n);
528 else
529 dsp_add(scalarover_perf8, 4, sp[0]->s_vec, &x->x_g,
530 sp[1]->s_vec, sp[0]->s_n);
533 static void over_setup(void)
535 over_class = class_new(gensym("/~"), (t_newmethod)over_new, 0,
536 sizeof(t_over), 0, A_GIMME, 0);
537 CLASS_MAINSIGNALIN(over_class, t_over, x_f);
538 class_addmethod(over_class, (t_method)over_dsp, gensym("dsp"), 0);
539 class_sethelpsymbol(over_class, gensym("sigbinops"));
540 scalarover_class = class_new(gensym("/~"), 0, 0,
541 sizeof(t_scalarover), 0, 0);
542 CLASS_MAINSIGNALIN(scalarover_class, t_scalarover, x_f);
543 class_addmethod(scalarover_class, (t_method)scalarover_dsp, gensym("dsp"),
545 class_sethelpsymbol(scalarover_class, gensym("sigbinops"));
548 /* ----------------------------- max ----------------------------- */
549 static t_class *max_class, *scalarmax_class;
551 typedef struct _max
553 t_object x_obj;
554 float x_f;
555 } t_max;
557 typedef struct _scalarmax
559 t_object x_obj;
560 float x_f;
561 t_float x_g;
562 } t_scalarmax;
564 static void *max_new(t_symbol *s, int argc, t_atom *argv)
566 if (argc > 1) post("max~: extra arguments ignored");
567 if (argc)
569 t_scalarmax *x = (t_scalarmax *)pd_new(scalarmax_class);
570 floatinlet_new(&x->x_obj, &x->x_g);
571 x->x_g = atom_getfloatarg(0, argc, argv);
572 outlet_new(&x->x_obj, &s_signal);
573 x->x_f = 0;
574 return (x);
576 else
578 t_max *x = (t_max *)pd_new(max_class);
579 inlet_new(&x->x_obj, &x->x_obj.ob_pd, &s_signal, &s_signal);
580 outlet_new(&x->x_obj, &s_signal);
581 x->x_f = 0;
582 return (x);
586 t_int *max_perform(t_int *w)
588 t_sample *in1 = (t_sample *)(w[1]);
589 t_sample *in2 = (t_sample *)(w[2]);
590 t_sample *out = (t_sample *)(w[3]);
591 int n = (int)(w[4]);
592 while (n--)
594 t_sample f = *in1++, g = *in2++;
595 *out++ = (f > g ? f : g);
597 return (w+5);
600 t_int *max_perf8(t_int *w)
602 t_sample *in1 = (t_sample *)(w[1]);
603 t_sample *in2 = (t_sample *)(w[2]);
604 t_sample *out = (t_sample *)(w[3]);
605 int n = (int)(w[4]);
606 for (; n; n -= 8, in1 += 8, in2 += 8, out += 8)
608 t_sample f0 = in1[0], f1 = in1[1], f2 = in1[2], f3 = in1[3];
609 t_sample f4 = in1[4], f5 = in1[5], f6 = in1[6], f7 = in1[7];
611 t_sample g0 = in2[0], g1 = in2[1], g2 = in2[2], g3 = in2[3];
612 t_sample g4 = in2[4], g5 = in2[5], g6 = in2[6], g7 = in2[7];
614 out[0] = (f0 > g0 ? f0 : g0); out[1] = (f1 > g1 ? f1 : g1);
615 out[2] = (f2 > g2 ? f2 : g2); out[3] = (f3 > g3 ? f3 : g3);
616 out[4] = (f4 > g4 ? f4 : g4); out[5] = (f5 > g5 ? f5 : g5);
617 out[6] = (f6 > g6 ? f6 : g6); out[7] = (f7 > g7 ? f7 : g7);
619 return (w+5);
622 t_int *scalarmax_perform(t_int *w)
624 t_sample *in = (t_sample *)(w[1]);
625 t_sample f = ftofix(*(t_float *)(w[2]));
626 t_sample *out = (t_sample *)(w[3]);
627 int n = (int)(w[4]);
628 while (n--)
630 t_sample g = *in++;
631 *out++ = (f > g ? f : g);
633 return (w+5);
636 t_int *scalarmax_perf8(t_int *w)
638 t_sample *in = (t_sample *)(w[1]);
639 t_sample g = ftofix(*(t_float *)(w[2]));
640 t_sample *out = (t_sample *)(w[3]);
641 int n = (int)(w[4]);
642 for (; n; n -= 8, in += 8, out += 8)
644 t_sample f0 = in[0], f1 = in[1], f2 = in[2], f3 = in[3];
645 t_sample f4 = in[4], f5 = in[5], f6 = in[6], f7 = in[7];
647 out[0] = (f0 > g ? f0 : g); out[1] = (f1 > g ? f1 : g);
648 out[2] = (f2 > g ? f2 : g); out[3] = (f3 > g ? f3 : g);
649 out[4] = (f4 > g ? f4 : g); out[5] = (f5 > g ? f5 : g);
650 out[6] = (f6 > g ? f6 : g); out[7] = (f7 > g ? f7 : g);
652 return (w+5);
655 static void max_dsp(t_max *x, t_signal **sp)
657 if (sp[0]->s_n&7)
658 dsp_add(max_perform, 4,
659 sp[0]->s_vec, sp[1]->s_vec, sp[2]->s_vec, sp[0]->s_n);
660 else
661 dsp_add(max_perf8, 4,
662 sp[0]->s_vec, sp[1]->s_vec, sp[2]->s_vec, sp[0]->s_n);
665 static void scalarmax_dsp(t_scalarmax *x, t_signal **sp)
667 if (sp[0]->s_n&7)
668 dsp_add(scalarmax_perform, 4, sp[0]->s_vec, &x->x_g,
669 sp[1]->s_vec, sp[0]->s_n);
670 else
671 dsp_add(scalarmax_perf8, 4, sp[0]->s_vec, &x->x_g,
672 sp[1]->s_vec, sp[0]->s_n);
675 static void max_setup(void)
677 max_class = class_new(gensym("max~"), (t_newmethod)max_new, 0,
678 sizeof(t_max), 0, A_GIMME, 0);
679 CLASS_MAINSIGNALIN(max_class, t_max, x_f);
680 class_addmethod(max_class, (t_method)max_dsp, gensym("dsp"), 0);
681 class_sethelpsymbol(max_class, gensym("sigbinops"));
682 scalarmax_class = class_new(gensym("max~"), 0, 0,
683 sizeof(t_scalarmax), 0, 0);
684 CLASS_MAINSIGNALIN(scalarmax_class, t_scalarmax, x_f);
685 class_addmethod(scalarmax_class, (t_method)scalarmax_dsp, gensym("dsp"),
687 class_sethelpsymbol(scalarmax_class, gensym("sigbinops"));
690 /* ----------------------------- min ----------------------------- */
691 static t_class *min_class, *scalarmin_class;
693 typedef struct _min
695 t_object x_obj;
696 float x_f;
697 } t_min;
699 typedef struct _scalarmin
701 t_object x_obj;
702 t_float x_g;
703 float x_f;
704 } t_scalarmin;
706 static void *min_new(t_symbol *s, int argc, t_atom *argv)
708 if (argc > 1) post("min~: extra arguments ignored");
709 if (argc)
711 t_scalarmin *x = (t_scalarmin *)pd_new(scalarmin_class);
712 floatinlet_new(&x->x_obj, &x->x_g);
713 x->x_g = atom_getfloatarg(0, argc, argv);
714 outlet_new(&x->x_obj, &s_signal);
715 x->x_f = 0;
716 return (x);
718 else
720 t_min *x = (t_min *)pd_new(min_class);
721 inlet_new(&x->x_obj, &x->x_obj.ob_pd, &s_signal, &s_signal);
722 outlet_new(&x->x_obj, &s_signal);
723 x->x_f = 0;
724 return (x);
728 t_int *min_perform(t_int *w)
730 t_sample *in1 = (t_sample *)(w[1]);
731 t_sample *in2 = (t_sample *)(w[2]);
732 t_sample *out = (t_sample *)(w[3]);
733 int n = (int)(w[4]);
734 while (n--)
736 t_sample f = *in1++, g = *in2++;
737 *out++ = (f < g ? f : g);
739 return (w+5);
742 t_int *min_perf8(t_int *w)
744 t_sample *in1 = (t_sample *)(w[1]);
745 t_sample *in2 = (t_sample *)(w[2]);
746 t_sample *out = (t_sample *)(w[3]);
747 int n = (int)(w[4]);
748 for (; n; n -= 8, in1 += 8, in2 += 8, out += 8)
750 t_sample f0 = in1[0], f1 = in1[1], f2 = in1[2], f3 = in1[3];
751 t_sample f4 = in1[4], f5 = in1[5], f6 = in1[6], f7 = in1[7];
753 t_sample g0 = in2[0], g1 = in2[1], g2 = in2[2], g3 = in2[3];
754 t_sample g4 = in2[4], g5 = in2[5], g6 = in2[6], g7 = in2[7];
756 out[0] = (f0 < g0 ? f0 : g0); out[1] = (f1 < g1 ? f1 : g1);
757 out[2] = (f2 < g2 ? f2 : g2); out[3] = (f3 < g3 ? f3 : g3);
758 out[4] = (f4 < g4 ? f4 : g4); out[5] = (f5 < g5 ? f5 : g5);
759 out[6] = (f6 < g6 ? f6 : g6); out[7] = (f7 < g7 ? f7 : g7);
761 return (w+5);
764 t_int *scalarmin_perform(t_int *w)
766 t_sample *in = (t_sample *)(w[1]);
767 t_sample f = ftofix(*(t_float *)(w[2]));
768 t_sample *out = (t_sample *)(w[3]);
769 int n = (int)(w[4]);
770 while (n--)
772 t_sample g = *in++;
773 *out++ = (f < g ? f : g);
775 return (w+5);
778 t_int *scalarmin_perf8(t_int *w)
780 t_sample *in = (t_sample *)(w[1]);
781 t_sample g = ftofix(*(t_float *)(w[2]));
782 t_sample *out = (t_sample *)(w[3]);
783 int n = (int)(w[4]);
784 for (; n; n -= 8, in += 8, out += 8)
786 t_sample f0 = in[0], f1 = in[1], f2 = in[2], f3 = in[3];
787 t_sample f4 = in[4], f5 = in[5], f6 = in[6], f7 = in[7];
789 out[0] = (f0 < g ? f0 : g); out[1] = (f1 < g ? f1 : g);
790 out[2] = (f2 < g ? f2 : g); out[3] = (f3 < g ? f3 : g);
791 out[4] = (f4 < g ? f4 : g); out[5] = (f5 < g ? f5 : g);
792 out[6] = (f6 < g ? f6 : g); out[7] = (f7 < g ? f7 : g);
794 return (w+5);
797 static void min_dsp(t_min *x, t_signal **sp)
799 if (sp[0]->s_n&7)
800 dsp_add(min_perform, 4,
801 sp[0]->s_vec, sp[1]->s_vec, sp[2]->s_vec, sp[0]->s_n);
802 else
803 dsp_add(min_perf8, 4,
804 sp[0]->s_vec, sp[1]->s_vec, sp[2]->s_vec, sp[0]->s_n);
807 static void scalarmin_dsp(t_scalarmin *x, t_signal **sp)
809 if (sp[0]->s_n&7)
810 dsp_add(scalarmin_perform, 4, sp[0]->s_vec, &x->x_g,
811 sp[1]->s_vec, sp[0]->s_n);
812 else
813 dsp_add(scalarmin_perf8, 4, sp[0]->s_vec, &x->x_g,
814 sp[1]->s_vec, sp[0]->s_n);
817 static void min_setup(void)
819 min_class = class_new(gensym("min~"), (t_newmethod)min_new, 0,
820 sizeof(t_min), 0, A_GIMME, 0);
821 CLASS_MAINSIGNALIN(min_class, t_min, x_f);
822 class_addmethod(min_class, (t_method)min_dsp, gensym("dsp"), 0);
823 class_sethelpsymbol(min_class, gensym("sigbinops"));
824 scalarmin_class = class_new(gensym("min~"), 0, 0,
825 sizeof(t_scalarmin), 0, 0);
826 CLASS_MAINSIGNALIN(scalarmin_class, t_scalarmin, x_f);
827 class_addmethod(scalarmin_class, (t_method)scalarmin_dsp, gensym("dsp"),
829 class_sethelpsymbol(scalarmin_class, gensym("sigbinops"));
832 /* ----------------------- global setup routine ---------------- */
833 void d_arithmetic_setup(void)
835 plus_setup();
836 minus_setup();
837 times_setup();
838 over_setup();
839 max_setup();
840 min_setup();
843 /* Copyright (c) 1997-1999 Miller Puckette.
844 * For information on usage and redistribution, and for a DISCLAIMER OF ALL
845 * WARRANTIES, see the file, "LICENSE.txt," in this distribution. */
847 /* arithmetic binops (+, -, *, /).
848 If no creation argument is given, there are two signal inlets for vector/vector
849 operation; otherwise it's vector/scalar and the second inlet takes a float
850 to reset the value.
853 #include "m_pd.h"
855 /* ----------------------------- plus ----------------------------- */
856 static t_class *plus_class, *scalarplus_class;
858 typedef struct _plus
860 t_object x_obj;
861 float x_f;
862 } t_plus;
864 typedef struct _scalarplus
866 t_object x_obj;
867 float x_f;
868 t_float x_g; /* inlet value */
869 } t_scalarplus;
871 static void *plus_new(t_symbol *s, int argc, t_atom *argv)
873 if (argc > 1) post("+~: extra arguments ignored");
874 if (argc)
876 t_scalarplus *x = (t_scalarplus *)pd_new(scalarplus_class);
877 floatinlet_new(&x->x_obj, &x->x_g);
878 x->x_g = atom_getfloatarg(0, argc, argv);
879 outlet_new(&x->x_obj, &s_signal);
880 x->x_f = 0;
881 return (x);
883 else
885 t_plus *x = (t_plus *)pd_new(plus_class);
886 inlet_new(&x->x_obj, &x->x_obj.ob_pd, &s_signal, &s_signal);
887 outlet_new(&x->x_obj, &s_signal);
888 x->x_f = 0;
889 return (x);
893 t_int *plus_perform(t_int *w)
895 t_sample *in1 = (t_sample *)(w[1]);
896 t_sample *in2 = (t_sample *)(w[2]);
897 t_sample *out = (t_sample *)(w[3]);
898 int n = (int)(w[4]);
899 while (n--) *out++ = *in1++ + *in2++;
900 return (w+5);
903 t_int *plus_perf8(t_int *w)
905 t_sample *in1 = (t_sample *)(w[1]);
906 t_sample *in2 = (t_sample *)(w[2]);
907 t_sample *out = (t_sample *)(w[3]);
908 int n = (int)(w[4]);
909 for (; n; n -= 8, in1 += 8, in2 += 8, out += 8)
911 t_sample f0 = in1[0], f1 = in1[1], f2 = in1[2], f3 = in1[3];
912 t_sample f4 = in1[4], f5 = in1[5], f6 = in1[6], f7 = in1[7];
914 t_sample g0 = in2[0], g1 = in2[1], g2 = in2[2], g3 = in2[3];
915 t_sample g4 = in2[4], g5 = in2[5], g6 = in2[6], g7 = in2[7];
917 out[0] = f0 + g0; out[1] = f1 + g1; out[2] = f2 + g2; out[3] = f3 + g3;
918 out[4] = f4 + g4; out[5] = f5 + g5; out[6] = f6 + g6; out[7] = f7 + g7;
920 return (w+5);
923 t_int *scalarplus_perform(t_int *w)
925 t_sample *in = (t_sample *)(w[1]);
926 t_sample f = ftofix(*(t_float *)(w[2]));
927 t_sample *out = (t_sample *)(w[3]);
928 int n = (int)(w[4]);
929 while (n--) *out++ = *in++ + f;
930 return (w+5);
933 t_int *scalarplus_perf8(t_int *w)
935 t_sample *in = (t_sample *)(w[1]);
936 t_sample g = ftofix(*(t_float *)(w[2]));
937 t_sample *out = (t_sample *)(w[3]);
938 int n = (int)(w[4]);
939 for (; n; n -= 8, in += 8, out += 8)
941 t_sample f0 = in[0], f1 = in[1], f2 = in[2], f3 = in[3];
942 t_sample f4 = in[4], f5 = in[5], f6 = in[6], f7 = in[7];
944 out[0] = f0 + g; out[1] = f1 + g; out[2] = f2 + g; out[3] = f3 + g;
945 out[4] = f4 + g; out[5] = f5 + g; out[6] = f6 + g; out[7] = f7 + g;
947 return (w+5);
950 void dsp_add_plus(t_sample *in1, t_sample *in2, t_sample *out, int n)
952 if (n&7)
953 dsp_add(plus_perform, 4, in1, in2, out, n);
954 else
955 dsp_add(plus_perf8, 4, in1, in2, out, n);
958 static void plus_dsp(t_plus *x, t_signal **sp)
960 dsp_add_plus(sp[0]->s_vec, sp[1]->s_vec, sp[2]->s_vec, sp[0]->s_n);
963 static void scalarplus_dsp(t_scalarplus *x, t_signal **sp)
965 if (sp[0]->s_n&7)
966 dsp_add(scalarplus_perform, 4, sp[0]->s_vec, &x->x_g,
967 sp[1]->s_vec, sp[0]->s_n);
968 else
969 dsp_add(scalarplus_perf8, 4, sp[0]->s_vec, &x->x_g,
970 sp[1]->s_vec, sp[0]->s_n);
973 static void plus_setup(void)
975 plus_class = class_new(gensym("+~"), (t_newmethod)plus_new, 0,
976 sizeof(t_plus), 0, A_GIMME, 0);
977 class_addmethod(plus_class, (t_method)plus_dsp, gensym("dsp"), 0);
978 CLASS_MAINSIGNALIN(plus_class, t_plus, x_f);
979 class_sethelpsymbol(plus_class, gensym("sigbinops"));
980 scalarplus_class = class_new(gensym("+~"), 0, 0,
981 sizeof(t_scalarplus), 0, 0);
982 CLASS_MAINSIGNALIN(scalarplus_class, t_scalarplus, x_f);
983 class_addmethod(scalarplus_class, (t_method)scalarplus_dsp, gensym("dsp"),
985 class_sethelpsymbol(scalarplus_class, gensym("sigbinops"));
988 /* ----------------------------- minus ----------------------------- */
989 static t_class *minus_class, *scalarminus_class;
991 typedef struct _minus
993 t_object x_obj;
994 float x_f;
995 } t_minus;
997 typedef struct _scalarminus
999 t_object x_obj;
1000 float x_f;
1001 t_float x_g;
1002 } t_scalarminus;
1004 static void *minus_new(t_symbol *s, int argc, t_atom *argv)
1006 if (argc > 1) post("-~: extra arguments ignored");
1007 if (argc)
1009 t_scalarminus *x = (t_scalarminus *)pd_new(scalarminus_class);
1010 floatinlet_new(&x->x_obj, &x->x_g);
1011 x->x_g = atom_getfloatarg(0, argc, argv);
1012 outlet_new(&x->x_obj, &s_signal);
1013 x->x_f = 0;
1014 return (x);
1016 else
1018 t_minus *x = (t_minus *)pd_new(minus_class);
1019 inlet_new(&x->x_obj, &x->x_obj.ob_pd, &s_signal, &s_signal);
1020 outlet_new(&x->x_obj, &s_signal);
1021 x->x_f = 0;
1022 return (x);
1026 t_int *minus_perform(t_int *w)
1028 t_sample *in1 = (t_sample *)(w[1]);
1029 t_sample *in2 = (t_sample *)(w[2]);
1030 t_sample *out = (t_sample *)(w[3]);
1031 int n = (int)(w[4]);
1032 while (n--) *out++ = *in1++ - *in2++;
1033 return (w+5);
1036 t_int *minus_perf8(t_int *w)
1038 t_sample *in1 = (t_sample *)(w[1]);
1039 t_sample *in2 = (t_sample *)(w[2]);
1040 t_sample *out = (t_sample *)(w[3]);
1041 int n = (int)(w[4]);
1042 for (; n; n -= 8, in1 += 8, in2 += 8, out += 8)
1044 t_sample f0 = in1[0], f1 = in1[1], f2 = in1[2], f3 = in1[3];
1045 t_sample f4 = in1[4], f5 = in1[5], f6 = in1[6], f7 = in1[7];
1047 t_sample g0 = in2[0], g1 = in2[1], g2 = in2[2], g3 = in2[3];
1048 t_sample g4 = in2[4], g5 = in2[5], g6 = in2[6], g7 = in2[7];
1050 out[0] = f0 - g0; out[1] = f1 - g1; out[2] = f2 - g2; out[3] = f3 - g3;
1051 out[4] = f4 - g4; out[5] = f5 - g5; out[6] = f6 - g6; out[7] = f7 - g7;
1053 return (w+5);
1056 t_int *scalarminus_perform(t_int *w)
1058 t_sample *in = (t_sample *)(w[1]);
1059 t_sample f = ftofix(*(t_float *)(w[2]));
1060 t_sample *out = (t_sample *)(w[3]);
1061 int n = (int)(w[4]);
1062 while (n--) *out++ = *in++ - f;
1063 return (w+5);
1066 t_int *scalarminus_perf8(t_int *w)
1068 t_sample *in = (t_sample *)(w[1]);
1069 t_sample g = ftofix(*(t_float *)(w[2]));
1070 t_sample *out = (t_sample *)(w[3]);
1071 int n = (int)(w[4]);
1072 for (; n; n -= 8, in += 8, out += 8)
1074 t_sample f0 = in[0], f1 = in[1], f2 = in[2], f3 = in[3];
1075 t_sample f4 = in[4], f5 = in[5], f6 = in[6], f7 = in[7];
1077 out[0] = f0 - g; out[1] = f1 - g; out[2] = f2 - g; out[3] = f3 - g;
1078 out[4] = f4 - g; out[5] = f5 - g; out[6] = f6 - g; out[7] = f7 - g;
1080 return (w+5);
1083 static void minus_dsp(t_minus *x, t_signal **sp)
1085 if (sp[0]->s_n&7)
1086 dsp_add(minus_perform, 4,
1087 sp[0]->s_vec, sp[1]->s_vec, sp[2]->s_vec, sp[0]->s_n);
1088 else
1089 dsp_add(minus_perf8, 4,
1090 sp[0]->s_vec, sp[1]->s_vec, sp[2]->s_vec, sp[0]->s_n);
1093 static void scalarminus_dsp(t_scalarminus *x, t_signal **sp)
1095 if (sp[0]->s_n&7)
1096 dsp_add(scalarminus_perform, 4, sp[0]->s_vec, &x->x_g,
1097 sp[1]->s_vec, sp[0]->s_n);
1098 else
1099 dsp_add(scalarminus_perf8, 4, sp[0]->s_vec, &x->x_g,
1100 sp[1]->s_vec, sp[0]->s_n);
1103 static void minus_setup(void)
1105 minus_class = class_new(gensym("-~"), (t_newmethod)minus_new, 0,
1106 sizeof(t_minus), 0, A_GIMME, 0);
1107 CLASS_MAINSIGNALIN(minus_class, t_minus, x_f);
1108 class_addmethod(minus_class, (t_method)minus_dsp, gensym("dsp"), 0);
1109 class_sethelpsymbol(minus_class, gensym("sigbinops"));
1110 scalarminus_class = class_new(gensym("-~"), 0, 0,
1111 sizeof(t_scalarminus), 0, 0);
1112 CLASS_MAINSIGNALIN(scalarminus_class, t_scalarminus, x_f);
1113 class_addmethod(scalarminus_class, (t_method)scalarminus_dsp, gensym("dsp"),
1115 class_sethelpsymbol(scalarminus_class, gensym("sigbinops"));
1118 /* ----------------------------- times ----------------------------- */
1120 static t_class *times_class, *scalartimes_class;
1122 typedef struct _times
1124 t_object x_obj;
1125 float x_f;
1126 } t_times;
1128 typedef struct _scalartimes
1130 t_object x_obj;
1131 float x_f;
1132 t_float x_g;
1133 } t_scalartimes;
1135 static void *times_new(t_symbol *s, int argc, t_atom *argv)
1137 if (argc > 1) post("*~: extra arguments ignored");
1138 if (argc)
1140 t_scalartimes *x = (t_scalartimes *)pd_new(scalartimes_class);
1141 floatinlet_new(&x->x_obj, &x->x_g);
1142 x->x_g = atom_getfloatarg(0, argc, argv);
1143 outlet_new(&x->x_obj, &s_signal);
1144 x->x_f = 0;
1145 return (x);
1147 else
1149 t_times *x = (t_times *)pd_new(times_class);
1150 inlet_new(&x->x_obj, &x->x_obj.ob_pd, &s_signal, &s_signal);
1151 outlet_new(&x->x_obj, &s_signal);
1152 x->x_f = 0;
1153 return (x);
1157 t_int *times_perform(t_int *w)
1159 t_sample *in1 = (t_sample *)(w[1]);
1160 t_sample *in2 = (t_sample *)(w[2]);
1161 t_sample *out = (t_sample *)(w[3]);
1162 int n = (int)(w[4]);
1163 while (n--) *out++ = mult(*in1++,*in2++);
1164 return (w+5);
1167 t_int *times_perf8(t_int *w)
1169 t_sample *in1 = (t_sample *)(w[1]);
1170 t_sample *in2 = (t_sample *)(w[2]);
1171 t_sample *out = (t_sample *)(w[3]);
1172 int n = (int)(w[4]);
1173 for (; n; n -= 8, in1 += 8, in2 += 8, out += 8)
1175 t_sample f0 = in1[0], f1 = in1[1], f2 = in1[2], f3 = in1[3];
1176 t_sample f4 = in1[4], f5 = in1[5], f6 = in1[6], f7 = in1[7];
1178 t_sample g0 = in2[0], g1 = in2[1], g2 = in2[2], g3 = in2[3];
1179 t_sample g4 = in2[4], g5 = in2[5], g6 = in2[6], g7 = in2[7];
1181 out[0] = mult(f0,g0); out[1] = mult(f1,g1); out[2] = mult(f2,g2); out[3] = mult(f3,g3);
1182 out[4] = mult(f4,g4); out[5] = mult(f5,g5); out[6] = mult(f6,g6); out[7] = mult(f7,g7);
1184 return (w+5);
1187 t_int *scalartimes_perform(t_int *w)
1189 t_sample *in = (t_sample *)(w[1]);
1190 t_sample f = ftofix(*(t_float *)(w[2]));
1191 t_sample *out = (t_sample *)(w[3]);
1192 int n = (int)(w[4]);
1193 while (n--) *out++ = mult(*in++,f);
1194 return (w+5);
1197 t_int *scalartimes_perf8(t_int *w)
1199 t_sample *in = (t_sample *)(w[1]);
1200 t_sample g = ftofix(*(t_float *)(w[2]));
1201 t_sample *out = (t_sample *)(w[3]);
1202 int n = (int)(w[4]);
1203 for (; n; n -= 8, in += 8, out += 8)
1205 t_sample f0 = in[0], f1 = in[1], f2 = in[2], f3 = in[3];
1206 t_sample f4 = in[4], f5 = in[5], f6 = in[6], f7 = in[7];
1208 out[0] = mult(f0,g); out[1] = mult(f1,g); out[2] = mult(f2,g); out[3] = mult(f3,g);
1209 out[4] = mult(f4,g); out[5] = mult(f5,g); out[6] = mult(f6,g); out[7] = mult(f7,g);
1211 return (w+5);
1214 static void times_dsp(t_times *x, t_signal **sp)
1216 if (sp[0]->s_n&7)
1217 dsp_add(times_perform, 4,
1218 sp[0]->s_vec, sp[1]->s_vec, sp[2]->s_vec, sp[0]->s_n);
1219 else
1220 dsp_add(times_perf8, 4,
1221 sp[0]->s_vec, sp[1]->s_vec, sp[2]->s_vec, sp[0]->s_n);
1224 static void scalartimes_dsp(t_scalartimes *x, t_signal **sp)
1226 if (sp[0]->s_n&7)
1227 dsp_add(scalartimes_perform, 4, sp[0]->s_vec, &x->x_g,
1228 sp[1]->s_vec, sp[0]->s_n);
1229 else
1230 dsp_add(scalartimes_perf8, 4, sp[0]->s_vec, &x->x_g,
1231 sp[1]->s_vec, sp[0]->s_n);
1234 static void times_setup(void)
1236 times_class = class_new(gensym("*~"), (t_newmethod)times_new, 0,
1237 sizeof(t_times), 0, A_GIMME, 0);
1238 CLASS_MAINSIGNALIN(times_class, t_times, x_f);
1239 class_addmethod(times_class, (t_method)times_dsp, gensym("dsp"), 0);
1240 class_sethelpsymbol(times_class, gensym("sigbinops"));
1241 scalartimes_class = class_new(gensym("*~"), 0, 0,
1242 sizeof(t_scalartimes), 0, 0);
1243 CLASS_MAINSIGNALIN(scalartimes_class, t_scalartimes, x_f);
1244 class_addmethod(scalartimes_class, (t_method)scalartimes_dsp, gensym("dsp"),
1246 class_sethelpsymbol(scalartimes_class, gensym("sigbinops"));
1249 /* ----------------------------- over ----------------------------- */
1250 static t_class *over_class, *scalarover_class;
1252 typedef struct _over
1254 t_object x_obj;
1255 float x_f;
1256 } t_over;
1258 typedef struct _scalarover
1260 t_object x_obj;
1261 float x_f;
1262 t_float x_g;
1263 } t_scalarover;
1265 static void *over_new(t_symbol *s, int argc, t_atom *argv)
1267 if (argc > 1) post("/~: extra arguments ignored");
1268 if (argc)
1270 t_scalarover *x = (t_scalarover *)pd_new(scalarover_class);
1271 floatinlet_new(&x->x_obj, &x->x_g);
1272 x->x_g = atom_getfloatarg(0, argc, argv);
1273 outlet_new(&x->x_obj, &s_signal);
1274 x->x_f = 0;
1275 return (x);
1277 else
1279 t_over *x = (t_over *)pd_new(over_class);
1280 inlet_new(&x->x_obj, &x->x_obj.ob_pd, &s_signal, &s_signal);
1281 outlet_new(&x->x_obj, &s_signal);
1282 x->x_f = 0;
1283 return (x);
1287 t_int *over_perform(t_int *w)
1289 t_sample *in1 = (t_sample *)(w[1]);
1290 t_sample *in2 = (t_sample *)(w[2]);
1291 t_sample *out = (t_sample *)(w[3]);
1292 int n = (int)(w[4]);
1293 while (n--)
1295 float g = *in2++;
1296 *out++ = (g ? *in1++ / g : 0);
1298 return (w+5);
1301 t_int *over_perf8(t_int *w)
1303 t_sample *in1 = (t_sample *)(w[1]);
1304 t_sample *in2 = (t_sample *)(w[2]);
1305 t_sample *out = (t_sample *)(w[3]);
1306 int n = (int)(w[4]);
1307 for (; n; n -= 8, in1 += 8, in2 += 8, out += 8)
1309 t_sample f0 = in1[0], f1 = in1[1], f2 = in1[2], f3 = in1[3];
1310 t_sample f4 = in1[4], f5 = in1[5], f6 = in1[6], f7 = in1[7];
1312 t_sample g0 = in2[0], g1 = in2[1], g2 = in2[2], g3 = in2[3];
1313 t_sample g4 = in2[4], g5 = in2[5], g6 = in2[6], g7 = in2[7];
1315 out[0] = (g0? idiv(f0,g0) : 0);
1316 out[1] = (g1? idiv(f1,g1) : 0);
1317 out[2] = (g2? idiv(f2,g2) : 0);
1318 out[3] = (g3? idiv(f3,g3) : 0);
1319 out[4] = (g4? idiv(f4,g4) : 0);
1320 out[5] = (g5? idiv(f5,g5) : 0);
1321 out[6] = (g6? idiv(f6,g6) : 0);
1322 out[7] = (g7? idiv(f7,g7) : 0);
1324 return (w+5);
1327 t_int *scalarover_perform(t_int *w)
1329 t_sample *in = (t_sample *)(w[1]);
1330 t_sample f = idiv(ftofix(1.),ftofix(*(t_float *)(w[2])));
1331 t_sample *out = (t_sample *)(w[3]);
1332 int n = (int)(w[4]);
1333 while (n--) *out++ = mult(*in++,f);
1334 return (w+5);
1337 t_int *scalarover_perf8(t_int *w)
1339 t_sample *in = (t_sample *)(w[1]);
1340 t_sample g = ftofix(*(t_float *)(w[2]));
1341 t_sample *out = (t_sample *)(w[3]);
1342 int n = (int)(w[4]);
1343 if (g) g = idiv(ftofix(1.f),g);
1344 for (; n; n -= 8, in += 8, out += 8)
1346 t_sample f0 = in[0], f1 = in[1], f2 = in[2], f3 = in[3];
1347 t_sample f4 = in[4], f5 = in[5], f6 = in[6], f7 = in[7];
1349 out[0] = mult(f0,g); out[1] = mult(f1,g); out[2] = mult(f2,g); out[3] = mult(f3,g);
1350 out[4] = mult(f4,g); out[5] = mult(f5,g); out[6] = mult(f6,g); out[7] = mult(f7,g);
1352 return (w+5);
1355 static void over_dsp(t_over *x, t_signal **sp)
1357 if (sp[0]->s_n&7)
1358 dsp_add(over_perform, 4,
1359 sp[0]->s_vec, sp[1]->s_vec, sp[2]->s_vec, sp[0]->s_n);
1360 else
1361 dsp_add(over_perf8, 4,
1362 sp[0]->s_vec, sp[1]->s_vec, sp[2]->s_vec, sp[0]->s_n);
1365 static void scalarover_dsp(t_scalarover *x, t_signal **sp)
1367 if (sp[0]->s_n&7)
1368 dsp_add(scalarover_perform, 4, sp[0]->s_vec, &x->x_g,
1369 sp[1]->s_vec, sp[0]->s_n);
1370 else
1371 dsp_add(scalarover_perf8, 4, sp[0]->s_vec, &x->x_g,
1372 sp[1]->s_vec, sp[0]->s_n);
1375 static void over_setup(void)
1377 over_class = class_new(gensym("/~"), (t_newmethod)over_new, 0,
1378 sizeof(t_over), 0, A_GIMME, 0);
1379 CLASS_MAINSIGNALIN(over_class, t_over, x_f);
1380 class_addmethod(over_class, (t_method)over_dsp, gensym("dsp"), 0);
1381 class_sethelpsymbol(over_class, gensym("sigbinops"));
1382 scalarover_class = class_new(gensym("/~"), 0, 0,
1383 sizeof(t_scalarover), 0, 0);
1384 CLASS_MAINSIGNALIN(scalarover_class, t_scalarover, x_f);
1385 class_addmethod(scalarover_class, (t_method)scalarover_dsp, gensym("dsp"),
1387 class_sethelpsymbol(scalarover_class, gensym("sigbinops"));
1390 /* ----------------------------- max ----------------------------- */
1391 static t_class *max_class, *scalarmax_class;
1393 typedef struct _max
1395 t_object x_obj;
1396 float x_f;
1397 } t_max;
1399 typedef struct _scalarmax
1401 t_object x_obj;
1402 float x_f;
1403 t_float x_g;
1404 } t_scalarmax;
1406 static void *max_new(t_symbol *s, int argc, t_atom *argv)
1408 if (argc > 1) post("max~: extra arguments ignored");
1409 if (argc)
1411 t_scalarmax *x = (t_scalarmax *)pd_new(scalarmax_class);
1412 floatinlet_new(&x->x_obj, &x->x_g);
1413 x->x_g = atom_getfloatarg(0, argc, argv);
1414 outlet_new(&x->x_obj, &s_signal);
1415 x->x_f = 0;
1416 return (x);
1418 else
1420 t_max *x = (t_max *)pd_new(max_class);
1421 inlet_new(&x->x_obj, &x->x_obj.ob_pd, &s_signal, &s_signal);
1422 outlet_new(&x->x_obj, &s_signal);
1423 x->x_f = 0;
1424 return (x);
1428 t_int *max_perform(t_int *w)
1430 t_sample *in1 = (t_sample *)(w[1]);
1431 t_sample *in2 = (t_sample *)(w[2]);
1432 t_sample *out = (t_sample *)(w[3]);
1433 int n = (int)(w[4]);
1434 while (n--)
1436 t_sample f = *in1++, g = *in2++;
1437 *out++ = (f > g ? f : g);
1439 return (w+5);
1442 t_int *max_perf8(t_int *w)
1444 t_sample *in1 = (t_sample *)(w[1]);
1445 t_sample *in2 = (t_sample *)(w[2]);
1446 t_sample *out = (t_sample *)(w[3]);
1447 int n = (int)(w[4]);
1448 for (; n; n -= 8, in1 += 8, in2 += 8, out += 8)
1450 t_sample f0 = in1[0], f1 = in1[1], f2 = in1[2], f3 = in1[3];
1451 t_sample f4 = in1[4], f5 = in1[5], f6 = in1[6], f7 = in1[7];
1453 t_sample g0 = in2[0], g1 = in2[1], g2 = in2[2], g3 = in2[3];
1454 t_sample g4 = in2[4], g5 = in2[5], g6 = in2[6], g7 = in2[7];
1456 out[0] = (f0 > g0 ? f0 : g0); out[1] = (f1 > g1 ? f1 : g1);
1457 out[2] = (f2 > g2 ? f2 : g2); out[3] = (f3 > g3 ? f3 : g3);
1458 out[4] = (f4 > g4 ? f4 : g4); out[5] = (f5 > g5 ? f5 : g5);
1459 out[6] = (f6 > g6 ? f6 : g6); out[7] = (f7 > g7 ? f7 : g7);
1461 return (w+5);
1464 t_int *scalarmax_perform(t_int *w)
1466 t_sample *in = (t_sample *)(w[1]);
1467 t_sample f = ftofix(*(t_float *)(w[2]));
1468 t_sample *out = (t_sample *)(w[3]);
1469 int n = (int)(w[4]);
1470 while (n--)
1472 t_sample g = *in++;
1473 *out++ = (f > g ? f : g);
1475 return (w+5);
1478 t_int *scalarmax_perf8(t_int *w)
1480 t_sample *in = (t_sample *)(w[1]);
1481 t_sample g = ftofix(*(t_float *)(w[2]));
1482 t_sample *out = (t_sample *)(w[3]);
1483 int n = (int)(w[4]);
1484 for (; n; n -= 8, in += 8, out += 8)
1486 t_sample f0 = in[0], f1 = in[1], f2 = in[2], f3 = in[3];
1487 t_sample f4 = in[4], f5 = in[5], f6 = in[6], f7 = in[7];
1489 out[0] = (f0 > g ? f0 : g); out[1] = (f1 > g ? f1 : g);
1490 out[2] = (f2 > g ? f2 : g); out[3] = (f3 > g ? f3 : g);
1491 out[4] = (f4 > g ? f4 : g); out[5] = (f5 > g ? f5 : g);
1492 out[6] = (f6 > g ? f6 : g); out[7] = (f7 > g ? f7 : g);
1494 return (w+5);
1497 static void max_dsp(t_max *x, t_signal **sp)
1499 if (sp[0]->s_n&7)
1500 dsp_add(max_perform, 4,
1501 sp[0]->s_vec, sp[1]->s_vec, sp[2]->s_vec, sp[0]->s_n);
1502 else
1503 dsp_add(max_perf8, 4,
1504 sp[0]->s_vec, sp[1]->s_vec, sp[2]->s_vec, sp[0]->s_n);
1507 static void scalarmax_dsp(t_scalarmax *x, t_signal **sp)
1509 if (sp[0]->s_n&7)
1510 dsp_add(scalarmax_perform, 4, sp[0]->s_vec, &x->x_g,
1511 sp[1]->s_vec, sp[0]->s_n);
1512 else
1513 dsp_add(scalarmax_perf8, 4, sp[0]->s_vec, &x->x_g,
1514 sp[1]->s_vec, sp[0]->s_n);
1517 static void max_setup(void)
1519 max_class = class_new(gensym("max~"), (t_newmethod)max_new, 0,
1520 sizeof(t_max), 0, A_GIMME, 0);
1521 CLASS_MAINSIGNALIN(max_class, t_max, x_f);
1522 class_addmethod(max_class, (t_method)max_dsp, gensym("dsp"), 0);
1523 class_sethelpsymbol(max_class, gensym("sigbinops"));
1524 scalarmax_class = class_new(gensym("max~"), 0, 0,
1525 sizeof(t_scalarmax), 0, 0);
1526 CLASS_MAINSIGNALIN(scalarmax_class, t_scalarmax, x_f);
1527 class_addmethod(scalarmax_class, (t_method)scalarmax_dsp, gensym("dsp"),
1529 class_sethelpsymbol(scalarmax_class, gensym("sigbinops"));
1532 /* ----------------------------- min ----------------------------- */
1533 static t_class *min_class, *scalarmin_class;
1535 typedef struct _min
1537 t_object x_obj;
1538 float x_f;
1539 } t_min;
1541 typedef struct _scalarmin
1543 t_object x_obj;
1544 t_float x_g;
1545 float x_f;
1546 } t_scalarmin;
1548 static void *min_new(t_symbol *s, int argc, t_atom *argv)
1550 if (argc > 1) post("min~: extra arguments ignored");
1551 if (argc)
1553 t_scalarmin *x = (t_scalarmin *)pd_new(scalarmin_class);
1554 floatinlet_new(&x->x_obj, &x->x_g);
1555 x->x_g = atom_getfloatarg(0, argc, argv);
1556 outlet_new(&x->x_obj, &s_signal);
1557 x->x_f = 0;
1558 return (x);
1560 else
1562 t_min *x = (t_min *)pd_new(min_class);
1563 inlet_new(&x->x_obj, &x->x_obj.ob_pd, &s_signal, &s_signal);
1564 outlet_new(&x->x_obj, &s_signal);
1565 x->x_f = 0;
1566 return (x);
1570 t_int *min_perform(t_int *w)
1572 t_sample *in1 = (t_sample *)(w[1]);
1573 t_sample *in2 = (t_sample *)(w[2]);
1574 t_sample *out = (t_sample *)(w[3]);
1575 int n = (int)(w[4]);
1576 while (n--)
1578 t_sample f = *in1++, g = *in2++;
1579 *out++ = (f < g ? f : g);
1581 return (w+5);
1584 t_int *min_perf8(t_int *w)
1586 t_sample *in1 = (t_sample *)(w[1]);
1587 t_sample *in2 = (t_sample *)(w[2]);
1588 t_sample *out = (t_sample *)(w[3]);
1589 int n = (int)(w[4]);
1590 for (; n; n -= 8, in1 += 8, in2 += 8, out += 8)
1592 t_sample f0 = in1[0], f1 = in1[1], f2 = in1[2], f3 = in1[3];
1593 t_sample f4 = in1[4], f5 = in1[5], f6 = in1[6], f7 = in1[7];
1595 t_sample g0 = in2[0], g1 = in2[1], g2 = in2[2], g3 = in2[3];
1596 t_sample g4 = in2[4], g5 = in2[5], g6 = in2[6], g7 = in2[7];
1598 out[0] = (f0 < g0 ? f0 : g0); out[1] = (f1 < g1 ? f1 : g1);
1599 out[2] = (f2 < g2 ? f2 : g2); out[3] = (f3 < g3 ? f3 : g3);
1600 out[4] = (f4 < g4 ? f4 : g4); out[5] = (f5 < g5 ? f5 : g5);
1601 out[6] = (f6 < g6 ? f6 : g6); out[7] = (f7 < g7 ? f7 : g7);
1603 return (w+5);
1606 t_int *scalarmin_perform(t_int *w)
1608 t_sample *in = (t_sample *)(w[1]);
1609 t_sample f = ftofix(*(t_float *)(w[2]));
1610 t_sample *out = (t_sample *)(w[3]);
1611 int n = (int)(w[4]);
1612 while (n--)
1614 t_sample g = *in++;
1615 *out++ = (f < g ? f : g);
1617 return (w+5);
1620 t_int *scalarmin_perf8(t_int *w)
1622 t_sample *in = (t_sample *)(w[1]);
1623 t_sample g = ftofix(*(t_float *)(w[2]));
1624 t_sample *out = (t_sample *)(w[3]);
1625 int n = (int)(w[4]);
1626 for (; n; n -= 8, in += 8, out += 8)
1628 t_sample f0 = in[0], f1 = in[1], f2 = in[2], f3 = in[3];
1629 t_sample f4 = in[4], f5 = in[5], f6 = in[6], f7 = in[7];
1631 out[0] = (f0 < g ? f0 : g); out[1] = (f1 < g ? f1 : g);
1632 out[2] = (f2 < g ? f2 : g); out[3] = (f3 < g ? f3 : g);
1633 out[4] = (f4 < g ? f4 : g); out[5] = (f5 < g ? f5 : g);
1634 out[6] = (f6 < g ? f6 : g); out[7] = (f7 < g ? f7 : g);
1636 return (w+5);
1639 static void min_dsp(t_min *x, t_signal **sp)
1641 if (sp[0]->s_n&7)
1642 dsp_add(min_perform, 4,
1643 sp[0]->s_vec, sp[1]->s_vec, sp[2]->s_vec, sp[0]->s_n);
1644 else
1645 dsp_add(min_perf8, 4,
1646 sp[0]->s_vec, sp[1]->s_vec, sp[2]->s_vec, sp[0]->s_n);
1649 static void scalarmin_dsp(t_scalarmin *x, t_signal **sp)
1651 if (sp[0]->s_n&7)
1652 dsp_add(scalarmin_perform, 4, sp[0]->s_vec, &x->x_g,
1653 sp[1]->s_vec, sp[0]->s_n);
1654 else
1655 dsp_add(scalarmin_perf8, 4, sp[0]->s_vec, &x->x_g,
1656 sp[1]->s_vec, sp[0]->s_n);
1659 static void min_setup(void)
1661 min_class = class_new(gensym("min~"), (t_newmethod)min_new, 0,
1662 sizeof(t_min), 0, A_GIMME, 0);
1663 CLASS_MAINSIGNALIN(min_class, t_min, x_f);
1664 class_addmethod(min_class, (t_method)min_dsp, gensym("dsp"), 0);
1665 class_sethelpsymbol(min_class, gensym("sigbinops"));
1666 scalarmin_class = class_new(gensym("min~"), 0, 0,
1667 sizeof(t_scalarmin), 0, 0);
1668 CLASS_MAINSIGNALIN(scalarmin_class, t_scalarmin, x_f);
1669 class_addmethod(scalarmin_class, (t_method)scalarmin_dsp, gensym("dsp"),
1671 class_sethelpsymbol(scalarmin_class, gensym("sigbinops"));
1674 /* ----------------------- global setup routine ---------------- */
1675 void d_arithmetic_setup(void)
1677 plus_setup();
1678 minus_setup();
1679 times_setup();
1680 over_setup();
1681 max_setup();
1682 min_setup();