 Timestamp:
 Sep 15, 2009, 5:02:45 PM (10 years ago)
 Branches:
 feature/autosink, feature/constantq, feature/pitchshift, feature/pydocstrings, feature/timestretch, master, pitchshift, sampler, timestretch, yinfft+
 Children:
 06cae6c
 Parents:
 6f1727f
 File:

 1 edited
Legend:
 Unmodified
 Added
 Removed

src/tempo/beattracking.c
r6f1727f r7bf3dcb 1 1 /* 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 2 Copyright (C) 2005 Matthew Davies and Paul Brossier 3 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. 8 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. 13 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. 17 17 18 18 */ … … 23 23 #include "tempo/beattracking.h" 24 24 25 uint_t fvec_gettimesig(fvec_t * acf, uint_t acflen, uint_t gp); 26 void aubio_beattracking_checkstate(aubio_beattracking_t * bt); 27 28 struct _aubio_beattracking_t { 29 fvec_t * rwv; /** rayleigh weighting for beat period in general model */ 30 fvec_t * dfwv; /** exponential weighting for beat alignment in general model */ 31 fvec_t * gwv; /** gaussian weighting for beat period in context dependant model */ 32 fvec_t * phwv; /** gaussian weighting for beat alignment in context dependant model */ 33 fvec_t * dfrev; /** reversed onset detection function */ 34 fvec_t * acf; /** vector for autocorrelation function (of current detection function frame) */ 35 fvec_t * acfout; /** store result of passing acf through s.i.c.f.b. */ 36 fvec_t * phout; 37 uint_t timesig; /** time signature of input, set to zero until context dependent model activated */ 38 uint_t step; 39 uint_t rayparam; /** Rayleigh parameter */ 40 smpl_t lastbeat; 41 sint_t counter; 42 uint_t flagstep; 43 smpl_t g_var; 44 smpl_t gp; 45 smpl_t bp; 46 smpl_t rp; 47 smpl_t rp1; 48 smpl_t rp2; 25 uint_t fvec_gettimesig (fvec_t * acf, uint_t acflen, uint_t gp); 26 void aubio_beattracking_checkstate (aubio_beattracking_t * bt); 27 28 struct _aubio_beattracking_t 29 { 30 fvec_t *rwv; /** rayleigh weighting for beat period in general model */ 31 fvec_t *dfwv; /** exponential weighting for beat alignment in general model */ 32 fvec_t *gwv; /** gaussian weighting for beat period in context dependant model */ 33 fvec_t *phwv; /** gaussian weighting for beat alignment in context dependant model */ 34 fvec_t *dfrev; /** reversed onset detection function */ 35 fvec_t *acf; /** vector for autocorrelation function (of current detection function frame) */ 36 fvec_t *acfout; /** store result of passing acf through s.i.c.f.b. */ 37 fvec_t *phout; 38 uint_t timesig; /** time signature of input, set to zero until context dependent model activated */ 39 uint_t step; 40 uint_t rayparam; /** Rayleigh parameter */ 41 smpl_t lastbeat; 42 sint_t counter; 43 uint_t flagstep; 44 smpl_t g_var; 45 smpl_t gp; 46 smpl_t bp; 47 smpl_t rp; 48 smpl_t rp1; 49 smpl_t rp2; 49 50 }; 50 51 51 aubio_beattracking_t * new_aubio_beattracking(uint_t winlen, 52 uint_t channels) { 53 54 aubio_beattracking_t * p = AUBIO_NEW(aubio_beattracking_t); 55 uint_t i = 0; 56 /* parameter for rayleigh weight vector  sets preferred tempo to 57 * 120bpm [43] */ 58 smpl_t rayparam = 48./512. * winlen; 59 smpl_t dfwvnorm = EXP((LOG(2.0)/rayparam)*(winlen+2)); 60 /** length over which beat period is found [128] */ 61 uint_t laglen = winlen/4; 62 /** step increment  both in detection function samples i.e. 11.6ms or 63 * 1 onset frame [128] */ 64 uint_t step = winlen/4; /* 1.5 seconds */ 65 66 p>lastbeat = 0; 67 p>counter = 0; 68 p>flagstep = 0; 69 p>g_var = 3.901; // constthresh empirically derived! 70 p>rp = 1; 71 p>gp = 0; 72 73 p>rayparam = rayparam; 74 p>step = step; 75 p>rwv = new_fvec(laglen,1); 76 p>gwv = new_fvec(laglen,1); 77 p>dfwv = new_fvec(winlen,1); 78 p>dfrev = new_fvec(winlen,channels); 79 p>acf = new_fvec(winlen,channels); 80 p>acfout = new_fvec(laglen,channels); 81 p>phwv = new_fvec(2*laglen,1); 82 p>phout = new_fvec(winlen,channels); 83 84 p>timesig = 0; 85 86 /* exponential weighting, dfwv = 0.5 when i = 43 */ 87 for (i=0;i<winlen;i++) { 88 p>dfwv>data[0][i] = (EXP((LOG(2.0)/rayparam)*(i+1))) 89 / dfwvnorm; 90 } 91 92 for (i=0;i<(laglen);i++){ 93 p>rwv>data[0][i] = ((smpl_t)(i+1.) / SQR((smpl_t)rayparam)) * 94 EXP((SQR((smpl_t)(i+1.)) / (2.*SQR((smpl_t)rayparam)))); 52 aubio_beattracking_t * 53 new_aubio_beattracking (uint_t winlen, uint_t channels) 54 { 55 56 aubio_beattracking_t *p = AUBIO_NEW (aubio_beattracking_t); 57 uint_t i = 0; 58 /* parameter for rayleigh weight vector  sets preferred tempo to 59 * 120bpm [43] */ 60 smpl_t rayparam = 48. / 512. * winlen; 61 smpl_t dfwvnorm = EXP ((LOG (2.0) / rayparam) * (winlen + 2)); 62 /* length over which beat period is found [128] */ 63 uint_t laglen = winlen / 4; 64 /* step increment  both in detection function samples i.e. 11.6ms or 65 * 1 onset frame [128] */ 66 uint_t step = winlen / 4; /* 1.5 seconds */ 67 68 p>lastbeat = 0; 69 p>counter = 0; 70 p>flagstep = 0; 71 p>g_var = 3.901; // constthresh empirically derived! 72 p>rp = 1; 73 p>gp = 0; 74 75 p>rayparam = rayparam; 76 p>step = step; 77 p>rwv = new_fvec (laglen, 1); 78 p>gwv = new_fvec (laglen, 1); 79 p>dfwv = new_fvec (winlen, 1); 80 p>dfrev = new_fvec (winlen, channels); 81 p>acf = new_fvec (winlen, channels); 82 p>acfout = new_fvec (laglen, channels); 83 p>phwv = new_fvec (2 * laglen, 1); 84 p>phout = new_fvec (winlen, channels); 85 86 p>timesig = 0; 87 88 /* exponential weighting, dfwv = 0.5 when i = 43 */ 89 for (i = 0; i < winlen; i++) { 90 p>dfwv>data[0][i] = (EXP ((LOG (2.0) / rayparam) * (i + 1))) 91 / dfwvnorm; 92 } 93 94 for (i = 0; i < (laglen); i++) { 95 p>rwv>data[0][i] = ((smpl_t) (i + 1.) / SQR ((smpl_t) rayparam)) * 96 EXP ((SQR ((smpl_t) (i + 1.)) / (2. * SQR ((smpl_t) rayparam)))); 97 } 98 99 return p; 100 101 } 102 103 void 104 del_aubio_beattracking (aubio_beattracking_t * p) 105 { 106 del_fvec (p>rwv); 107 del_fvec (p>gwv); 108 del_fvec (p>dfwv); 109 del_fvec (p>dfrev); 110 del_fvec (p>acf); 111 del_fvec (p>acfout); 112 del_fvec (p>phwv); 113 del_fvec (p>phout); 114 AUBIO_FREE (p); 115 } 116 117 118 void 119 aubio_beattracking_do (aubio_beattracking_t * bt, fvec_t * dfframe, 120 fvec_t * output) 121 { 122 123 uint_t i, k; 124 uint_t step = bt>step; 125 uint_t laglen = bt>rwv>length; 126 uint_t winlen = bt>dfwv>length; 127 uint_t maxindex = 0; 128 //number of harmonics in shift invariant comb filterbank 129 uint_t numelem = 4; 130 131 smpl_t phase; // beat alignment (step  lastbeat) 132 smpl_t beat; // beat position 133 smpl_t bp; // beat period 134 uint_t a, b; // used to build shift invariant comb filterbank 135 uint_t kmax; // number of elements used to find beat phase 136 137 /* copy dfframe, apply detection function weighting, and revert */ 138 fvec_copy (dfframe, bt>dfrev); 139 fvec_weight (bt>dfrev, bt>dfwv); 140 fvec_rev (bt>dfrev); 141 142 /* compute autocorrelation function */ 143 aubio_autocorr (dfframe, bt>acf); 144 145 /* if timesig is unknown, use metrically unbiased version of filterbank */ 146 if (!bt>timesig) { 147 numelem = 4; 148 } else { 149 numelem = bt>timesig; 150 } 151 152 /* first and last output values are left intentionally as zero */ 153 fvec_zeros (bt>acfout); 154 155 /* compute shift invariant comb filterbank */ 156 for (i = 1; i < laglen  1; i++) { 157 for (a = 1; a <= numelem; a++) { 158 for (b = (1  a); b < a; b++) { 159 bt>acfout>data[0][i] += bt>acf>data[0][a * (i + 1) + b  1] 160 * 1. / (2. * a  1.); 161 } 162 } 163 } 164 /* apply Rayleigh weight */ 165 fvec_weight (bt>acfout, bt>rwv); 166 167 /* find nonzero Rayleigh period */ 168 maxindex = vec_max_elem (bt>acfout); 169 bt>rp = maxindex ? vec_quadint (bt>acfout, maxindex, 1) : 1; 170 //rp = (maxindex==127) ? 43 : maxindex; //rayparam 171 bt>rp = (maxindex == bt>acfout>length  1) ? bt>rayparam : maxindex; //rayparam 172 173 /* activate biased filterbank */ 174 aubio_beattracking_checkstate (bt); 175 #if 0 // debug metronome mode 176 bt>bp = 36.9142; 177 #endif 178 bp = bt>bp; 179 /* end of biased filterbank */ 180 181 182 /* deliberate integer operation, could be set to 3 max eventually */ 183 kmax = FLOOR (winlen / bp); 184 185 /* initialize output */ 186 fvec_zeros (bt>phout); 187 for (i = 0; i < bp; i++) { 188 for (k = 0; k < kmax; k++) { 189 bt>phout>data[0][i] += bt>dfrev>data[0][i + (uint_t) ROUND (bp * k)]; 190 } 191 } 192 fvec_weight (bt>phout, bt>phwv); 193 194 /* find Rayleigh period */ 195 maxindex = vec_max_elem (bt>phout); 196 if (maxindex == winlen) 197 maxindex = 0; 198 phase = 1. + vec_quadint (bt>phout, maxindex, 1); 199 #if 0 // debug metronome mode 200 phase = step  bt>lastbeat; 201 #endif 202 203 /* reset output */ 204 fvec_zeros (output); 205 206 i = 1; 207 beat = bp  phase; 208 /* start counting the beats */ 209 if (beat >= 0) { 210 output>data[0][i] = beat; 211 i++; 212 } 213 214 while (beat + bp <= step) { 215 beat += bp; 216 output>data[0][i] = beat; 217 i++; 218 } 219 220 bt>lastbeat = beat; 221 /* store the number of beat found in this frame as the first element */ 222 output>data[0][0] = i; 223 } 224 225 uint_t 226 fvec_gettimesig (fvec_t * acf, uint_t acflen, uint_t gp) 227 { 228 sint_t k = 0; 229 smpl_t three_energy = 0., four_energy = 0.; 230 if (acflen > 6 * gp + 2) { 231 for (k = 2; k < 2; k++) { 232 three_energy += acf>data[0][3 * gp + k]; 233 four_energy += acf>data[0][4 * gp + k]; 234 } 235 } else { 236 /*Expanded to be more accurate in time sig estimation */ 237 for (k = 2; k < 2; k++) { 238 three_energy += acf>data[0][3 * gp + k] + acf>data[0][6 * gp + k]; 239 four_energy += acf>data[0][4 * gp + k] + acf>data[0][2 * gp + k]; 240 } 241 } 242 return (three_energy > four_energy) ? 3 : 4; 243 } 244 245 void 246 aubio_beattracking_checkstate (aubio_beattracking_t * bt) 247 { 248 uint_t i, j, a, b; 249 uint_t flagconst = 0; 250 sint_t counter = bt>counter; 251 uint_t flagstep = bt>flagstep; 252 smpl_t gp = bt>gp; 253 smpl_t bp = bt>bp; 254 smpl_t rp = bt>rp; 255 smpl_t rp1 = bt>rp1; 256 smpl_t rp2 = bt>rp2; 257 uint_t laglen = bt>rwv>length; 258 uint_t acflen = bt>acf>length; 259 uint_t step = bt>step; 260 fvec_t *acf = bt>acf; 261 fvec_t *acfout = bt>acfout; 262 263 if (gp) { 264 // doshiftfbank again only if context dependent model is in operation 265 //acfout = doshiftfbank(acf,gwv,timesig,laglen,acfout); 266 //don't need acfout now, so can reuse vector 267 // gwv is, in first loop, definitely all zeros, but will have 268 // proper values when context dependent model is activated 269 fvec_zeros (acfout); 270 for (i = 1; i < laglen  1; i++) { 271 for (a = 1; a <= bt>timesig; a++) { 272 for (b = (1  a); b < a; b++) { 273 acfout>data[0][i] += acf>data[0][a * (i + 1) + b  1]; 95 274 } 96 97 return p; 98 99 } 100 101 void del_aubio_beattracking(aubio_beattracking_t * p) { 102 del_fvec(p>rwv); 103 del_fvec(p>gwv); 104 del_fvec(p>dfwv); 105 del_fvec(p>dfrev); 106 del_fvec(p>acf); 107 del_fvec(p>acfout); 108 del_fvec(p>phwv); 109 del_fvec(p>phout); 110 AUBIO_FREE(p); 111 } 112 113 114 void aubio_beattracking_do(aubio_beattracking_t * bt, fvec_t * dfframe, fvec_t * output) { 115 116 uint_t i,k; 117 uint_t step = bt>step; 118 uint_t laglen = bt>rwv>length; 119 uint_t winlen = bt>dfwv>length; 120 uint_t maxindex = 0; 121 //number of harmonics in shift invariant comb filterbank 122 uint_t numelem = 4; 123 124 smpl_t phase; // beat alignment (step  lastbeat) 125 smpl_t beat; // beat position 126 smpl_t bp; // beat period 127 uint_t a,b; // used to build shift invariant comb filterbank 128 uint_t kmax; // number of elements used to find beat phase 129 130 /* copy dfframe, apply detection function weighting, and revert */ 131 fvec_copy(dfframe, bt>dfrev); 132 fvec_weight(bt>dfrev, bt>dfwv); 133 fvec_rev(bt>dfrev); 134 135 /* compute autocorrelation function */ 136 aubio_autocorr(dfframe,bt>acf); 137 138 /* if timesig is unknown, use metrically unbiased version of filterbank */ 139 if(!bt>timesig) { 140 numelem = 4; 141 } else { 142 numelem = bt>timesig; 143 } 144 145 /* first and last output values are left intentionally as zero */ 146 fvec_zeros(bt>acfout); 147 148 /* compute shift invariant comb filterbank */ 149 for(i=1;i<laglen1;i++){ 150 for (a=1; a<=numelem; a++){ 151 for(b=(1a); b<a; b++){ 152 bt>acfout>data[0][i] += bt>acf>data[0][a*(i+1)+b1] 153 * 1./(2.*a1.); 154 } 155 } 156 } 157 /* apply Rayleigh weight */ 158 fvec_weight(bt>acfout, bt>rwv); 159 160 /* find nonzero Rayleigh period */ 161 maxindex = vec_max_elem(bt>acfout); 162 bt>rp = maxindex ? vec_quadint(bt>acfout, maxindex, 1) : 1; 163 //rp = (maxindex==127) ? 43 : maxindex; //rayparam 164 bt>rp = (maxindex==bt>acfout>length1) ? bt>rayparam : maxindex; //rayparam 165 166 /* activate biased filterbank */ 167 aubio_beattracking_checkstate(bt); 168 #if 0 // debug metronome mode 169 bt>bp = 36.9142; 170 #endif 171 bp = bt>bp; 172 /* end of biased filterbank */ 173 174 175 /* deliberate integer operation, could be set to 3 max eventually */ 176 kmax = FLOOR(winlen/bp); 177 178 /* initialize output */ 179 fvec_zeros(bt>phout); 180 for(i=0;i<bp;i++){ 181 for(k=0;k<kmax;k++){ 182 bt>phout>data[0][i] += bt>dfrev>data[0][i+(uint_t)ROUND(bp*k)]; 183 } 184 } 185 fvec_weight(bt>phout, bt>phwv); 186 187 /* find Rayleigh period */ 188 maxindex = vec_max_elem(bt>phout); 189 if (maxindex == winlen) maxindex = 0; 190 phase = 1. + vec_quadint(bt>phout, maxindex, 1); 191 #if 0 // debug metronome mode 192 phase = step  bt>lastbeat; 193 #endif 194 195 /* reset output */ 196 fvec_zeros(output); 197 198 i = 1; 199 beat = bp  phase; 200 /* start counting the beats */ 201 if(beat >= 0) { 202 output>data[0][i] = beat; 203 i++; 204 } 205 206 while( beat + bp <= step) { 207 beat += bp; 208 output>data[0][i] = beat; 209 i++; 210 } 211 212 bt>lastbeat = beat; 213 /* store the number of beat found in this frame as the first element */ 214 output>data[0][0] = i; 215 } 216 217 uint_t fvec_gettimesig(fvec_t * acf, uint_t acflen, uint_t gp){ 218 sint_t k = 0; 219 smpl_t three_energy = 0., four_energy = 0.; 220 if( acflen > 6 * gp + 2 ){ 221 for(k=2;k<2;k++){ 222 three_energy += acf>data[0][3*gp+k]; 223 four_energy += acf>data[0][4*gp+k]; 224 } 225 } 226 else{ /*Expanded to be more accurate in time sig estimation*/ 227 for(k=2;k<2;k++){ 228 three_energy += acf>data[0][3*gp+k]+acf>data[0][6*gp+k]; 229 four_energy += acf>data[0][4*gp+k]+acf>data[0][2*gp+k]; 230 } 231 } 232 return (three_energy > four_energy) ? 3 : 4; 233 } 234 235 void aubio_beattracking_checkstate(aubio_beattracking_t * bt) { 236 uint_t i,j,a,b; 237 uint_t flagconst = 0; 238 sint_t counter = bt>counter; 239 uint_t flagstep = bt>flagstep; 240 smpl_t gp = bt>gp; 241 smpl_t bp = bt>bp; 242 smpl_t rp = bt>rp; 243 smpl_t rp1 = bt>rp1; 244 smpl_t rp2 = bt>rp2; 245 uint_t laglen = bt>rwv>length; 246 uint_t acflen = bt>acf>length; 247 uint_t step = bt>step; 248 fvec_t * acf = bt>acf; 249 fvec_t * acfout = bt>acfout; 250 251 if (gp) { 252 // doshiftfbank again only if context dependent model is in operation 253 //acfout = doshiftfbank(acf,gwv,timesig,laglen,acfout); 254 //don't need acfout now, so can reuse vector 255 // gwv is, in first loop, definitely all zeros, but will have 256 // proper values when context dependent model is activated 257 fvec_zeros(acfout); 258 for(i=1;i<laglen1;i++){ 259 for (a=1;a<=bt>timesig;a++){ 260 for(b=(1a);b<a;b++){ 261 acfout>data[0][i] += acf>data[0][a*(i+1)+b1]; 262 } 263 } 264 } 265 fvec_weight(acfout, bt>gwv); 266 gp = vec_quadint(acfout, vec_max_elem(acfout), 1); 267 /* 268 while(gp<32) gp =gp*2; 269 while(gp>64) gp = gp/2; 270 */ 271 } else { 272 //still only using general model 273 gp = 0; 274 } 275 276 //now look for step change  i.e. a difference between gp and rp that 277 // is greater than 2*constthresh  always true in first case, since gp = 0 278 if(counter == 0){ 279 if(ABS(gp  rp) > 2.*bt>g_var) { 280 flagstep = 1; // have observed step change. 281 counter = 3; // setup 3 frame counter 282 } else { 283 flagstep = 0; 284 } 285 } 286 287 //i.e. 3rd frame after flagstep initially set 288 if (counter==1 && flagstep==1) { 289 //check for consistency between previous beatperiod values 290 if(ABS(2.*rp  rp1 rp2) < bt>g_var) { 291 //if true, can activate context dependent model 292 flagconst = 1; 293 counter = 0; // reset counter and flagstep 294 } else { 295 //if not consistent, then don't flag consistency! 296 flagconst = 0; 297 counter = 2; // let it look next time 298 } 299 } else if (counter > 0) { 300 //if counter doesn't = 1, 301 counter = counter1; 302 } 303 304 rp2 = rp1; rp1 = rp; 305 306 if (flagconst) { 307 /* first run of new hypothesis */ 308 gp = rp; 309 bt>timesig = fvec_gettimesig(acf,acflen, gp); 310 for(j=0;j<laglen;j++) 311 bt>gwv>data[0][j] = EXP(.5*SQR((smpl_t)(j+1.gp))/SQR(bt>g_var)); 312 flagconst = 0; 313 bp = gp; 314 /* flat phase weighting */ 315 fvec_ones(bt>phwv); 316 } else if (bt>timesig) { 317 /* context dependant model */ 318 bp = gp; 319 /* gaussian phase weighting */ 320 if (step > bt>lastbeat) { 321 for(j=0;j<2*laglen;j++) { 322 bt>phwv>data[0][j] = EXP(.5*SQR((smpl_t)(1.+jstep+bt>lastbeat))/(bp/8.)); 323 } 324 } else { 325 //AUBIO_DBG("NOT using phase weighting as step is %d and lastbeat %d \n", 326 // step,bt>lastbeat); 327 fvec_ones(bt>phwv); 328 } 329 } else { 330 /* initial state */ 331 bp = rp; 332 /* flat phase weighting */ 333 fvec_ones(bt>phwv); 334 } 335 336 /* do some further checks on the final bp value */ 337 338 /* if tempo is > 206 bpm, half it */ 339 while (bp < 25) { 340 //AUBIO_DBG("warning, doubling the beat period from %d\n", bp); 341 //AUBIO_DBG("warning, halving the tempo from %f\n", 60.*samplerate/hopsize/bp); 342 bp = bp*2; 343 } 344 345 //AUBIO_DBG("tempo:\t%3.5f bpm  ", 5168./bp); 346 347 /* smoothing */ 348 //bp = (uint_t) (0.8 * (smpl_t)bp + 0.2 * (smpl_t)bp2); 349 //AUBIO_DBG("tempo:\t%3.5f bpm smoothed  bp2 %d  bp %d  ", 5168./bp, bp2, bp); 350 //bp2 = bp; 351 //AUBIO_DBG("time signature: %d \n", bt>timesig); 352 bt>counter = counter; 353 bt>flagstep = flagstep; 354 bt>gp = gp; 355 bt>bp = bp; 356 bt>rp1 = rp1; 357 bt>rp2 = rp2; 358 359 } 360 361 smpl_t aubio_beattracking_get_bpm(aubio_beattracking_t * bt) { 362 if (bt>timesig != 0 && bt>counter == 0 && bt>flagstep == 0) { 363 return 5168. / vec_quadint(bt>acfout, bt>bp, 1); 364 } else { 365 return 0.; 366 } 367 } 368 369 smpl_t aubio_beattracking_get_confidence(aubio_beattracking_t * bt) { 370 if (bt>gp) return vec_max(bt>acfout); 371 else return 0.; 372 } 275 } 276 } 277 fvec_weight (acfout, bt>gwv); 278 gp = vec_quadint (acfout, vec_max_elem (acfout), 1); 279 /* 280 while(gp<32) gp =gp*2; 281 while(gp>64) gp = gp/2; 282 */ 283 } else { 284 //still only using general model 285 gp = 0; 286 } 287 288 //now look for step change  i.e. a difference between gp and rp that 289 // is greater than 2*constthresh  always true in first case, since gp = 0 290 if (counter == 0) { 291 if (ABS (gp  rp) > 2. * bt>g_var) { 292 flagstep = 1; // have observed step change. 293 counter = 3; // setup 3 frame counter 294 } else { 295 flagstep = 0; 296 } 297 } 298 //i.e. 3rd frame after flagstep initially set 299 if (counter == 1 && flagstep == 1) { 300 //check for consistency between previous beatperiod values 301 if (ABS (2. * rp  rp1  rp2) < bt>g_var) { 302 //if true, can activate context dependent model 303 flagconst = 1; 304 counter = 0; // reset counter and flagstep 305 } else { 306 //if not consistent, then don't flag consistency! 307 flagconst = 0; 308 counter = 2; // let it look next time 309 } 310 } else if (counter > 0) { 311 //if counter doesn't = 1, 312 counter = counter  1; 313 } 314 315 rp2 = rp1; 316 rp1 = rp; 317 318 if (flagconst) { 319 /* first run of new hypothesis */ 320 gp = rp; 321 bt>timesig = fvec_gettimesig (acf, acflen, gp); 322 for (j = 0; j < laglen; j++) 323 bt>gwv>data[0][j] = 324 EXP (.5 * SQR ((smpl_t) (j + 1.  gp)) / SQR (bt>g_var)); 325 flagconst = 0; 326 bp = gp; 327 /* flat phase weighting */ 328 fvec_ones (bt>phwv); 329 } else if (bt>timesig) { 330 /* context dependant model */ 331 bp = gp; 332 /* gaussian phase weighting */ 333 if (step > bt>lastbeat) { 334 for (j = 0; j < 2 * laglen; j++) { 335 bt>phwv>data[0][j] = 336 EXP (.5 * SQR ((smpl_t) (1. + j  step + 337 bt>lastbeat)) / (bp / 8.)); 338 } 339 } else { 340 //AUBIO_DBG("NOT using phase weighting as step is %d and lastbeat %d \n", 341 // step,bt>lastbeat); 342 fvec_ones (bt>phwv); 343 } 344 } else { 345 /* initial state */ 346 bp = rp; 347 /* flat phase weighting */ 348 fvec_ones (bt>phwv); 349 } 350 351 /* do some further checks on the final bp value */ 352 353 /* if tempo is > 206 bpm, half it */ 354 while (bp < 25) { 355 //AUBIO_DBG("warning, doubling the beat period from %d\n", bp); 356 //AUBIO_DBG("warning, halving the tempo from %f\n", 60.*samplerate/hopsize/bp); 357 bp = bp * 2; 358 } 359 360 //AUBIO_DBG("tempo:\t%3.5f bpm  ", 5168./bp); 361 362 /* smoothing */ 363 //bp = (uint_t) (0.8 * (smpl_t)bp + 0.2 * (smpl_t)bp2); 364 //AUBIO_DBG("tempo:\t%3.5f bpm smoothed  bp2 %d  bp %d  ", 5168./bp, bp2, bp); 365 //bp2 = bp; 366 //AUBIO_DBG("time signature: %d \n", bt>timesig); 367 bt>counter = counter; 368 bt>flagstep = flagstep; 369 bt>gp = gp; 370 bt>bp = bp; 371 bt>rp1 = rp1; 372 bt>rp2 = rp2; 373 } 374 375 smpl_t 376 aubio_beattracking_get_bpm (aubio_beattracking_t * bt) 377 { 378 if (bt>timesig != 0 && bt>counter == 0 && bt>flagstep == 0) { 379 return 5168. / vec_quadint (bt>acfout, bt>bp, 1); 380 } else { 381 return 0.; 382 } 383 } 384 385 smpl_t 386 aubio_beattracking_get_confidence (aubio_beattracking_t * bt) 387 { 388 if (bt>gp) { 389 return vec_max (bt>acfout); 390 } else { 391 return 0.; 392 } 393 }
Note: See TracChangeset
for help on using the changeset viewer.