FS#8961 - Anti-Aliased Fonts.
[kugel-rb.git] / apps / plugins / pdbox / PDa / src / d_ctl.c
blobaa8df4fae817d79c6881ef9db7f4cc42a1f21dad
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. */
5 /* sig~ and line~ control-to-signal converters;
6 snapshot~ signal-to-control converter.
7 */
9 #include "m_pd.h"
10 #include "math.h"
12 /* -------------------------- sig~ ------------------------------ */
13 static t_class *sig_tilde_class;
15 typedef struct _sig
17 t_object x_obj;
18 float x_f;
19 } t_sig;
21 static t_int *sig_tilde_perform(t_int *w)
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);
31 static t_int *sig_tilde_perf8(t_int *w)
33 t_float f = *(t_float *)(w[1]);
34 t_float *out = (t_float *)(w[2]);
35 int n = (int)(w[3]);
37 for (; n; n -= 8, out += 8)
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;
48 return (w+4);
51 void dsp_add_scalarcopy(t_sample *in, t_sample *out, int n)
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);
59 static void sig_tilde_float(t_sig *x, t_float f)
61 x->x_f = f;
64 static void sig_tilde_dsp(t_sig *x, t_signal **sp)
66 dsp_add(sig_tilde_perform, 3, &x->x_f, sp[0]->s_vec, sp[0]->s_n);
69 static void *sig_tilde_new(t_floatarg f)
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);
77 #ifndef ROCKBOX
78 static
79 #endif
80 void sig_tilde_setup(void)
82 sig_tilde_class = class_new(gensym("sig~"), (t_newmethod)sig_tilde_new, 0,
83 sizeof(t_sig), 0, A_DEFFLOAT, 0);
84 class_addfloat(sig_tilde_class, (t_method)sig_tilde_float);
85 class_addmethod(sig_tilde_class, (t_method)sig_tilde_dsp, gensym("dsp"), 0);
89 #ifndef FIXEDPOINT
91 /* -------------------------- line~ ------------------------------ */
92 static t_class *line_tilde_class;
94 typedef struct _line
96 t_object x_obj;
97 float x_target;
98 float x_value;
99 float x_biginc;
100 float x_inc;
101 float x_1overn;
102 float x_dspticktomsec;
103 float x_inletvalue;
104 float x_inletwas;
105 int x_ticksleft;
106 int x_retarget;
107 } t_line;
109 static t_int *line_tilde_perform(t_int *w)
111 t_line *x = (t_line *)(w[1]);
112 t_float *out = (t_float *)(w[2]);
113 int n = (int)(w[3]);
114 float f = x->x_value;
116 if (PD_BIGORSMALL(f))
117 x->x_value = f = 0;
118 if (x->x_retarget)
120 int nticks = x->x_inletwas * x->x_dspticktomsec;
121 if (!nticks) nticks = 1;
122 x->x_ticksleft = nticks;
123 x->x_biginc = (x->x_target - x->x_value)/(float)nticks;
124 x->x_inc = x->x_1overn * x->x_biginc;
125 x->x_retarget = 0;
127 if (x->x_ticksleft)
129 float f = x->x_value;
130 while (n--) *out++ = f, f += x->x_inc;
131 x->x_value += x->x_biginc;
132 x->x_ticksleft--;
134 else
136 x->x_value = x->x_target;
137 while (n--) *out++ = x->x_value;
139 return (w+4);
142 static void line_tilde_float(t_line *x, t_float f)
144 if (x->x_inletvalue <= 0)
146 x->x_target = x->x_value = f;
147 x->x_ticksleft = x->x_retarget = 0;
149 else
151 x->x_target = f;
152 x->x_retarget = 1;
153 x->x_inletwas = x->x_inletvalue;
154 x->x_inletvalue = 0;
158 static void line_tilde_stop(t_line *x)
160 x->x_target = x->x_value;
161 x->x_ticksleft = x->x_retarget = 0;
164 static void line_tilde_dsp(t_line *x, t_signal **sp)
166 dsp_add(line_tilde_perform, 3, x, sp[0]->s_vec, sp[0]->s_n);
167 x->x_1overn = 1./sp[0]->s_n;
168 x->x_dspticktomsec = sp[0]->s_sr / (1000 * sp[0]->s_n);
171 static void *line_tilde_new(void)
173 t_line *x = (t_line *)pd_new(line_tilde_class);
174 outlet_new(&x->x_obj, gensym("signal"));
175 floatinlet_new(&x->x_obj, &x->x_inletvalue);
176 x->x_ticksleft = x->x_retarget = 0;
177 x->x_value = x->x_target = x->x_inletvalue = x->x_inletwas = 0;
178 return (x);
181 static void line_tilde_setup(void)
183 line_tilde_class = class_new(gensym("line~"), line_tilde_new, 0,
184 sizeof(t_line), 0, 0);
185 class_addfloat(line_tilde_class, (t_method)line_tilde_float);
186 class_addmethod(line_tilde_class, (t_method)line_tilde_dsp,
187 gensym("dsp"), 0);
188 class_addmethod(line_tilde_class, (t_method)line_tilde_stop,
189 gensym("stop"), 0);
192 /* -------------------------- vline~ ------------------------------ */
193 static t_class *vline_tilde_class;
195 typedef struct _vseg
197 double s_targettime;
198 double s_starttime;
199 float s_target;
200 struct _vseg *s_next;
201 } t_vseg;
203 typedef struct _vline
205 t_object x_obj;
206 double x_value;
207 double x_inc;
208 double x_referencetime;
209 double x_samppermsec;
210 double x_msecpersamp;
211 double x_targettime;
212 float x_target;
213 float x_inlet1;
214 float x_inlet2;
215 t_vseg *x_list;
216 } t_vline;
218 static t_int *vline_tilde_perform(t_int *w)
220 t_vline *x = (t_vline *)(w[1]);
221 t_float *out = (t_float *)(w[2]);
222 int n = (int)(w[3]), i;
223 double f = x->x_value;
224 double inc = x->x_inc;
225 double msecpersamp = x->x_msecpersamp;
226 double samppermsec = x->x_samppermsec;
227 double timenow = clock_gettimesince(x->x_referencetime) - n * msecpersamp;
228 t_vseg *s = x->x_list;
229 for (i = 0; i < n; i++)
231 double timenext = timenow + msecpersamp;
232 checknext:
233 if (s)
235 /* has starttime elapsed? If so update value and increment */
236 if (s->s_starttime < timenext)
238 if (x->x_targettime <= timenext)
239 f = x->x_target, inc = 0;
240 /* if zero-length segment bash output value */
241 if (s->s_targettime <= s->s_starttime)
243 f = s->s_target;
244 inc = 0;
246 else
248 double incpermsec = (s->s_target - f)/
249 (s->s_targettime - s->s_starttime);
250 f = f + incpermsec * (timenext - s->s_starttime);
251 inc = incpermsec * msecpersamp;
253 x->x_inc = inc;
254 x->x_target = s->s_target;
255 x->x_targettime = s->s_targettime;
256 x->x_list = s->s_next;
257 t_freebytes(s, sizeof(*s));
258 s = x->x_list;
259 goto checknext;
262 if (x->x_targettime <= timenext)
263 f = x->x_target, inc = x->x_inc = 0, x->x_targettime = 1e20;
264 *out++ = f;
265 f = f + inc;
266 timenow = timenext;
268 x->x_value = f;
269 return (w+4);
272 static void vline_tilde_stop(t_vline *x)
274 t_vseg *s1, *s2;
275 for (s1 = x->x_list; s1; s1 = s2)
276 s2 = s1->s_next, t_freebytes(s1, sizeof(*s1));
277 x->x_list = 0;
278 x->x_inc = 0;
279 x->x_inlet1 = x->x_inlet2 = 0;
280 x->x_target = x->x_value;
281 x->x_targettime = 1e20;
284 static void vline_tilde_float(t_vline *x, t_float f)
286 double timenow = clock_gettimesince(x->x_referencetime);
287 float inlet1 = (x->x_inlet1 < 0 ? 0 : x->x_inlet1);
288 float inlet2 = x->x_inlet2;
289 double starttime = timenow + inlet2;
290 t_vseg *s1, *s2, *deletefrom = 0, *snew;
291 if (PD_BIGORSMALL(f))
292 f = 0;
294 /* negative delay input means stop and jump immediately to new value */
295 if (inlet2 < 0)
297 x->x_value = f;
298 vline_tilde_stop(x);
299 return;
301 snew = (t_vseg *)t_getbytes(sizeof(*snew));
302 /* check if we supplant the first item in the list. We supplant
303 an item by having an earlier starttime, or an equal starttime unless
304 the equal one was instantaneous and the new one isn't (in which case
305 we'll do a jump-and-slide starting at that time.) */
306 if (!x->x_list || x->x_list->s_starttime > starttime ||
307 (x->x_list->s_starttime == starttime &&
308 (x->x_list->s_targettime > x->x_list->s_starttime || inlet1 <= 0)))
310 deletefrom = x->x_list;
311 x->x_list = snew;
313 else
315 for (s1 = x->x_list; s2 = s1->s_next; s1 = s2)
317 if (s2->s_starttime > starttime ||
318 (s2->s_starttime == starttime &&
319 (s2->s_targettime > s2->s_starttime || inlet1 <= 0)))
321 deletefrom = s2;
322 s1->s_next = snew;
323 goto didit;
326 s1->s_next = snew;
327 deletefrom = 0;
328 didit: ;
330 while (deletefrom)
332 s1 = deletefrom->s_next;
333 t_freebytes(deletefrom, sizeof(*deletefrom));
334 deletefrom = s1;
336 snew->s_next = 0;
337 snew->s_target = f;
338 snew->s_starttime = starttime;
339 snew->s_targettime = starttime + inlet1;
340 x->x_inlet1 = x->x_inlet2 = 0;
343 static void vline_tilde_dsp(t_vline *x, t_signal **sp)
345 dsp_add(vline_tilde_perform, 3, x, sp[0]->s_vec, sp[0]->s_n);
346 x->x_samppermsec = ((double)(sp[0]->s_sr)) / 1000;
347 x->x_msecpersamp = ((double)1000) / sp[0]->s_sr;
350 static void *vline_tilde_new(void)
352 t_vline *x = (t_vline *)pd_new(vline_tilde_class);
353 outlet_new(&x->x_obj, gensym("signal"));
354 floatinlet_new(&x->x_obj, &x->x_inlet1);
355 floatinlet_new(&x->x_obj, &x->x_inlet2);
356 x->x_inlet1 = x->x_inlet2 = 0;
357 x->x_value = x->x_inc = 0;
358 x->x_referencetime = clock_getlogicaltime();
359 x->x_list = 0;
360 x->x_samppermsec = 0;
361 x->x_targettime = 1e20;
362 return (x);
365 static void vline_tilde_setup(void)
367 vline_tilde_class = class_new(gensym("vline~"), vline_tilde_new,
368 (t_method)vline_tilde_stop, sizeof(t_vline), 0, 0);
369 class_addfloat(vline_tilde_class, (t_method)vline_tilde_float);
370 class_addmethod(vline_tilde_class, (t_method)vline_tilde_dsp,
371 gensym("dsp"), 0);
372 class_addmethod(vline_tilde_class, (t_method)vline_tilde_stop,
373 gensym("stop"), 0);
376 /* -------------------------- snapshot~ ------------------------------ */
377 static t_class *snapshot_tilde_class;
379 typedef struct _snapshot
381 t_object x_obj;
382 t_sample x_value;
383 float x_f;
384 } t_snapshot;
386 static void *snapshot_tilde_new(void)
388 t_snapshot *x = (t_snapshot *)pd_new(snapshot_tilde_class);
389 x->x_value = 0;
390 outlet_new(&x->x_obj, &s_float);
391 x->x_f = 0;
392 return (x);
395 static t_int *snapshot_tilde_perform(t_int *w)
397 t_float *in = (t_float *)(w[1]);
398 t_float *out = (t_float *)(w[2]);
399 *out = *in;
400 return (w+3);
403 static void snapshot_tilde_dsp(t_snapshot *x, t_signal **sp)
405 dsp_add(snapshot_tilde_perform, 2, sp[0]->s_vec + (sp[0]->s_n-1),
406 &x->x_value);
409 static void snapshot_tilde_bang(t_snapshot *x)
411 outlet_float(x->x_obj.ob_outlet, x->x_value);
414 static void snapshot_tilde_set(t_snapshot *x, t_floatarg f)
416 x->x_value = f;
419 static void snapshot_tilde_setup(void)
421 snapshot_tilde_class = class_new(gensym("snapshot~"), snapshot_tilde_new, 0,
422 sizeof(t_snapshot), 0, 0);
423 CLASS_MAINSIGNALIN(snapshot_tilde_class, t_snapshot, x_f);
424 class_addmethod(snapshot_tilde_class, (t_method)snapshot_tilde_dsp,
425 gensym("dsp"), 0);
426 class_addmethod(snapshot_tilde_class, (t_method)snapshot_tilde_set,
427 gensym("set"), A_DEFFLOAT, 0);
428 class_addbang(snapshot_tilde_class, snapshot_tilde_bang);
431 /* -------------------------- vsnapshot~ ------------------------------ */
432 static t_class *vsnapshot_tilde_class;
434 typedef struct _vsnapshot
436 t_object x_obj;
437 int x_n;
438 int x_gotone;
439 t_sample *x_vec;
440 float x_f;
441 float x_sampspermsec;
442 double x_time;
443 } t_vsnapshot;
445 static void *vsnapshot_tilde_new(void)
447 t_vsnapshot *x = (t_vsnapshot *)pd_new(vsnapshot_tilde_class);
448 outlet_new(&x->x_obj, &s_float);
449 x->x_f = 0;
450 x->x_n = 0;
451 x->x_vec = 0;
452 x->x_gotone = 0;
453 return (x);
456 static t_int *vsnapshot_tilde_perform(t_int *w)
458 t_float *in = (t_float *)(w[1]);
459 t_vsnapshot *x = (t_vsnapshot *)(w[2]);
460 t_float *out = x->x_vec;
461 int n = x->x_n, i;
462 for (i = 0; i < n; i++)
463 out[i] = in[i];
464 x->x_time = clock_getlogicaltime();
465 x->x_gotone = 1;
466 return (w+3);
469 static void vsnapshot_tilde_dsp(t_vsnapshot *x, t_signal **sp)
471 int n = sp[0]->s_n;
472 if (n != x->x_n)
474 if (x->x_vec)
475 t_freebytes(x->x_vec, x->x_n * sizeof(t_sample));
476 x->x_vec = (t_sample *)getbytes(n * sizeof(t_sample));
477 x->x_gotone = 0;
478 x->x_n = n;
480 x->x_sampspermsec = sp[0]->s_sr / 1000;
481 dsp_add(vsnapshot_tilde_perform, 2, sp[0]->s_vec, x);
484 static void vsnapshot_tilde_bang(t_vsnapshot *x)
486 float val;
487 if (x->x_gotone)
489 int indx = clock_gettimesince(x->x_time) * x->x_sampspermsec;
490 if (indx < 0)
491 indx = 0;
492 else if (indx >= x->x_n)
493 indx = x->x_n - 1;
494 val = x->x_vec[indx];
496 else val = 0;
497 outlet_float(x->x_obj.ob_outlet, val);
500 static void vsnapshot_tilde_ff(t_vsnapshot *x)
502 if (x->x_vec)
503 t_freebytes(x->x_vec, x->x_n * sizeof(t_sample));
506 static void vsnapshot_tilde_setup(void)
508 vsnapshot_tilde_class = class_new(gensym("vsnapshot~"),
509 vsnapshot_tilde_new, (t_method)vsnapshot_tilde_ff,
510 sizeof(t_vsnapshot), 0, 0);
511 CLASS_MAINSIGNALIN(vsnapshot_tilde_class, t_vsnapshot, x_f);
512 class_addmethod(vsnapshot_tilde_class, (t_method)vsnapshot_tilde_dsp, gensym("dsp"), 0);
513 class_addbang(vsnapshot_tilde_class, vsnapshot_tilde_bang);
517 /* ---------------- env~ - simple envelope follower. ----------------- */
519 #define MAXOVERLAP 10
520 #define MAXVSTAKEN 64
522 typedef struct sigenv
524 t_object x_obj; /* header */
525 void *x_outlet; /* a "float" outlet */
526 void *x_clock; /* a "clock" object */
527 float *x_buf; /* a Hanning window */
528 int x_phase; /* number of points since last output */
529 int x_period; /* requested period of output */
530 int x_realperiod; /* period rounded up to vecsize multiple */
531 int x_npoints; /* analysis window size in samples */
532 float x_result; /* result to output */
533 float x_sumbuf[MAXOVERLAP]; /* summing buffer */
534 float x_f;
535 } t_sigenv;
537 t_class *env_tilde_class;
538 static void env_tilde_tick(t_sigenv *x);
540 static void *env_tilde_new(t_floatarg fnpoints, t_floatarg fperiod)
542 int npoints = fnpoints;
543 int period = fperiod;
544 t_sigenv *x;
545 float *buf;
546 int i;
548 if (npoints < 1) npoints = 1024;
549 if (period < 1) period = npoints/2;
550 if (period < npoints / MAXOVERLAP + 1)
551 period = npoints / MAXOVERLAP + 1;
552 if (!(buf = getbytes(sizeof(float) * (npoints + MAXVSTAKEN))))
554 error("env: couldn't allocate buffer");
555 return (0);
557 x = (t_sigenv *)pd_new(env_tilde_class);
558 x->x_buf = buf;
559 x->x_npoints = npoints;
560 x->x_phase = 0;
561 x->x_period = period;
562 for (i = 0; i < MAXOVERLAP; i++) x->x_sumbuf[i] = 0;
563 for (i = 0; i < npoints; i++)
564 buf[i] = (1. - cos((2 * 3.14159 * i) / npoints))/npoints;
565 for (; i < npoints+MAXVSTAKEN; i++) buf[i] = 0;
566 x->x_clock = clock_new(x, (t_method)env_tilde_tick);
567 x->x_outlet = outlet_new(&x->x_obj, gensym("float"));
568 x->x_f = 0;
569 return (x);
572 static t_int *env_tilde_perform(t_int *w)
574 t_sigenv *x = (t_sigenv *)(w[1]);
575 t_float *in = (t_float *)(w[2]);
576 int n = (int)(w[3]);
577 int count;
578 float *sump;
579 in += n;
580 for (count = x->x_phase, sump = x->x_sumbuf;
581 count < x->x_npoints; count += x->x_realperiod, sump++)
583 float *hp = x->x_buf + count;
584 float *fp = in;
585 float sum = *sump;
586 int i;
588 for (i = 0; i < n; i++)
590 fp--;
591 sum += *hp++ * (*fp * *fp);
593 *sump = sum;
595 sump[0] = 0;
596 x->x_phase -= n;
597 if (x->x_phase < 0)
599 x->x_result = x->x_sumbuf[0];
600 for (count = x->x_realperiod, sump = x->x_sumbuf;
601 count < x->x_npoints; count += x->x_realperiod, sump++)
602 sump[0] = sump[1];
603 sump[0] = 0;
604 x->x_phase = x->x_realperiod - n;
605 clock_delay(x->x_clock, 0L);
607 return (w+4);
610 static void env_tilde_dsp(t_sigenv *x, t_signal **sp)
612 if (x->x_period % sp[0]->s_n) x->x_realperiod =
613 x->x_period + sp[0]->s_n - (x->x_period % sp[0]->s_n);
614 else x->x_realperiod = x->x_period;
615 dsp_add(env_tilde_perform, 3, x, sp[0]->s_vec, sp[0]->s_n);
616 if (sp[0]->s_n > MAXVSTAKEN) bug("env_tilde_dsp");
619 static void env_tilde_tick(t_sigenv *x) /* callback function for the clock */
621 outlet_float(x->x_outlet, powtodb(x->x_result));
624 static void env_tilde_ff(t_sigenv *x) /* cleanup on free */
626 clock_free(x->x_clock);
627 freebytes(x->x_buf, (x->x_npoints + MAXVSTAKEN) * sizeof(float));
631 void env_tilde_setup(void )
633 env_tilde_class = class_new(gensym("env~"), (t_newmethod)env_tilde_new,
634 (t_method)env_tilde_ff, sizeof(t_sigenv), 0, A_DEFFLOAT, A_DEFFLOAT, 0);
635 CLASS_MAINSIGNALIN(env_tilde_class, t_sigenv, x_f);
636 class_addmethod(env_tilde_class, (t_method)env_tilde_dsp, gensym("dsp"), 0);
639 /* --------------------- threshold~ ----------------------------- */
641 static t_class *threshold_tilde_class;
643 typedef struct _threshold_tilde
645 t_object x_obj;
646 t_outlet *x_outlet1; /* bang out for high thresh */
647 t_outlet *x_outlet2; /* bang out for low thresh */
648 t_clock *x_clock; /* wakeup for message output */
649 float x_f; /* scalar inlet */
650 int x_state; /* 1 = high, 0 = low */
651 float x_hithresh; /* value of high threshold */
652 float x_lothresh; /* value of low threshold */
653 float x_deadwait; /* msec remaining in dead period */
654 float x_msecpertick; /* msec per DSP tick */
655 float x_hideadtime; /* hi dead time in msec */
656 float x_lodeadtime; /* lo dead time in msec */
657 } t_threshold_tilde;
659 static void threshold_tilde_tick(t_threshold_tilde *x);
660 static void threshold_tilde_set(t_threshold_tilde *x,
661 t_floatarg hithresh, t_floatarg hideadtime,
662 t_floatarg lothresh, t_floatarg lodeadtime);
664 static t_threshold_tilde *threshold_tilde_new(t_floatarg hithresh,
665 t_floatarg hideadtime, t_floatarg lothresh, t_floatarg lodeadtime)
667 t_threshold_tilde *x = (t_threshold_tilde *)
668 pd_new(threshold_tilde_class);
669 x->x_state = 0; /* low state */
670 x->x_deadwait = 0; /* no dead time */
671 x->x_clock = clock_new(x, (t_method)threshold_tilde_tick);
672 x->x_outlet1 = outlet_new(&x->x_obj, &s_bang);
673 x->x_outlet2 = outlet_new(&x->x_obj, &s_bang);
674 inlet_new(&x->x_obj, &x->x_obj.ob_pd, &s_float, gensym("ft1"));
675 x->x_msecpertick = 0.;
676 x->x_f = 0;
677 threshold_tilde_set(x, hithresh, hideadtime, lothresh, lodeadtime);
678 return (x);
681 /* "set" message to specify thresholds and dead times */
682 static void threshold_tilde_set(t_threshold_tilde *x,
683 t_floatarg hithresh, t_floatarg hideadtime,
684 t_floatarg lothresh, t_floatarg lodeadtime)
686 if (lothresh > hithresh)
687 lothresh = hithresh;
688 x->x_hithresh = hithresh;
689 x->x_hideadtime = hideadtime;
690 x->x_lothresh = lothresh;
691 x->x_lodeadtime = lodeadtime;
694 /* number in inlet sets state -- note incompatible with JMAX which used
695 "int" message for this, impossible here because of auto signal conversion */
696 static void threshold_tilde_ft1(t_threshold_tilde *x, t_floatarg f)
698 x->x_state = (f != 0);
699 x->x_deadwait = 0;
702 static void threshold_tilde_tick(t_threshold_tilde *x)
704 if (x->x_state)
705 outlet_bang(x->x_outlet1);
706 else outlet_bang(x->x_outlet2);
709 static t_int *threshold_tilde_perform(t_int *w)
711 float *in1 = (float *)(w[1]);
712 t_threshold_tilde *x = (t_threshold_tilde *)(w[2]);
713 int n = (t_int)(w[3]);
714 if (x->x_deadwait > 0)
715 x->x_deadwait -= x->x_msecpertick;
716 else if (x->x_state)
718 /* we're high; look for low sample */
719 for (; n--; in1++)
721 if (*in1 < x->x_lothresh)
723 clock_delay(x->x_clock, 0L);
724 x->x_state = 0;
725 x->x_deadwait = x->x_lodeadtime;
726 goto done;
730 else
732 /* we're low; look for high sample */
733 for (; n--; in1++)
735 if (*in1 >= x->x_hithresh)
737 clock_delay(x->x_clock, 0L);
738 x->x_state = 1;
739 x->x_deadwait = x->x_hideadtime;
740 goto done;
744 done:
745 return (w+4);
748 void threshold_tilde_dsp(t_threshold_tilde *x, t_signal **sp)
750 x->x_msecpertick = 1000. * sp[0]->s_n / sp[0]->s_sr;
751 dsp_add(threshold_tilde_perform, 3, sp[0]->s_vec, x, sp[0]->s_n);
754 static void threshold_tilde_ff(t_threshold_tilde *x)
756 clock_free(x->x_clock);
759 static void threshold_tilde_setup( void)
761 threshold_tilde_class = class_new(gensym("threshold~"),
762 (t_newmethod)threshold_tilde_new, (t_method)threshold_tilde_ff,
763 sizeof(t_threshold_tilde), 0,
764 A_DEFFLOAT, A_DEFFLOAT, A_DEFFLOAT, A_DEFFLOAT, 0);
765 CLASS_MAINSIGNALIN(threshold_tilde_class, t_threshold_tilde, x_f);
766 class_addmethod(threshold_tilde_class, (t_method)threshold_tilde_set,
767 gensym("set"), A_FLOAT, A_FLOAT, A_FLOAT, A_FLOAT, 0);
768 class_addmethod(threshold_tilde_class, (t_method)threshold_tilde_ft1,
769 gensym("ft1"), A_FLOAT, 0);
770 class_addmethod(threshold_tilde_class, (t_method)threshold_tilde_dsp,
771 gensym("dsp"), 0);
774 /* ------------------------ global setup routine ------------------------- */
776 void d_ctl_setup(void)
778 sig_tilde_setup();
779 line_tilde_setup();
780 vline_tilde_setup();
781 snapshot_tilde_setup();
782 vsnapshot_tilde_setup();
783 env_tilde_setup();
784 threshold_tilde_setup();
787 #endif