1 #include "../src/m_pd.h"
2 #include <../src/m_fixed.h>
4 static t_class
*threshold_tilde_class
;
6 typedef struct _threshold_tilde
9 t_outlet
*x_outlet1
; /* bang out for high thresh */
10 t_outlet
*x_outlet2
; /* bang out for low thresh */
11 t_clock
*x_clock
; /* wakeup for message output */
12 float x_f
; /* scalar inlet */
13 int x_state
; /* 1 = high, 0 = low */
14 t_sample x_hithresh
; /* value of high threshold */
15 t_sample x_lothresh
; /* value of low threshold */
16 float x_deadwait
; /* msec remaining in dead period */
17 float x_msecpertick
; /* msec per DSP tick */
18 float x_hideadtime
; /* hi dead time in msec */
19 float x_lodeadtime
; /* lo dead time in msec */
22 static void threshold_tilde_tick(t_threshold_tilde
*x
);
23 static void threshold_tilde_set(t_threshold_tilde
*x
,
24 t_floatarg hithresh
, t_floatarg hideadtime
,
25 t_floatarg lothresh
, t_floatarg lodeadtime
);
27 static t_threshold_tilde
*threshold_tilde_new(t_floatarg hithresh
,
28 t_floatarg hideadtime
, t_floatarg lothresh
, t_floatarg lodeadtime
)
30 t_threshold_tilde
*x
= (t_threshold_tilde
*)
31 pd_new(threshold_tilde_class
);
32 x
->x_state
= 0; /* low state */
33 x
->x_deadwait
= 0; /* no dead time */
34 x
->x_clock
= clock_new(x
, (t_method
)threshold_tilde_tick
);
35 x
->x_outlet1
= outlet_new(&x
->x_obj
, &s_bang
);
36 x
->x_outlet2
= outlet_new(&x
->x_obj
, &s_bang
);
37 inlet_new(&x
->x_obj
, &x
->x_obj
.ob_pd
, &s_float
, gensym("ft1"));
38 x
->x_msecpertick
= 0.;
40 threshold_tilde_set(x
, hithresh
, hideadtime
, lothresh
, lodeadtime
);
44 /* "set" message to specify thresholds and dead times */
45 static void threshold_tilde_set(t_threshold_tilde
*x
,
46 t_floatarg hithresh
, t_floatarg hideadtime
,
47 t_floatarg lothresh
, t_floatarg lodeadtime
)
49 if (lothresh
> hithresh
)
51 x
->x_hithresh
= ftofix(hithresh
);
52 x
->x_hideadtime
= hideadtime
;
53 x
->x_lothresh
= ftofix(lothresh
);
54 x
->x_lodeadtime
= lodeadtime
;
57 /* number in inlet sets state -- note incompatible with JMAX which used
58 "int" message for this, impossible here because of auto signal conversion */
59 static void threshold_tilde_ft1(t_threshold_tilde
*x
, t_floatarg f
)
61 x
->x_state
= (f
!= 0);
65 static void threshold_tilde_tick(t_threshold_tilde
*x
)
68 outlet_bang(x
->x_outlet1
);
69 else outlet_bang(x
->x_outlet2
);
72 static t_int
*threshold_tilde_perform(t_int
*w
)
74 t_sample
*in1
= (t_sample
*)(w
[1]);
75 t_threshold_tilde
*x
= (t_threshold_tilde
*)(w
[2]);
76 int n
= (t_int
)(w
[3]);
77 if (x
->x_deadwait
> 0)
78 x
->x_deadwait
-= x
->x_msecpertick
;
81 /* we're high; look for low sample */
84 if (*in1
< x
->x_lothresh
)
86 clock_delay(x
->x_clock
, 0L);
88 x
->x_deadwait
= x
->x_lodeadtime
;
95 /* we're low; look for high sample */
98 if (*in1
>= x
->x_hithresh
)
100 clock_delay(x
->x_clock
, 0L);
102 x
->x_deadwait
= x
->x_hideadtime
;
111 void threshold_tilde_dsp(t_threshold_tilde
*x
, t_signal
**sp
)
113 x
->x_msecpertick
= 1000. * sp
[0]->s_n
/ sp
[0]->s_sr
;
114 dsp_add(threshold_tilde_perform
, 3, sp
[0]->s_vec
, x
, sp
[0]->s_n
);
117 static void threshold_tilde_ff(t_threshold_tilde
*x
)
119 clock_free(x
->x_clock
);
122 void threshold_tilde_setup( void)
124 threshold_tilde_class
= class_new(gensym("threshold~"),
125 (t_newmethod
)threshold_tilde_new
, (t_method
)threshold_tilde_ff
,
126 sizeof(t_threshold_tilde
), 0,
127 A_DEFFLOAT
, A_DEFFLOAT
, A_DEFFLOAT
, A_DEFFLOAT
, 0);
128 CLASS_MAINSIGNALIN(threshold_tilde_class
, t_threshold_tilde
, x_f
);
129 class_addmethod(threshold_tilde_class
, (t_method
)threshold_tilde_set
,
130 gensym("set"), A_FLOAT
, A_FLOAT
, A_FLOAT
, A_FLOAT
, 0);
131 class_addmethod(threshold_tilde_class
, (t_method
)threshold_tilde_ft1
,
132 gensym("ft1"), A_FLOAT
, 0);
133 class_addmethod(threshold_tilde_class
, (t_method
)threshold_tilde_dsp
,