summaryrefslogtreecommitdiff
path: root/apps/plugins/pdbox/PDa/src/d_array.c
diff options
context:
space:
mode:
Diffstat (limited to 'apps/plugins/pdbox/PDa/src/d_array.c')
-rw-r--r--apps/plugins/pdbox/PDa/src/d_array.c1074
1 files changed, 0 insertions, 1074 deletions
diff --git a/apps/plugins/pdbox/PDa/src/d_array.c b/apps/plugins/pdbox/PDa/src/d_array.c
deleted file mode 100644
index 7139e4dc3d..0000000000
--- a/apps/plugins/pdbox/PDa/src/d_array.c
+++ /dev/null
@@ -1,1074 +0,0 @@
1/* Copyright (c) 1997-1999 Miller Puckette and others.
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/* sampling */
6
7/* LATER make tabread4 and tabread~ */
8
9#include "m_pd.h"
10
11
12/* ------------------------- tabwrite~ -------------------------- */
13
14static t_class *tabwrite_tilde_class;
15
16typedef struct _tabwrite_tilde
17{
18 t_object x_obj;
19 int x_phase;
20 int x_nsampsintab;
21 float *x_vec;
22 t_symbol *x_arrayname;
23 t_clock *x_clock;
24 float x_f;
25} t_tabwrite_tilde;
26
27static void tabwrite_tilde_tick(t_tabwrite_tilde *x);
28
29static void *tabwrite_tilde_new(t_symbol *s)
30{
31 t_tabwrite_tilde *x = (t_tabwrite_tilde *)pd_new(tabwrite_tilde_class);
32 x->x_clock = clock_new(x, (t_method)tabwrite_tilde_tick);
33 x->x_phase = 0x7fffffff;
34 x->x_arrayname = s;
35 x->x_f = 0;
36 return (x);
37}
38
39static t_int *tabwrite_tilde_perform(t_int *w)
40{
41 t_tabwrite_tilde *x = (t_tabwrite_tilde *)(w[1]);
42 t_float *in = (t_float *)(w[2]);
43 int n = (int)(w[3]), phase = x->x_phase, endphase = x->x_nsampsintab;
44 if (!x->x_vec) goto bad;
45
46 if (endphase > phase)
47 {
48 int nxfer = endphase - phase;
49 float *fp = x->x_vec + phase;
50 if (nxfer > n) nxfer = n;
51 phase += nxfer;
52 while (nxfer--)
53 {
54 float f = *in++;
55 if (PD_BIGORSMALL(f))
56 f = 0;
57 *fp++ = f;
58 }
59 if (phase >= endphase)
60 {
61 clock_delay(x->x_clock, 0);
62 phase = 0x7fffffff;
63 }
64 x->x_phase = phase;
65 }
66bad:
67 return (w+4);
68}
69
70void tabwrite_tilde_set(t_tabwrite_tilde *x, t_symbol *s)
71{
72 t_garray *a;
73
74 x->x_arrayname = s;
75 if (!(a = (t_garray *)pd_findbyclass(x->x_arrayname, garray_class)))
76 {
77 if (*s->s_name) pd_error(x, "tabwrite~: %s: no such array",
78 x->x_arrayname->s_name);
79 x->x_vec = 0;
80 }
81 else if (!garray_getfloatarray(a, &x->x_nsampsintab, &x->x_vec))
82 {
83 pd_error(x, "%s: bad template for tabwrite~", x->x_arrayname->s_name);
84 x->x_vec = 0;
85 }
86 else garray_usedindsp(a);
87}
88
89static void tabwrite_tilde_dsp(t_tabwrite_tilde *x, t_signal **sp)
90{
91 tabwrite_tilde_set(x, x->x_arrayname);
92 dsp_add(tabwrite_tilde_perform, 3, x, sp[0]->s_vec, sp[0]->s_n);
93}
94
95static void tabwrite_tilde_bang(t_tabwrite_tilde *x)
96{
97 x->x_phase = 0;
98}
99
100static void tabwrite_tilde_stop(t_tabwrite_tilde *x)
101{
102 if (x->x_phase != 0x7fffffff)
103 {
104 tabwrite_tilde_tick(x);
105 x->x_phase = 0x7fffffff;
106 }
107}
108
109static void tabwrite_tilde_tick(t_tabwrite_tilde *x)
110{
111 t_garray *a = (t_garray *)pd_findbyclass(x->x_arrayname, garray_class);
112 if (!a) bug("tabwrite_tilde_tick");
113 else garray_redraw(a);
114}
115
116static void tabwrite_tilde_free(t_tabwrite_tilde *x)
117{
118 clock_free(x->x_clock);
119}
120
121static void tabwrite_tilde_setup(void)
122{
123 tabwrite_tilde_class = class_new(gensym("tabwrite~"),
124 (t_newmethod)tabwrite_tilde_new, (t_method)tabwrite_tilde_free,
125 sizeof(t_tabwrite_tilde), 0, A_DEFSYM, 0);
126 CLASS_MAINSIGNALIN(tabwrite_tilde_class, t_tabwrite_tilde, x_f);
127 class_addmethod(tabwrite_tilde_class, (t_method)tabwrite_tilde_dsp,
128 gensym("dsp"), 0);
129 class_addmethod(tabwrite_tilde_class, (t_method)tabwrite_tilde_set,
130 gensym("set"), A_SYMBOL, 0);
131 class_addmethod(tabwrite_tilde_class, (t_method)tabwrite_tilde_stop,
132 gensym("stop"), 0);
133 class_addbang(tabwrite_tilde_class, tabwrite_tilde_bang);
134}
135
136/* ------------ tabplay~ - non-transposing sample playback --------------- */
137
138static t_class *tabplay_tilde_class;
139
140typedef struct _tabplay_tilde
141{
142 t_object x_obj;
143 t_outlet *x_bangout;
144 int x_phase;
145 int x_nsampsintab;
146 int x_limit;
147 float *x_vec;
148 t_symbol *x_arrayname;
149 t_clock *x_clock;
150} t_tabplay_tilde;
151
152static void tabplay_tilde_tick(t_tabplay_tilde *x);
153
154static void *tabplay_tilde_new(t_symbol *s)
155{
156 t_tabplay_tilde *x = (t_tabplay_tilde *)pd_new(tabplay_tilde_class);
157 x->x_clock = clock_new(x, (t_method)tabplay_tilde_tick);
158 x->x_phase = 0x7fffffff;
159 x->x_limit = 0;
160 x->x_arrayname = s;
161 outlet_new(&x->x_obj, &s_signal);
162 x->x_bangout = outlet_new(&x->x_obj, &s_bang);
163 return (x);
164}
165
166static t_int *tabplay_tilde_perform(t_int *w)
167{
168 t_tabplay_tilde *x = (t_tabplay_tilde *)(w[1]);
169 t_float *out = (t_float *)(w[2]), *fp;
170 int n = (int)(w[3]), phase = x->x_phase,
171 endphase = (x->x_nsampsintab < x->x_limit ?
172 x->x_nsampsintab : x->x_limit), nxfer, n3;
173 if (!x->x_vec || phase >= endphase)
174 goto zero;
175
176 nxfer = endphase - phase;
177 fp = x->x_vec + phase;
178 if (nxfer > n)
179 nxfer = n;
180 n3 = n - nxfer;
181 phase += nxfer;
182 while (nxfer--)
183 *out++ = *fp++;
184 if (phase >= endphase)
185 {
186 clock_delay(x->x_clock, 0);
187 x->x_phase = 0x7fffffff;
188 while (n3--)
189 *out++ = 0;
190 }
191 else x->x_phase = phase;
192
193 return (w+4);
194zero:
195 while (n--) *out++ = 0;
196 return (w+4);
197}
198
199void tabplay_tilde_set(t_tabplay_tilde *x, t_symbol *s)
200{
201 t_garray *a;
202
203 x->x_arrayname = s;
204 if (!(a = (t_garray *)pd_findbyclass(x->x_arrayname, garray_class)))
205 {
206 if (*s->s_name) pd_error(x, "tabplay~: %s: no such array",
207 x->x_arrayname->s_name);
208 x->x_vec = 0;
209 }
210 else if (!garray_getfloatarray(a, &x->x_nsampsintab, &x->x_vec))
211 {
212 pd_error(x, "%s: bad template for tabplay~", x->x_arrayname->s_name);
213 x->x_vec = 0;
214 }
215 else garray_usedindsp(a);
216}
217
218static void tabplay_tilde_dsp(t_tabplay_tilde *x, t_signal **sp)
219{
220 tabplay_tilde_set(x, x->x_arrayname);
221 dsp_add(tabplay_tilde_perform, 3, x, sp[0]->s_vec, sp[0]->s_n);
222}
223
224static void tabplay_tilde_list(t_tabplay_tilde *x, t_symbol *s,
225 int argc, t_atom *argv)
226{
227 long start = atom_getfloatarg(0, argc, argv);
228 long length = atom_getfloatarg(1, argc, argv);
229 if (start < 0) start = 0;
230 if (length <= 0)
231 x->x_limit = 0x7fffffff;
232 else
233 x->x_limit = start + length;
234 x->x_phase = start;
235}
236
237static void tabplay_tilde_stop(t_tabplay_tilde *x)
238{
239 x->x_phase = 0x7fffffff;
240}
241
242static void tabplay_tilde_tick(t_tabplay_tilde *x)
243{
244 outlet_bang(x->x_bangout);
245}
246
247static void tabplay_tilde_free(t_tabplay_tilde *x)
248{
249 clock_free(x->x_clock);
250}
251
252static void tabplay_tilde_setup(void)
253{
254 tabplay_tilde_class = class_new(gensym("tabplay~"),
255 (t_newmethod)tabplay_tilde_new, (t_method)tabplay_tilde_free,
256 sizeof(t_tabplay_tilde), 0, A_DEFSYM, 0);
257 class_addmethod(tabplay_tilde_class, (t_method)tabplay_tilde_dsp,
258 gensym("dsp"), 0);
259 class_addmethod(tabplay_tilde_class, (t_method)tabplay_tilde_stop,
260 gensym("stop"), 0);
261 class_addmethod(tabplay_tilde_class, (t_method)tabplay_tilde_set,
262 gensym("set"), A_DEFSYM, 0);
263 class_addlist(tabplay_tilde_class, tabplay_tilde_list);
264}
265
266/******************** tabread~ ***********************/
267
268static t_class *tabread_tilde_class;
269
270typedef struct _tabread_tilde
271{
272 t_object x_obj;
273 int x_npoints;
274 float *x_vec;
275 t_symbol *x_arrayname;
276 float x_f;
277} t_tabread_tilde;
278
279static void *tabread_tilde_new(t_symbol *s)
280{
281 t_tabread_tilde *x = (t_tabread_tilde *)pd_new(tabread_tilde_class);
282 x->x_arrayname = s;
283 x->x_vec = 0;
284 outlet_new(&x->x_obj, gensym("signal"));
285 x->x_f = 0;
286 return (x);
287}
288
289static t_int *tabread_tilde_perform(t_int *w)
290{
291 t_tabread_tilde *x = (t_tabread_tilde *)(w[1]);
292 t_float *in = (t_float *)(w[2]);
293 t_float *out = (t_float *)(w[3]);
294 int n = (int)(w[4]);
295 int maxindex;
296 float *buf = x->x_vec, *fp;
297 int i;
298
299 maxindex = x->x_npoints - 1;
300 if (!buf) goto zero;
301
302 for (i = 0; i < n; i++)
303 {
304 int index = *in++;
305 if (index < 0)
306 index = 0;
307 else if (index > maxindex)
308 index = maxindex;
309 *out++ = buf[index];
310 }
311 return (w+5);
312 zero:
313 while (n--) *out++ = 0;
314
315 return (w+5);
316}
317
318void tabread_tilde_set(t_tabread_tilde *x, t_symbol *s)
319{
320 t_garray *a;
321
322 x->x_arrayname = s;
323 if (!(a = (t_garray *)pd_findbyclass(x->x_arrayname, garray_class)))
324 {
325 if (*s->s_name)
326 pd_error(x, "tabread~: %s: no such array", x->x_arrayname->s_name);
327 x->x_vec = 0;
328 }
329 else if (!garray_getfloatarray(a, &x->x_npoints, &x->x_vec))
330 {
331 pd_error(x, "%s: bad template for tabread~", x->x_arrayname->s_name);
332 x->x_vec = 0;
333 }
334 else garray_usedindsp(a);
335}
336
337static void tabread_tilde_dsp(t_tabread_tilde *x, t_signal **sp)
338{
339 tabread_tilde_set(x, x->x_arrayname);
340
341 dsp_add(tabread_tilde_perform, 4, x,
342 sp[0]->s_vec, sp[1]->s_vec, sp[0]->s_n);
343
344}
345
346static void tabread_tilde_free(t_tabread_tilde *x)
347{
348}
349
350static void tabread_tilde_setup(void)
351{
352 tabread_tilde_class = class_new(gensym("tabread~"),
353 (t_newmethod)tabread_tilde_new, (t_method)tabread_tilde_free,
354 sizeof(t_tabread_tilde), 0, A_DEFSYM, 0);
355 CLASS_MAINSIGNALIN(tabread_tilde_class, t_tabread_tilde, x_f);
356 class_addmethod(tabread_tilde_class, (t_method)tabread_tilde_dsp,
357 gensym("dsp"), 0);
358 class_addmethod(tabread_tilde_class, (t_method)tabread_tilde_set,
359 gensym("set"), A_SYMBOL, 0);
360}
361
362/******************** tabread4~ ***********************/
363
364static t_class *tabread4_tilde_class;
365
366typedef struct _tabread4_tilde
367{
368 t_object x_obj;
369 int x_npoints;
370 float *x_vec;
371 t_symbol *x_arrayname;
372 float x_f;
373} t_tabread4_tilde;
374
375static void *tabread4_tilde_new(t_symbol *s)
376{
377 t_tabread4_tilde *x = (t_tabread4_tilde *)pd_new(tabread4_tilde_class);
378 x->x_arrayname = s;
379 x->x_vec = 0;
380 outlet_new(&x->x_obj, gensym("signal"));
381 x->x_f = 0;
382 return (x);
383}
384
385static t_int *tabread4_tilde_perform(t_int *w)
386{
387 t_tabread4_tilde *x = (t_tabread4_tilde *)(w[1]);
388 t_float *in = (t_float *)(w[2]);
389 t_float *out = (t_float *)(w[3]);
390 int n = (int)(w[4]);
391 int maxindex;
392 float *buf = x->x_vec, *fp;
393 int i;
394
395 maxindex = x->x_npoints - 3;
396
397 if (!buf) goto zero;
398
399#if 0 /* test for spam -- I'm not ready to deal with this */
400 for (i = 0, xmax = 0, xmin = maxindex, fp = in1; i < n; i++, fp++)
401 {
402 float f = *in1;
403 if (f < xmin) xmin = f;
404 else if (f > xmax) xmax = f;
405 }
406 if (xmax < xmin + x->c_maxextent) xmax = xmin + x->c_maxextent;
407 for (i = 0, splitlo = xmin+ x->c_maxextent, splithi = xmax - x->c_maxextent,
408 fp = in1; i < n; i++, fp++)
409 {
410 float f = *in1;
411 if (f > splitlo && f < splithi) goto zero;
412 }
413#endif
414
415 for (i = 0; i < n; i++)
416 {
417 float findex = *in++;
418 int index = findex;
419 float frac, a, b, c, d, cminusb;
420 static int count;
421 if (index < 1)
422 index = 1, frac = 0;
423 else if (index > maxindex)
424 index = maxindex, frac = 1;
425 else frac = findex - index;
426 fp = buf + index;
427 a = fp[-1];
428 b = fp[0];
429 c = fp[1];
430 d = fp[2];
431 /* if (!i && !(count++ & 1023))
432 post("fp = %lx, shit = %lx, b = %f", fp, buf->b_shit, b); */
433 cminusb = c-b;
434 *out++ = b + frac * (
435 cminusb - 0.1666667f * (1.-frac) * (
436 (d - a - 3.0f * cminusb) * frac + (d + 2.0f*a - 3.0f*b)
437 )
438 );
439 }
440 return (w+5);
441 zero:
442 while (n--) *out++ = 0;
443
444 return (w+5);
445}
446
447void tabread4_tilde_set(t_tabread4_tilde *x, t_symbol *s)
448{
449 t_garray *a;
450
451 x->x_arrayname = s;
452 if (!(a = (t_garray *)pd_findbyclass(x->x_arrayname, garray_class)))
453 {
454 if (*s->s_name)
455 pd_error(x, "tabread4~: %s: no such array", x->x_arrayname->s_name);
456 x->x_vec = 0;
457 }
458 else if (!garray_getfloatarray(a, &x->x_npoints, &x->x_vec))
459 {
460 pd_error(x, "%s: bad template for tabread4~", x->x_arrayname->s_name);
461 x->x_vec = 0;
462 }
463 else garray_usedindsp(a);
464}
465
466static void tabread4_tilde_dsp(t_tabread4_tilde *x, t_signal **sp)
467{
468 tabread4_tilde_set(x, x->x_arrayname);
469
470 dsp_add(tabread4_tilde_perform, 4, x,
471 sp[0]->s_vec, sp[1]->s_vec, sp[0]->s_n);
472
473}
474
475static void tabread4_tilde_free(t_tabread4_tilde *x)
476{
477}
478
479static void tabread4_tilde_setup(void)
480{
481 tabread4_tilde_class = class_new(gensym("tabread4~"),
482 (t_newmethod)tabread4_tilde_new, (t_method)tabread4_tilde_free,
483 sizeof(t_tabread4_tilde), 0, A_DEFSYM, 0);
484 CLASS_MAINSIGNALIN(tabread4_tilde_class, t_tabread4_tilde, x_f);
485 class_addmethod(tabread4_tilde_class, (t_method)tabread4_tilde_dsp,
486 gensym("dsp"), 0);
487 class_addmethod(tabread4_tilde_class, (t_method)tabread4_tilde_set,
488 gensym("set"), A_SYMBOL, 0);
489}
490
491/******************** tabosc4~ ***********************/
492
493/* this is all copied from d_osc.c... what include file could this go in? */
494#define UNITBIT32 1572864. /* 3*2^19; bit 32 has place value 1 */
495
496 /* machine-dependent definitions. These ifdefs really
497 should have been by CPU type and not by operating system! */
498#ifdef IRIX
499 /* big-endian. Most significant byte is at low address in memory */
500#define HIOFFSET 0 /* word offset to find MSB */
501#define LOWOFFSET 1 /* word offset to find LSB */
502#define int32 long /* a data type that has 32 bits */
503#else
504#ifdef MSW
505 /* little-endian; most significant byte is at highest address */
506#define HIOFFSET 1
507#define LOWOFFSET 0
508#define int32 long
509#else
510#ifdef __FreeBSD__
511#include <machine/endian.h>
512#if BYTE_ORDER == LITTLE_ENDIAN
513#define HIOFFSET 1
514#define LOWOFFSET 0
515#else
516#define HIOFFSET 0 /* word offset to find MSB */
517#define LOWOFFSET 1 /* word offset to find LSB */
518#endif /* BYTE_ORDER */
519#include <sys/types.h>
520#define int32 int32_t
521#endif
522
523#ifdef __linux__
524#include <endian.h>
525#if !defined(__BYTE_ORDER) || !defined(__LITTLE_ENDIAN)
526#error No byte order defined
527#endif
528
529#if __BYTE_ORDER == __LITTLE_ENDIAN
530#define HIOFFSET 1
531#define LOWOFFSET 0
532#else
533#define HIOFFSET 0 /* word offset to find MSB */
534#define LOWOFFSET 1 /* word offset to find LSB */
535#endif /* __BYTE_ORDER */
536
537#include <sys/types.h>
538#define int32 int32_t
539
540#else
541#ifdef MACOSX
542#define HIOFFSET 0 /* word offset to find MSB */
543#define LOWOFFSET 1 /* word offset to find LSB */
544#define int32 int /* a data type that has 32 bits */
545
546#endif /* MACOSX */
547#endif /* __linux__ */
548#endif /* MSW */
549#endif /* SGI */
550
551union tabfudge
552{
553 double tf_d;
554 int32 tf_i[2];
555};
556
557static t_class *tabosc4_tilde_class;
558
559typedef struct _tabosc4_tilde
560{
561 t_object x_obj;
562 float x_fnpoints;
563 float x_finvnpoints;
564 float *x_vec;
565 t_symbol *x_arrayname;
566 float x_f;
567 double x_phase;
568 float x_conv;
569} t_tabosc4_tilde;
570
571static void *tabosc4_tilde_new(t_symbol *s)
572{
573 t_tabosc4_tilde *x = (t_tabosc4_tilde *)pd_new(tabosc4_tilde_class);
574 x->x_arrayname = s;
575 x->x_vec = 0;
576 x->x_fnpoints = 512.;
577 x->x_finvnpoints = (1./512.);
578 outlet_new(&x->x_obj, gensym("signal"));
579 inlet_new(&x->x_obj, &x->x_obj.ob_pd, &s_float, gensym("ft1"));
580 x->x_f = 0;
581 return (x);
582}
583
584static t_int *tabosc4_tilde_perform(t_int *w)
585{
586 t_tabosc4_tilde *x = (t_tabosc4_tilde *)(w[1]);
587 t_float *in = (t_float *)(w[2]);
588 t_float *out = (t_float *)(w[3]);
589 int n = (int)(w[4]);
590 int normhipart;
591 union tabfudge tf;
592 float fnpoints = x->x_fnpoints;
593 int mask = fnpoints - 1;
594 float conv = fnpoints * x->x_conv;
595 int maxindex;
596 float *tab = x->x_vec, *addr;
597 int i;
598 double dphase = fnpoints * x->x_phase + UNITBIT32;
599
600 if (!tab) goto zero;
601 tf.tf_d = UNITBIT32;
602 normhipart = tf.tf_i[HIOFFSET];
603
604#if 1
605 while (n--)
606 {
607 float frac, a, b, c, d, cminusb;
608 tf.tf_d = dphase;
609 dphase += *in++ * conv;
610 addr = tab + (tf.tf_i[HIOFFSET] & mask);
611 tf.tf_i[HIOFFSET] = normhipart;
612 frac = tf.tf_d - UNITBIT32;
613 a = addr[0];
614 b = addr[1];
615 c = addr[2];
616 d = addr[3];
617 cminusb = c-b;
618 *out++ = b + frac * (
619 cminusb - 0.1666667f * (1.-frac) * (
620 (d - a - 3.0f * cminusb) * frac + (d + 2.0f*a - 3.0f*b)
621 )
622 );
623 }
624#endif
625
626 tf.tf_d = UNITBIT32 * fnpoints;
627 normhipart = tf.tf_i[HIOFFSET];
628 tf.tf_d = dphase + (UNITBIT32 * fnpoints - UNITBIT32);
629 tf.tf_i[HIOFFSET] = normhipart;
630 x->x_phase = (tf.tf_d - UNITBIT32 * fnpoints) * x->x_finvnpoints;
631 return (w+5);
632 zero:
633 while (n--) *out++ = 0;
634
635 return (w+5);
636}
637
638void tabosc4_tilde_set(t_tabosc4_tilde *x, t_symbol *s)
639{
640 t_garray *a;
641 int npoints, pointsinarray;
642
643 x->x_arrayname = s;
644 if (!(a = (t_garray *)pd_findbyclass(x->x_arrayname, garray_class)))
645 {
646 if (*s->s_name)
647 pd_error(x, "tabosc4~: %s: no such array", x->x_arrayname->s_name);
648 x->x_vec = 0;
649 }
650 else if (!garray_getfloatarray(a, &pointsinarray, &x->x_vec))
651 {
652 pd_error(x, "%s: bad template for tabosc4~", x->x_arrayname->s_name);
653 x->x_vec = 0;
654 }
655 else if ((npoints = pointsinarray - 3) != (1 << ilog2(pointsinarray - 3)))
656 {
657 pd_error(x, "%s: number of points (%d) not a power of 2 plus three",
658 x->x_arrayname->s_name, pointsinarray);
659 x->x_vec = 0;
660 garray_usedindsp(a);
661 }
662 else
663 {
664 x->x_fnpoints = npoints;
665 x->x_finvnpoints = 1./npoints;
666 garray_usedindsp(a);
667 }
668}
669
670static void tabosc4_tilde_ft1(t_tabosc4_tilde *x, t_float f)
671{
672 x->x_phase = f;
673}
674
675static void tabosc4_tilde_dsp(t_tabosc4_tilde *x, t_signal **sp)
676{
677 x->x_conv = 1. / sp[0]->s_sr;
678 tabosc4_tilde_set(x, x->x_arrayname);
679
680 dsp_add(tabosc4_tilde_perform, 4, x,
681 sp[0]->s_vec, sp[1]->s_vec, sp[0]->s_n);
682}
683
684static void tabosc4_tilde_setup(void)
685{
686 tabosc4_tilde_class = class_new(gensym("tabosc4~"),
687 (t_newmethod)tabosc4_tilde_new, 0,
688 sizeof(t_tabosc4_tilde), 0, A_DEFSYM, 0);
689 CLASS_MAINSIGNALIN(tabosc4_tilde_class, t_tabosc4_tilde, x_f);
690 class_addmethod(tabosc4_tilde_class, (t_method)tabosc4_tilde_dsp,
691 gensym("dsp"), 0);
692 class_addmethod(tabosc4_tilde_class, (t_method)tabosc4_tilde_set,
693 gensym("set"), A_SYMBOL, 0);
694 class_addmethod(tabosc4_tilde_class, (t_method)tabosc4_tilde_ft1,
695 gensym("ft1"), A_FLOAT, 0);
696}
697
698/* ------------------------ tabsend~ ------------------------- */
699
700static t_class *tabsend_class;
701
702typedef struct _tabsend
703{
704 t_object x_obj;
705 float *x_vec;
706 int x_graphperiod;
707 int x_graphcount;
708 t_symbol *x_arrayname;
709 t_clock *x_clock;
710 float x_f;
711} t_tabsend;
712
713static void tabsend_tick(t_tabsend *x);
714
715static void *tabsend_new(t_symbol *s)
716{
717 t_tabsend *x = (t_tabsend *)pd_new(tabsend_class);
718 x->x_graphcount = 0;
719 x->x_arrayname = s;
720 x->x_clock = clock_new(x, (t_method)tabsend_tick);
721 x->x_f = 0;
722 return (x);
723}
724
725static t_int *tabsend_perform(t_int *w)
726{
727 t_tabsend *x = (t_tabsend *)(w[1]);
728 t_float *in = (t_float *)(w[2]);
729 int n = w[3];
730 t_float *dest = x->x_vec;
731 int i = x->x_graphcount;
732 if (!x->x_vec) goto bad;
733
734 while (n--)
735 {
736 float f = *in++;
737 if (PD_BIGORSMALL(f))
738 f = 0;
739 *dest++ = f;
740 }
741 if (!i--)
742 {
743 clock_delay(x->x_clock, 0);
744 i = x->x_graphperiod;
745 }
746 x->x_graphcount = i;
747bad:
748 return (w+4);
749}
750
751static void tabsend_dsp(t_tabsend *x, t_signal **sp)
752{
753 int i, vecsize;
754 t_garray *a;
755
756 if (!(a = (t_garray *)pd_findbyclass(x->x_arrayname, garray_class)))
757 {
758 if (*x->x_arrayname->s_name)
759 pd_error(x, "tabsend~: %s: no such array", x->x_arrayname->s_name);
760 }
761 else if (!garray_getfloatarray(a, &vecsize, &x->x_vec))
762 pd_error(x, "%s: bad template for tabsend~", x->x_arrayname->s_name);
763 else
764 {
765 int n = sp[0]->s_n;
766 int ticksper = sp[0]->s_sr/n;
767 if (ticksper < 1) ticksper = 1;
768 x->x_graphperiod = ticksper;
769 if (x->x_graphcount > ticksper) x->x_graphcount = ticksper;
770 if (n < vecsize) vecsize = n;
771 garray_usedindsp(a);
772 dsp_add(tabsend_perform, 3, x, sp[0]->s_vec, vecsize);
773 }
774}
775
776static void tabsend_tick(t_tabsend *x)
777{
778 t_garray *a = (t_garray *)pd_findbyclass(x->x_arrayname, garray_class);
779 if (!a) bug("tabsend_tick");
780 else garray_redraw(a);
781}
782
783static void tabsend_free(t_tabsend *x)
784{
785 clock_free(x->x_clock);
786}
787
788static void tabsend_setup(void)
789{
790 tabsend_class = class_new(gensym("tabsend~"), (t_newmethod)tabsend_new,
791 (t_method)tabsend_free, sizeof(t_tabsend), 0, A_DEFSYM, 0);
792 CLASS_MAINSIGNALIN(tabsend_class, t_tabsend, x_f);
793 class_addmethod(tabsend_class, (t_method)tabsend_dsp, gensym("dsp"), 0);
794}
795
796/* ------------------------ tabreceive~ ------------------------- */
797
798static t_class *tabreceive_class;
799
800typedef struct _tabreceive
801{
802 t_object x_obj;
803 float *x_vec;
804 t_symbol *x_arrayname;
805} t_tabreceive;
806
807static t_int *tabreceive_perform(t_int *w)
808{
809 t_tabreceive *x = (t_tabreceive *)(w[1]);
810 t_float *out = (t_float *)(w[2]);
811 int n = w[3];
812 t_float *from = x->x_vec;
813 if (from) while (n--) *out++ = *from++;
814 else while (n--) *out++ = 0;
815 return (w+4);
816}
817
818static void tabreceive_dsp(t_tabreceive *x, t_signal **sp)
819{
820 t_garray *a;
821 int vecsize;
822
823 if (!(a = (t_garray *)pd_findbyclass(x->x_arrayname, garray_class)))
824 {
825 if (*x->x_arrayname->s_name)
826 pd_error(x, "tabsend~: %s: no such array", x->x_arrayname->s_name);
827 }
828 else if (!garray_getfloatarray(a, &vecsize, &x->x_vec))
829 pd_error(x, "%s: bad template for tabreceive~", x->x_arrayname->s_name);
830 else
831 {
832 int n = sp[0]->s_n;
833 if (n < vecsize) vecsize = n;
834 garray_usedindsp(a);
835 dsp_add(tabreceive_perform, 3, x, sp[0]->s_vec, vecsize);
836 }
837}
838
839static void *tabreceive_new(t_symbol *s)
840{
841 t_tabreceive *x = (t_tabreceive *)pd_new(tabreceive_class);
842 x->x_arrayname = s;
843 outlet_new(&x->x_obj, &s_signal);
844 return (x);
845}
846
847static void tabreceive_setup(void)
848{
849 tabreceive_class = class_new(gensym("tabreceive~"),
850 (t_newmethod)tabreceive_new, 0,
851 sizeof(t_tabreceive), 0, A_DEFSYM, 0);
852 class_addmethod(tabreceive_class, (t_method)tabreceive_dsp,
853 gensym("dsp"), 0);
854}
855
856
857/* ---------- tabread: control, non-interpolating ------------------------ */
858
859static t_class *tabread_class;
860
861typedef struct _tabread
862{
863 t_object x_obj;
864 t_symbol *x_arrayname;
865} t_tabread;
866
867static void tabread_float(t_tabread *x, t_float f)
868{
869 t_garray *a;
870 int npoints;
871 t_float *vec;
872
873 if (!(a = (t_garray *)pd_findbyclass(x->x_arrayname, garray_class)))
874 pd_error(x, "%s: no such array", x->x_arrayname->s_name);
875 else if (!garray_getfloatarray(a, &npoints, &vec))
876 pd_error(x, "%s: bad template for tabread", x->x_arrayname->s_name);
877 else
878 {
879 int n = f;
880 if (n < 0) n = 0;
881 else if (n >= npoints) n = npoints - 1;
882 outlet_float(x->x_obj.ob_outlet, (npoints ? vec[n] : 0));
883 }
884}
885
886static void tabread_set(t_tabread *x, t_symbol *s)
887{
888 x->x_arrayname = s;
889}
890
891static void *tabread_new(t_symbol *s)
892{
893 t_tabread *x = (t_tabread *)pd_new(tabread_class);
894 x->x_arrayname = s;
895 outlet_new(&x->x_obj, &s_float);
896 return (x);
897}
898
899static void tabread_setup(void)
900{
901 tabread_class = class_new(gensym("tabread"), (t_newmethod)tabread_new,
902 0, sizeof(t_tabread), 0, A_DEFSYM, 0);
903 class_addfloat(tabread_class, (t_method)tabread_float);
904 class_addmethod(tabread_class, (t_method)tabread_set, gensym("set"),
905 A_SYMBOL, 0);
906}
907
908/* ---------- tabread4: control, non-interpolating ------------------------ */
909
910static t_class *tabread4_class;
911
912typedef struct _tabread4
913{
914 t_object x_obj;
915 t_symbol *x_arrayname;
916} t_tabread4;
917
918static void tabread4_float(t_tabread4 *x, t_float f)
919{
920 t_garray *a;
921 int npoints;
922 t_float *vec;
923
924 if (!(a = (t_garray *)pd_findbyclass(x->x_arrayname, garray_class)))
925 pd_error(x, "%s: no such array", x->x_arrayname->s_name);
926 else if (!garray_getfloatarray(a, &npoints, &vec))
927 pd_error(x, "%s: bad template for tabread4", x->x_arrayname->s_name);
928 else if (npoints < 4)
929 outlet_float(x->x_obj.ob_outlet, 0);
930 else if (f <= 1)
931 outlet_float(x->x_obj.ob_outlet, vec[1]);
932 else if (f >= npoints - 2)
933 outlet_float(x->x_obj.ob_outlet, vec[npoints - 2]);
934 else
935 {
936 int n = f;
937 float a, b, c, d, cminusb, frac, *fp;
938 if (n >= npoints - 2)
939 n = npoints - 3;
940 fp = vec + n;
941 frac = f - n;
942 a = fp[-1];
943 b = fp[0];
944 c = fp[1];
945 d = fp[2];
946 cminusb = c-b;
947 outlet_float(x->x_obj.ob_outlet, b + frac * (
948 cminusb - 0.1666667f * (1.-frac) * (
949 (d - a - 3.0f * cminusb) * frac + (d + 2.0f*a - 3.0f*b))));
950 }
951}
952
953static void tabread4_set(t_tabread4 *x, t_symbol *s)
954{
955 x->x_arrayname = s;
956}
957
958static void *tabread4_new(t_symbol *s)
959{
960 t_tabread4 *x = (t_tabread4 *)pd_new(tabread4_class);
961 x->x_arrayname = s;
962 outlet_new(&x->x_obj, &s_float);
963 return (x);
964}
965
966static void tabread4_setup(void)
967{
968 tabread4_class = class_new(gensym("tabread4"), (t_newmethod)tabread4_new,
969 0, sizeof(t_tabread4), 0, A_DEFSYM, 0);
970 class_addfloat(tabread4_class, (t_method)tabread4_float);
971 class_addmethod(tabread4_class, (t_method)tabread4_set, gensym("set"),
972 A_SYMBOL, 0);
973}
974
975/* ------------------ tabwrite: control ------------------------ */
976
977static t_class *tabwrite_class;
978
979typedef struct _tabwrite
980{
981 t_object x_obj;
982 t_symbol *x_arrayname;
983 t_clock *x_clock;
984 float x_ft1;
985 double x_updtime;
986 int x_set;
987} t_tabwrite;
988
989static void tabwrite_tick(t_tabwrite *x)
990{
991 t_garray *a = (t_garray *)pd_findbyclass(x->x_arrayname, garray_class);
992 if (!a) bug("tabwrite_tick");
993 else garray_redraw(a);
994 x->x_set = 0;
995 x->x_updtime = clock_getsystime();
996}
997
998static void tabwrite_float(t_tabwrite *x, t_float f)
999{
1000 int i, vecsize;
1001 t_garray *a;
1002 t_float *vec;
1003
1004 if (!(a = (t_garray *)pd_findbyclass(x->x_arrayname, garray_class)))
1005 pd_error(x, "%s: no such array", x->x_arrayname->s_name);
1006 else if (!garray_getfloatarray(a, &vecsize, &vec))
1007 pd_error(x, "%s: bad template for tabwrite", x->x_arrayname->s_name);
1008 else
1009 {
1010 int n = x->x_ft1;
1011 double timesince = clock_gettimesince(x->x_updtime);
1012 if (n < 0) n = 0;
1013 else if (n >= vecsize) n = vecsize-1;
1014 vec[n] = f;
1015 if (timesince > 1000)
1016 {
1017 tabwrite_tick(x);
1018 }
1019 else
1020 {
1021 if (x->x_set == 0)
1022 {
1023 clock_delay(x->x_clock, 1000 - timesince);
1024 x->x_set = 1;
1025 }
1026 }
1027 }
1028}
1029
1030static void tabwrite_set(t_tabwrite *x, t_symbol *s)
1031{
1032 x->x_arrayname = s;
1033}
1034
1035static void tabwrite_free(t_tabwrite *x)
1036{
1037 clock_free(x->x_clock);
1038}
1039
1040static void *tabwrite_new(t_symbol *s)
1041{
1042 t_tabwrite *x = (t_tabwrite *)pd_new(tabwrite_class);
1043 x->x_ft1 = 0;
1044 x->x_arrayname = s;
1045 x->x_updtime = clock_getsystime();
1046 x->x_clock = clock_new(x, (t_method)tabwrite_tick);
1047 floatinlet_new(&x->x_obj, &x->x_ft1);
1048 return (x);
1049}
1050
1051void tabwrite_setup(void)
1052{
1053 tabwrite_class = class_new(gensym("tabwrite"), (t_newmethod)tabwrite_new,
1054 (t_method)tabwrite_free, sizeof(t_tabwrite), 0, A_DEFSYM, 0);
1055 class_addfloat(tabwrite_class, (t_method)tabwrite_float);
1056 class_addmethod(tabwrite_class, (t_method)tabwrite_set, gensym("set"), A_SYMBOL, 0);
1057}
1058
1059/* ------------------------ global setup routine ------------------------- */
1060
1061void d_array_setup(void)
1062{
1063 tabwrite_tilde_setup();
1064 tabplay_tilde_setup();
1065 tabread_tilde_setup();
1066 tabread4_tilde_setup();
1067 tabosc4_tilde_setup();
1068 tabsend_setup();
1069 tabreceive_setup();
1070 tabread_setup();
1071 tabread4_setup();
1072 tabwrite_setup();
1073}
1074