A modern Music Player Daemon based on Rockbox open source high quality audio player
libadwaita
audio
rust
zig
deno
mpris
rockbox
mpd
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. */
4
5/* arithmetic binops (+, -, *, /).
6If no creation argument is given, there are two signal inlets for vector/vector
7operation; otherwise it's vector/scalar and the second inlet takes a float
8to reset the value.
9*/
10
11#include "m_pd.h"
12
13/* ----------------------------- plus ----------------------------- */
14static t_class *plus_class, *scalarplus_class;
15
16typedef struct _plus
17{
18 t_object x_obj;
19 float x_f;
20} t_plus;
21
22typedef struct _scalarplus
23{
24 t_object x_obj;
25 float x_f;
26 t_float x_g; /* inlet value */
27} t_scalarplus;
28
29static void *plus_new(t_symbol *s, int argc, t_atom *argv)
30{
31#ifdef ROCKBOX
32 (void) s;
33#endif
34 if (argc > 1) post("+~: extra arguments ignored");
35 if (argc)
36 {
37 t_scalarplus *x = (t_scalarplus *)pd_new(scalarplus_class);
38 floatinlet_new(&x->x_obj, &x->x_g);
39 x->x_g = atom_getfloatarg(0, argc, argv);
40 outlet_new(&x->x_obj, &s_signal);
41 x->x_f = 0;
42 return (x);
43 }
44 else
45 {
46 t_plus *x = (t_plus *)pd_new(plus_class);
47 inlet_new(&x->x_obj, &x->x_obj.ob_pd, &s_signal, &s_signal);
48 outlet_new(&x->x_obj, &s_signal);
49 x->x_f = 0;
50 return (x);
51 }
52}
53
54t_int *plus_perform(t_int *w)
55{
56 t_sample *in1 = (t_sample *)(w[1]);
57 t_sample *in2 = (t_sample *)(w[2]);
58 t_sample *out = (t_sample *)(w[3]);
59 int n = (int)(w[4]);
60 while (n--) *out++ = *in1++ + *in2++;
61 return (w+5);
62}
63
64t_int *plus_perf8(t_int *w)
65{
66 t_sample *in1 = (t_sample *)(w[1]);
67 t_sample *in2 = (t_sample *)(w[2]);
68 t_sample *out = (t_sample *)(w[3]);
69 int n = (int)(w[4]);
70 for (; n; n -= 8, in1 += 8, in2 += 8, out += 8)
71 {
72 t_sample f0 = in1[0], f1 = in1[1], f2 = in1[2], f3 = in1[3];
73 t_sample f4 = in1[4], f5 = in1[5], f6 = in1[6], f7 = in1[7];
74
75 t_sample g0 = in2[0], g1 = in2[1], g2 = in2[2], g3 = in2[3];
76 t_sample g4 = in2[4], g5 = in2[5], g6 = in2[6], g7 = in2[7];
77
78 out[0] = f0 + g0; out[1] = f1 + g1; out[2] = f2 + g2; out[3] = f3 + g3;
79 out[4] = f4 + g4; out[5] = f5 + g5; out[6] = f6 + g6; out[7] = f7 + g7;
80 }
81 return (w+5);
82}
83
84t_int *scalarplus_perform(t_int *w)
85{
86 t_sample *in = (t_sample *)(w[1]);
87 t_sample f = ftofix(*(t_float *)(w[2]));
88 t_sample *out = (t_sample *)(w[3]);
89 int n = (int)(w[4]);
90 while (n--) *out++ = *in++ + f;
91 return (w+5);
92}
93
94t_int *scalarplus_perf8(t_int *w)
95{
96 t_sample *in = (t_sample *)(w[1]);
97 t_sample g = ftofix(*(t_float *)(w[2]));
98 t_sample *out = (t_sample *)(w[3]);
99 int n = (int)(w[4]);
100 for (; n; n -= 8, in += 8, out += 8)
101 {
102 t_sample f0 = in[0], f1 = in[1], f2 = in[2], f3 = in[3];
103 t_sample f4 = in[4], f5 = in[5], f6 = in[6], f7 = in[7];
104
105 out[0] = f0 + g; out[1] = f1 + g; out[2] = f2 + g; out[3] = f3 + g;
106 out[4] = f4 + g; out[5] = f5 + g; out[6] = f6 + g; out[7] = f7 + g;
107 }
108 return (w+5);
109}
110
111void dsp_add_plus(t_sample *in1, t_sample *in2, t_sample *out, int n)
112{
113 if (n&7)
114 dsp_add(plus_perform, 4, in1, in2, out, n);
115 else
116 dsp_add(plus_perf8, 4, in1, in2, out, n);
117}
118
119static void plus_dsp(t_plus *x, t_signal **sp)
120{
121#ifdef ROCKBOX
122 (void) x;
123#endif
124 dsp_add_plus(sp[0]->s_vec, sp[1]->s_vec, sp[2]->s_vec, sp[0]->s_n);
125}
126
127static void scalarplus_dsp(t_scalarplus *x, t_signal **sp)
128{
129 if (sp[0]->s_n&7)
130 dsp_add(scalarplus_perform, 4, sp[0]->s_vec, &x->x_g,
131 sp[1]->s_vec, sp[0]->s_n);
132 else
133 dsp_add(scalarplus_perf8, 4, sp[0]->s_vec, &x->x_g,
134 sp[1]->s_vec, sp[0]->s_n);
135}
136
137static void plus_setup(void)
138{
139 plus_class = class_new(gensym("+~"), (t_newmethod)plus_new, 0,
140 sizeof(t_plus), 0, A_GIMME, 0);
141 class_addmethod(plus_class, (t_method)plus_dsp, gensym("dsp"), 0);
142 CLASS_MAINSIGNALIN(plus_class, t_plus, x_f);
143 class_sethelpsymbol(plus_class, gensym("sigbinops"));
144 scalarplus_class = class_new(gensym("+~"), 0, 0,
145 sizeof(t_scalarplus), 0, 0);
146 CLASS_MAINSIGNALIN(scalarplus_class, t_scalarplus, x_f);
147 class_addmethod(scalarplus_class, (t_method)scalarplus_dsp, gensym("dsp"),
148 0);
149 class_sethelpsymbol(scalarplus_class, gensym("sigbinops"));
150}
151
152/* ----------------------------- minus ----------------------------- */
153static t_class *minus_class, *scalarminus_class;
154
155typedef struct _minus
156{
157 t_object x_obj;
158 float x_f;
159} t_minus;
160
161typedef struct _scalarminus
162{
163 t_object x_obj;
164 float x_f;
165 t_float x_g;
166} t_scalarminus;
167
168static void *minus_new(t_symbol *s, int argc, t_atom *argv)
169{
170#ifdef ROCKBOX
171 (void) s;
172#endif
173 if (argc > 1) post("-~: extra arguments ignored");
174 if (argc)
175 {
176 t_scalarminus *x = (t_scalarminus *)pd_new(scalarminus_class);
177 floatinlet_new(&x->x_obj, &x->x_g);
178 x->x_g = atom_getfloatarg(0, argc, argv);
179 outlet_new(&x->x_obj, &s_signal);
180 x->x_f = 0;
181 return (x);
182 }
183 else
184 {
185 t_minus *x = (t_minus *)pd_new(minus_class);
186 inlet_new(&x->x_obj, &x->x_obj.ob_pd, &s_signal, &s_signal);
187 outlet_new(&x->x_obj, &s_signal);
188 x->x_f = 0;
189 return (x);
190 }
191}
192
193t_int *minus_perform(t_int *w)
194{
195 t_sample *in1 = (t_sample *)(w[1]);
196 t_sample *in2 = (t_sample *)(w[2]);
197 t_sample *out = (t_sample *)(w[3]);
198 int n = (int)(w[4]);
199 while (n--) *out++ = *in1++ - *in2++;
200 return (w+5);
201}
202
203t_int *minus_perf8(t_int *w)
204{
205 t_sample *in1 = (t_sample *)(w[1]);
206 t_sample *in2 = (t_sample *)(w[2]);
207 t_sample *out = (t_sample *)(w[3]);
208 int n = (int)(w[4]);
209 for (; n; n -= 8, in1 += 8, in2 += 8, out += 8)
210 {
211 t_sample f0 = in1[0], f1 = in1[1], f2 = in1[2], f3 = in1[3];
212 t_sample f4 = in1[4], f5 = in1[5], f6 = in1[6], f7 = in1[7];
213
214 t_sample g0 = in2[0], g1 = in2[1], g2 = in2[2], g3 = in2[3];
215 t_sample g4 = in2[4], g5 = in2[5], g6 = in2[6], g7 = in2[7];
216
217 out[0] = f0 - g0; out[1] = f1 - g1; out[2] = f2 - g2; out[3] = f3 - g3;
218 out[4] = f4 - g4; out[5] = f5 - g5; out[6] = f6 - g6; out[7] = f7 - g7;
219 }
220 return (w+5);
221}
222
223t_int *scalarminus_perform(t_int *w)
224{
225 t_sample *in = (t_sample *)(w[1]);
226 t_sample f = ftofix(*(t_float *)(w[2]));
227 t_sample *out = (t_sample *)(w[3]);
228 int n = (int)(w[4]);
229 while (n--) *out++ = *in++ - f;
230 return (w+5);
231}
232
233t_int *scalarminus_perf8(t_int *w)
234{
235 t_sample *in = (t_sample *)(w[1]);
236 t_sample g = ftofix(*(t_float *)(w[2]));
237 t_sample *out = (t_sample *)(w[3]);
238 int n = (int)(w[4]);
239 for (; n; n -= 8, in += 8, out += 8)
240 {
241 t_sample f0 = in[0], f1 = in[1], f2 = in[2], f3 = in[3];
242 t_sample f4 = in[4], f5 = in[5], f6 = in[6], f7 = in[7];
243
244 out[0] = f0 - g; out[1] = f1 - g; out[2] = f2 - g; out[3] = f3 - g;
245 out[4] = f4 - g; out[5] = f5 - g; out[6] = f6 - g; out[7] = f7 - g;
246 }
247 return (w+5);
248}
249
250static void minus_dsp(t_minus *x, t_signal **sp)
251{
252#ifdef ROCKBOX
253 (void) x;
254#endif
255 if (sp[0]->s_n&7)
256 dsp_add(minus_perform, 4,
257 sp[0]->s_vec, sp[1]->s_vec, sp[2]->s_vec, sp[0]->s_n);
258 else
259 dsp_add(minus_perf8, 4,
260 sp[0]->s_vec, sp[1]->s_vec, sp[2]->s_vec, sp[0]->s_n);
261}
262
263static void scalarminus_dsp(t_scalarminus *x, t_signal **sp)
264{
265 if (sp[0]->s_n&7)
266 dsp_add(scalarminus_perform, 4, sp[0]->s_vec, &x->x_g,
267 sp[1]->s_vec, sp[0]->s_n);
268 else
269 dsp_add(scalarminus_perf8, 4, sp[0]->s_vec, &x->x_g,
270 sp[1]->s_vec, sp[0]->s_n);
271}
272
273static void minus_setup(void)
274{
275 minus_class = class_new(gensym("-~"), (t_newmethod)minus_new, 0,
276 sizeof(t_minus), 0, A_GIMME, 0);
277 CLASS_MAINSIGNALIN(minus_class, t_minus, x_f);
278 class_addmethod(minus_class, (t_method)minus_dsp, gensym("dsp"), 0);
279 class_sethelpsymbol(minus_class, gensym("sigbinops"));
280 scalarminus_class = class_new(gensym("-~"), 0, 0,
281 sizeof(t_scalarminus), 0, 0);
282 CLASS_MAINSIGNALIN(scalarminus_class, t_scalarminus, x_f);
283 class_addmethod(scalarminus_class, (t_method)scalarminus_dsp, gensym("dsp"),
284 0);
285 class_sethelpsymbol(scalarminus_class, gensym("sigbinops"));
286}
287
288/* ----------------------------- times ----------------------------- */
289
290static t_class *times_class, *scalartimes_class;
291
292typedef struct _times
293{
294 t_object x_obj;
295 float x_f;
296} t_times;
297
298typedef struct _scalartimes
299{
300 t_object x_obj;
301 float x_f;
302 t_float x_g;
303} t_scalartimes;
304
305static void *times_new(t_symbol *s, int argc, t_atom *argv)
306{
307#ifdef ROCKBOX
308 (void) s;
309#endif
310 if (argc > 1) post("*~: extra arguments ignored");
311 if (argc)
312 {
313 t_scalartimes *x = (t_scalartimes *)pd_new(scalartimes_class);
314 floatinlet_new(&x->x_obj, &x->x_g);
315 x->x_g = atom_getfloatarg(0, argc, argv);
316 outlet_new(&x->x_obj, &s_signal);
317 x->x_f = 0;
318 return (x);
319 }
320 else
321 {
322 t_times *x = (t_times *)pd_new(times_class);
323 inlet_new(&x->x_obj, &x->x_obj.ob_pd, &s_signal, &s_signal);
324 outlet_new(&x->x_obj, &s_signal);
325 x->x_f = 0;
326 return (x);
327 }
328}
329
330t_int *times_perform(t_int *w)
331{
332 t_sample *in1 = (t_sample *)(w[1]);
333 t_sample *in2 = (t_sample *)(w[2]);
334 t_sample *out = (t_sample *)(w[3]);
335 int n = (int)(w[4]);
336 while (n--) *out++ = mult(*in1++,*in2++);
337 return (w+5);
338}
339
340t_int *times_perf8(t_int *w)
341{
342 t_sample *in1 = (t_sample *)(w[1]);
343 t_sample *in2 = (t_sample *)(w[2]);
344 t_sample *out = (t_sample *)(w[3]);
345 int n = (int)(w[4]);
346 for (; n; n -= 8, in1 += 8, in2 += 8, out += 8)
347 {
348 t_sample f0 = in1[0], f1 = in1[1], f2 = in1[2], f3 = in1[3];
349 t_sample f4 = in1[4], f5 = in1[5], f6 = in1[6], f7 = in1[7];
350
351 t_sample g0 = in2[0], g1 = in2[1], g2 = in2[2], g3 = in2[3];
352 t_sample g4 = in2[4], g5 = in2[5], g6 = in2[6], g7 = in2[7];
353
354 out[0] = mult(f0,g0); out[1] = mult(f1,g1); out[2] = mult(f2,g2); out[3] = mult(f3,g3);
355 out[4] = mult(f4,g4); out[5] = mult(f5,g5); out[6] = mult(f6,g6); out[7] = mult(f7,g7);
356 }
357 return (w+5);
358}
359
360t_int *scalartimes_perform(t_int *w)
361{
362 t_sample *in = (t_sample *)(w[1]);
363 t_sample f = ftofix(*(t_float *)(w[2]));
364 t_sample *out = (t_sample *)(w[3]);
365 int n = (int)(w[4]);
366 while (n--) *out++ = mult(*in++,f);
367 return (w+5);
368}
369
370t_int *scalartimes_perf8(t_int *w)
371{
372 t_sample *in = (t_sample *)(w[1]);
373 t_sample g = ftofix(*(t_float *)(w[2]));
374 t_sample *out = (t_sample *)(w[3]);
375 int n = (int)(w[4]);
376 for (; n; n -= 8, in += 8, out += 8)
377 {
378 t_sample f0 = in[0], f1 = in[1], f2 = in[2], f3 = in[3];
379 t_sample f4 = in[4], f5 = in[5], f6 = in[6], f7 = in[7];
380
381 out[0] = mult(f0,g); out[1] = mult(f1,g); out[2] = mult(f2,g); out[3] = mult(f3,g);
382 out[4] = mult(f4,g); out[5] = mult(f5,g); out[6] = mult(f6,g); out[7] = mult(f7,g);
383 }
384 return (w+5);
385}
386
387static void times_dsp(t_times *x, t_signal **sp)
388{
389#ifdef ROCKBOX
390 (void) x;
391#endif
392 if (sp[0]->s_n&7)
393 dsp_add(times_perform, 4,
394 sp[0]->s_vec, sp[1]->s_vec, sp[2]->s_vec, sp[0]->s_n);
395 else
396 dsp_add(times_perf8, 4,
397 sp[0]->s_vec, sp[1]->s_vec, sp[2]->s_vec, sp[0]->s_n);
398}
399
400static void scalartimes_dsp(t_scalartimes *x, t_signal **sp)
401{
402 if (sp[0]->s_n&7)
403 dsp_add(scalartimes_perform, 4, sp[0]->s_vec, &x->x_g,
404 sp[1]->s_vec, sp[0]->s_n);
405 else
406 dsp_add(scalartimes_perf8, 4, sp[0]->s_vec, &x->x_g,
407 sp[1]->s_vec, sp[0]->s_n);
408}
409
410static void times_setup(void)
411{
412 times_class = class_new(gensym("*~"), (t_newmethod)times_new, 0,
413 sizeof(t_times), 0, A_GIMME, 0);
414 CLASS_MAINSIGNALIN(times_class, t_times, x_f);
415 class_addmethod(times_class, (t_method)times_dsp, gensym("dsp"), 0);
416 class_sethelpsymbol(times_class, gensym("sigbinops"));
417 scalartimes_class = class_new(gensym("*~"), 0, 0,
418 sizeof(t_scalartimes), 0, 0);
419 CLASS_MAINSIGNALIN(scalartimes_class, t_scalartimes, x_f);
420 class_addmethod(scalartimes_class, (t_method)scalartimes_dsp, gensym("dsp"),
421 0);
422 class_sethelpsymbol(scalartimes_class, gensym("sigbinops"));
423}
424
425/* ----------------------------- over ----------------------------- */
426static t_class *over_class, *scalarover_class;
427
428typedef struct _over
429{
430 t_object x_obj;
431 float x_f;
432} t_over;
433
434typedef struct _scalarover
435{
436 t_object x_obj;
437 float x_f;
438 t_float x_g;
439} t_scalarover;
440
441static void *over_new(t_symbol *s, int argc, t_atom *argv)
442{
443#ifdef ROCKBOX
444 (void) s;
445#endif
446 if (argc > 1) post("/~: extra arguments ignored");
447 if (argc)
448 {
449 t_scalarover *x = (t_scalarover *)pd_new(scalarover_class);
450 floatinlet_new(&x->x_obj, &x->x_g);
451 x->x_g = atom_getfloatarg(0, argc, argv);
452 outlet_new(&x->x_obj, &s_signal);
453 x->x_f = 0;
454 return (x);
455 }
456 else
457 {
458 t_over *x = (t_over *)pd_new(over_class);
459 inlet_new(&x->x_obj, &x->x_obj.ob_pd, &s_signal, &s_signal);
460 outlet_new(&x->x_obj, &s_signal);
461 x->x_f = 0;
462 return (x);
463 }
464}
465
466t_int *over_perform(t_int *w)
467{
468 t_sample *in1 = (t_sample *)(w[1]);
469 t_sample *in2 = (t_sample *)(w[2]);
470 t_sample *out = (t_sample *)(w[3]);
471 int n = (int)(w[4]);
472 while (n--)
473 {
474 float g = *in2++;
475 *out++ = (g ? *in1++ / g : 0);
476 }
477 return (w+5);
478}
479
480t_int *over_perf8(t_int *w)
481{
482 t_sample *in1 = (t_sample *)(w[1]);
483 t_sample *in2 = (t_sample *)(w[2]);
484 t_sample *out = (t_sample *)(w[3]);
485 int n = (int)(w[4]);
486 for (; n; n -= 8, in1 += 8, in2 += 8, out += 8)
487 {
488 t_sample f0 = in1[0], f1 = in1[1], f2 = in1[2], f3 = in1[3];
489 t_sample f4 = in1[4], f5 = in1[5], f6 = in1[6], f7 = in1[7];
490
491 t_sample g0 = in2[0], g1 = in2[1], g2 = in2[2], g3 = in2[3];
492 t_sample g4 = in2[4], g5 = in2[5], g6 = in2[6], g7 = in2[7];
493
494 out[0] = (g0? idiv(f0,g0) : 0);
495 out[1] = (g1? idiv(f1,g1) : 0);
496 out[2] = (g2? idiv(f2,g2) : 0);
497 out[3] = (g3? idiv(f3,g3) : 0);
498 out[4] = (g4? idiv(f4,g4) : 0);
499 out[5] = (g5? idiv(f5,g5) : 0);
500 out[6] = (g6? idiv(f6,g6) : 0);
501 out[7] = (g7? idiv(f7,g7) : 0);
502 }
503 return (w+5);
504}
505
506t_int *scalarover_perform(t_int *w)
507{
508 t_sample *in = (t_sample *)(w[1]);
509 t_sample f = idiv(ftofix(1.),ftofix(*(t_float *)(w[2])));
510 t_sample *out = (t_sample *)(w[3]);
511 int n = (int)(w[4]);
512 while (n--) *out++ = mult(*in++,f);
513 return (w+5);
514}
515
516t_int *scalarover_perf8(t_int *w)
517{
518 t_sample *in = (t_sample *)(w[1]);
519 t_sample g = ftofix(*(t_float *)(w[2]));
520 t_sample *out = (t_sample *)(w[3]);
521 int n = (int)(w[4]);
522 if (g) g = idiv(ftofix(1.f),g);
523 for (; n; n -= 8, in += 8, out += 8)
524 {
525 t_sample f0 = in[0], f1 = in[1], f2 = in[2], f3 = in[3];
526 t_sample f4 = in[4], f5 = in[5], f6 = in[6], f7 = in[7];
527
528 out[0] = mult(f0,g); out[1] = mult(f1,g); out[2] = mult(f2,g); out[3] = mult(f3,g);
529 out[4] = mult(f4,g); out[5] = mult(f5,g); out[6] = mult(f6,g); out[7] = mult(f7,g);
530 }
531 return (w+5);
532}
533
534static void over_dsp(t_over *x, t_signal **sp)
535{
536#ifdef ROCKBOX
537 (void) x;
538#endif
539 if (sp[0]->s_n&7)
540 dsp_add(over_perform, 4,
541 sp[0]->s_vec, sp[1]->s_vec, sp[2]->s_vec, sp[0]->s_n);
542 else
543 dsp_add(over_perf8, 4,
544 sp[0]->s_vec, sp[1]->s_vec, sp[2]->s_vec, sp[0]->s_n);
545}
546
547static void scalarover_dsp(t_scalarover *x, t_signal **sp)
548{
549 if (sp[0]->s_n&7)
550 dsp_add(scalarover_perform, 4, sp[0]->s_vec, &x->x_g,
551 sp[1]->s_vec, sp[0]->s_n);
552 else
553 dsp_add(scalarover_perf8, 4, sp[0]->s_vec, &x->x_g,
554 sp[1]->s_vec, sp[0]->s_n);
555}
556
557static void over_setup(void)
558{
559 over_class = class_new(gensym("/~"), (t_newmethod)over_new, 0,
560 sizeof(t_over), 0, A_GIMME, 0);
561 CLASS_MAINSIGNALIN(over_class, t_over, x_f);
562 class_addmethod(over_class, (t_method)over_dsp, gensym("dsp"), 0);
563 class_sethelpsymbol(over_class, gensym("sigbinops"));
564 scalarover_class = class_new(gensym("/~"), 0, 0,
565 sizeof(t_scalarover), 0, 0);
566 CLASS_MAINSIGNALIN(scalarover_class, t_scalarover, x_f);
567 class_addmethod(scalarover_class, (t_method)scalarover_dsp, gensym("dsp"),
568 0);
569 class_sethelpsymbol(scalarover_class, gensym("sigbinops"));
570}
571
572/* ----------------------------- max ----------------------------- */
573static t_class *max_class, *scalarmax_class;
574
575typedef struct _max
576{
577 t_object x_obj;
578 float x_f;
579} t_max;
580
581typedef struct _scalarmax
582{
583 t_object x_obj;
584 float x_f;
585 t_float x_g;
586} t_scalarmax;
587
588static void *max_new(t_symbol *s, int argc, t_atom *argv)
589{
590#ifdef ROCKBOX
591 (void) s;
592#endif
593 if (argc > 1) post("max~: extra arguments ignored");
594 if (argc)
595 {
596 t_scalarmax *x = (t_scalarmax *)pd_new(scalarmax_class);
597 floatinlet_new(&x->x_obj, &x->x_g);
598 x->x_g = atom_getfloatarg(0, argc, argv);
599 outlet_new(&x->x_obj, &s_signal);
600 x->x_f = 0;
601 return (x);
602 }
603 else
604 {
605 t_max *x = (t_max *)pd_new(max_class);
606 inlet_new(&x->x_obj, &x->x_obj.ob_pd, &s_signal, &s_signal);
607 outlet_new(&x->x_obj, &s_signal);
608 x->x_f = 0;
609 return (x);
610 }
611}
612
613t_int *max_perform(t_int *w)
614{
615 t_sample *in1 = (t_sample *)(w[1]);
616 t_sample *in2 = (t_sample *)(w[2]);
617 t_sample *out = (t_sample *)(w[3]);
618 int n = (int)(w[4]);
619 while (n--)
620 {
621 t_sample f = *in1++, g = *in2++;
622 *out++ = (f > g ? f : g);
623 }
624 return (w+5);
625}
626
627t_int *max_perf8(t_int *w)
628{
629 t_sample *in1 = (t_sample *)(w[1]);
630 t_sample *in2 = (t_sample *)(w[2]);
631 t_sample *out = (t_sample *)(w[3]);
632 int n = (int)(w[4]);
633 for (; n; n -= 8, in1 += 8, in2 += 8, out += 8)
634 {
635 t_sample f0 = in1[0], f1 = in1[1], f2 = in1[2], f3 = in1[3];
636 t_sample f4 = in1[4], f5 = in1[5], f6 = in1[6], f7 = in1[7];
637
638 t_sample g0 = in2[0], g1 = in2[1], g2 = in2[2], g3 = in2[3];
639 t_sample g4 = in2[4], g5 = in2[5], g6 = in2[6], g7 = in2[7];
640
641 out[0] = (f0 > g0 ? f0 : g0); out[1] = (f1 > g1 ? f1 : g1);
642 out[2] = (f2 > g2 ? f2 : g2); out[3] = (f3 > g3 ? f3 : g3);
643 out[4] = (f4 > g4 ? f4 : g4); out[5] = (f5 > g5 ? f5 : g5);
644 out[6] = (f6 > g6 ? f6 : g6); out[7] = (f7 > g7 ? f7 : g7);
645 }
646 return (w+5);
647}
648
649t_int *scalarmax_perform(t_int *w)
650{
651 t_sample *in = (t_sample *)(w[1]);
652 t_sample f = ftofix(*(t_float *)(w[2]));
653 t_sample *out = (t_sample *)(w[3]);
654 int n = (int)(w[4]);
655 while (n--)
656 {
657 t_sample g = *in++;
658 *out++ = (f > g ? f : g);
659 }
660 return (w+5);
661}
662
663t_int *scalarmax_perf8(t_int *w)
664{
665 t_sample *in = (t_sample *)(w[1]);
666 t_sample g = ftofix(*(t_float *)(w[2]));
667 t_sample *out = (t_sample *)(w[3]);
668 int n = (int)(w[4]);
669 for (; n; n -= 8, in += 8, out += 8)
670 {
671 t_sample f0 = in[0], f1 = in[1], f2 = in[2], f3 = in[3];
672 t_sample f4 = in[4], f5 = in[5], f6 = in[6], f7 = in[7];
673
674 out[0] = (f0 > g ? f0 : g); out[1] = (f1 > g ? f1 : g);
675 out[2] = (f2 > g ? f2 : g); out[3] = (f3 > g ? f3 : g);
676 out[4] = (f4 > g ? f4 : g); out[5] = (f5 > g ? f5 : g);
677 out[6] = (f6 > g ? f6 : g); out[7] = (f7 > g ? f7 : g);
678 }
679 return (w+5);
680}
681
682static void max_dsp(t_max *x, t_signal **sp)
683{
684#ifdef ROCKBOX
685 (void) x;
686#endif
687 if (sp[0]->s_n&7)
688 dsp_add(max_perform, 4,
689 sp[0]->s_vec, sp[1]->s_vec, sp[2]->s_vec, sp[0]->s_n);
690 else
691 dsp_add(max_perf8, 4,
692 sp[0]->s_vec, sp[1]->s_vec, sp[2]->s_vec, sp[0]->s_n);
693}
694
695static void scalarmax_dsp(t_scalarmax *x, t_signal **sp)
696{
697 if (sp[0]->s_n&7)
698 dsp_add(scalarmax_perform, 4, sp[0]->s_vec, &x->x_g,
699 sp[1]->s_vec, sp[0]->s_n);
700 else
701 dsp_add(scalarmax_perf8, 4, sp[0]->s_vec, &x->x_g,
702 sp[1]->s_vec, sp[0]->s_n);
703}
704
705static void max_setup(void)
706{
707 max_class = class_new(gensym("max~"), (t_newmethod)max_new, 0,
708 sizeof(t_max), 0, A_GIMME, 0);
709 CLASS_MAINSIGNALIN(max_class, t_max, x_f);
710 class_addmethod(max_class, (t_method)max_dsp, gensym("dsp"), 0);
711 class_sethelpsymbol(max_class, gensym("sigbinops"));
712 scalarmax_class = class_new(gensym("max~"), 0, 0,
713 sizeof(t_scalarmax), 0, 0);
714 CLASS_MAINSIGNALIN(scalarmax_class, t_scalarmax, x_f);
715 class_addmethod(scalarmax_class, (t_method)scalarmax_dsp, gensym("dsp"),
716 0);
717 class_sethelpsymbol(scalarmax_class, gensym("sigbinops"));
718}
719
720/* ----------------------------- min ----------------------------- */
721static t_class *min_class, *scalarmin_class;
722
723typedef struct _min
724{
725 t_object x_obj;
726 float x_f;
727} t_min;
728
729typedef struct _scalarmin
730{
731 t_object x_obj;
732 t_float x_g;
733 float x_f;
734} t_scalarmin;
735
736static void *min_new(t_symbol *s, int argc, t_atom *argv)
737{
738#ifdef ROCKBOX
739 (void) s;
740#endif
741 if (argc > 1) post("min~: extra arguments ignored");
742 if (argc)
743 {
744 t_scalarmin *x = (t_scalarmin *)pd_new(scalarmin_class);
745 floatinlet_new(&x->x_obj, &x->x_g);
746 x->x_g = atom_getfloatarg(0, argc, argv);
747 outlet_new(&x->x_obj, &s_signal);
748 x->x_f = 0;
749 return (x);
750 }
751 else
752 {
753 t_min *x = (t_min *)pd_new(min_class);
754 inlet_new(&x->x_obj, &x->x_obj.ob_pd, &s_signal, &s_signal);
755 outlet_new(&x->x_obj, &s_signal);
756 x->x_f = 0;
757 return (x);
758 }
759}
760
761t_int *min_perform(t_int *w)
762{
763 t_sample *in1 = (t_sample *)(w[1]);
764 t_sample *in2 = (t_sample *)(w[2]);
765 t_sample *out = (t_sample *)(w[3]);
766 int n = (int)(w[4]);
767 while (n--)
768 {
769 t_sample f = *in1++, g = *in2++;
770 *out++ = (f < g ? f : g);
771 }
772 return (w+5);
773}
774
775t_int *min_perf8(t_int *w)
776{
777 t_sample *in1 = (t_sample *)(w[1]);
778 t_sample *in2 = (t_sample *)(w[2]);
779 t_sample *out = (t_sample *)(w[3]);
780 int n = (int)(w[4]);
781 for (; n; n -= 8, in1 += 8, in2 += 8, out += 8)
782 {
783 t_sample f0 = in1[0], f1 = in1[1], f2 = in1[2], f3 = in1[3];
784 t_sample f4 = in1[4], f5 = in1[5], f6 = in1[6], f7 = in1[7];
785
786 t_sample g0 = in2[0], g1 = in2[1], g2 = in2[2], g3 = in2[3];
787 t_sample g4 = in2[4], g5 = in2[5], g6 = in2[6], g7 = in2[7];
788
789 out[0] = (f0 < g0 ? f0 : g0); out[1] = (f1 < g1 ? f1 : g1);
790 out[2] = (f2 < g2 ? f2 : g2); out[3] = (f3 < g3 ? f3 : g3);
791 out[4] = (f4 < g4 ? f4 : g4); out[5] = (f5 < g5 ? f5 : g5);
792 out[6] = (f6 < g6 ? f6 : g6); out[7] = (f7 < g7 ? f7 : g7);
793 }
794 return (w+5);
795}
796
797t_int *scalarmin_perform(t_int *w)
798{
799 t_sample *in = (t_sample *)(w[1]);
800 t_sample f = ftofix(*(t_float *)(w[2]));
801 t_sample *out = (t_sample *)(w[3]);
802 int n = (int)(w[4]);
803 while (n--)
804 {
805 t_sample g = *in++;
806 *out++ = (f < g ? f : g);
807 }
808 return (w+5);
809}
810
811t_int *scalarmin_perf8(t_int *w)
812{
813 t_sample *in = (t_sample *)(w[1]);
814 t_sample g = ftofix(*(t_float *)(w[2]));
815 t_sample *out = (t_sample *)(w[3]);
816 int n = (int)(w[4]);
817 for (; n; n -= 8, in += 8, out += 8)
818 {
819 t_sample f0 = in[0], f1 = in[1], f2 = in[2], f3 = in[3];
820 t_sample f4 = in[4], f5 = in[5], f6 = in[6], f7 = in[7];
821
822 out[0] = (f0 < g ? f0 : g); out[1] = (f1 < g ? f1 : g);
823 out[2] = (f2 < g ? f2 : g); out[3] = (f3 < g ? f3 : g);
824 out[4] = (f4 < g ? f4 : g); out[5] = (f5 < g ? f5 : g);
825 out[6] = (f6 < g ? f6 : g); out[7] = (f7 < g ? f7 : g);
826 }
827 return (w+5);
828}
829
830static void min_dsp(t_min *x, t_signal **sp)
831{
832#ifdef ROCKBOX
833 (void) x;
834#endif
835 if (sp[0]->s_n&7)
836 dsp_add(min_perform, 4,
837 sp[0]->s_vec, sp[1]->s_vec, sp[2]->s_vec, sp[0]->s_n);
838 else
839 dsp_add(min_perf8, 4,
840 sp[0]->s_vec, sp[1]->s_vec, sp[2]->s_vec, sp[0]->s_n);
841}
842
843static void scalarmin_dsp(t_scalarmin *x, t_signal **sp)
844{
845 if (sp[0]->s_n&7)
846 dsp_add(scalarmin_perform, 4, sp[0]->s_vec, &x->x_g,
847 sp[1]->s_vec, sp[0]->s_n);
848 else
849 dsp_add(scalarmin_perf8, 4, sp[0]->s_vec, &x->x_g,
850 sp[1]->s_vec, sp[0]->s_n);
851}
852
853static void min_setup(void)
854{
855 min_class = class_new(gensym("min~"), (t_newmethod)min_new, 0,
856 sizeof(t_min), 0, A_GIMME, 0);
857 CLASS_MAINSIGNALIN(min_class, t_min, x_f);
858 class_addmethod(min_class, (t_method)min_dsp, gensym("dsp"), 0);
859 class_sethelpsymbol(min_class, gensym("sigbinops"));
860 scalarmin_class = class_new(gensym("min~"), 0, 0,
861 sizeof(t_scalarmin), 0, 0);
862 CLASS_MAINSIGNALIN(scalarmin_class, t_scalarmin, x_f);
863 class_addmethod(scalarmin_class, (t_method)scalarmin_dsp, gensym("dsp"),
864 0);
865 class_sethelpsymbol(scalarmin_class, gensym("sigbinops"));
866}
867
868/* ----------------------- global setup routine ---------------- */
869void d_arithmetic_setup(void)
870{
871 plus_setup();
872 minus_setup();
873 times_setup();
874 over_setup();
875 max_setup();
876 min_setup();
877}
878