aubiotss~.c: udpate for 0.4.0
[pd-aubio.git] / aubiotss~.c
1 /**
2  *
3  * a puredata wrapper for aubio tss detection functions 
4  *
5  * Thanks to Johannes M Zmolnig for writing the excellent HOWTO:
6  *       http://iem.kug.ac.at/pd/externals-HOWTO/  
7  *
8  * */
9
10 #include <m_pd.h>
11 #define AUBIO_UNSTABLE 1
12 #include <aubio/aubio.h>
13
14 char aubiotss_version[] = "aubiotss~ version 0.1";
15
16 static t_class *aubiotss_tilde_class;
17
18 void aubiotss_tilde_setup (void);
19
20 typedef struct _aubiotss_tilde 
21 {
22         t_object x_obj;
23         t_float thres;  
24         t_int pos; /*frames%dspblocksize*/
25         t_int bufsize;
26         t_int hopsize;
27         aubio_pvoc_t * pv;
28         aubio_pvoc_t * pvt;
29         aubio_pvoc_t * pvs;
30         aubio_tss_t * tss;
31         fvec_t *vec;
32         cvec_t *fftgrain;
33         cvec_t *cstead;
34         cvec_t *ctrans;
35         fvec_t *trans;
36         fvec_t *stead;
37 } t_aubiotss_tilde;
38
39 static t_int *aubiotss_tilde_perform(t_int *w) 
40 {
41         t_aubiotss_tilde *x = (t_aubiotss_tilde *)(w[1]);
42         t_sample *in          = (t_sample *)(w[2]);
43         t_sample *outtrans    = (t_sample *)(w[3]);
44         t_sample *outstead    = (t_sample *)(w[4]);
45         int n                 = (int)(w[5]);
46         int j;
47         for (j=0;j<n;j++) {
48                 /* write input to datanew */
49                 fvec_set_sample(x->vec, in[j], x->pos);
50                 /*time for fft*/
51                 if (x->pos == x->hopsize-1) {         
52                         /* block loop */
53                         /* test for silence */
54                         //if (!aubio_silence_detection(x->vec, x->threshold2))
55                         aubio_pvoc_do  (x->pv,  x->vec, x->fftgrain);
56                         aubio_tss_set_threshold ( x->tss, x->thres);
57                         aubio_tss_do   (x->tss, x->fftgrain, x->ctrans, x->cstead);
58                         aubio_pvoc_rdo (x->pvt, x->ctrans, x->trans);
59                         aubio_pvoc_rdo (x->pvs, x->cstead, x->stead);
60                         //}
61                         /* end of block loop */
62                         x->pos = -1; /* so it will be zero next j loop */
63                 }
64                 x->pos++;
65                 *outtrans++ = x->trans->data[x->pos];
66                 *outstead++ = x->stead->data[x->pos];
67         }
68         return (w+6);
69 }
70
71 static void aubiotss_tilde_dsp(t_aubiotss_tilde *x, t_signal **sp)
72 {
73         dsp_add(aubiotss_tilde_perform, 5, x, 
74                         sp[0]->s_vec, sp[1]->s_vec, sp[2]->s_vec, sp[0]->s_n);
75 }
76
77 static void aubiotss_tilde_debug(t_aubiotss_tilde *x)
78 {
79         post("aubiotss~ bufsize:\t%d", x->bufsize);
80         post("aubiotss~ hopsize:\t%d", x->hopsize);
81         post("aubiotss~ threshold:\t%f", x->thres);
82         post("aubiotss~ audio in:\t%f", x->vec->data[0]);
83         post("aubiotss~ audio out:\t%f", x->stead->data[0]);
84 }
85
86 static void *aubiotss_tilde_new (t_floatarg f)
87         //, t_floatarg bufsize)
88 {
89         t_aubiotss_tilde *x = 
90                 (t_aubiotss_tilde *)pd_new(aubiotss_tilde_class);
91
92         x->thres    = (f < 1e-5) ? 0.01 : (f > 1.) ? 1. : f;
93         x->bufsize  = 1024; //(bufsize < 64) ? 1024: (bufsize > 16385) ? 16385: bufsize;
94         x->hopsize  = x->bufsize / 4;
95
96         x->vec = (fvec_t *)new_fvec(x->hopsize);
97
98         x->fftgrain  = (cvec_t *)new_cvec(x->bufsize);
99         x->ctrans = (cvec_t *)new_cvec(x->bufsize);
100         x->cstead = (cvec_t *)new_cvec(x->bufsize);
101
102         x->trans = (fvec_t *)new_fvec(x->hopsize);
103         x->stead = (fvec_t *)new_fvec(x->hopsize);
104
105         x->pv  = (aubio_pvoc_t *)new_aubio_pvoc(x->bufsize, x->hopsize);
106         x->pvt = (aubio_pvoc_t *)new_aubio_pvoc(x->bufsize, x->hopsize);
107         x->pvs = (aubio_pvoc_t *)new_aubio_pvoc(x->bufsize, x->hopsize);
108
109         x->tss = (aubio_tss_t *)new_aubio_tss(x->bufsize, x->hopsize);
110
111         floatinlet_new (&x->x_obj, &x->thres);
112         outlet_new(&x->x_obj, gensym("signal"));
113         outlet_new(&x->x_obj, gensym("signal"));
114         post(aubiotss_version);
115         return (void *)x;
116 }
117
118 void aubiotss_tilde_setup (void)
119 {
120         aubiotss_tilde_class = class_new (gensym ("aubiotss~"),
121                         (t_newmethod)aubiotss_tilde_new,
122                         0, sizeof (t_aubiotss_tilde),
123                         CLASS_DEFAULT, A_DEFFLOAT, 0);
124         class_addmethod(aubiotss_tilde_class, 
125                         (t_method)aubiotss_tilde_dsp, 
126                         gensym("dsp"), 0);
127         class_addmethod(aubiotss_tilde_class, 
128                         (t_method)aubiotss_tilde_debug,
129                         gensym("debug"), 0);
130         CLASS_MAINSIGNALIN(aubiotss_tilde_class, 
131                         t_aubiotss_tilde, thres);
132 }