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();
1075 /* Copyright (c) 1997-1999 Miller Puckette and others.
1076 * For information on usage and redistribution, and for a DISCLAIMER OF ALL
1077 * WARRANTIES, see the file, "LICENSE.txt," in this distribution. */
1081 /* LATER make tabread4 and tabread~ */
1086 /* ------------------------- tabwrite~ -------------------------- */
1088 static t_class
*tabwrite_tilde_class
;
1090 typedef struct _tabwrite_tilde
1096 t_symbol
*x_arrayname
;
1101 static void tabwrite_tilde_tick(t_tabwrite_tilde
*x
);
1103 static void *tabwrite_tilde_new(t_symbol
*s
)
1105 t_tabwrite_tilde
*x
= (t_tabwrite_tilde
*)pd_new(tabwrite_tilde_class
);
1106 x
->x_clock
= clock_new(x
, (t_method
)tabwrite_tilde_tick
);
1107 x
->x_phase
= 0x7fffffff;
1113 static t_int
*tabwrite_tilde_perform(t_int
*w
)
1115 t_tabwrite_tilde
*x
= (t_tabwrite_tilde
*)(w
[1]);
1116 t_float
*in
= (t_float
*)(w
[2]);
1117 int n
= (int)(w
[3]), phase
= x
->x_phase
, endphase
= x
->x_nsampsintab
;
1118 if (!x
->x_vec
) goto bad
;
1120 if (endphase
> phase
)
1122 int nxfer
= endphase
- phase
;
1123 float *fp
= x
->x_vec
+ phase
;
1124 if (nxfer
> n
) nxfer
= n
;
1129 if (PD_BIGORSMALL(f
))
1133 if (phase
>= endphase
)
1135 clock_delay(x
->x_clock
, 0);
1144 void tabwrite_tilde_set(t_tabwrite_tilde
*x
, t_symbol
*s
)
1149 if (!(a
= (t_garray
*)pd_findbyclass(x
->x_arrayname
, garray_class
)))
1151 if (*s
->s_name
) pd_error(x
, "tabwrite~: %s: no such array",
1152 x
->x_arrayname
->s_name
);
1155 else if (!garray_getfloatarray(a
, &x
->x_nsampsintab
, &x
->x_vec
))
1157 pd_error(x
, "%s: bad template for tabwrite~", x
->x_arrayname
->s_name
);
1160 else garray_usedindsp(a
);
1163 static void tabwrite_tilde_dsp(t_tabwrite_tilde
*x
, t_signal
**sp
)
1165 tabwrite_tilde_set(x
, x
->x_arrayname
);
1166 dsp_add(tabwrite_tilde_perform
, 3, x
, sp
[0]->s_vec
, sp
[0]->s_n
);
1169 static void tabwrite_tilde_bang(t_tabwrite_tilde
*x
)
1174 static void tabwrite_tilde_stop(t_tabwrite_tilde
*x
)
1176 if (x
->x_phase
!= 0x7fffffff)
1178 tabwrite_tilde_tick(x
);
1179 x
->x_phase
= 0x7fffffff;
1183 static void tabwrite_tilde_tick(t_tabwrite_tilde
*x
)
1185 t_garray
*a
= (t_garray
*)pd_findbyclass(x
->x_arrayname
, garray_class
);
1186 if (!a
) bug("tabwrite_tilde_tick");
1187 else garray_redraw(a
);
1190 static void tabwrite_tilde_free(t_tabwrite_tilde
*x
)
1192 clock_free(x
->x_clock
);
1195 static void tabwrite_tilde_setup(void)
1197 tabwrite_tilde_class
= class_new(gensym("tabwrite~"),
1198 (t_newmethod
)tabwrite_tilde_new
, (t_method
)tabwrite_tilde_free
,
1199 sizeof(t_tabwrite_tilde
), 0, A_DEFSYM
, 0);
1200 CLASS_MAINSIGNALIN(tabwrite_tilde_class
, t_tabwrite_tilde
, x_f
);
1201 class_addmethod(tabwrite_tilde_class
, (t_method
)tabwrite_tilde_dsp
,
1203 class_addmethod(tabwrite_tilde_class
, (t_method
)tabwrite_tilde_set
,
1204 gensym("set"), A_SYMBOL
, 0);
1205 class_addmethod(tabwrite_tilde_class
, (t_method
)tabwrite_tilde_stop
,
1207 class_addbang(tabwrite_tilde_class
, tabwrite_tilde_bang
);
1210 /* ------------ tabplay~ - non-transposing sample playback --------------- */
1212 static t_class
*tabplay_tilde_class
;
1214 typedef struct _tabplay_tilde
1217 t_outlet
*x_bangout
;
1222 t_symbol
*x_arrayname
;
1226 static void tabplay_tilde_tick(t_tabplay_tilde
*x
);
1228 static void *tabplay_tilde_new(t_symbol
*s
)
1230 t_tabplay_tilde
*x
= (t_tabplay_tilde
*)pd_new(tabplay_tilde_class
);
1231 x
->x_clock
= clock_new(x
, (t_method
)tabplay_tilde_tick
);
1232 x
->x_phase
= 0x7fffffff;
1235 outlet_new(&x
->x_obj
, &s_signal
);
1236 x
->x_bangout
= outlet_new(&x
->x_obj
, &s_bang
);
1240 static t_int
*tabplay_tilde_perform(t_int
*w
)
1242 t_tabplay_tilde
*x
= (t_tabplay_tilde
*)(w
[1]);
1243 t_float
*out
= (t_float
*)(w
[2]), *fp
;
1244 int n
= (int)(w
[3]), phase
= x
->x_phase
,
1245 endphase
= (x
->x_nsampsintab
< x
->x_limit
?
1246 x
->x_nsampsintab
: x
->x_limit
), nxfer
, n3
;
1247 if (!x
->x_vec
|| phase
>= endphase
)
1250 nxfer
= endphase
- phase
;
1251 fp
= x
->x_vec
+ phase
;
1258 if (phase
>= endphase
)
1260 clock_delay(x
->x_clock
, 0);
1261 x
->x_phase
= 0x7fffffff;
1265 else x
->x_phase
= phase
;
1269 while (n
--) *out
++ = 0;
1273 void tabplay_tilde_set(t_tabplay_tilde
*x
, t_symbol
*s
)
1278 if (!(a
= (t_garray
*)pd_findbyclass(x
->x_arrayname
, garray_class
)))
1280 if (*s
->s_name
) pd_error(x
, "tabplay~: %s: no such array",
1281 x
->x_arrayname
->s_name
);
1284 else if (!garray_getfloatarray(a
, &x
->x_nsampsintab
, &x
->x_vec
))
1286 pd_error(x
, "%s: bad template for tabplay~", x
->x_arrayname
->s_name
);
1289 else garray_usedindsp(a
);
1292 static void tabplay_tilde_dsp(t_tabplay_tilde
*x
, t_signal
**sp
)
1294 tabplay_tilde_set(x
, x
->x_arrayname
);
1295 dsp_add(tabplay_tilde_perform
, 3, x
, sp
[0]->s_vec
, sp
[0]->s_n
);
1298 static void tabplay_tilde_list(t_tabplay_tilde
*x
, t_symbol
*s
,
1299 int argc
, t_atom
*argv
)
1301 long start
= atom_getfloatarg(0, argc
, argv
);
1302 long length
= atom_getfloatarg(1, argc
, argv
);
1303 if (start
< 0) start
= 0;
1305 x
->x_limit
= 0x7fffffff;
1307 x
->x_limit
= start
+ length
;
1311 static void tabplay_tilde_stop(t_tabplay_tilde
*x
)
1313 x
->x_phase
= 0x7fffffff;
1316 static void tabplay_tilde_tick(t_tabplay_tilde
*x
)
1318 outlet_bang(x
->x_bangout
);
1321 static void tabplay_tilde_free(t_tabplay_tilde
*x
)
1323 clock_free(x
->x_clock
);
1326 static void tabplay_tilde_setup(void)
1328 tabplay_tilde_class
= class_new(gensym("tabplay~"),
1329 (t_newmethod
)tabplay_tilde_new
, (t_method
)tabplay_tilde_free
,
1330 sizeof(t_tabplay_tilde
), 0, A_DEFSYM
, 0);
1331 class_addmethod(tabplay_tilde_class
, (t_method
)tabplay_tilde_dsp
,
1333 class_addmethod(tabplay_tilde_class
, (t_method
)tabplay_tilde_stop
,
1335 class_addmethod(tabplay_tilde_class
, (t_method
)tabplay_tilde_set
,
1336 gensym("set"), A_DEFSYM
, 0);
1337 class_addlist(tabplay_tilde_class
, tabplay_tilde_list
);
1340 /******************** tabread~ ***********************/
1342 static t_class
*tabread_tilde_class
;
1344 typedef struct _tabread_tilde
1349 t_symbol
*x_arrayname
;
1353 static void *tabread_tilde_new(t_symbol
*s
)
1355 t_tabread_tilde
*x
= (t_tabread_tilde
*)pd_new(tabread_tilde_class
);
1358 outlet_new(&x
->x_obj
, gensym("signal"));
1363 static t_int
*tabread_tilde_perform(t_int
*w
)
1365 t_tabread_tilde
*x
= (t_tabread_tilde
*)(w
[1]);
1366 t_float
*in
= (t_float
*)(w
[2]);
1367 t_float
*out
= (t_float
*)(w
[3]);
1368 int n
= (int)(w
[4]);
1370 float *buf
= x
->x_vec
, *fp
;
1373 maxindex
= x
->x_npoints
- 1;
1374 if (!buf
) goto zero
;
1376 for (i
= 0; i
< n
; i
++)
1381 else if (index
> maxindex
)
1383 *out
++ = buf
[index
];
1387 while (n
--) *out
++ = 0;
1392 void tabread_tilde_set(t_tabread_tilde
*x
, t_symbol
*s
)
1397 if (!(a
= (t_garray
*)pd_findbyclass(x
->x_arrayname
, garray_class
)))
1400 pd_error(x
, "tabread~: %s: no such array", x
->x_arrayname
->s_name
);
1403 else if (!garray_getfloatarray(a
, &x
->x_npoints
, &x
->x_vec
))
1405 pd_error(x
, "%s: bad template for tabread~", x
->x_arrayname
->s_name
);
1408 else garray_usedindsp(a
);
1411 static void tabread_tilde_dsp(t_tabread_tilde
*x
, t_signal
**sp
)
1413 tabread_tilde_set(x
, x
->x_arrayname
);
1415 dsp_add(tabread_tilde_perform
, 4, x
,
1416 sp
[0]->s_vec
, sp
[1]->s_vec
, sp
[0]->s_n
);
1420 static void tabread_tilde_free(t_tabread_tilde
*x
)
1424 static void tabread_tilde_setup(void)
1426 tabread_tilde_class
= class_new(gensym("tabread~"),
1427 (t_newmethod
)tabread_tilde_new
, (t_method
)tabread_tilde_free
,
1428 sizeof(t_tabread_tilde
), 0, A_DEFSYM
, 0);
1429 CLASS_MAINSIGNALIN(tabread_tilde_class
, t_tabread_tilde
, x_f
);
1430 class_addmethod(tabread_tilde_class
, (t_method
)tabread_tilde_dsp
,
1432 class_addmethod(tabread_tilde_class
, (t_method
)tabread_tilde_set
,
1433 gensym("set"), A_SYMBOL
, 0);
1436 /******************** tabread4~ ***********************/
1438 static t_class
*tabread4_tilde_class
;
1440 typedef struct _tabread4_tilde
1445 t_symbol
*x_arrayname
;
1449 static void *tabread4_tilde_new(t_symbol
*s
)
1451 t_tabread4_tilde
*x
= (t_tabread4_tilde
*)pd_new(tabread4_tilde_class
);
1454 outlet_new(&x
->x_obj
, gensym("signal"));
1459 static t_int
*tabread4_tilde_perform(t_int
*w
)
1461 t_tabread4_tilde
*x
= (t_tabread4_tilde
*)(w
[1]);
1462 t_float
*in
= (t_float
*)(w
[2]);
1463 t_float
*out
= (t_float
*)(w
[3]);
1464 int n
= (int)(w
[4]);
1466 float *buf
= x
->x_vec
, *fp
;
1469 maxindex
= x
->x_npoints
- 3;
1471 if (!buf
) goto zero
;
1473 #if 0 /* test for spam -- I'm not ready to deal with this */
1474 for (i
= 0, xmax
= 0, xmin
= maxindex
, fp
= in1
; i
< n
; i
++, fp
++)
1477 if (f
< xmin
) xmin
= f
;
1478 else if (f
> xmax
) xmax
= f
;
1480 if (xmax
< xmin
+ x
->c_maxextent
) xmax
= xmin
+ x
->c_maxextent
;
1481 for (i
= 0, splitlo
= xmin
+ x
->c_maxextent
, splithi
= xmax
- x
->c_maxextent
,
1482 fp
= in1
; i
< n
; i
++, fp
++)
1485 if (f
> splitlo
&& f
< splithi
) goto zero
;
1489 for (i
= 0; i
< n
; i
++)
1491 float findex
= *in
++;
1493 float frac
, a
, b
, c
, d
, cminusb
;
1496 index
= 1, frac
= 0;
1497 else if (index
> maxindex
)
1498 index
= maxindex
, frac
= 1;
1499 else frac
= findex
- index
;
1505 /* if (!i && !(count++ & 1023))
1506 post("fp = %lx, shit = %lx, b = %f", fp, buf->b_shit, b); */
1508 *out
++ = b
+ frac
* (
1509 cminusb
- 0.1666667f
* (1.-frac
) * (
1510 (d
- a
- 3.0f
* cminusb
) * frac
+ (d
+ 2.0f
*a
- 3.0f
*b
)
1516 while (n
--) *out
++ = 0;
1521 void tabread4_tilde_set(t_tabread4_tilde
*x
, t_symbol
*s
)
1526 if (!(a
= (t_garray
*)pd_findbyclass(x
->x_arrayname
, garray_class
)))
1529 pd_error(x
, "tabread4~: %s: no such array", x
->x_arrayname
->s_name
);
1532 else if (!garray_getfloatarray(a
, &x
->x_npoints
, &x
->x_vec
))
1534 pd_error(x
, "%s: bad template for tabread4~", x
->x_arrayname
->s_name
);
1537 else garray_usedindsp(a
);
1540 static void tabread4_tilde_dsp(t_tabread4_tilde
*x
, t_signal
**sp
)
1542 tabread4_tilde_set(x
, x
->x_arrayname
);
1544 dsp_add(tabread4_tilde_perform
, 4, x
,
1545 sp
[0]->s_vec
, sp
[1]->s_vec
, sp
[0]->s_n
);
1549 static void tabread4_tilde_free(t_tabread4_tilde
*x
)
1553 static void tabread4_tilde_setup(void)
1555 tabread4_tilde_class
= class_new(gensym("tabread4~"),
1556 (t_newmethod
)tabread4_tilde_new
, (t_method
)tabread4_tilde_free
,
1557 sizeof(t_tabread4_tilde
), 0, A_DEFSYM
, 0);
1558 CLASS_MAINSIGNALIN(tabread4_tilde_class
, t_tabread4_tilde
, x_f
);
1559 class_addmethod(tabread4_tilde_class
, (t_method
)tabread4_tilde_dsp
,
1561 class_addmethod(tabread4_tilde_class
, (t_method
)tabread4_tilde_set
,
1562 gensym("set"), A_SYMBOL
, 0);
1565 /******************** tabosc4~ ***********************/
1567 /* this is all copied from d_osc.c... what include file could this go in? */
1568 #define UNITBIT32 1572864. /* 3*2^19; bit 32 has place value 1 */
1570 /* machine-dependent definitions. These ifdefs really
1571 should have been by CPU type and not by operating system! */
1573 /* big-endian. Most significant byte is at low address in memory */
1574 #define HIOFFSET 0 /* word offset to find MSB */
1575 #define LOWOFFSET 1 /* word offset to find LSB */
1576 #define int32 long /* a data type that has 32 bits */
1579 /* little-endian; most significant byte is at highest address */
1585 #include <machine/endian.h>
1586 #if BYTE_ORDER == LITTLE_ENDIAN
1590 #define HIOFFSET 0 /* word offset to find MSB */
1591 #define LOWOFFSET 1 /* word offset to find LSB */
1592 #endif /* BYTE_ORDER */
1593 #include <sys/types.h>
1594 #define int32 int32_t
1599 #if !defined(__BYTE_ORDER) || !defined(__LITTLE_ENDIAN)
1600 #error No byte order defined
1603 #if __BYTE_ORDER == __LITTLE_ENDIAN
1607 #define HIOFFSET 0 /* word offset to find MSB */
1608 #define LOWOFFSET 1 /* word offset to find LSB */
1609 #endif /* __BYTE_ORDER */
1611 #include <sys/types.h>
1612 #define int32 int32_t
1616 #define HIOFFSET 0 /* word offset to find MSB */
1617 #define LOWOFFSET 1 /* word offset to find LSB */
1618 #define int32 int /* a data type that has 32 bits */
1621 #endif /* __linux__ */
1631 static t_class
*tabosc4_tilde_class
;
1633 typedef struct _tabosc4_tilde
1637 float x_finvnpoints
;
1639 t_symbol
*x_arrayname
;
1645 static void *tabosc4_tilde_new(t_symbol
*s
)
1647 t_tabosc4_tilde
*x
= (t_tabosc4_tilde
*)pd_new(tabosc4_tilde_class
);
1650 x
->x_fnpoints
= 512.;
1651 x
->x_finvnpoints
= (1./512.);
1652 outlet_new(&x
->x_obj
, gensym("signal"));
1653 inlet_new(&x
->x_obj
, &x
->x_obj
.ob_pd
, &s_float
, gensym("ft1"));
1658 static t_int
*tabosc4_tilde_perform(t_int
*w
)
1660 t_tabosc4_tilde
*x
= (t_tabosc4_tilde
*)(w
[1]);
1661 t_float
*in
= (t_float
*)(w
[2]);
1662 t_float
*out
= (t_float
*)(w
[3]);
1663 int n
= (int)(w
[4]);
1666 float fnpoints
= x
->x_fnpoints
;
1667 int mask
= fnpoints
- 1;
1668 float conv
= fnpoints
* x
->x_conv
;
1670 float *tab
= x
->x_vec
, *addr
;
1672 double dphase
= fnpoints
* x
->x_phase
+ UNITBIT32
;
1674 if (!tab
) goto zero
;
1675 tf
.tf_d
= UNITBIT32
;
1676 normhipart
= tf
.tf_i
[HIOFFSET
];
1681 float frac
, a
, b
, c
, d
, cminusb
;
1683 dphase
+= *in
++ * conv
;
1684 addr
= tab
+ (tf
.tf_i
[HIOFFSET
] & mask
);
1685 tf
.tf_i
[HIOFFSET
] = normhipart
;
1686 frac
= tf
.tf_d
- UNITBIT32
;
1692 *out
++ = b
+ frac
* (
1693 cminusb
- 0.1666667f
* (1.-frac
) * (
1694 (d
- a
- 3.0f
* cminusb
) * frac
+ (d
+ 2.0f
*a
- 3.0f
*b
)
1700 tf
.tf_d
= UNITBIT32
* fnpoints
;
1701 normhipart
= tf
.tf_i
[HIOFFSET
];
1702 tf
.tf_d
= dphase
+ (UNITBIT32
* fnpoints
- UNITBIT32
);
1703 tf
.tf_i
[HIOFFSET
] = normhipart
;
1704 x
->x_phase
= (tf
.tf_d
- UNITBIT32
* fnpoints
) * x
->x_finvnpoints
;
1707 while (n
--) *out
++ = 0;
1712 void tabosc4_tilde_set(t_tabosc4_tilde
*x
, t_symbol
*s
)
1715 int npoints
, pointsinarray
;
1718 if (!(a
= (t_garray
*)pd_findbyclass(x
->x_arrayname
, garray_class
)))
1721 pd_error(x
, "tabosc4~: %s: no such array", x
->x_arrayname
->s_name
);
1724 else if (!garray_getfloatarray(a
, &pointsinarray
, &x
->x_vec
))
1726 pd_error(x
, "%s: bad template for tabosc4~", x
->x_arrayname
->s_name
);
1729 else if ((npoints
= pointsinarray
- 3) != (1 << ilog2(pointsinarray
- 3)))
1731 pd_error(x
, "%s: number of points (%d) not a power of 2 plus three",
1732 x
->x_arrayname
->s_name
, pointsinarray
);
1734 garray_usedindsp(a
);
1738 x
->x_fnpoints
= npoints
;
1739 x
->x_finvnpoints
= 1./npoints
;
1740 garray_usedindsp(a
);
1744 static void tabosc4_tilde_ft1(t_tabosc4_tilde
*x
, t_float f
)
1749 static void tabosc4_tilde_dsp(t_tabosc4_tilde
*x
, t_signal
**sp
)
1751 x
->x_conv
= 1. / sp
[0]->s_sr
;
1752 tabosc4_tilde_set(x
, x
->x_arrayname
);
1754 dsp_add(tabosc4_tilde_perform
, 4, x
,
1755 sp
[0]->s_vec
, sp
[1]->s_vec
, sp
[0]->s_n
);
1758 static void tabosc4_tilde_setup(void)
1760 tabosc4_tilde_class
= class_new(gensym("tabosc4~"),
1761 (t_newmethod
)tabosc4_tilde_new
, 0,
1762 sizeof(t_tabosc4_tilde
), 0, A_DEFSYM
, 0);
1763 CLASS_MAINSIGNALIN(tabosc4_tilde_class
, t_tabosc4_tilde
, x_f
);
1764 class_addmethod(tabosc4_tilde_class
, (t_method
)tabosc4_tilde_dsp
,
1766 class_addmethod(tabosc4_tilde_class
, (t_method
)tabosc4_tilde_set
,
1767 gensym("set"), A_SYMBOL
, 0);
1768 class_addmethod(tabosc4_tilde_class
, (t_method
)tabosc4_tilde_ft1
,
1769 gensym("ft1"), A_FLOAT
, 0);
1772 /* ------------------------ tabsend~ ------------------------- */
1774 static t_class
*tabsend_class
;
1776 typedef struct _tabsend
1782 t_symbol
*x_arrayname
;
1787 static void tabsend_tick(t_tabsend
*x
);
1789 static void *tabsend_new(t_symbol
*s
)
1791 t_tabsend
*x
= (t_tabsend
*)pd_new(tabsend_class
);
1792 x
->x_graphcount
= 0;
1794 x
->x_clock
= clock_new(x
, (t_method
)tabsend_tick
);
1799 static t_int
*tabsend_perform(t_int
*w
)
1801 t_tabsend
*x
= (t_tabsend
*)(w
[1]);
1802 t_float
*in
= (t_float
*)(w
[2]);
1804 t_float
*dest
= x
->x_vec
;
1805 int i
= x
->x_graphcount
;
1806 if (!x
->x_vec
) goto bad
;
1811 if (PD_BIGORSMALL(f
))
1817 clock_delay(x
->x_clock
, 0);
1818 i
= x
->x_graphperiod
;
1820 x
->x_graphcount
= i
;
1825 static void tabsend_dsp(t_tabsend
*x
, t_signal
**sp
)
1830 if (!(a
= (t_garray
*)pd_findbyclass(x
->x_arrayname
, garray_class
)))
1832 if (*x
->x_arrayname
->s_name
)
1833 pd_error(x
, "tabsend~: %s: no such array", x
->x_arrayname
->s_name
);
1835 else if (!garray_getfloatarray(a
, &vecsize
, &x
->x_vec
))
1836 pd_error(x
, "%s: bad template for tabsend~", x
->x_arrayname
->s_name
);
1840 int ticksper
= sp
[0]->s_sr
/n
;
1841 if (ticksper
< 1) ticksper
= 1;
1842 x
->x_graphperiod
= ticksper
;
1843 if (x
->x_graphcount
> ticksper
) x
->x_graphcount
= ticksper
;
1844 if (n
< vecsize
) vecsize
= n
;
1845 garray_usedindsp(a
);
1846 dsp_add(tabsend_perform
, 3, x
, sp
[0]->s_vec
, vecsize
);
1850 static void tabsend_tick(t_tabsend
*x
)
1852 t_garray
*a
= (t_garray
*)pd_findbyclass(x
->x_arrayname
, garray_class
);
1853 if (!a
) bug("tabsend_tick");
1854 else garray_redraw(a
);
1857 static void tabsend_free(t_tabsend
*x
)
1859 clock_free(x
->x_clock
);
1862 static void tabsend_setup(void)
1864 tabsend_class
= class_new(gensym("tabsend~"), (t_newmethod
)tabsend_new
,
1865 (t_method
)tabsend_free
, sizeof(t_tabsend
), 0, A_DEFSYM
, 0);
1866 CLASS_MAINSIGNALIN(tabsend_class
, t_tabsend
, x_f
);
1867 class_addmethod(tabsend_class
, (t_method
)tabsend_dsp
, gensym("dsp"), 0);
1870 /* ------------------------ tabreceive~ ------------------------- */
1872 static t_class
*tabreceive_class
;
1874 typedef struct _tabreceive
1878 t_symbol
*x_arrayname
;
1881 static t_int
*tabreceive_perform(t_int
*w
)
1883 t_tabreceive
*x
= (t_tabreceive
*)(w
[1]);
1884 t_float
*out
= (t_float
*)(w
[2]);
1886 t_float
*from
= x
->x_vec
;
1887 if (from
) while (n
--) *out
++ = *from
++;
1888 else while (n
--) *out
++ = 0;
1892 static void tabreceive_dsp(t_tabreceive
*x
, t_signal
**sp
)
1897 if (!(a
= (t_garray
*)pd_findbyclass(x
->x_arrayname
, garray_class
)))
1899 if (*x
->x_arrayname
->s_name
)
1900 pd_error(x
, "tabsend~: %s: no such array", x
->x_arrayname
->s_name
);
1902 else if (!garray_getfloatarray(a
, &vecsize
, &x
->x_vec
))
1903 pd_error(x
, "%s: bad template for tabreceive~", x
->x_arrayname
->s_name
);
1907 if (n
< vecsize
) vecsize
= n
;
1908 garray_usedindsp(a
);
1909 dsp_add(tabreceive_perform
, 3, x
, sp
[0]->s_vec
, vecsize
);
1913 static void *tabreceive_new(t_symbol
*s
)
1915 t_tabreceive
*x
= (t_tabreceive
*)pd_new(tabreceive_class
);
1917 outlet_new(&x
->x_obj
, &s_signal
);
1921 static void tabreceive_setup(void)
1923 tabreceive_class
= class_new(gensym("tabreceive~"),
1924 (t_newmethod
)tabreceive_new
, 0,
1925 sizeof(t_tabreceive
), 0, A_DEFSYM
, 0);
1926 class_addmethod(tabreceive_class
, (t_method
)tabreceive_dsp
,
1931 /* ---------- tabread: control, non-interpolating ------------------------ */
1933 static t_class
*tabread_class
;
1935 typedef struct _tabread
1938 t_symbol
*x_arrayname
;
1941 static void tabread_float(t_tabread
*x
, t_float f
)
1947 if (!(a
= (t_garray
*)pd_findbyclass(x
->x_arrayname
, garray_class
)))
1948 pd_error(x
, "%s: no such array", x
->x_arrayname
->s_name
);
1949 else if (!garray_getfloatarray(a
, &npoints
, &vec
))
1950 pd_error(x
, "%s: bad template for tabread", x
->x_arrayname
->s_name
);
1955 else if (n
>= npoints
) n
= npoints
- 1;
1956 outlet_float(x
->x_obj
.ob_outlet
, (npoints
? vec
[n
] : 0));
1960 static void tabread_set(t_tabread
*x
, t_symbol
*s
)
1965 static void *tabread_new(t_symbol
*s
)
1967 t_tabread
*x
= (t_tabread
*)pd_new(tabread_class
);
1969 outlet_new(&x
->x_obj
, &s_float
);
1973 static void tabread_setup(void)
1975 tabread_class
= class_new(gensym("tabread"), (t_newmethod
)tabread_new
,
1976 0, sizeof(t_tabread
), 0, A_DEFSYM
, 0);
1977 class_addfloat(tabread_class
, (t_method
)tabread_float
);
1978 class_addmethod(tabread_class
, (t_method
)tabread_set
, gensym("set"),
1982 /* ---------- tabread4: control, non-interpolating ------------------------ */
1984 static t_class
*tabread4_class
;
1986 typedef struct _tabread4
1989 t_symbol
*x_arrayname
;
1992 static void tabread4_float(t_tabread4
*x
, t_float f
)
1998 if (!(a
= (t_garray
*)pd_findbyclass(x
->x_arrayname
, garray_class
)))
1999 pd_error(x
, "%s: no such array", x
->x_arrayname
->s_name
);
2000 else if (!garray_getfloatarray(a
, &npoints
, &vec
))
2001 pd_error(x
, "%s: bad template for tabread4", x
->x_arrayname
->s_name
);
2002 else if (npoints
< 4)
2003 outlet_float(x
->x_obj
.ob_outlet
, 0);
2005 outlet_float(x
->x_obj
.ob_outlet
, vec
[1]);
2006 else if (f
>= npoints
- 2)
2007 outlet_float(x
->x_obj
.ob_outlet
, vec
[npoints
- 2]);
2011 float a
, b
, c
, d
, cminusb
, frac
, *fp
;
2012 if (n
>= npoints
- 2)
2021 outlet_float(x
->x_obj
.ob_outlet
, b
+ frac
* (
2022 cminusb
- 0.1666667f
* (1.-frac
) * (
2023 (d
- a
- 3.0f
* cminusb
) * frac
+ (d
+ 2.0f
*a
- 3.0f
*b
))));
2027 static void tabread4_set(t_tabread4
*x
, t_symbol
*s
)
2032 static void *tabread4_new(t_symbol
*s
)
2034 t_tabread4
*x
= (t_tabread4
*)pd_new(tabread4_class
);
2036 outlet_new(&x
->x_obj
, &s_float
);
2040 static void tabread4_setup(void)
2042 tabread4_class
= class_new(gensym("tabread4"), (t_newmethod
)tabread4_new
,
2043 0, sizeof(t_tabread4
), 0, A_DEFSYM
, 0);
2044 class_addfloat(tabread4_class
, (t_method
)tabread4_float
);
2045 class_addmethod(tabread4_class
, (t_method
)tabread4_set
, gensym("set"),
2049 /* ------------------ tabwrite: control ------------------------ */
2051 static t_class
*tabwrite_class
;
2053 typedef struct _tabwrite
2056 t_symbol
*x_arrayname
;
2063 static void tabwrite_tick(t_tabwrite
*x
)
2065 t_garray
*a
= (t_garray
*)pd_findbyclass(x
->x_arrayname
, garray_class
);
2066 if (!a
) bug("tabwrite_tick");
2067 else garray_redraw(a
);
2069 x
->x_updtime
= clock_getsystime();
2072 static void tabwrite_float(t_tabwrite
*x
, t_float f
)
2078 if (!(a
= (t_garray
*)pd_findbyclass(x
->x_arrayname
, garray_class
)))
2079 pd_error(x
, "%s: no such array", x
->x_arrayname
->s_name
);
2080 else if (!garray_getfloatarray(a
, &vecsize
, &vec
))
2081 pd_error(x
, "%s: bad template for tabwrite", x
->x_arrayname
->s_name
);
2085 double timesince
= clock_gettimesince(x
->x_updtime
);
2087 else if (n
>= vecsize
) n
= vecsize
-1;
2089 if (timesince
> 1000)
2097 clock_delay(x
->x_clock
, 1000 - timesince
);
2104 static void tabwrite_set(t_tabwrite
*x
, t_symbol
*s
)
2109 static void tabwrite_free(t_tabwrite
*x
)
2111 clock_free(x
->x_clock
);
2114 static void *tabwrite_new(t_symbol
*s
)
2116 t_tabwrite
*x
= (t_tabwrite
*)pd_new(tabwrite_class
);
2119 x
->x_updtime
= clock_getsystime();
2120 x
->x_clock
= clock_new(x
, (t_method
)tabwrite_tick
);
2121 floatinlet_new(&x
->x_obj
, &x
->x_ft1
);
2125 void tabwrite_setup(void)
2127 tabwrite_class
= class_new(gensym("tabwrite"), (t_newmethod
)tabwrite_new
,
2128 (t_method
)tabwrite_free
, sizeof(t_tabwrite
), 0, A_DEFSYM
, 0);
2129 class_addfloat(tabwrite_class
, (t_method
)tabwrite_float
);
2130 class_addmethod(tabwrite_class
, (t_method
)tabwrite_set
, gensym("set"), A_SYMBOL
, 0);
2133 /* ------------------------ global setup routine ------------------------- */
2135 void d_array_setup(void)
2137 tabwrite_tilde_setup();
2138 tabplay_tilde_setup();
2139 tabread_tilde_setup();
2140 tabread4_tilde_setup();
2141 tabosc4_tilde_setup();