A modern Music Player Daemon based on Rockbox open source high quality audio player
libadwaita audio rust zig deno mpris rockbox mpd
at master 136 lines 4.2 kB view raw
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