diff options
author | Peter D'Hoye <peter.dhoye@gmail.com> | 2009-05-22 21:58:48 +0000 |
---|---|---|
committer | Peter D'Hoye <peter.dhoye@gmail.com> | 2009-05-22 21:58:48 +0000 |
commit | 513389b4c1bc8afe4b2dc9947c534bfeb105e3da (patch) | |
tree | 10e673b35651ac567fed2eda0c679c7ade64cbc6 /apps/plugins/pdbox/PDa/src/d_ctl.c | |
parent | 95fa7f6a2ef466444fbe3fe87efc6d5db6b77b36 (diff) | |
download | rockbox-513389b4c1bc8afe4b2dc9947c534bfeb105e3da.tar.gz rockbox-513389b4c1bc8afe4b2dc9947c534bfeb105e3da.zip |
Add FS #10214. Initial commit of the original PDa code for the GSoC Pure Data plugin project of Wincent Balin. Stripped some non-sourcefiles and added a rockbox readme that needs a bit more info from Wincent. Is added to CATEGORIES and viewers, but not yet to SUBDIRS (ie doesn't build yet)
git-svn-id: svn://svn.rockbox.org/rockbox/trunk@21044 a1c6a512-1295-4272-9138-f99709370657
Diffstat (limited to 'apps/plugins/pdbox/PDa/src/d_ctl.c')
-rw-r--r-- | apps/plugins/pdbox/PDa/src/d_ctl.c | 1568 |
1 files changed, 1568 insertions, 0 deletions
diff --git a/apps/plugins/pdbox/PDa/src/d_ctl.c b/apps/plugins/pdbox/PDa/src/d_ctl.c new file mode 100644 index 0000000000..d3262af800 --- /dev/null +++ b/apps/plugins/pdbox/PDa/src/d_ctl.c | |||
@@ -0,0 +1,1568 @@ | |||
1 | /* Copyright (c) 1997-1999 Miller Puckette. | ||
2 | * For information on usage and redistribution, and for a DISCLAIMER OF ALL | ||
3 | * WARRANTIES, see the file, "LICENSE.txt," in this distribution. */ | ||
4 | |||
5 | /* sig~ and line~ control-to-signal converters; | ||
6 | snapshot~ signal-to-control converter. | ||
7 | */ | ||
8 | |||
9 | #include "m_pd.h" | ||
10 | #include "math.h" | ||
11 | |||
12 | /* -------------------------- sig~ ------------------------------ */ | ||
13 | static t_class *sig_tilde_class; | ||
14 | |||
15 | typedef struct _sig | ||
16 | { | ||
17 | t_object x_obj; | ||
18 | float x_f; | ||
19 | } t_sig; | ||
20 | |||
21 | static t_int *sig_tilde_perform(t_int *w) | ||
22 | { | ||
23 | t_float f = *(t_float *)(w[1]); | ||
24 | t_float *out = (t_float *)(w[2]); | ||
25 | int n = (int)(w[3]); | ||
26 | while (n--) | ||
27 | *out++ = f; | ||
28 | return (w+4); | ||
29 | } | ||
30 | |||
31 | static t_int *sig_tilde_perf8(t_int *w) | ||
32 | { | ||
33 | t_float f = *(t_float *)(w[1]); | ||
34 | t_float *out = (t_float *)(w[2]); | ||
35 | int n = (int)(w[3]); | ||
36 | |||
37 | for (; n; n -= 8, out += 8) | ||
38 | { | ||
39 | out[0] = f; | ||
40 | out[1] = f; | ||
41 | out[2] = f; | ||
42 | out[3] = f; | ||
43 | out[4] = f; | ||
44 | out[5] = f; | ||
45 | out[6] = f; | ||
46 | out[7] = f; | ||
47 | } | ||
48 | return (w+4); | ||
49 | } | ||
50 | |||
51 | void dsp_add_scalarcopy(t_sample *in, t_sample *out, int n) | ||
52 | { | ||
53 | if (n&7) | ||
54 | dsp_add(sig_tilde_perform, 3, in, out, n); | ||
55 | else | ||
56 | dsp_add(sig_tilde_perf8, 3, in, out, n); | ||
57 | } | ||
58 | |||
59 | static void sig_tilde_float(t_sig *x, t_float f) | ||
60 | { | ||
61 | x->x_f = f; | ||
62 | } | ||
63 | |||
64 | static void sig_tilde_dsp(t_sig *x, t_signal **sp) | ||
65 | { | ||
66 | dsp_add(sig_tilde_perform, 3, &x->x_f, sp[0]->s_vec, sp[0]->s_n); | ||
67 | } | ||
68 | |||
69 | static void *sig_tilde_new(t_floatarg f) | ||
70 | { | ||
71 | t_sig *x = (t_sig *)pd_new(sig_tilde_class); | ||
72 | x->x_f = f; | ||
73 | outlet_new(&x->x_obj, gensym("signal")); | ||
74 | return (x); | ||
75 | } | ||
76 | |||
77 | static void sig_tilde_setup(void) | ||
78 | { | ||
79 | sig_tilde_class = class_new(gensym("sig~"), (t_newmethod)sig_tilde_new, 0, | ||
80 | sizeof(t_sig), 0, A_DEFFLOAT, 0); | ||
81 | class_addfloat(sig_tilde_class, (t_method)sig_tilde_float); | ||
82 | class_addmethod(sig_tilde_class, (t_method)sig_tilde_dsp, gensym("dsp"), 0); | ||
83 | } | ||
84 | |||
85 | |||
86 | #ifndef FIXEDPOINT | ||
87 | |||
88 | /* -------------------------- line~ ------------------------------ */ | ||
89 | static t_class *line_tilde_class; | ||
90 | |||
91 | typedef struct _line | ||
92 | { | ||
93 | t_object x_obj; | ||
94 | float x_target; | ||
95 | float x_value; | ||
96 | float x_biginc; | ||
97 | float x_inc; | ||
98 | float x_1overn; | ||
99 | float x_dspticktomsec; | ||
100 | float x_inletvalue; | ||
101 | float x_inletwas; | ||
102 | int x_ticksleft; | ||
103 | int x_retarget; | ||
104 | } t_line; | ||
105 | |||
106 | static t_int *line_tilde_perform(t_int *w) | ||
107 | { | ||
108 | t_line *x = (t_line *)(w[1]); | ||
109 | t_float *out = (t_float *)(w[2]); | ||
110 | int n = (int)(w[3]); | ||
111 | float f = x->x_value; | ||
112 | |||
113 | if (PD_BIGORSMALL(f)) | ||
114 | x->x_value = f = 0; | ||
115 | if (x->x_retarget) | ||
116 | { | ||
117 | int nticks = x->x_inletwas * x->x_dspticktomsec; | ||
118 | if (!nticks) nticks = 1; | ||
119 | x->x_ticksleft = nticks; | ||
120 | x->x_biginc = (x->x_target - x->x_value)/(float)nticks; | ||
121 | x->x_inc = x->x_1overn * x->x_biginc; | ||
122 | x->x_retarget = 0; | ||
123 | } | ||
124 | if (x->x_ticksleft) | ||
125 | { | ||
126 | float f = x->x_value; | ||
127 | while (n--) *out++ = f, f += x->x_inc; | ||
128 | x->x_value += x->x_biginc; | ||
129 | x->x_ticksleft--; | ||
130 | } | ||
131 | else | ||
132 | { | ||
133 | x->x_value = x->x_target; | ||
134 | while (n--) *out++ = x->x_value; | ||
135 | } | ||
136 | return (w+4); | ||
137 | } | ||
138 | |||
139 | static void line_tilde_float(t_line *x, t_float f) | ||
140 | { | ||
141 | if (x->x_inletvalue <= 0) | ||
142 | { | ||
143 | x->x_target = x->x_value = f; | ||
144 | x->x_ticksleft = x->x_retarget = 0; | ||
145 | } | ||
146 | else | ||
147 | { | ||
148 | x->x_target = f; | ||
149 | x->x_retarget = 1; | ||
150 | x->x_inletwas = x->x_inletvalue; | ||
151 | x->x_inletvalue = 0; | ||
152 | } | ||
153 | } | ||
154 | |||
155 | static void line_tilde_stop(t_line *x) | ||
156 | { | ||
157 | x->x_target = x->x_value; | ||
158 | x->x_ticksleft = x->x_retarget = 0; | ||
159 | } | ||
160 | |||
161 | static void line_tilde_dsp(t_line *x, t_signal **sp) | ||
162 | { | ||
163 | dsp_add(line_tilde_perform, 3, x, sp[0]->s_vec, sp[0]->s_n); | ||
164 | x->x_1overn = 1./sp[0]->s_n; | ||
165 | x->x_dspticktomsec = sp[0]->s_sr / (1000 * sp[0]->s_n); | ||
166 | } | ||
167 | |||
168 | static void *line_tilde_new(void) | ||
169 | { | ||
170 | t_line *x = (t_line *)pd_new(line_tilde_class); | ||
171 | outlet_new(&x->x_obj, gensym("signal")); | ||
172 | floatinlet_new(&x->x_obj, &x->x_inletvalue); | ||
173 | x->x_ticksleft = x->x_retarget = 0; | ||
174 | x->x_value = x->x_target = x->x_inletvalue = x->x_inletwas = 0; | ||
175 | return (x); | ||
176 | } | ||
177 | |||
178 | static void line_tilde_setup(void) | ||
179 | { | ||
180 | line_tilde_class = class_new(gensym("line~"), line_tilde_new, 0, | ||
181 | sizeof(t_line), 0, 0); | ||
182 | class_addfloat(line_tilde_class, (t_method)line_tilde_float); | ||
183 | class_addmethod(line_tilde_class, (t_method)line_tilde_dsp, | ||
184 | gensym("dsp"), 0); | ||
185 | class_addmethod(line_tilde_class, (t_method)line_tilde_stop, | ||
186 | gensym("stop"), 0); | ||
187 | } | ||
188 | |||
189 | /* -------------------------- vline~ ------------------------------ */ | ||
190 | static t_class *vline_tilde_class; | ||
191 | |||
192 | typedef struct _vseg | ||
193 | { | ||
194 | double s_targettime; | ||
195 | double s_starttime; | ||
196 | float s_target; | ||
197 | struct _vseg *s_next; | ||
198 | } t_vseg; | ||
199 | |||
200 | typedef struct _vline | ||
201 | { | ||
202 | t_object x_obj; | ||
203 | double x_value; | ||
204 | double x_inc; | ||
205 | double x_referencetime; | ||
206 | double x_samppermsec; | ||
207 | double x_msecpersamp; | ||
208 | double x_targettime; | ||
209 | float x_target; | ||
210 | float x_inlet1; | ||
211 | float x_inlet2; | ||
212 | t_vseg *x_list; | ||
213 | } t_vline; | ||
214 | |||
215 | static t_int *vline_tilde_perform(t_int *w) | ||
216 | { | ||
217 | t_vline *x = (t_vline *)(w[1]); | ||
218 | t_float *out = (t_float *)(w[2]); | ||
219 | int n = (int)(w[3]), i; | ||
220 | double f = x->x_value; | ||
221 | double inc = x->x_inc; | ||
222 | double msecpersamp = x->x_msecpersamp; | ||
223 | double samppermsec = x->x_samppermsec; | ||
224 | double timenow = clock_gettimesince(x->x_referencetime) - n * msecpersamp; | ||
225 | t_vseg *s = x->x_list; | ||
226 | for (i = 0; i < n; i++) | ||
227 | { | ||
228 | double timenext = timenow + msecpersamp; | ||
229 | checknext: | ||
230 | if (s) | ||
231 | { | ||
232 | /* has starttime elapsed? If so update value and increment */ | ||
233 | if (s->s_starttime < timenext) | ||
234 | { | ||
235 | if (x->x_targettime <= timenext) | ||
236 | f = x->x_target, inc = 0; | ||
237 | /* if zero-length segment bash output value */ | ||
238 | if (s->s_targettime <= s->s_starttime) | ||
239 | { | ||
240 | f = s->s_target; | ||
241 | inc = 0; | ||
242 | } | ||
243 | else | ||
244 | { | ||
245 | double incpermsec = (s->s_target - f)/ | ||
246 | (s->s_targettime - s->s_starttime); | ||
247 | f = f + incpermsec * (timenext - s->s_starttime); | ||
248 | inc = incpermsec * msecpersamp; | ||
249 | } | ||
250 | x->x_inc = inc; | ||
251 | x->x_target = s->s_target; | ||
252 | x->x_targettime = s->s_targettime; | ||
253 | x->x_list = s->s_next; | ||
254 | t_freebytes(s, sizeof(*s)); | ||
255 | s = x->x_list; | ||
256 | goto checknext; | ||
257 | } | ||
258 | } | ||
259 | if (x->x_targettime <= timenext) | ||
260 | f = x->x_target, inc = x->x_inc = 0, x->x_targettime = 1e20; | ||
261 | *out++ = f; | ||
262 | f = f + inc; | ||
263 | timenow = timenext; | ||
264 | } | ||
265 | x->x_value = f; | ||
266 | return (w+4); | ||
267 | } | ||
268 | |||
269 | static void vline_tilde_stop(t_vline *x) | ||
270 | { | ||
271 | t_vseg *s1, *s2; | ||
272 | for (s1 = x->x_list; s1; s1 = s2) | ||
273 | s2 = s1->s_next, t_freebytes(s1, sizeof(*s1)); | ||
274 | x->x_list = 0; | ||
275 | x->x_inc = 0; | ||
276 | x->x_inlet1 = x->x_inlet2 = 0; | ||
277 | x->x_target = x->x_value; | ||
278 | x->x_targettime = 1e20; | ||
279 | } | ||
280 | |||
281 | static void vline_tilde_float(t_vline *x, t_float f) | ||
282 | { | ||
283 | double timenow = clock_gettimesince(x->x_referencetime); | ||
284 | float inlet1 = (x->x_inlet1 < 0 ? 0 : x->x_inlet1); | ||
285 | float inlet2 = x->x_inlet2; | ||
286 | double starttime = timenow + inlet2; | ||
287 | t_vseg *s1, *s2, *deletefrom = 0, *snew; | ||
288 | if (PD_BIGORSMALL(f)) | ||
289 | f = 0; | ||
290 | |||
291 | /* negative delay input means stop and jump immediately to new value */ | ||
292 | if (inlet2 < 0) | ||
293 | { | ||
294 | x->x_value = f; | ||
295 | vline_tilde_stop(x); | ||
296 | return; | ||
297 | } | ||
298 | snew = (t_vseg *)t_getbytes(sizeof(*snew)); | ||
299 | /* check if we supplant the first item in the list. We supplant | ||
300 | an item by having an earlier starttime, or an equal starttime unless | ||
301 | the equal one was instantaneous and the new one isn't (in which case | ||
302 | we'll do a jump-and-slide starting at that time.) */ | ||
303 | if (!x->x_list || x->x_list->s_starttime > starttime || | ||
304 | (x->x_list->s_starttime == starttime && | ||
305 | (x->x_list->s_targettime > x->x_list->s_starttime || inlet1 <= 0))) | ||
306 | { | ||
307 | deletefrom = x->x_list; | ||
308 | x->x_list = snew; | ||
309 | } | ||
310 | else | ||
311 | { | ||
312 | for (s1 = x->x_list; s2 = s1->s_next; s1 = s2) | ||
313 | { | ||
314 | if (s2->s_starttime > starttime || | ||
315 | (s2->s_starttime == starttime && | ||
316 | (s2->s_targettime > s2->s_starttime || inlet1 <= 0))) | ||
317 | { | ||
318 | deletefrom = s2; | ||
319 | s1->s_next = snew; | ||
320 | goto didit; | ||
321 | } | ||
322 | } | ||
323 | s1->s_next = snew; | ||
324 | deletefrom = 0; | ||
325 | didit: ; | ||
326 | } | ||
327 | while (deletefrom) | ||
328 | { | ||
329 | s1 = deletefrom->s_next; | ||
330 | t_freebytes(deletefrom, sizeof(*deletefrom)); | ||
331 | deletefrom = s1; | ||
332 | } | ||
333 | snew->s_next = 0; | ||
334 | snew->s_target = f; | ||
335 | snew->s_starttime = starttime; | ||
336 | snew->s_targettime = starttime + inlet1; | ||
337 | x->x_inlet1 = x->x_inlet2 = 0; | ||
338 | } | ||
339 | |||
340 | static void vline_tilde_dsp(t_vline *x, t_signal **sp) | ||
341 | { | ||
342 | dsp_add(vline_tilde_perform, 3, x, sp[0]->s_vec, sp[0]->s_n); | ||
343 | x->x_samppermsec = ((double)(sp[0]->s_sr)) / 1000; | ||
344 | x->x_msecpersamp = ((double)1000) / sp[0]->s_sr; | ||
345 | } | ||
346 | |||
347 | static void *vline_tilde_new(void) | ||
348 | { | ||
349 | t_vline *x = (t_vline *)pd_new(vline_tilde_class); | ||
350 | outlet_new(&x->x_obj, gensym("signal")); | ||
351 | floatinlet_new(&x->x_obj, &x->x_inlet1); | ||
352 | floatinlet_new(&x->x_obj, &x->x_inlet2); | ||
353 | x->x_inlet1 = x->x_inlet2 = 0; | ||
354 | x->x_value = x->x_inc = 0; | ||
355 | x->x_referencetime = clock_getlogicaltime(); | ||
356 | x->x_list = 0; | ||
357 | x->x_samppermsec = 0; | ||
358 | x->x_targettime = 1e20; | ||
359 | return (x); | ||
360 | } | ||
361 | |||
362 | static void vline_tilde_setup(void) | ||
363 | { | ||
364 | vline_tilde_class = class_new(gensym("vline~"), vline_tilde_new, | ||
365 | (t_method)vline_tilde_stop, sizeof(t_vline), 0, 0); | ||
366 | class_addfloat(vline_tilde_class, (t_method)vline_tilde_float); | ||
367 | class_addmethod(vline_tilde_class, (t_method)vline_tilde_dsp, | ||
368 | gensym("dsp"), 0); | ||
369 | class_addmethod(vline_tilde_class, (t_method)vline_tilde_stop, | ||
370 | gensym("stop"), 0); | ||
371 | } | ||
372 | |||
373 | /* -------------------------- snapshot~ ------------------------------ */ | ||
374 | static t_class *snapshot_tilde_class; | ||
375 | |||
376 | typedef struct _snapshot | ||
377 | { | ||
378 | t_object x_obj; | ||
379 | t_sample x_value; | ||
380 | float x_f; | ||
381 | } t_snapshot; | ||
382 | |||
383 | static void *snapshot_tilde_new(void) | ||
384 | { | ||
385 | t_snapshot *x = (t_snapshot *)pd_new(snapshot_tilde_class); | ||
386 | x->x_value = 0; | ||
387 | outlet_new(&x->x_obj, &s_float); | ||
388 | x->x_f = 0; | ||
389 | return (x); | ||
390 | } | ||
391 | |||
392 | static t_int *snapshot_tilde_perform(t_int *w) | ||
393 | { | ||
394 | t_float *in = (t_float *)(w[1]); | ||
395 | t_float *out = (t_float *)(w[2]); | ||
396 | *out = *in; | ||
397 | return (w+3); | ||
398 | } | ||
399 | |||
400 | static void snapshot_tilde_dsp(t_snapshot *x, t_signal **sp) | ||
401 | { | ||
402 | dsp_add(snapshot_tilde_perform, 2, sp[0]->s_vec + (sp[0]->s_n-1), | ||
403 | &x->x_value); | ||
404 | } | ||
405 | |||
406 | static void snapshot_tilde_bang(t_snapshot *x) | ||
407 | { | ||
408 | outlet_float(x->x_obj.ob_outlet, x->x_value); | ||
409 | } | ||
410 | |||
411 | static void snapshot_tilde_set(t_snapshot *x, t_floatarg f) | ||
412 | { | ||
413 | x->x_value = f; | ||
414 | } | ||
415 | |||
416 | static void snapshot_tilde_setup(void) | ||
417 | { | ||
418 | snapshot_tilde_class = class_new(gensym("snapshot~"), snapshot_tilde_new, 0, | ||
419 | sizeof(t_snapshot), 0, 0); | ||
420 | CLASS_MAINSIGNALIN(snapshot_tilde_class, t_snapshot, x_f); | ||
421 | class_addmethod(snapshot_tilde_class, (t_method)snapshot_tilde_dsp, | ||
422 | gensym("dsp"), 0); | ||
423 | class_addmethod(snapshot_tilde_class, (t_method)snapshot_tilde_set, | ||
424 | gensym("set"), A_DEFFLOAT, 0); | ||
425 | class_addbang(snapshot_tilde_class, snapshot_tilde_bang); | ||
426 | } | ||
427 | |||
428 | /* -------------------------- vsnapshot~ ------------------------------ */ | ||
429 | static t_class *vsnapshot_tilde_class; | ||
430 | |||
431 | typedef struct _vsnapshot | ||
432 | { | ||
433 | t_object x_obj; | ||
434 | int x_n; | ||
435 | int x_gotone; | ||
436 | t_sample *x_vec; | ||
437 | float x_f; | ||
438 | float x_sampspermsec; | ||
439 | double x_time; | ||
440 | } t_vsnapshot; | ||
441 | |||
442 | static void *vsnapshot_tilde_new(void) | ||
443 | { | ||
444 | t_vsnapshot *x = (t_vsnapshot *)pd_new(vsnapshot_tilde_class); | ||
445 | outlet_new(&x->x_obj, &s_float); | ||
446 | x->x_f = 0; | ||
447 | x->x_n = 0; | ||
448 | x->x_vec = 0; | ||
449 | x->x_gotone = 0; | ||
450 | return (x); | ||
451 | } | ||
452 | |||
453 | static t_int *vsnapshot_tilde_perform(t_int *w) | ||
454 | { | ||
455 | t_float *in = (t_float *)(w[1]); | ||
456 | t_vsnapshot *x = (t_vsnapshot *)(w[2]); | ||
457 | t_float *out = x->x_vec; | ||
458 | int n = x->x_n, i; | ||
459 | for (i = 0; i < n; i++) | ||
460 | out[i] = in[i]; | ||
461 | x->x_time = clock_getlogicaltime(); | ||
462 | x->x_gotone = 1; | ||
463 | return (w+3); | ||
464 | } | ||
465 | |||
466 | static void vsnapshot_tilde_dsp(t_vsnapshot *x, t_signal **sp) | ||
467 | { | ||
468 | int n = sp[0]->s_n; | ||
469 | if (n != x->x_n) | ||
470 | { | ||
471 | if (x->x_vec) | ||
472 | t_freebytes(x->x_vec, x->x_n * sizeof(t_sample)); | ||
473 | x->x_vec = (t_sample *)getbytes(n * sizeof(t_sample)); | ||
474 | x->x_gotone = 0; | ||
475 | x->x_n = n; | ||
476 | } | ||
477 | x->x_sampspermsec = sp[0]->s_sr / 1000; | ||
478 | dsp_add(vsnapshot_tilde_perform, 2, sp[0]->s_vec, x); | ||
479 | } | ||
480 | |||
481 | static void vsnapshot_tilde_bang(t_vsnapshot *x) | ||
482 | { | ||
483 | float val; | ||
484 | if (x->x_gotone) | ||
485 | { | ||
486 | int indx = clock_gettimesince(x->x_time) * x->x_sampspermsec; | ||
487 | if (indx < 0) | ||
488 | indx = 0; | ||
489 | else if (indx >= x->x_n) | ||
490 | indx = x->x_n - 1; | ||
491 | val = x->x_vec[indx]; | ||
492 | } | ||
493 | else val = 0; | ||
494 | outlet_float(x->x_obj.ob_outlet, val); | ||
495 | } | ||
496 | |||
497 | static void vsnapshot_tilde_ff(t_vsnapshot *x) | ||
498 | { | ||
499 | if (x->x_vec) | ||
500 | t_freebytes(x->x_vec, x->x_n * sizeof(t_sample)); | ||
501 | } | ||
502 | |||
503 | static void vsnapshot_tilde_setup(void) | ||
504 | { | ||
505 | vsnapshot_tilde_class = class_new(gensym("vsnapshot~"), | ||
506 | vsnapshot_tilde_new, (t_method)vsnapshot_tilde_ff, | ||
507 | sizeof(t_vsnapshot), 0, 0); | ||
508 | CLASS_MAINSIGNALIN(vsnapshot_tilde_class, t_vsnapshot, x_f); | ||
509 | class_addmethod(vsnapshot_tilde_class, (t_method)vsnapshot_tilde_dsp, gensym("dsp"), 0); | ||
510 | class_addbang(vsnapshot_tilde_class, vsnapshot_tilde_bang); | ||
511 | } | ||
512 | |||
513 | |||
514 | /* ---------------- env~ - simple envelope follower. ----------------- */ | ||
515 | |||
516 | #define MAXOVERLAP 10 | ||
517 | #define MAXVSTAKEN 64 | ||
518 | |||
519 | typedef struct sigenv | ||
520 | { | ||
521 | t_object x_obj; /* header */ | ||
522 | void *x_outlet; /* a "float" outlet */ | ||
523 | void *x_clock; /* a "clock" object */ | ||
524 | float *x_buf; /* a Hanning window */ | ||
525 | int x_phase; /* number of points since last output */ | ||
526 | int x_period; /* requested period of output */ | ||
527 | int x_realperiod; /* period rounded up to vecsize multiple */ | ||
528 | int x_npoints; /* analysis window size in samples */ | ||
529 | float x_result; /* result to output */ | ||
530 | float x_sumbuf[MAXOVERLAP]; /* summing buffer */ | ||
531 | float x_f; | ||
532 | } t_sigenv; | ||
533 | |||
534 | t_class *env_tilde_class; | ||
535 | static void env_tilde_tick(t_sigenv *x); | ||
536 | |||
537 | static void *env_tilde_new(t_floatarg fnpoints, t_floatarg fperiod) | ||
538 | { | ||
539 | int npoints = fnpoints; | ||
540 | int period = fperiod; | ||
541 | t_sigenv *x; | ||
542 | float *buf; | ||
543 | int i; | ||
544 | |||
545 | if (npoints < 1) npoints = 1024; | ||
546 | if (period < 1) period = npoints/2; | ||
547 | if (period < npoints / MAXOVERLAP + 1) | ||
548 | period = npoints / MAXOVERLAP + 1; | ||
549 | if (!(buf = getbytes(sizeof(float) * (npoints + MAXVSTAKEN)))) | ||
550 | { | ||
551 | error("env: couldn't allocate buffer"); | ||
552 | return (0); | ||
553 | } | ||
554 | x = (t_sigenv *)pd_new(env_tilde_class); | ||
555 | x->x_buf = buf; | ||
556 | x->x_npoints = npoints; | ||
557 | x->x_phase = 0; | ||
558 | x->x_period = period; | ||
559 | for (i = 0; i < MAXOVERLAP; i++) x->x_sumbuf[i] = 0; | ||
560 | for (i = 0; i < npoints; i++) | ||
561 | buf[i] = (1. - cos((2 * 3.14159 * i) / npoints))/npoints; | ||
562 | for (; i < npoints+MAXVSTAKEN; i++) buf[i] = 0; | ||
563 | x->x_clock = clock_new(x, (t_method)env_tilde_tick); | ||
564 | x->x_outlet = outlet_new(&x->x_obj, gensym("float")); | ||
565 | x->x_f = 0; | ||
566 | return (x); | ||
567 | } | ||
568 | |||
569 | static t_int *env_tilde_perform(t_int *w) | ||
570 | { | ||
571 | t_sigenv *x = (t_sigenv *)(w[1]); | ||
572 | t_float *in = (t_float *)(w[2]); | ||
573 | int n = (int)(w[3]); | ||
574 | int count; | ||
575 | float *sump; | ||
576 | in += n; | ||
577 | for (count = x->x_phase, sump = x->x_sumbuf; | ||
578 | count < x->x_npoints; count += x->x_realperiod, sump++) | ||
579 | { | ||
580 | float *hp = x->x_buf + count; | ||
581 | float *fp = in; | ||
582 | float sum = *sump; | ||
583 | int i; | ||
584 | |||
585 | for (i = 0; i < n; i++) | ||
586 | { | ||
587 | fp--; | ||
588 | sum += *hp++ * (*fp * *fp); | ||
589 | } | ||
590 | *sump = sum; | ||
591 | } | ||
592 | sump[0] = 0; | ||
593 | x->x_phase -= n; | ||
594 | if (x->x_phase < 0) | ||
595 | { | ||
596 | x->x_result = x->x_sumbuf[0]; | ||
597 | for (count = x->x_realperiod, sump = x->x_sumbuf; | ||
598 | count < x->x_npoints; count += x->x_realperiod, sump++) | ||
599 | sump[0] = sump[1]; | ||
600 | sump[0] = 0; | ||
601 | x->x_phase = x->x_realperiod - n; | ||
602 | clock_delay(x->x_clock, 0L); | ||
603 | } | ||
604 | return (w+4); | ||
605 | } | ||
606 | |||
607 | static void env_tilde_dsp(t_sigenv *x, t_signal **sp) | ||
608 | { | ||
609 | if (x->x_period % sp[0]->s_n) x->x_realperiod = | ||
610 | x->x_period + sp[0]->s_n - (x->x_period % sp[0]->s_n); | ||
611 | else x->x_realperiod = x->x_period; | ||
612 | dsp_add(env_tilde_perform, 3, x, sp[0]->s_vec, sp[0]->s_n); | ||
613 | if (sp[0]->s_n > MAXVSTAKEN) bug("env_tilde_dsp"); | ||
614 | } | ||
615 | |||
616 | static void env_tilde_tick(t_sigenv *x) /* callback function for the clock */ | ||
617 | { | ||
618 | outlet_float(x->x_outlet, powtodb(x->x_result)); | ||
619 | } | ||
620 | |||
621 | static void env_tilde_ff(t_sigenv *x) /* cleanup on free */ | ||
622 | { | ||
623 | clock_free(x->x_clock); | ||
624 | freebytes(x->x_buf, (x->x_npoints + MAXVSTAKEN) * sizeof(float)); | ||
625 | } | ||
626 | |||
627 | |||
628 | void env_tilde_setup(void ) | ||
629 | { | ||
630 | env_tilde_class = class_new(gensym("env~"), (t_newmethod)env_tilde_new, | ||
631 | (t_method)env_tilde_ff, sizeof(t_sigenv), 0, A_DEFFLOAT, A_DEFFLOAT, 0); | ||
632 | CLASS_MAINSIGNALIN(env_tilde_class, t_sigenv, x_f); | ||
633 | class_addmethod(env_tilde_class, (t_method)env_tilde_dsp, gensym("dsp"), 0); | ||
634 | } | ||
635 | |||
636 | /* --------------------- threshold~ ----------------------------- */ | ||
637 | |||
638 | static t_class *threshold_tilde_class; | ||
639 | |||
640 | typedef struct _threshold_tilde | ||
641 | { | ||
642 | t_object x_obj; | ||
643 | t_outlet *x_outlet1; /* bang out for high thresh */ | ||
644 | t_outlet *x_outlet2; /* bang out for low thresh */ | ||
645 | t_clock *x_clock; /* wakeup for message output */ | ||
646 | float x_f; /* scalar inlet */ | ||
647 | int x_state; /* 1 = high, 0 = low */ | ||
648 | float x_hithresh; /* value of high threshold */ | ||
649 | float x_lothresh; /* value of low threshold */ | ||
650 | float x_deadwait; /* msec remaining in dead period */ | ||
651 | float x_msecpertick; /* msec per DSP tick */ | ||
652 | float x_hideadtime; /* hi dead time in msec */ | ||
653 | float x_lodeadtime; /* lo dead time in msec */ | ||
654 | } t_threshold_tilde; | ||
655 | |||
656 | static void threshold_tilde_tick(t_threshold_tilde *x); | ||
657 | static void threshold_tilde_set(t_threshold_tilde *x, | ||
658 | t_floatarg hithresh, t_floatarg hideadtime, | ||
659 | t_floatarg lothresh, t_floatarg lodeadtime); | ||
660 | |||
661 | static t_threshold_tilde *threshold_tilde_new(t_floatarg hithresh, | ||
662 | t_floatarg hideadtime, t_floatarg lothresh, t_floatarg lodeadtime) | ||
663 | { | ||
664 | t_threshold_tilde *x = (t_threshold_tilde *) | ||
665 | pd_new(threshold_tilde_class); | ||
666 | x->x_state = 0; /* low state */ | ||
667 | x->x_deadwait = 0; /* no dead time */ | ||
668 | x->x_clock = clock_new(x, (t_method)threshold_tilde_tick); | ||
669 | x->x_outlet1 = outlet_new(&x->x_obj, &s_bang); | ||
670 | x->x_outlet2 = outlet_new(&x->x_obj, &s_bang); | ||
671 | inlet_new(&x->x_obj, &x->x_obj.ob_pd, &s_float, gensym("ft1")); | ||
672 | x->x_msecpertick = 0.; | ||
673 | x->x_f = 0; | ||
674 | threshold_tilde_set(x, hithresh, hideadtime, lothresh, lodeadtime); | ||
675 | return (x); | ||
676 | } | ||
677 | |||
678 | /* "set" message to specify thresholds and dead times */ | ||
679 | static void threshold_tilde_set(t_threshold_tilde *x, | ||
680 | t_floatarg hithresh, t_floatarg hideadtime, | ||
681 | t_floatarg lothresh, t_floatarg lodeadtime) | ||
682 | { | ||
683 | if (lothresh > hithresh) | ||
684 | lothresh = hithresh; | ||
685 | x->x_hithresh = hithresh; | ||
686 | x->x_hideadtime = hideadtime; | ||
687 | x->x_lothresh = lothresh; | ||
688 | x->x_lodeadtime = lodeadtime; | ||
689 | } | ||
690 | |||
691 | /* number in inlet sets state -- note incompatible with JMAX which used | ||
692 | "int" message for this, impossible here because of auto signal conversion */ | ||
693 | static void threshold_tilde_ft1(t_threshold_tilde *x, t_floatarg f) | ||
694 | { | ||
695 | x->x_state = (f != 0); | ||
696 | x->x_deadwait = 0; | ||
697 | } | ||
698 | |||
699 | static void threshold_tilde_tick(t_threshold_tilde *x) | ||
700 | { | ||
701 | if (x->x_state) | ||
702 | outlet_bang(x->x_outlet1); | ||
703 | else outlet_bang(x->x_outlet2); | ||
704 | } | ||
705 | |||
706 | static t_int *threshold_tilde_perform(t_int *w) | ||
707 | { | ||
708 | float *in1 = (float *)(w[1]); | ||
709 | t_threshold_tilde *x = (t_threshold_tilde *)(w[2]); | ||
710 | int n = (t_int)(w[3]); | ||
711 | if (x->x_deadwait > 0) | ||
712 | x->x_deadwait -= x->x_msecpertick; | ||
713 | else if (x->x_state) | ||
714 | { | ||
715 | /* we're high; look for low sample */ | ||
716 | for (; n--; in1++) | ||
717 | { | ||
718 | if (*in1 < x->x_lothresh) | ||
719 | { | ||
720 | clock_delay(x->x_clock, 0L); | ||
721 | x->x_state = 0; | ||
722 | x->x_deadwait = x->x_lodeadtime; | ||
723 | goto done; | ||
724 | } | ||
725 | } | ||
726 | } | ||
727 | else | ||
728 | { | ||
729 | /* we're low; look for high sample */ | ||
730 | for (; n--; in1++) | ||
731 | { | ||
732 | if (*in1 >= x->x_hithresh) | ||
733 | { | ||
734 | clock_delay(x->x_clock, 0L); | ||
735 | x->x_state = 1; | ||
736 | x->x_deadwait = x->x_hideadtime; | ||
737 | goto done; | ||
738 | } | ||
739 | } | ||
740 | } | ||
741 | done: | ||
742 | return (w+4); | ||
743 | } | ||
744 | |||
745 | void threshold_tilde_dsp(t_threshold_tilde *x, t_signal **sp) | ||
746 | { | ||
747 | x->x_msecpertick = 1000. * sp[0]->s_n / sp[0]->s_sr; | ||
748 | dsp_add(threshold_tilde_perform, 3, sp[0]->s_vec, x, sp[0]->s_n); | ||
749 | } | ||
750 | |||
751 | static void threshold_tilde_ff(t_threshold_tilde *x) | ||
752 | { | ||
753 | clock_free(x->x_clock); | ||
754 | } | ||
755 | |||
756 | static void threshold_tilde_setup( void) | ||
757 | { | ||
758 | threshold_tilde_class = class_new(gensym("threshold~"), | ||
759 | (t_newmethod)threshold_tilde_new, (t_method)threshold_tilde_ff, | ||
760 | sizeof(t_threshold_tilde), 0, | ||
761 | A_DEFFLOAT, A_DEFFLOAT, A_DEFFLOAT, A_DEFFLOAT, 0); | ||
762 | CLASS_MAINSIGNALIN(threshold_tilde_class, t_threshold_tilde, x_f); | ||
763 | class_addmethod(threshold_tilde_class, (t_method)threshold_tilde_set, | ||
764 | gensym("set"), A_FLOAT, A_FLOAT, A_FLOAT, A_FLOAT, 0); | ||
765 | class_addmethod(threshold_tilde_class, (t_method)threshold_tilde_ft1, | ||
766 | gensym("ft1"), A_FLOAT, 0); | ||
767 | class_addmethod(threshold_tilde_class, (t_method)threshold_tilde_dsp, | ||
768 | gensym("dsp"), 0); | ||
769 | } | ||
770 | |||
771 | /* ------------------------ global setup routine ------------------------- */ | ||
772 | |||
773 | void d_ctl_setup(void) | ||
774 | { | ||
775 | sig_tilde_setup(); | ||
776 | line_tilde_setup(); | ||
777 | vline_tilde_setup(); | ||
778 | snapshot_tilde_setup(); | ||
779 | vsnapshot_tilde_setup(); | ||
780 | env_tilde_setup(); | ||
781 | threshold_tilde_setup(); | ||
782 | } | ||
783 | |||
784 | #endif | ||
785 | /* Copyright (c) 1997-1999 Miller Puckette. | ||
786 | * For information on usage and redistribution, and for a DISCLAIMER OF ALL | ||
787 | * WARRANTIES, see the file, "LICENSE.txt," in this distribution. */ | ||
788 | |||
789 | /* sig~ and line~ control-to-signal converters; | ||
790 | snapshot~ signal-to-control converter. | ||
791 | */ | ||
792 | |||
793 | #include "m_pd.h" | ||
794 | #include "math.h" | ||
795 | |||
796 | /* -------------------------- sig~ ------------------------------ */ | ||
797 | static t_class *sig_tilde_class; | ||
798 | |||
799 | typedef struct _sig | ||
800 | { | ||
801 | t_object x_obj; | ||
802 | float x_f; | ||
803 | } t_sig; | ||
804 | |||
805 | static t_int *sig_tilde_perform(t_int *w) | ||
806 | { | ||
807 | t_float f = *(t_float *)(w[1]); | ||
808 | t_float *out = (t_float *)(w[2]); | ||
809 | int n = (int)(w[3]); | ||
810 | while (n--) | ||
811 | *out++ = f; | ||
812 | return (w+4); | ||
813 | } | ||
814 | |||
815 | static t_int *sig_tilde_perf8(t_int *w) | ||
816 | { | ||
817 | t_float f = *(t_float *)(w[1]); | ||
818 | t_float *out = (t_float *)(w[2]); | ||
819 | int n = (int)(w[3]); | ||
820 | |||
821 | for (; n; n -= 8, out += 8) | ||
822 | { | ||
823 | out[0] = f; | ||
824 | out[1] = f; | ||
825 | out[2] = f; | ||
826 | out[3] = f; | ||
827 | out[4] = f; | ||
828 | out[5] = f; | ||
829 | out[6] = f; | ||
830 | out[7] = f; | ||
831 | } | ||
832 | return (w+4); | ||
833 | } | ||
834 | |||
835 | void dsp_add_scalarcopy(t_sample *in, t_sample *out, int n) | ||
836 | { | ||
837 | if (n&7) | ||
838 | dsp_add(sig_tilde_perform, 3, in, out, n); | ||
839 | else | ||
840 | dsp_add(sig_tilde_perf8, 3, in, out, n); | ||
841 | } | ||
842 | |||
843 | static void sig_tilde_float(t_sig *x, t_float f) | ||
844 | { | ||
845 | x->x_f = f; | ||
846 | } | ||
847 | |||
848 | static void sig_tilde_dsp(t_sig *x, t_signal **sp) | ||
849 | { | ||
850 | dsp_add(sig_tilde_perform, 3, &x->x_f, sp[0]->s_vec, sp[0]->s_n); | ||
851 | } | ||
852 | |||
853 | static void *sig_tilde_new(t_floatarg f) | ||
854 | { | ||
855 | t_sig *x = (t_sig *)pd_new(sig_tilde_class); | ||
856 | x->x_f = f; | ||
857 | outlet_new(&x->x_obj, gensym("signal")); | ||
858 | return (x); | ||
859 | } | ||
860 | |||
861 | static void sig_tilde_setup(void) | ||
862 | { | ||
863 | sig_tilde_class = class_new(gensym("sig~"), (t_newmethod)sig_tilde_new, 0, | ||
864 | sizeof(t_sig), 0, A_DEFFLOAT, 0); | ||
865 | class_addfloat(sig_tilde_class, (t_method)sig_tilde_float); | ||
866 | class_addmethod(sig_tilde_class, (t_method)sig_tilde_dsp, gensym("dsp"), 0); | ||
867 | } | ||
868 | |||
869 | |||
870 | #ifndef FIXEDPOINT | ||
871 | |||
872 | /* -------------------------- line~ ------------------------------ */ | ||
873 | static t_class *line_tilde_class; | ||
874 | |||
875 | typedef struct _line | ||
876 | { | ||
877 | t_object x_obj; | ||
878 | float x_target; | ||
879 | float x_value; | ||
880 | float x_biginc; | ||
881 | float x_inc; | ||
882 | float x_1overn; | ||
883 | float x_dspticktomsec; | ||
884 | float x_inletvalue; | ||
885 | float x_inletwas; | ||
886 | int x_ticksleft; | ||
887 | int x_retarget; | ||
888 | } t_line; | ||
889 | |||
890 | static t_int *line_tilde_perform(t_int *w) | ||
891 | { | ||
892 | t_line *x = (t_line *)(w[1]); | ||
893 | t_float *out = (t_float *)(w[2]); | ||
894 | int n = (int)(w[3]); | ||
895 | float f = x->x_value; | ||
896 | |||
897 | if (PD_BIGORSMALL(f)) | ||
898 | x->x_value = f = 0; | ||
899 | if (x->x_retarget) | ||
900 | { | ||
901 | int nticks = x->x_inletwas * x->x_dspticktomsec; | ||
902 | if (!nticks) nticks = 1; | ||
903 | x->x_ticksleft = nticks; | ||
904 | x->x_biginc = (x->x_target - x->x_value)/(float)nticks; | ||
905 | x->x_inc = x->x_1overn * x->x_biginc; | ||
906 | x->x_retarget = 0; | ||
907 | } | ||
908 | if (x->x_ticksleft) | ||
909 | { | ||
910 | float f = x->x_value; | ||
911 | while (n--) *out++ = f, f += x->x_inc; | ||
912 | x->x_value += x->x_biginc; | ||
913 | x->x_ticksleft--; | ||
914 | } | ||
915 | else | ||
916 | { | ||
917 | x->x_value = x->x_target; | ||
918 | while (n--) *out++ = x->x_value; | ||
919 | } | ||
920 | return (w+4); | ||
921 | } | ||
922 | |||
923 | static void line_tilde_float(t_line *x, t_float f) | ||
924 | { | ||
925 | if (x->x_inletvalue <= 0) | ||
926 | { | ||
927 | x->x_target = x->x_value = f; | ||
928 | x->x_ticksleft = x->x_retarget = 0; | ||
929 | } | ||
930 | else | ||
931 | { | ||
932 | x->x_target = f; | ||
933 | x->x_retarget = 1; | ||
934 | x->x_inletwas = x->x_inletvalue; | ||
935 | x->x_inletvalue = 0; | ||
936 | } | ||
937 | } | ||
938 | |||
939 | static void line_tilde_stop(t_line *x) | ||
940 | { | ||
941 | x->x_target = x->x_value; | ||
942 | x->x_ticksleft = x->x_retarget = 0; | ||
943 | } | ||
944 | |||
945 | static void line_tilde_dsp(t_line *x, t_signal **sp) | ||
946 | { | ||
947 | dsp_add(line_tilde_perform, 3, x, sp[0]->s_vec, sp[0]->s_n); | ||
948 | x->x_1overn = 1./sp[0]->s_n; | ||
949 | x->x_dspticktomsec = sp[0]->s_sr / (1000 * sp[0]->s_n); | ||
950 | } | ||
951 | |||
952 | static void *line_tilde_new(void) | ||
953 | { | ||
954 | t_line *x = (t_line *)pd_new(line_tilde_class); | ||
955 | outlet_new(&x->x_obj, gensym("signal")); | ||
956 | floatinlet_new(&x->x_obj, &x->x_inletvalue); | ||
957 | x->x_ticksleft = x->x_retarget = 0; | ||
958 | x->x_value = x->x_target = x->x_inletvalue = x->x_inletwas = 0; | ||
959 | return (x); | ||
960 | } | ||
961 | |||
962 | static void line_tilde_setup(void) | ||
963 | { | ||
964 | line_tilde_class = class_new(gensym("line~"), line_tilde_new, 0, | ||
965 | sizeof(t_line), 0, 0); | ||
966 | class_addfloat(line_tilde_class, (t_method)line_tilde_float); | ||
967 | class_addmethod(line_tilde_class, (t_method)line_tilde_dsp, | ||
968 | gensym("dsp"), 0); | ||
969 | class_addmethod(line_tilde_class, (t_method)line_tilde_stop, | ||
970 | gensym("stop"), 0); | ||
971 | } | ||
972 | |||
973 | /* -------------------------- vline~ ------------------------------ */ | ||
974 | static t_class *vline_tilde_class; | ||
975 | |||
976 | typedef struct _vseg | ||
977 | { | ||
978 | double s_targettime; | ||
979 | double s_starttime; | ||
980 | float s_target; | ||
981 | struct _vseg *s_next; | ||
982 | } t_vseg; | ||
983 | |||
984 | typedef struct _vline | ||
985 | { | ||
986 | t_object x_obj; | ||
987 | double x_value; | ||
988 | double x_inc; | ||
989 | double x_referencetime; | ||
990 | double x_samppermsec; | ||
991 | double x_msecpersamp; | ||
992 | double x_targettime; | ||
993 | float x_target; | ||
994 | float x_inlet1; | ||
995 | float x_inlet2; | ||
996 | t_vseg *x_list; | ||
997 | } t_vline; | ||
998 | |||
999 | static t_int *vline_tilde_perform(t_int *w) | ||
1000 | { | ||
1001 | t_vline *x = (t_vline *)(w[1]); | ||
1002 | t_float *out = (t_float *)(w[2]); | ||
1003 | int n = (int)(w[3]), i; | ||
1004 | double f = x->x_value; | ||
1005 | double inc = x->x_inc; | ||
1006 | double msecpersamp = x->x_msecpersamp; | ||
1007 | double samppermsec = x->x_samppermsec; | ||
1008 | double timenow = clock_gettimesince(x->x_referencetime) - n * msecpersamp; | ||
1009 | t_vseg *s = x->x_list; | ||
1010 | for (i = 0; i < n; i++) | ||
1011 | { | ||
1012 | double timenext = timenow + msecpersamp; | ||
1013 | checknext: | ||
1014 | if (s) | ||
1015 | { | ||
1016 | /* has starttime elapsed? If so update value and increment */ | ||
1017 | if (s->s_starttime < timenext) | ||
1018 | { | ||
1019 | if (x->x_targettime <= timenext) | ||
1020 | f = x->x_target, inc = 0; | ||
1021 | /* if zero-length segment bash output value */ | ||
1022 | if (s->s_targettime <= s->s_starttime) | ||
1023 | { | ||
1024 | f = s->s_target; | ||
1025 | inc = 0; | ||
1026 | } | ||
1027 | else | ||
1028 | { | ||
1029 | double incpermsec = (s->s_target - f)/ | ||
1030 | (s->s_targettime - s->s_starttime); | ||
1031 | f = f + incpermsec * (timenext - s->s_starttime); | ||
1032 | inc = incpermsec * msecpersamp; | ||
1033 | } | ||
1034 | x->x_inc = inc; | ||
1035 | x->x_target = s->s_target; | ||
1036 | x->x_targettime = s->s_targettime; | ||
1037 | x->x_list = s->s_next; | ||
1038 | t_freebytes(s, sizeof(*s)); | ||
1039 | s = x->x_list; | ||
1040 | goto checknext; | ||
1041 | } | ||
1042 | } | ||
1043 | if (x->x_targettime <= timenext) | ||
1044 | f = x->x_target, inc = x->x_inc = 0, x->x_targettime = 1e20; | ||
1045 | *out++ = f; | ||
1046 | f = f + inc; | ||
1047 | timenow = timenext; | ||
1048 | } | ||
1049 | x->x_value = f; | ||
1050 | return (w+4); | ||
1051 | } | ||
1052 | |||
1053 | static void vline_tilde_stop(t_vline *x) | ||
1054 | { | ||
1055 | t_vseg *s1, *s2; | ||
1056 | for (s1 = x->x_list; s1; s1 = s2) | ||
1057 | s2 = s1->s_next, t_freebytes(s1, sizeof(*s1)); | ||
1058 | x->x_list = 0; | ||
1059 | x->x_inc = 0; | ||
1060 | x->x_inlet1 = x->x_inlet2 = 0; | ||
1061 | x->x_target = x->x_value; | ||
1062 | x->x_targettime = 1e20; | ||
1063 | } | ||
1064 | |||
1065 | static void vline_tilde_float(t_vline *x, t_float f) | ||
1066 | { | ||
1067 | double timenow = clock_gettimesince(x->x_referencetime); | ||
1068 | float inlet1 = (x->x_inlet1 < 0 ? 0 : x->x_inlet1); | ||
1069 | float inlet2 = x->x_inlet2; | ||
1070 | double starttime = timenow + inlet2; | ||
1071 | t_vseg *s1, *s2, *deletefrom = 0, *snew; | ||
1072 | if (PD_BIGORSMALL(f)) | ||
1073 | f = 0; | ||
1074 | |||
1075 | /* negative delay input means stop and jump immediately to new value */ | ||
1076 | if (inlet2 < 0) | ||
1077 | { | ||
1078 | x->x_value = f; | ||
1079 | vline_tilde_stop(x); | ||
1080 | return; | ||
1081 | } | ||
1082 | snew = (t_vseg *)t_getbytes(sizeof(*snew)); | ||
1083 | /* check if we supplant the first item in the list. We supplant | ||
1084 | an item by having an earlier starttime, or an equal starttime unless | ||
1085 | the equal one was instantaneous and the new one isn't (in which case | ||
1086 | we'll do a jump-and-slide starting at that time.) */ | ||
1087 | if (!x->x_list || x->x_list->s_starttime > starttime || | ||
1088 | (x->x_list->s_starttime == starttime && | ||
1089 | (x->x_list->s_targettime > x->x_list->s_starttime || inlet1 <= 0))) | ||
1090 | { | ||
1091 | deletefrom = x->x_list; | ||
1092 | x->x_list = snew; | ||
1093 | } | ||
1094 | else | ||
1095 | { | ||
1096 | for (s1 = x->x_list; s2 = s1->s_next; s1 = s2) | ||
1097 | { | ||
1098 | if (s2->s_starttime > starttime || | ||
1099 | (s2->s_starttime == starttime && | ||
1100 | (s2->s_targettime > s2->s_starttime || inlet1 <= 0))) | ||
1101 | { | ||
1102 | deletefrom = s2; | ||
1103 | s1->s_next = snew; | ||
1104 | goto didit; | ||
1105 | } | ||
1106 | } | ||
1107 | s1->s_next = snew; | ||
1108 | deletefrom = 0; | ||
1109 | didit: ; | ||
1110 | } | ||
1111 | while (deletefrom) | ||
1112 | { | ||
1113 | s1 = deletefrom->s_next; | ||
1114 | t_freebytes(deletefrom, sizeof(*deletefrom)); | ||
1115 | deletefrom = s1; | ||
1116 | } | ||
1117 | snew->s_next = 0; | ||
1118 | snew->s_target = f; | ||
1119 | snew->s_starttime = starttime; | ||
1120 | snew->s_targettime = starttime + inlet1; | ||
1121 | x->x_inlet1 = x->x_inlet2 = 0; | ||
1122 | } | ||
1123 | |||
1124 | static void vline_tilde_dsp(t_vline *x, t_signal **sp) | ||
1125 | { | ||
1126 | dsp_add(vline_tilde_perform, 3, x, sp[0]->s_vec, sp[0]->s_n); | ||
1127 | x->x_samppermsec = ((double)(sp[0]->s_sr)) / 1000; | ||
1128 | x->x_msecpersamp = ((double)1000) / sp[0]->s_sr; | ||
1129 | } | ||
1130 | |||
1131 | static void *vline_tilde_new(void) | ||
1132 | { | ||
1133 | t_vline *x = (t_vline *)pd_new(vline_tilde_class); | ||
1134 | outlet_new(&x->x_obj, gensym("signal")); | ||
1135 | floatinlet_new(&x->x_obj, &x->x_inlet1); | ||
1136 | floatinlet_new(&x->x_obj, &x->x_inlet2); | ||
1137 | x->x_inlet1 = x->x_inlet2 = 0; | ||
1138 | x->x_value = x->x_inc = 0; | ||
1139 | x->x_referencetime = clock_getlogicaltime(); | ||
1140 | x->x_list = 0; | ||
1141 | x->x_samppermsec = 0; | ||
1142 | x->x_targettime = 1e20; | ||
1143 | return (x); | ||
1144 | } | ||
1145 | |||
1146 | static void vline_tilde_setup(void) | ||
1147 | { | ||
1148 | vline_tilde_class = class_new(gensym("vline~"), vline_tilde_new, | ||
1149 | (t_method)vline_tilde_stop, sizeof(t_vline), 0, 0); | ||
1150 | class_addfloat(vline_tilde_class, (t_method)vline_tilde_float); | ||
1151 | class_addmethod(vline_tilde_class, (t_method)vline_tilde_dsp, | ||
1152 | gensym("dsp"), 0); | ||
1153 | class_addmethod(vline_tilde_class, (t_method)vline_tilde_stop, | ||
1154 | gensym("stop"), 0); | ||
1155 | } | ||
1156 | |||
1157 | /* -------------------------- snapshot~ ------------------------------ */ | ||
1158 | static t_class *snapshot_tilde_class; | ||
1159 | |||
1160 | typedef struct _snapshot | ||
1161 | { | ||
1162 | t_object x_obj; | ||
1163 | t_sample x_value; | ||
1164 | float x_f; | ||
1165 | } t_snapshot; | ||
1166 | |||
1167 | static void *snapshot_tilde_new(void) | ||
1168 | { | ||
1169 | t_snapshot *x = (t_snapshot *)pd_new(snapshot_tilde_class); | ||
1170 | x->x_value = 0; | ||
1171 | outlet_new(&x->x_obj, &s_float); | ||
1172 | x->x_f = 0; | ||
1173 | return (x); | ||
1174 | } | ||
1175 | |||
1176 | static t_int *snapshot_tilde_perform(t_int *w) | ||
1177 | { | ||
1178 | t_float *in = (t_float *)(w[1]); | ||
1179 | t_float *out = (t_float *)(w[2]); | ||
1180 | *out = *in; | ||
1181 | return (w+3); | ||
1182 | } | ||
1183 | |||
1184 | static void snapshot_tilde_dsp(t_snapshot *x, t_signal **sp) | ||
1185 | { | ||
1186 | dsp_add(snapshot_tilde_perform, 2, sp[0]->s_vec + (sp[0]->s_n-1), | ||
1187 | &x->x_value); | ||
1188 | } | ||
1189 | |||
1190 | static void snapshot_tilde_bang(t_snapshot *x) | ||
1191 | { | ||
1192 | outlet_float(x->x_obj.ob_outlet, x->x_value); | ||
1193 | } | ||
1194 | |||
1195 | static void snapshot_tilde_set(t_snapshot *x, t_floatarg f) | ||
1196 | { | ||
1197 | x->x_value = f; | ||
1198 | } | ||
1199 | |||
1200 | static void snapshot_tilde_setup(void) | ||
1201 | { | ||
1202 | snapshot_tilde_class = class_new(gensym("snapshot~"), snapshot_tilde_new, 0, | ||
1203 | sizeof(t_snapshot), 0, 0); | ||
1204 | CLASS_MAINSIGNALIN(snapshot_tilde_class, t_snapshot, x_f); | ||
1205 | class_addmethod(snapshot_tilde_class, (t_method)snapshot_tilde_dsp, | ||
1206 | gensym("dsp"), 0); | ||
1207 | class_addmethod(snapshot_tilde_class, (t_method)snapshot_tilde_set, | ||
1208 | gensym("set"), A_DEFFLOAT, 0); | ||
1209 | class_addbang(snapshot_tilde_class, snapshot_tilde_bang); | ||
1210 | } | ||
1211 | |||
1212 | /* -------------------------- vsnapshot~ ------------------------------ */ | ||
1213 | static t_class *vsnapshot_tilde_class; | ||
1214 | |||
1215 | typedef struct _vsnapshot | ||
1216 | { | ||
1217 | t_object x_obj; | ||
1218 | int x_n; | ||
1219 | int x_gotone; | ||
1220 | t_sample *x_vec; | ||
1221 | float x_f; | ||
1222 | float x_sampspermsec; | ||
1223 | double x_time; | ||
1224 | } t_vsnapshot; | ||
1225 | |||
1226 | static void *vsnapshot_tilde_new(void) | ||
1227 | { | ||
1228 | t_vsnapshot *x = (t_vsnapshot *)pd_new(vsnapshot_tilde_class); | ||
1229 | outlet_new(&x->x_obj, &s_float); | ||
1230 | x->x_f = 0; | ||
1231 | x->x_n = 0; | ||
1232 | x->x_vec = 0; | ||
1233 | x->x_gotone = 0; | ||
1234 | return (x); | ||
1235 | } | ||
1236 | |||
1237 | static t_int *vsnapshot_tilde_perform(t_int *w) | ||
1238 | { | ||
1239 | t_float *in = (t_float *)(w[1]); | ||
1240 | t_vsnapshot *x = (t_vsnapshot *)(w[2]); | ||
1241 | t_float *out = x->x_vec; | ||
1242 | int n = x->x_n, i; | ||
1243 | for (i = 0; i < n; i++) | ||
1244 | out[i] = in[i]; | ||
1245 | x->x_time = clock_getlogicaltime(); | ||
1246 | x->x_gotone = 1; | ||
1247 | return (w+3); | ||
1248 | } | ||
1249 | |||
1250 | static void vsnapshot_tilde_dsp(t_vsnapshot *x, t_signal **sp) | ||
1251 | { | ||
1252 | int n = sp[0]->s_n; | ||
1253 | if (n != x->x_n) | ||
1254 | { | ||
1255 | if (x->x_vec) | ||
1256 | t_freebytes(x->x_vec, x->x_n * sizeof(t_sample)); | ||
1257 | x->x_vec = (t_sample *)getbytes(n * sizeof(t_sample)); | ||
1258 | x->x_gotone = 0; | ||
1259 | x->x_n = n; | ||
1260 | } | ||
1261 | x->x_sampspermsec = sp[0]->s_sr / 1000; | ||
1262 | dsp_add(vsnapshot_tilde_perform, 2, sp[0]->s_vec, x); | ||
1263 | } | ||
1264 | |||
1265 | static void vsnapshot_tilde_bang(t_vsnapshot *x) | ||
1266 | { | ||
1267 | float val; | ||
1268 | if (x->x_gotone) | ||
1269 | { | ||
1270 | int indx = clock_gettimesince(x->x_time) * x->x_sampspermsec; | ||
1271 | if (indx < 0) | ||
1272 | indx = 0; | ||
1273 | else if (indx >= x->x_n) | ||
1274 | indx = x->x_n - 1; | ||
1275 | val = x->x_vec[indx]; | ||
1276 | } | ||
1277 | else val = 0; | ||
1278 | outlet_float(x->x_obj.ob_outlet, val); | ||
1279 | } | ||
1280 | |||
1281 | static void vsnapshot_tilde_ff(t_vsnapshot *x) | ||
1282 | { | ||
1283 | if (x->x_vec) | ||
1284 | t_freebytes(x->x_vec, x->x_n * sizeof(t_sample)); | ||
1285 | } | ||
1286 | |||
1287 | static void vsnapshot_tilde_setup(void) | ||
1288 | { | ||
1289 | vsnapshot_tilde_class = class_new(gensym("vsnapshot~"), | ||
1290 | vsnapshot_tilde_new, (t_method)vsnapshot_tilde_ff, | ||
1291 | sizeof(t_vsnapshot), 0, 0); | ||
1292 | CLASS_MAINSIGNALIN(vsnapshot_tilde_class, t_vsnapshot, x_f); | ||
1293 | class_addmethod(vsnapshot_tilde_class, (t_method)vsnapshot_tilde_dsp, gensym("dsp"), 0); | ||
1294 | class_addbang(vsnapshot_tilde_class, vsnapshot_tilde_bang); | ||
1295 | } | ||
1296 | |||
1297 | |||
1298 | /* ---------------- env~ - simple envelope follower. ----------------- */ | ||
1299 | |||
1300 | #define MAXOVERLAP 10 | ||
1301 | #define MAXVSTAKEN 64 | ||
1302 | |||
1303 | typedef struct sigenv | ||
1304 | { | ||
1305 | t_object x_obj; /* header */ | ||
1306 | void *x_outlet; /* a "float" outlet */ | ||
1307 | void *x_clock; /* a "clock" object */ | ||
1308 | float *x_buf; /* a Hanning window */ | ||
1309 | int x_phase; /* number of points since last output */ | ||
1310 | int x_period; /* requested period of output */ | ||
1311 | int x_realperiod; /* period rounded up to vecsize multiple */ | ||
1312 | int x_npoints; /* analysis window size in samples */ | ||
1313 | float x_result; /* result to output */ | ||
1314 | float x_sumbuf[MAXOVERLAP]; /* summing buffer */ | ||
1315 | float x_f; | ||
1316 | } t_sigenv; | ||
1317 | |||
1318 | t_class *env_tilde_class; | ||
1319 | static void env_tilde_tick(t_sigenv *x); | ||
1320 | |||
1321 | static void *env_tilde_new(t_floatarg fnpoints, t_floatarg fperiod) | ||
1322 | { | ||
1323 | int npoints = fnpoints; | ||
1324 | int period = fperiod; | ||
1325 | t_sigenv *x; | ||
1326 | float *buf; | ||
1327 | int i; | ||
1328 | |||
1329 | if (npoints < 1) npoints = 1024; | ||
1330 | if (period < 1) period = npoints/2; | ||
1331 | if (period < npoints / MAXOVERLAP + 1) | ||
1332 | period = npoints / MAXOVERLAP + 1; | ||
1333 | if (!(buf = getbytes(sizeof(float) * (npoints + MAXVSTAKEN)))) | ||
1334 | { | ||
1335 | error("env: couldn't allocate buffer"); | ||
1336 | return (0); | ||
1337 | } | ||
1338 | x = (t_sigenv *)pd_new(env_tilde_class); | ||
1339 | x->x_buf = buf; | ||
1340 | x->x_npoints = npoints; | ||
1341 | x->x_phase = 0; | ||
1342 | x->x_period = period; | ||
1343 | for (i = 0; i < MAXOVERLAP; i++) x->x_sumbuf[i] = 0; | ||
1344 | for (i = 0; i < npoints; i++) | ||
1345 | buf[i] = (1. - cos((2 * 3.14159 * i) / npoints))/npoints; | ||
1346 | for (; i < npoints+MAXVSTAKEN; i++) buf[i] = 0; | ||
1347 | x->x_clock = clock_new(x, (t_method)env_tilde_tick); | ||
1348 | x->x_outlet = outlet_new(&x->x_obj, gensym("float")); | ||
1349 | x->x_f = 0; | ||
1350 | return (x); | ||
1351 | } | ||
1352 | |||
1353 | static t_int *env_tilde_perform(t_int *w) | ||
1354 | { | ||
1355 | t_sigenv *x = (t_sigenv *)(w[1]); | ||
1356 | t_float *in = (t_float *)(w[2]); | ||
1357 | int n = (int)(w[3]); | ||
1358 | int count; | ||
1359 | float *sump; | ||
1360 | in += n; | ||
1361 | for (count = x->x_phase, sump = x->x_sumbuf; | ||
1362 | count < x->x_npoints; count += x->x_realperiod, sump++) | ||
1363 | { | ||
1364 | float *hp = x->x_buf + count; | ||
1365 | float *fp = in; | ||
1366 | float sum = *sump; | ||
1367 | int i; | ||
1368 | |||
1369 | for (i = 0; i < n; i++) | ||
1370 | { | ||
1371 | fp--; | ||
1372 | sum += *hp++ * (*fp * *fp); | ||
1373 | } | ||
1374 | *sump = sum; | ||
1375 | } | ||
1376 | sump[0] = 0; | ||
1377 | x->x_phase -= n; | ||
1378 | if (x->x_phase < 0) | ||
1379 | { | ||
1380 | x->x_result = x->x_sumbuf[0]; | ||
1381 | for (count = x->x_realperiod, sump = x->x_sumbuf; | ||
1382 | count < x->x_npoints; count += x->x_realperiod, sump++) | ||
1383 | sump[0] = sump[1]; | ||
1384 | sump[0] = 0; | ||
1385 | x->x_phase = x->x_realperiod - n; | ||
1386 | clock_delay(x->x_clock, 0L); | ||
1387 | } | ||
1388 | return (w+4); | ||
1389 | } | ||
1390 | |||
1391 | static void env_tilde_dsp(t_sigenv *x, t_signal **sp) | ||
1392 | { | ||
1393 | if (x->x_period % sp[0]->s_n) x->x_realperiod = | ||
1394 | x->x_period + sp[0]->s_n - (x->x_period % sp[0]->s_n); | ||
1395 | else x->x_realperiod = x->x_period; | ||
1396 | dsp_add(env_tilde_perform, 3, x, sp[0]->s_vec, sp[0]->s_n); | ||
1397 | if (sp[0]->s_n > MAXVSTAKEN) bug("env_tilde_dsp"); | ||
1398 | } | ||
1399 | |||
1400 | static void env_tilde_tick(t_sigenv *x) /* callback function for the clock */ | ||
1401 | { | ||
1402 | outlet_float(x->x_outlet, powtodb(x->x_result)); | ||
1403 | } | ||
1404 | |||
1405 | static void env_tilde_ff(t_sigenv *x) /* cleanup on free */ | ||
1406 | { | ||
1407 | clock_free(x->x_clock); | ||
1408 | freebytes(x->x_buf, (x->x_npoints + MAXVSTAKEN) * sizeof(float)); | ||
1409 | } | ||
1410 | |||
1411 | |||
1412 | void env_tilde_setup(void ) | ||
1413 | { | ||
1414 | env_tilde_class = class_new(gensym("env~"), (t_newmethod)env_tilde_new, | ||
1415 | (t_method)env_tilde_ff, sizeof(t_sigenv), 0, A_DEFFLOAT, A_DEFFLOAT, 0); | ||
1416 | CLASS_MAINSIGNALIN(env_tilde_class, t_sigenv, x_f); | ||
1417 | class_addmethod(env_tilde_class, (t_method)env_tilde_dsp, gensym("dsp"), 0); | ||
1418 | } | ||
1419 | |||
1420 | /* --------------------- threshold~ ----------------------------- */ | ||
1421 | |||
1422 | static t_class *threshold_tilde_class; | ||
1423 | |||
1424 | typedef struct _threshold_tilde | ||
1425 | { | ||
1426 | t_object x_obj; | ||
1427 | t_outlet *x_outlet1; /* bang out for high thresh */ | ||
1428 | t_outlet *x_outlet2; /* bang out for low thresh */ | ||
1429 | t_clock *x_clock; /* wakeup for message output */ | ||
1430 | float x_f; /* scalar inlet */ | ||
1431 | int x_state; /* 1 = high, 0 = low */ | ||
1432 | float x_hithresh; /* value of high threshold */ | ||
1433 | float x_lothresh; /* value of low threshold */ | ||
1434 | float x_deadwait; /* msec remaining in dead period */ | ||
1435 | float x_msecpertick; /* msec per DSP tick */ | ||
1436 | float x_hideadtime; /* hi dead time in msec */ | ||
1437 | float x_lodeadtime; /* lo dead time in msec */ | ||
1438 | } t_threshold_tilde; | ||
1439 | |||
1440 | static void threshold_tilde_tick(t_threshold_tilde *x); | ||
1441 | static void threshold_tilde_set(t_threshold_tilde *x, | ||
1442 | t_floatarg hithresh, t_floatarg hideadtime, | ||
1443 | t_floatarg lothresh, t_floatarg lodeadtime); | ||
1444 | |||
1445 | static t_threshold_tilde *threshold_tilde_new(t_floatarg hithresh, | ||
1446 | t_floatarg hideadtime, t_floatarg lothresh, t_floatarg lodeadtime) | ||
1447 | { | ||
1448 | t_threshold_tilde *x = (t_threshold_tilde *) | ||
1449 | pd_new(threshold_tilde_class); | ||
1450 | x->x_state = 0; /* low state */ | ||
1451 | x->x_deadwait = 0; /* no dead time */ | ||
1452 | x->x_clock = clock_new(x, (t_method)threshold_tilde_tick); | ||
1453 | x->x_outlet1 = outlet_new(&x->x_obj, &s_bang); | ||
1454 | x->x_outlet2 = outlet_new(&x->x_obj, &s_bang); | ||
1455 | inlet_new(&x->x_obj, &x->x_obj.ob_pd, &s_float, gensym("ft1")); | ||
1456 | x->x_msecpertick = 0.; | ||
1457 | x->x_f = 0; | ||
1458 | threshold_tilde_set(x, hithresh, hideadtime, lothresh, lodeadtime); | ||
1459 | return (x); | ||
1460 | } | ||
1461 | |||
1462 | /* "set" message to specify thresholds and dead times */ | ||
1463 | static void threshold_tilde_set(t_threshold_tilde *x, | ||
1464 | t_floatarg hithresh, t_floatarg hideadtime, | ||
1465 | t_floatarg lothresh, t_floatarg lodeadtime) | ||
1466 | { | ||
1467 | if (lothresh > hithresh) | ||
1468 | lothresh = hithresh; | ||
1469 | x->x_hithresh = hithresh; | ||
1470 | x->x_hideadtime = hideadtime; | ||
1471 | x->x_lothresh = lothresh; | ||
1472 | x->x_lodeadtime = lodeadtime; | ||
1473 | } | ||
1474 | |||
1475 | /* number in inlet sets state -- note incompatible with JMAX which used | ||
1476 | "int" message for this, impossible here because of auto signal conversion */ | ||
1477 | static void threshold_tilde_ft1(t_threshold_tilde *x, t_floatarg f) | ||
1478 | { | ||
1479 | x->x_state = (f != 0); | ||
1480 | x->x_deadwait = 0; | ||
1481 | } | ||
1482 | |||
1483 | static void threshold_tilde_tick(t_threshold_tilde *x) | ||
1484 | { | ||
1485 | if (x->x_state) | ||
1486 | outlet_bang(x->x_outlet1); | ||
1487 | else outlet_bang(x->x_outlet2); | ||
1488 | } | ||
1489 | |||
1490 | static t_int *threshold_tilde_perform(t_int *w) | ||
1491 | { | ||
1492 | float *in1 = (float *)(w[1]); | ||
1493 | t_threshold_tilde *x = (t_threshold_tilde *)(w[2]); | ||
1494 | int n = (t_int)(w[3]); | ||
1495 | if (x->x_deadwait > 0) | ||
1496 | x->x_deadwait -= x->x_msecpertick; | ||
1497 | else if (x->x_state) | ||
1498 | { | ||
1499 | /* we're high; look for low sample */ | ||
1500 | for (; n--; in1++) | ||
1501 | { | ||
1502 | if (*in1 < x->x_lothresh) | ||
1503 | { | ||
1504 | clock_delay(x->x_clock, 0L); | ||
1505 | x->x_state = 0; | ||
1506 | x->x_deadwait = x->x_lodeadtime; | ||
1507 | goto done; | ||
1508 | } | ||
1509 | } | ||
1510 | } | ||
1511 | else | ||
1512 | { | ||
1513 | /* we're low; look for high sample */ | ||
1514 | for (; n--; in1++) | ||
1515 | { | ||
1516 | if (*in1 >= x->x_hithresh) | ||
1517 | { | ||
1518 | clock_delay(x->x_clock, 0L); | ||
1519 | x->x_state = 1; | ||
1520 | x->x_deadwait = x->x_hideadtime; | ||
1521 | goto done; | ||
1522 | } | ||
1523 | } | ||
1524 | } | ||
1525 | done: | ||
1526 | return (w+4); | ||
1527 | } | ||
1528 | |||
1529 | void threshold_tilde_dsp(t_threshold_tilde *x, t_signal **sp) | ||
1530 | { | ||
1531 | x->x_msecpertick = 1000. * sp[0]->s_n / sp[0]->s_sr; | ||
1532 | dsp_add(threshold_tilde_perform, 3, sp[0]->s_vec, x, sp[0]->s_n); | ||
1533 | } | ||
1534 | |||
1535 | static void threshold_tilde_ff(t_threshold_tilde *x) | ||
1536 | { | ||
1537 | clock_free(x->x_clock); | ||
1538 | } | ||
1539 | |||
1540 | static void threshold_tilde_setup( void) | ||
1541 | { | ||
1542 | threshold_tilde_class = class_new(gensym("threshold~"), | ||
1543 | (t_newmethod)threshold_tilde_new, (t_method)threshold_tilde_ff, | ||
1544 | sizeof(t_threshold_tilde), 0, | ||
1545 | A_DEFFLOAT, A_DEFFLOAT, A_DEFFLOAT, A_DEFFLOAT, 0); | ||
1546 | CLASS_MAINSIGNALIN(threshold_tilde_class, t_threshold_tilde, x_f); | ||
1547 | class_addmethod(threshold_tilde_class, (t_method)threshold_tilde_set, | ||
1548 | gensym("set"), A_FLOAT, A_FLOAT, A_FLOAT, A_FLOAT, 0); | ||
1549 | class_addmethod(threshold_tilde_class, (t_method)threshold_tilde_ft1, | ||
1550 | gensym("ft1"), A_FLOAT, 0); | ||
1551 | class_addmethod(threshold_tilde_class, (t_method)threshold_tilde_dsp, | ||
1552 | gensym("dsp"), 0); | ||
1553 | } | ||
1554 | |||
1555 | /* ------------------------ global setup routine ------------------------- */ | ||
1556 | |||
1557 | void d_ctl_setup(void) | ||
1558 | { | ||
1559 | sig_tilde_setup(); | ||
1560 | line_tilde_setup(); | ||
1561 | vline_tilde_setup(); | ||
1562 | snapshot_tilde_setup(); | ||
1563 | vsnapshot_tilde_setup(); | ||
1564 | env_tilde_setup(); | ||
1565 | threshold_tilde_setup(); | ||
1566 | } | ||
1567 | |||
1568 | #endif | ||