diff options
Diffstat (limited to 'apps/plugins/pdbox/PDa/intern/tabplay~.c')
-rw-r--r-- | apps/plugins/pdbox/PDa/intern/tabplay~.c | 264 |
1 files changed, 264 insertions, 0 deletions
diff --git a/apps/plugins/pdbox/PDa/intern/tabplay~.c b/apps/plugins/pdbox/PDa/intern/tabplay~.c new file mode 100644 index 0000000000..c0032a1e12 --- /dev/null +++ b/apps/plugins/pdbox/PDa/intern/tabplay~.c | |||
@@ -0,0 +1,264 @@ | |||
1 | |||
2 | #define FIXEDPOINT | ||
3 | #include <m_pd.h> | ||
4 | #include <m_fixed.h> | ||
5 | |||
6 | static t_class *tabplay_tilde_class; | ||
7 | |||
8 | typedef struct _tabplay_tilde | ||
9 | { | ||
10 | t_object x_obj; | ||
11 | t_outlet *x_bangout; | ||
12 | int x_phase; | ||
13 | int x_nsampsintab; | ||
14 | int x_limit; | ||
15 | t_sample *x_vec; | ||
16 | t_symbol *x_arrayname; | ||
17 | t_clock *x_clock; | ||
18 | } t_tabplay_tilde; | ||
19 | |||
20 | static void tabplay_tilde_tick(t_tabplay_tilde *x); | ||
21 | |||
22 | static void *tabplay_tilde_new(t_symbol *s) | ||
23 | { | ||
24 | t_tabplay_tilde *x = (t_tabplay_tilde *)pd_new(tabplay_tilde_class); | ||
25 | x->x_clock = clock_new(x, (t_method)tabplay_tilde_tick); | ||
26 | x->x_phase = 0x7fffffff; | ||
27 | x->x_limit = 0; | ||
28 | x->x_arrayname = s; | ||
29 | outlet_new(&x->x_obj, &s_signal); | ||
30 | x->x_bangout = outlet_new(&x->x_obj, &s_bang); | ||
31 | return (x); | ||
32 | } | ||
33 | |||
34 | static t_int *tabplay_tilde_perform(t_int *w) | ||
35 | { | ||
36 | t_tabplay_tilde *x = (t_tabplay_tilde *)(w[1]); | ||
37 | t_sample *out = (t_sample *)(w[2]), *fp; | ||
38 | int n = (int)(w[3]), phase = x->x_phase, | ||
39 | endphase = (x->x_nsampsintab < x->x_limit ? | ||
40 | x->x_nsampsintab : x->x_limit), nxfer, n3; | ||
41 | if (!x->x_vec || phase >= endphase) | ||
42 | goto zero; | ||
43 | |||
44 | nxfer = endphase - phase; | ||
45 | fp = x->x_vec + phase; | ||
46 | if (nxfer > n) | ||
47 | nxfer = n; | ||
48 | n3 = n - nxfer; | ||
49 | phase += nxfer; | ||
50 | while (nxfer--) | ||
51 | *out++ = *fp++; | ||
52 | if (phase >= endphase) | ||
53 | { | ||
54 | clock_delay(x->x_clock, 0); | ||
55 | x->x_phase = 0x7fffffff; | ||
56 | while (n3--) | ||
57 | *out++ = 0; | ||
58 | } | ||
59 | else x->x_phase = phase; | ||
60 | |||
61 | return (w+4); | ||
62 | zero: | ||
63 | while (n--) *out++ = 0; | ||
64 | return (w+4); | ||
65 | } | ||
66 | |||
67 | void tabplay_tilde_set(t_tabplay_tilde *x, t_symbol *s) | ||
68 | { | ||
69 | t_garray *a; | ||
70 | |||
71 | x->x_arrayname = s; | ||
72 | if (!(a = (t_garray *)pd_findbyclass(x->x_arrayname, garray_class))) | ||
73 | { | ||
74 | if (*s->s_name) pd_error(x, "tabplay~: %s: no such array", | ||
75 | x->x_arrayname->s_name); | ||
76 | x->x_vec = 0; | ||
77 | } | ||
78 | else if (!garray_getfloatarray(a, &x->x_nsampsintab, &x->x_vec)) | ||
79 | { | ||
80 | error("%s: bad template for tabplay~", x->x_arrayname->s_name); | ||
81 | x->x_vec = 0; | ||
82 | } | ||
83 | else garray_usedindsp(a); | ||
84 | } | ||
85 | |||
86 | static void tabplay_tilde_dsp(t_tabplay_tilde *x, t_signal **sp) | ||
87 | { | ||
88 | tabplay_tilde_set(x, x->x_arrayname); | ||
89 | dsp_add(tabplay_tilde_perform, 3, x, sp[0]->s_vec, sp[0]->s_n); | ||
90 | } | ||
91 | |||
92 | static void tabplay_tilde_list(t_tabplay_tilde *x, t_symbol *s, | ||
93 | int argc, t_atom *argv) | ||
94 | { | ||
95 | long start = atom_getfloatarg(0, argc, argv); | ||
96 | long length = atom_getfloatarg(1, argc, argv); | ||
97 | if (start < 0) start = 0; | ||
98 | if (length <= 0) | ||
99 | x->x_limit = 0x7fffffff; | ||
100 | else | ||
101 | x->x_limit = start + length; | ||
102 | x->x_phase = start; | ||
103 | } | ||
104 | |||
105 | static void tabplay_tilde_stop(t_tabplay_tilde *x) | ||
106 | { | ||
107 | x->x_phase = 0x7fffffff; | ||
108 | } | ||
109 | |||
110 | static void tabplay_tilde_tick(t_tabplay_tilde *x) | ||
111 | { | ||
112 | outlet_bang(x->x_bangout); | ||
113 | } | ||
114 | |||
115 | static void tabplay_tilde_free(t_tabplay_tilde *x) | ||
116 | { | ||
117 | clock_free(x->x_clock); | ||
118 | } | ||
119 | |||
120 | void tabplay_tilde_setup(void) | ||
121 | { | ||
122 | tabplay_tilde_class = class_new(gensym("tabplay~"), | ||
123 | (t_newmethod)tabplay_tilde_new, (t_method)tabplay_tilde_free, | ||
124 | sizeof(t_tabplay_tilde), 0, A_DEFSYM, 0); | ||
125 | class_addmethod(tabplay_tilde_class, (t_method)tabplay_tilde_dsp, | ||
126 | gensym("dsp"), 0); | ||
127 | class_addmethod(tabplay_tilde_class, (t_method)tabplay_tilde_stop, | ||
128 | gensym("stop"), 0); | ||
129 | class_addmethod(tabplay_tilde_class, (t_method)tabplay_tilde_set, | ||
130 | gensym("set"), A_DEFSYM, 0); | ||
131 | class_addlist(tabplay_tilde_class, tabplay_tilde_list); | ||
132 | } | ||
133 | |||
134 | #define FIXEDPOINT | ||
135 | #include <m_pd.h> | ||
136 | #include <m_fixed.h> | ||
137 | |||
138 | static t_class *tabplay_tilde_class; | ||
139 | |||
140 | typedef 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 | t_sample *x_vec; | ||
148 | t_symbol *x_arrayname; | ||
149 | t_clock *x_clock; | ||
150 | } t_tabplay_tilde; | ||
151 | |||
152 | static void tabplay_tilde_tick(t_tabplay_tilde *x); | ||
153 | |||
154 | static 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 | |||
166 | static t_int *tabplay_tilde_perform(t_int *w) | ||
167 | { | ||
168 | t_tabplay_tilde *x = (t_tabplay_tilde *)(w[1]); | ||
169 | t_sample *out = (t_sample *)(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); | ||
194 | zero: | ||
195 | while (n--) *out++ = 0; | ||
196 | return (w+4); | ||
197 | } | ||
198 | |||
199 | void 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 | error("%s: bad template for tabplay~", x->x_arrayname->s_name); | ||
213 | x->x_vec = 0; | ||
214 | } | ||
215 | else garray_usedindsp(a); | ||
216 | } | ||
217 | |||
218 | static 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 | |||
224 | static 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 | |||
237 | static void tabplay_tilde_stop(t_tabplay_tilde *x) | ||
238 | { | ||
239 | x->x_phase = 0x7fffffff; | ||
240 | } | ||
241 | |||
242 | static void tabplay_tilde_tick(t_tabplay_tilde *x) | ||
243 | { | ||
244 | outlet_bang(x->x_bangout); | ||
245 | } | ||
246 | |||
247 | static void tabplay_tilde_free(t_tabplay_tilde *x) | ||
248 | { | ||
249 | clock_free(x->x_clock); | ||
250 | } | ||
251 | |||
252 | 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 | } | ||