2 Copyright (C) 2003 Paul Brossier
4 This program is free software; you can redistribute it and/or modify
5 it under the terms of the GNU General Public License as published by
6 the Free Software Foundation; either version 2 of the License, or
7 (at your option) any later version.
9 This program is distributed in the hope that it will be useful,
10 but WITHOUT ANY WARRANTY; without even the implied warranty of
11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 GNU General Public License for more details.
14 You should have received a copy of the GNU General Public License
15 along with this program; if not, write to the Free Software
16 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
20 #include "aubio_priv.h"
22 #include "mathutils.h"
26 /* peak picking parameters, default values in brackets
28 * [<----post----|--pre-->]
29 * .................|.............
32 struct _aubio_pickpeak_t {
33 /** thresh: offset threshold [0.033 or 0.01] */
35 /** win_post: median filter window length (causal part) [8] */
37 /** pre: median filter window (anti-causal part) [post-1] */
39 /** threshfn: name or handle of fn for computing adaptive threshold [@median] */
40 //aubio_thresholdfn_t thresholdfn;
41 /** picker: name or handle of fn for picking event times [@peakpick] */
42 aubio_pickerfn_t pickerfn;
44 /** biquad lowpass filter */
45 aubio_biquad_t * biquad;
46 /** original onsets */
48 /** modified onsets */
50 /* peak picked window [3] */
52 /** scratch pad for biquad and median */
55 /** \bug should be used to calculate filter coefficients */
56 /* cutoff: low-pass filter cutoff [0.34, 1] */
59 /* not used anymore */
60 /* time precision [512/44100 winlength/samplerate, fs/buffer_size */
62 /* alpha: normalisation exponent [9] */
67 /** modified version for real time, moving mean adaptive threshold this method
68 * is slightly more permissive than the offline one, and yelds to an increase
69 * of false positives. best */
70 uint_t aubio_peakpick_pimrt(fvec_t * onset, aubio_pickpeak_t * p) {
71 fvec_t * onset_keep = (fvec_t *)p->onset_keep;
72 fvec_t * onset_proc = (fvec_t *)p->onset_proc;
73 fvec_t * onset_peek = (fvec_t *)p->onset_peek;
74 fvec_t * scratch = (fvec_t *)p->scratch;
75 smpl_t mean = 0., median = 0.;
76 uint_t length = p->win_post + p->win_pre + 1;
79 /* store onset in onset_keep */
80 /* shift all elements but last, then write last */
81 /* for (i=0;i<channels;i++) { */
82 for (j=0;j<length-1;j++) {
83 onset_keep->data[i][j] = onset_keep->data[i][j+1];
84 onset_proc->data[i][j] = onset_keep->data[i][j];
86 onset_keep->data[i][length-1] = onset->data[i][0];
87 onset_proc->data[i][length-1] = onset->data[i][0];
90 /* filter onset_proc */
91 /** \bug filtfilt calculated post+pre times, should be only once !? */
92 aubio_biquad_do_filtfilt(p->biquad,onset_proc,scratch);
94 /* calculate mean and median for onset_proc */
95 /* for (i=0;i<onset_proc->channels;i++) { */
96 mean = vec_mean(onset_proc);
98 for (j = 0; j < length; j++)
99 scratch->data[i][j] = onset_proc->data[i][j];
100 median = vec_median(scratch);
103 /* for (i=0;i<onset->channels;i++) { */
104 /* shift peek array */
106 onset_peek->data[i][j] = onset_peek->data[i][j+1];
107 /* calculate new peek value */
108 onset_peek->data[i][2] =
109 onset_proc->data[i][p->win_post] - median - mean * p->threshold;
111 //AUBIO_DBG("%f\n", onset_peek->data[0][2]);
112 return (p->pickerfn)(onset_peek,1);
115 /** function added by Miguel Ramirez to return the onset detection amplitude in peakval */
116 uint_t aubio_peakpick_pimrt_wt(fvec_t * onset, pickparams_t * p, smpl_t* peakval)
118 fvec_t * onset_keep = (fvec_t *)p->onset_keep;
119 fvec_t * onset_proc = (fvec_t *)p->onset_proc;
120 fvec_t * onset_peek = (fvec_t *)p->onset_peek;
121 fvec_t * scratch = (fvec_t *)p->scratch;
122 smpl_t mean = 0., median = 0.;
123 uint_t length = p->win_post + p->win_pre + 1;
126 /* store onset in onset_keep */
127 /* shift all elements but last, then write last */
128 for (j=0;j<length-1;j++)
130 onset_keep->data[i][j] = onset_keep->data[i][j+1];
131 onset_proc->data[i][j] = onset_keep->data[i][j];
133 onset_keep->data[i][length-1] = onset->data[i][0];
134 onset_proc->data[i][length-1] = onset->data[i][0];
137 /* filter onset_proc */
138 /** \bug filtfilt calculated post+pre times should be only once !? */
140 aubio_biquad_do_filtfilt(p->biquad,onset_proc,scratch);
142 /* calculate mean and median for onset_proc */
144 mean = vec_mean(onset_proc);
145 /* copy to scratch */
146 for (j = 0; j < length; j++)
147 scratch->data[i][j] = onset_proc->data[i][j];
148 median = vec_median(scratch);
150 /* shift peek array */
152 onset_peek->data[i][j] = onset_peek->data[i][j+1];
153 /* calculate new peek value */
155 onset_peek->data[i][2] =
156 onset_proc->data[i][p->win_post] - median - mean * p->threshold;
158 uint_t isonset = (p->pickerfn)(onset_peek,1);
160 if ( isonset && peakval != NULL )
161 *peakval = onset_peek->data[i][1];
168 aubio_pickpeak_t * new_aubio_peakpicker(smpl_t threshold) {
169 aubio_pickpeak_t * t = AUBIO_NEW(aubio_pickpeak_t);
170 t->threshold = 0.1; /* 0.0668; 0.33; 0.082; 0.033; */
171 if (threshold > 0. && threshold < 10.)
172 t->threshold = threshold;
176 //t->thresholdfn = (aubio_thresholdfn_t)(vec_median); /* (vec_mean); */
177 t->pickerfn = (aubio_pickerfn_t)(vec_peakpick);
179 t->scratch = new_fvec(t->win_post+t->win_pre+1,1);
180 t->onset_keep = new_fvec(t->win_post+t->win_pre+1,1);
181 t->onset_proc = new_fvec(t->win_post+t->win_pre+1,1);
182 t->onset_peek = new_fvec(3,1);
184 /* cutoff: low-pass filter cutoff [0.34, 1] */
185 /* t->cutoff=0.34; */
186 t->biquad = new_aubio_biquad(0.1600,0.3200,0.1600,-0.5949,0.2348);
190 void del_aubio_peakpicker(aubio_pickpeak_t * p) {
191 //del_aubio_biquad(p->biquad);
192 del_fvec(p->onset_keep);
193 del_fvec(p->onset_proc);
194 del_fvec(p->onset_peek);
195 del_fvec(p->scratch);