A modern Music Player Daemon based on Rockbox open source high quality audio player
libadwaita
audio
rust
zig
deno
mpris
rockbox
mpd
1#include "../src/m_pd.h"
2#include "../src/m_fixed.h"
3
4static t_class *threshold_tilde_class;
5
6typedef struct _threshold_tilde
7{
8 t_object x_obj;
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 */
20} t_threshold_tilde;
21
22static void threshold_tilde_tick(t_threshold_tilde *x);
23static void threshold_tilde_set(t_threshold_tilde *x,
24 t_floatarg hithresh, t_floatarg hideadtime,
25 t_floatarg lothresh, t_floatarg lodeadtime);
26
27static t_threshold_tilde *threshold_tilde_new(t_floatarg hithresh,
28 t_floatarg hideadtime, t_floatarg lothresh, t_floatarg lodeadtime)
29{
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.;
39 x->x_f = 0;
40 threshold_tilde_set(x, hithresh, hideadtime, lothresh, lodeadtime);
41 return (x);
42}
43
44 /* "set" message to specify thresholds and dead times */
45static void threshold_tilde_set(t_threshold_tilde *x,
46 t_floatarg hithresh, t_floatarg hideadtime,
47 t_floatarg lothresh, t_floatarg lodeadtime)
48{
49 if (lothresh > hithresh)
50 lothresh = hithresh;
51 x->x_hithresh = ftofix(hithresh);
52 x->x_hideadtime = hideadtime;
53 x->x_lothresh = ftofix(lothresh);
54 x->x_lodeadtime = lodeadtime;
55}
56
57 /* number in inlet sets state -- note incompatible with JMAX which used
58 "int" message for this, impossible here because of auto signal conversion */
59static void threshold_tilde_ft1(t_threshold_tilde *x, t_floatarg f)
60{
61 x->x_state = (f != 0);
62 x->x_deadwait = 0;
63}
64
65static void threshold_tilde_tick(t_threshold_tilde *x)
66{
67 if (x->x_state)
68 outlet_bang(x->x_outlet1);
69 else outlet_bang(x->x_outlet2);
70}
71
72static t_int *threshold_tilde_perform(t_int *w)
73{
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;
79 else if (x->x_state)
80 {
81 /* we're high; look for low sample */
82 for (; n--; in1++)
83 {
84 if (*in1 < x->x_lothresh)
85 {
86 clock_delay(x->x_clock, 0L);
87 x->x_state = 0;
88 x->x_deadwait = x->x_lodeadtime;
89 goto done;
90 }
91 }
92 }
93 else
94 {
95 /* we're low; look for high sample */
96 for (; n--; in1++)
97 {
98 if (*in1 >= x->x_hithresh)
99 {
100 clock_delay(x->x_clock, 0L);
101 x->x_state = 1;
102 x->x_deadwait = x->x_hideadtime;
103 goto done;
104 }
105 }
106 }
107done:
108 return (w+4);
109}
110
111void threshold_tilde_dsp(t_threshold_tilde *x, t_signal **sp)
112{
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);
115}
116
117static void threshold_tilde_ff(t_threshold_tilde *x)
118{
119 clock_free(x->x_clock);
120}
121
122void threshold_tilde_setup( void)
123{
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,
134 gensym("dsp"), 0);
135}
136