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. */
7 /* LATER make tabread4 and tabread~ */
12 /* ------------------------- tabwrite~ -------------------------- */
14 static t_class
*tabwrite_tilde_class
;
16 typedef struct _tabwrite_tilde
22 t_symbol
*x_arrayname
;
27 static void tabwrite_tilde_tick(t_tabwrite_tilde
*x
);
29 static void *tabwrite_tilde_new(t_symbol
*s
)
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;
39 static t_int
*tabwrite_tilde_perform(t_int
*w
)
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
;
48 int nxfer
= endphase
- phase
;
49 float *fp
= x
->x_vec
+ phase
;
50 if (nxfer
> n
) nxfer
= n
;
59 if (phase
>= endphase
)
61 clock_delay(x
->x_clock
, 0);
70 void tabwrite_tilde_set(t_tabwrite_tilde
*x
, t_symbol
*s
)
75 if (!(a
= (t_garray
*)pd_findbyclass(x
->x_arrayname
, garray_class
)))
77 if (*s
->s_name
) pd_error(x
, "tabwrite~: %s: no such array",
78 x
->x_arrayname
->s_name
);
81 else if (!garray_getfloatarray(a
, &x
->x_nsampsintab
, &x
->x_vec
))
83 pd_error(x
, "%s: bad template for tabwrite~", x
->x_arrayname
->s_name
);
86 else garray_usedindsp(a
);
89 static void tabwrite_tilde_dsp(t_tabwrite_tilde
*x
, t_signal
**sp
)
91 tabwrite_tilde_set(x
, x
->x_arrayname
);
92 dsp_add(tabwrite_tilde_perform
, 3, x
, sp
[0]->s_vec
, sp
[0]->s_n
);
95 static void tabwrite_tilde_bang(t_tabwrite_tilde
*x
)
100 static void tabwrite_tilde_stop(t_tabwrite_tilde
*x
)
102 if (x
->x_phase
!= 0x7fffffff)
104 tabwrite_tilde_tick(x
);
105 x
->x_phase
= 0x7fffffff;
109 static void tabwrite_tilde_tick(t_tabwrite_tilde
*x
)
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
);
116 static void tabwrite_tilde_free(t_tabwrite_tilde
*x
)
118 clock_free(x
->x_clock
);
121 static void tabwrite_tilde_setup(void)
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
,
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
,
133 class_addbang(tabwrite_tilde_class
, tabwrite_tilde_bang
);
136 /* ------------ tabplay~ - non-transposing sample playback --------------- */
138 static t_class
*tabplay_tilde_class
;
140 typedef struct _tabplay_tilde
148 t_symbol
*x_arrayname
;
152 static void tabplay_tilde_tick(t_tabplay_tilde
*x
);
154 static void *tabplay_tilde_new(t_symbol
*s
)
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;
161 outlet_new(&x
->x_obj
, &s_signal
);
162 x
->x_bangout
= outlet_new(&x
->x_obj
, &s_bang
);
166 static t_int
*tabplay_tilde_perform(t_int
*w
)
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
)
176 nxfer
= endphase
- phase
;
177 fp
= x
->x_vec
+ phase
;
184 if (phase
>= endphase
)
186 clock_delay(x
->x_clock
, 0);
187 x
->x_phase
= 0x7fffffff;
191 else x
->x_phase
= phase
;
195 while (n
--) *out
++ = 0;
199 void tabplay_tilde_set(t_tabplay_tilde
*x
, t_symbol
*s
)
204 if (!(a
= (t_garray
*)pd_findbyclass(x
->x_arrayname
, garray_class
)))
206 if (*s
->s_name
) pd_error(x
, "tabplay~: %s: no such array",
207 x
->x_arrayname
->s_name
);
210 else if (!garray_getfloatarray(a
, &x
->x_nsampsintab
, &x
->x_vec
))
212 pd_error(x
, "%s: bad template for tabplay~", x
->x_arrayname
->s_name
);
215 else garray_usedindsp(a
);
218 static void tabplay_tilde_dsp(t_tabplay_tilde
*x
, t_signal
**sp
)
220 tabplay_tilde_set(x
, x
->x_arrayname
);
221 dsp_add(tabplay_tilde_perform
, 3, x
, sp
[0]->s_vec
, sp
[0]->s_n
);
224 static void tabplay_tilde_list(t_tabplay_tilde
*x
, t_symbol
*s
,
225 int argc
, t_atom
*argv
)
227 long start
= atom_getfloatarg(0, argc
, argv
);
228 long length
= atom_getfloatarg(1, argc
, argv
);
229 if (start
< 0) start
= 0;
231 x
->x_limit
= 0x7fffffff;
233 x
->x_limit
= start
+ length
;
237 static void tabplay_tilde_stop(t_tabplay_tilde
*x
)
239 x
->x_phase
= 0x7fffffff;
242 static void tabplay_tilde_tick(t_tabplay_tilde
*x
)
244 outlet_bang(x
->x_bangout
);
247 static void tabplay_tilde_free(t_tabplay_tilde
*x
)
249 clock_free(x
->x_clock
);
252 static void tabplay_tilde_setup(void)
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
,
259 class_addmethod(tabplay_tilde_class
, (t_method
)tabplay_tilde_stop
,
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
);
266 /******************** tabread~ ***********************/
268 static t_class
*tabread_tilde_class
;
270 typedef struct _tabread_tilde
275 t_symbol
*x_arrayname
;
279 static void *tabread_tilde_new(t_symbol
*s
)
281 t_tabread_tilde
*x
= (t_tabread_tilde
*)pd_new(tabread_tilde_class
);
284 outlet_new(&x
->x_obj
, gensym("signal"));
289 static t_int
*tabread_tilde_perform(t_int
*w
)
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]);
296 float *buf
= x
->x_vec
, *fp
;
299 maxindex
= x
->x_npoints
- 1;
302 for (i
= 0; i
< n
; i
++)
307 else if (index
> maxindex
)
313 while (n
--) *out
++ = 0;
318 void tabread_tilde_set(t_tabread_tilde
*x
, t_symbol
*s
)
323 if (!(a
= (t_garray
*)pd_findbyclass(x
->x_arrayname
, garray_class
)))
326 pd_error(x
, "tabread~: %s: no such array", x
->x_arrayname
->s_name
);
329 else if (!garray_getfloatarray(a
, &x
->x_npoints
, &x
->x_vec
))
331 pd_error(x
, "%s: bad template for tabread~", x
->x_arrayname
->s_name
);
334 else garray_usedindsp(a
);
337 static void tabread_tilde_dsp(t_tabread_tilde
*x
, t_signal
**sp
)
339 tabread_tilde_set(x
, x
->x_arrayname
);
341 dsp_add(tabread_tilde_perform
, 4, x
,
342 sp
[0]->s_vec
, sp
[1]->s_vec
, sp
[0]->s_n
);
346 static void tabread_tilde_free(t_tabread_tilde
*x
)
350 static void tabread_tilde_setup(void)
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
,
358 class_addmethod(tabread_tilde_class
, (t_method
)tabread_tilde_set
,
359 gensym("set"), A_SYMBOL
, 0);
362 /******************** tabread4~ ***********************/
364 static t_class
*tabread4_tilde_class
;
366 typedef struct _tabread4_tilde
371 t_symbol
*x_arrayname
;
375 static void *tabread4_tilde_new(t_symbol
*s
)
377 t_tabread4_tilde
*x
= (t_tabread4_tilde
*)pd_new(tabread4_tilde_class
);
380 outlet_new(&x
->x_obj
, gensym("signal"));
385 static t_int
*tabread4_tilde_perform(t_int
*w
)
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]);
392 float *buf
= x
->x_vec
, *fp
;
395 maxindex
= x
->x_npoints
- 3;
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
++)
403 if (f
< xmin
) xmin
= f
;
404 else if (f
> xmax
) xmax
= f
;
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
++)
411 if (f
> splitlo
&& f
< splithi
) goto zero
;
415 for (i
= 0; i
< n
; i
++)
417 float findex
= *in
++;
419 float frac
, a
, b
, c
, d
, cminusb
;
423 else if (index
> maxindex
)
424 index
= maxindex
, frac
= 1;
425 else frac
= findex
- index
;
431 /* if (!i && !(count++ & 1023))
432 post("fp = %lx, shit = %lx, b = %f", fp, buf->b_shit, 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
)
442 while (n
--) *out
++ = 0;
447 void tabread4_tilde_set(t_tabread4_tilde
*x
, t_symbol
*s
)
452 if (!(a
= (t_garray
*)pd_findbyclass(x
->x_arrayname
, garray_class
)))
455 pd_error(x
, "tabread4~: %s: no such array", x
->x_arrayname
->s_name
);
458 else if (!garray_getfloatarray(a
, &x
->x_npoints
, &x
->x_vec
))
460 pd_error(x
, "%s: bad template for tabread4~", x
->x_arrayname
->s_name
);
463 else garray_usedindsp(a
);
466 static void tabread4_tilde_dsp(t_tabread4_tilde
*x
, t_signal
**sp
)
468 tabread4_tilde_set(x
, x
->x_arrayname
);
470 dsp_add(tabread4_tilde_perform
, 4, x
,
471 sp
[0]->s_vec
, sp
[1]->s_vec
, sp
[0]->s_n
);
475 static void tabread4_tilde_free(t_tabread4_tilde
*x
)
479 static void tabread4_tilde_setup(void)
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
,
487 class_addmethod(tabread4_tilde_class
, (t_method
)tabread4_tilde_set
,
488 gensym("set"), A_SYMBOL
, 0);
491 /******************** tabosc4~ ***********************/
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 */
496 /* machine-dependent definitions. These ifdefs really
497 should have been by CPU type and not by operating system! */
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 */
505 /* little-endian; most significant byte is at highest address */
511 #include <machine/endian.h>
512 #if BYTE_ORDER == LITTLE_ENDIAN
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
525 #if !defined(__BYTE_ORDER) || !defined(__LITTLE_ENDIAN)
526 #error No byte order defined
529 #if __BYTE_ORDER == __LITTLE_ENDIAN
533 #define HIOFFSET 0 /* word offset to find MSB */
534 #define LOWOFFSET 1 /* word offset to find LSB */
535 #endif /* __BYTE_ORDER */
537 #include <sys/types.h>
538 #define int32 int32_t
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 */
547 #endif /* __linux__ */
557 static t_class
*tabosc4_tilde_class
;
559 typedef struct _tabosc4_tilde
565 t_symbol
*x_arrayname
;
571 static void *tabosc4_tilde_new(t_symbol
*s
)
573 t_tabosc4_tilde
*x
= (t_tabosc4_tilde
*)pd_new(tabosc4_tilde_class
);
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"));
584 static t_int
*tabosc4_tilde_perform(t_int
*w
)
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]);
592 float fnpoints
= x
->x_fnpoints
;
593 int mask
= fnpoints
- 1;
594 float conv
= fnpoints
* x
->x_conv
;
596 float *tab
= x
->x_vec
, *addr
;
598 double dphase
= fnpoints
* x
->x_phase
+ UNITBIT32
;
602 normhipart
= tf
.tf_i
[HIOFFSET
];
607 float frac
, a
, b
, c
, d
, cminusb
;
609 dphase
+= *in
++ * conv
;
610 addr
= tab
+ (tf
.tf_i
[HIOFFSET
] & mask
);
611 tf
.tf_i
[HIOFFSET
] = normhipart
;
612 frac
= tf
.tf_d
- UNITBIT32
;
618 *out
++ = b
+ frac
* (
619 cminusb
- 0.1666667f
* (1.-frac
) * (
620 (d
- a
- 3.0f
* cminusb
) * frac
+ (d
+ 2.0f
*a
- 3.0f
*b
)
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
;
633 while (n
--) *out
++ = 0;
638 void tabosc4_tilde_set(t_tabosc4_tilde
*x
, t_symbol
*s
)
641 int npoints
, pointsinarray
;
644 if (!(a
= (t_garray
*)pd_findbyclass(x
->x_arrayname
, garray_class
)))
647 pd_error(x
, "tabosc4~: %s: no such array", x
->x_arrayname
->s_name
);
650 else if (!garray_getfloatarray(a
, &pointsinarray
, &x
->x_vec
))
652 pd_error(x
, "%s: bad template for tabosc4~", x
->x_arrayname
->s_name
);
655 else if ((npoints
= pointsinarray
- 3) != (1 << ilog2(pointsinarray
- 3)))
657 pd_error(x
, "%s: number of points (%d) not a power of 2 plus three",
658 x
->x_arrayname
->s_name
, pointsinarray
);
664 x
->x_fnpoints
= npoints
;
665 x
->x_finvnpoints
= 1./npoints
;
670 static void tabosc4_tilde_ft1(t_tabosc4_tilde
*x
, t_float f
)
675 static void tabosc4_tilde_dsp(t_tabosc4_tilde
*x
, t_signal
**sp
)
677 x
->x_conv
= 1. / sp
[0]->s_sr
;
678 tabosc4_tilde_set(x
, x
->x_arrayname
);
680 dsp_add(tabosc4_tilde_perform
, 4, x
,
681 sp
[0]->s_vec
, sp
[1]->s_vec
, sp
[0]->s_n
);
684 static void tabosc4_tilde_setup(void)
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
,
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);
698 /* ------------------------ tabsend~ ------------------------- */
700 static t_class
*tabsend_class
;
702 typedef struct _tabsend
708 t_symbol
*x_arrayname
;
713 static void tabsend_tick(t_tabsend
*x
);
715 static void *tabsend_new(t_symbol
*s
)
717 t_tabsend
*x
= (t_tabsend
*)pd_new(tabsend_class
);
720 x
->x_clock
= clock_new(x
, (t_method
)tabsend_tick
);
725 static t_int
*tabsend_perform(t_int
*w
)
727 t_tabsend
*x
= (t_tabsend
*)(w
[1]);
728 t_float
*in
= (t_float
*)(w
[2]);
730 t_float
*dest
= x
->x_vec
;
731 int i
= x
->x_graphcount
;
732 if (!x
->x_vec
) goto bad
;
737 if (PD_BIGORSMALL(f
))
743 clock_delay(x
->x_clock
, 0);
744 i
= x
->x_graphperiod
;
751 static void tabsend_dsp(t_tabsend
*x
, t_signal
**sp
)
756 if (!(a
= (t_garray
*)pd_findbyclass(x
->x_arrayname
, garray_class
)))
758 if (*x
->x_arrayname
->s_name
)
759 pd_error(x
, "tabsend~: %s: no such array", x
->x_arrayname
->s_name
);
761 else if (!garray_getfloatarray(a
, &vecsize
, &x
->x_vec
))
762 pd_error(x
, "%s: bad template for tabsend~", x
->x_arrayname
->s_name
);
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
;
772 dsp_add(tabsend_perform
, 3, x
, sp
[0]->s_vec
, vecsize
);
776 static void tabsend_tick(t_tabsend
*x
)
778 t_garray
*a
= (t_garray
*)pd_findbyclass(x
->x_arrayname
, garray_class
);
779 if (!a
) bug("tabsend_tick");
780 else garray_redraw(a
);
783 static void tabsend_free(t_tabsend
*x
)
785 clock_free(x
->x_clock
);
788 static void tabsend_setup(void)
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);
796 /* ------------------------ tabreceive~ ------------------------- */
798 static t_class
*tabreceive_class
;
800 typedef struct _tabreceive
804 t_symbol
*x_arrayname
;
807 static t_int
*tabreceive_perform(t_int
*w
)
809 t_tabreceive
*x
= (t_tabreceive
*)(w
[1]);
810 t_float
*out
= (t_float
*)(w
[2]);
812 t_float
*from
= x
->x_vec
;
813 if (from
) while (n
--) *out
++ = *from
++;
814 else while (n
--) *out
++ = 0;
818 static void tabreceive_dsp(t_tabreceive
*x
, t_signal
**sp
)
823 if (!(a
= (t_garray
*)pd_findbyclass(x
->x_arrayname
, garray_class
)))
825 if (*x
->x_arrayname
->s_name
)
826 pd_error(x
, "tabsend~: %s: no such array", x
->x_arrayname
->s_name
);
828 else if (!garray_getfloatarray(a
, &vecsize
, &x
->x_vec
))
829 pd_error(x
, "%s: bad template for tabreceive~", x
->x_arrayname
->s_name
);
833 if (n
< vecsize
) vecsize
= n
;
835 dsp_add(tabreceive_perform
, 3, x
, sp
[0]->s_vec
, vecsize
);
839 static void *tabreceive_new(t_symbol
*s
)
841 t_tabreceive
*x
= (t_tabreceive
*)pd_new(tabreceive_class
);
843 outlet_new(&x
->x_obj
, &s_signal
);
847 static void tabreceive_setup(void)
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
,
857 /* ---------- tabread: control, non-interpolating ------------------------ */
859 static t_class
*tabread_class
;
861 typedef struct _tabread
864 t_symbol
*x_arrayname
;
867 static void tabread_float(t_tabread
*x
, t_float f
)
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
);
881 else if (n
>= npoints
) n
= npoints
- 1;
882 outlet_float(x
->x_obj
.ob_outlet
, (npoints
? vec
[n
] : 0));
886 static void tabread_set(t_tabread
*x
, t_symbol
*s
)
891 static void *tabread_new(t_symbol
*s
)
893 t_tabread
*x
= (t_tabread
*)pd_new(tabread_class
);
895 outlet_new(&x
->x_obj
, &s_float
);
899 static void tabread_setup(void)
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"),
908 /* ---------- tabread4: control, non-interpolating ------------------------ */
910 static t_class
*tabread4_class
;
912 typedef struct _tabread4
915 t_symbol
*x_arrayname
;
918 static void tabread4_float(t_tabread4
*x
, t_float f
)
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);
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]);
937 float a
, b
, c
, d
, cminusb
, frac
, *fp
;
938 if (n
>= npoints
- 2)
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
))));
953 static void tabread4_set(t_tabread4
*x
, t_symbol
*s
)
958 static void *tabread4_new(t_symbol
*s
)
960 t_tabread4
*x
= (t_tabread4
*)pd_new(tabread4_class
);
962 outlet_new(&x
->x_obj
, &s_float
);
966 static void tabread4_setup(void)
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"),
975 /* ------------------ tabwrite: control ------------------------ */
977 static t_class
*tabwrite_class
;
979 typedef struct _tabwrite
982 t_symbol
*x_arrayname
;
989 static void tabwrite_tick(t_tabwrite
*x
)
991 t_garray
*a
= (t_garray
*)pd_findbyclass(x
->x_arrayname
, garray_class
);
992 if (!a
) bug("tabwrite_tick");
993 else garray_redraw(a
);
995 x
->x_updtime
= clock_getsystime();
998 static void tabwrite_float(t_tabwrite
*x
, t_float f
)
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
);
1011 double timesince
= clock_gettimesince(x
->x_updtime
);
1013 else if (n
>= vecsize
) n
= vecsize
-1;
1015 if (timesince
> 1000)
1023 clock_delay(x
->x_clock
, 1000 - timesince
);
1030 static void tabwrite_set(t_tabwrite
*x
, t_symbol
*s
)
1035 static void tabwrite_free(t_tabwrite
*x
)
1037 clock_free(x
->x_clock
);
1040 static void *tabwrite_new(t_symbol
*s
)
1042 t_tabwrite
*x
= (t_tabwrite
*)pd_new(tabwrite_class
);
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
);
1051 void tabwrite_setup(void)
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);
1059 /* ------------------------ global setup routine ------------------------- */
1061 void d_array_setup(void)
1063 tabwrite_tilde_setup();
1064 tabplay_tilde_setup();
1065 tabread_tilde_setup();
1066 tabread4_tilde_setup();
1067 tabosc4_tilde_setup();