From: Paul Brossier Date: Tue, 7 Jun 2005 16:56:39 +0000 (+0000) Subject: updated beattracking.c ad aubiotrack.c to support variable hopsize X-Git-Tag: bzr2git~884 X-Git-Url: http://git.tremily.us/?a=commitdiff_plain;h=0ce9acc35b494f0c95b383c075fe422836928257;p=aubio.git updated beattracking.c ad aubiotrack.c to support variable hopsize --- diff --git a/examples/aubiotrack.c b/examples/aubiotrack.c index 772338e7..711399c6 100644 --- a/examples/aubiotrack.c +++ b/examples/aubiotrack.c @@ -26,9 +26,7 @@ fvec_t * dfframe = NULL; fvec_t * out = NULL; aubio_beattracking_t * bt = NULL; uint_t winlen = 512; -uint_t step = 128; -uint_t laglen = 128; -uint_t rayparam = 43; +uint_t step = 0; uint_t istactus = 0; int aubio_process(float **input, float **output, int nframes); @@ -83,6 +81,8 @@ int aubio_process(float **input, float **output, int nframes) { for (i = 1; i < btoutput[0]; i++ ) { if (pos2 == btoutput[i]) { //printf("pos2: %d\n", pos2); + //printf("tempo:\t%3.5f bpm \n", + //60.*44100./overlap_size/abs(btoutput[2]-btoutput[1])); /* test for silence */ if (aubio_silence_detection(ibuf, threshold2)==1) { isonset = 0; @@ -122,16 +122,18 @@ int main(int argc, char **argv) { /* override default settings */ examples_common_init(argc,argv); + winlen = SQR(512)/overlap_size; dfframe = new_fvec(winlen,channels); + step = winlen/4; out = new_fvec(step,channels); + /* test input : impulses starting from 15, at intervals of 50 samples */ //for(i=0;i<16;i++){ // dfframe->data[0][50*i+14] = 1.; //} - bt = new_aubio_beattracking(winlen,step, laglen, - rayparam, channels); + bt = new_aubio_beattracking(winlen,channels); examples_common_process(aubio_process,process_print); diff --git a/examples/utils.c b/examples/utils.c index 606e6bbf..5438353b 100644 --- a/examples/utils.c +++ b/examples/utils.c @@ -97,7 +97,7 @@ void usage (FILE * stream, int exit_code) } int parse_args (int argc, char **argv) { - const char *options = "hvjo:i:O:t:s:a"; + const char *options = "hvjo:i:O:t:s:H:a"; int next_option; struct option long_options[] = { @@ -110,6 +110,7 @@ int parse_args (int argc, char **argv) { {"threshold", 0, NULL, 't'}, {"silence" , 0, NULL, 's'}, {"averaging", 0, NULL, 'a'}, + {"hopsize", 0, NULL, 'H'}, {NULL , 0, NULL, 0} }; prog_name = argv[0]; @@ -168,6 +169,9 @@ int parse_args (int argc, char **argv) { case 'a': averaging = 1; break; + case 'H': + overlap_size = atoi(optarg); + break; case '?': /* unknown options */ usage(stderr, 1); break; diff --git a/src/beattracking.c b/src/beattracking.c index bd0a4005..cd656f66 100644 --- a/src/beattracking.c +++ b/src/beattracking.c @@ -22,38 +22,32 @@ #include "mathutils.h" #include "beattracking.h" +// 60*samplerate/winlen + /* maximum length for rp */ -static uint_t MAXRP = 512; static smpl_t constthresh = 3.901; //empirically derived! -static smpl_t stepthresh = 2.*3.901; uint_t fvec_gettimesig(smpl_t * acf, uint_t acflen, uint_t gp); void aubio_beattracking_checkstate(aubio_beattracking_t * bt); -smpl_t fvec_getperiod(smpl_t * acf, uint_t timesig, uint_t rp); +smpl_t fvec_getperiod(aubio_beattracking_t * bt, uint_t timesig, uint_t rp); /* could move to struct */ -uint_t gp=0, bp = 0, rp1 = 0, rp2 = 0, bp2 = 0; -smpl_t g_mu =0.; -smpl_t g_var = 3.901; -uint_t flagconst = 0; -uint_t flagstep = 0; +uint_t gp = 0, bp = 0, rp1 = 0, rp2 = 0, bp2 = 0; +smpl_t g_mu = 0.; +smpl_t g_var = 3.901; +uint_t flagconst = 0; +uint_t flagstep = 0; // needs to be a signed ? -sint_t counter = 0; -uint_t maxindex = 0; -uint_t timesig = 0; -uint_t rp = 1; -uint_t lastbeat = 0; +sint_t counter = 0; +uint_t maxindex = 0; +uint_t timesig = 0; +uint_t rp = 1; +uint_t lastbeat = 0; //number of harmonics in shift invariant comb filterbank -uint_t numelem = 4; -smpl_t myperiod = 0.; - +uint_t numelem = 4; +smpl_t myperiod = 0.; -// FIXME uint_t maxnumelem = 4; -uint_t len = 512; -smpl_t inds[4]; //vector for max index outputs for each harmonic -smpl_t local_acf[512]; //vector to store harmonics of filterbank of acf - struct _aubio_beattracking_t { fvec_t * rwv; /* rayleigh weight vector - rayleigh distribution function */ @@ -66,19 +60,22 @@ struct _aubio_beattracking_t { fvec_t * phout; //uint_t timesig; /* time signature of input, set to zero until context dependent model activated */ uint_t step; + fvec_t * locacf; /* vector to store harmonics of filterbank of acf */ + fvec_t * inds; /* vector for max index outputs for each harmonic */ + uint_t rayparam; /* Rayleigh parameter */ }; aubio_beattracking_t * new_aubio_beattracking(uint_t winlen, - uint_t step, - uint_t laglen, - uint_t rayparam, uint_t channels) { aubio_beattracking_t * p = AUBIO_NEW(aubio_beattracking_t); - uint_t i = 0; + smpl_t rayparam = 48./512. * winlen; smpl_t dfwvnorm = EXP((LOG(2.0)/rayparam)*(winlen+2)); + uint_t laglen = winlen/4; + uint_t step = winlen/4; /* 1.5 seconds */ + p->rayparam = rayparam; p->step = step; p->rwv = new_fvec(laglen,channels); p->gwv = new_fvec(laglen,channels); @@ -87,9 +84,13 @@ aubio_beattracking_t * new_aubio_beattracking(uint_t winlen, p->acf = new_fvec(winlen,channels); p->acfout = new_fvec(laglen,channels); p->phwv = new_fvec(2*laglen,channels); - p->phout = new_fvec(MAXRP,channels); + p->phout = new_fvec(winlen,channels); + //p->timesig = 0; + p->inds = new_fvec(maxnumelem,channels); + p->locacf = new_fvec(winlen,channels); + /* exponential weighting, dfwv = 0.5 when i = 43 */ for (i=0;idfwv->data[0][i] = (EXP((LOG(2.0)/rayparam)*(i+1))) @@ -114,6 +115,8 @@ void del_aubio_beattracking(aubio_beattracking_t * p) { del_fvec(p->acfout); del_fvec(p->phwv); del_fvec(p->phout); + del_fvec(p->locacf); + del_fvec(p->inds); AUBIO_FREE(p); } @@ -157,14 +160,12 @@ void aubio_beattracking_do(aubio_beattracking_t * bt, fvec_t * dfframe, fvec_t * /* get acfout - assume Rayleigh weightvector only */ /* if timesig is unknown, use metrically unbiased version of filterbank */ - //if(!timesig) - // AUBIO_DBG("using unbiased filterbank, timesig: %d\n", timesig); - //else - // AUBIO_DBG("using biased filterbank, timesig: %d\n", timesig); if(!timesig) numelem = 4; + // AUBIO_DBG("using unbiased filterbank, timesig: %d\n", timesig); else numelem = timesig; + // AUBIO_DBG("using biased filterbank, timesig: %d\n", timesig); /* first and last output values are left intentionally as zero */ for (i=0; i < bt->acfout->length; i++) @@ -182,23 +183,22 @@ void aubio_beattracking_do(aubio_beattracking_t * bt, fvec_t * dfframe, fvec_t * /* find non-zero Rayleigh period */ maxindex = vec_max_elem(bt->acfout); rp = maxindex ? maxindex : 1; - rp = (maxindex==127) ? 43 : maxindex; //rayparam + //rp = (maxindex==127) ? 43 : maxindex; //rayparam + rp = (maxindex==bt->acfout->length-1) ? bt->rayparam : maxindex; //rayparam // get float period - myperiod = fvec_getperiod(acf,timesig,rp); + myperiod = fvec_getperiod(bt,timesig,rp); //AUBIO_DBG("\nrp = %d myperiod = %f\n",rp,myperiod); //AUBIO_DBG("accurate tempo is %f bpm\n",5168./myperiod); - /* activate biased filterbank */ aubio_beattracking_checkstate(bt); /* end of biased filterbank */ /* initialize output */ - for(i=0;iphout->length;i++) {phout[i] = 0.;} - /* deliberate integer operation */ - /* could be set to 3 max eventually */ + /* deliberate integer operation, could be set to 3 max eventually */ kmax = winlen/bp; for(i=0;idata[0][0] = i; - } uint_t fvec_gettimesig(smpl_t * acf, uint_t acflen, uint_t gp){ @@ -261,15 +260,13 @@ uint_t fvec_gettimesig(smpl_t * acf, uint_t acflen, uint_t gp){ return (three_energy > four_energy) ? 3 : 4; } -smpl_t fvec_getperiod(smpl_t * acf, uint_t timesig, uint_t rp){ +smpl_t fvec_getperiod(aubio_beattracking_t * bt, uint_t timesig, uint_t rp){ /*function to make a more accurate beat period measurement.*/ smpl_t period = 0.; smpl_t maxval = 0.; - - - int a,b; + sint_t a,b; uint_t i,j; uint_t acfmi = rp; //acfout max index uint_t maxind = 0; @@ -280,17 +277,18 @@ smpl_t fvec_getperiod(smpl_t * acf, uint_t timesig, uint_t rp){ numelem = timesig; for (i=0;iinds->data[0][i] = 0.; - for (i=0;ilocacf->length;i++) // initialize + bt->locacf->data[0][i] = 0.; - // get appropriate acf elements from acf and store in local_acf - for (a=1;a<=4;a++){ - for(b=(1-a);blocacf->data[0][a*(acfmi)+b-1] = + bt->acf->data[0][a*(acfmi)+b-1]; + } + } for(i=0;imaxval){ - maxval = local_acf[j]; - maxind = j; - } - local_acf[maxind] = 0.; + if(bt->locacf->data[0][j]>maxval){ + maxval = bt->locacf->data[0][j]; + maxind = j; + } + //bt->locacf->data[0][maxind] = 0.; + bt->locacf->data[0][j] = 0.; } - //printf("\n\n"); //AUBIO_DBG("\n maxind is %d\n",maxind); - inds[i] = maxind; + bt->inds->data[0][i] = maxind; } for (i=0;iinds->data[0][i]/(i+1.);} period = period/numelem; @@ -356,9 +354,9 @@ void aubio_beattracking_checkstate(aubio_beattracking_t * bt) { } //now look for step change - i.e. a difference between gp and rp that - // is greater than stepthresh - always true in first case, since gp = 0 + // is greater than 2*constthresh - always true in first case, since gp = 0 if(counter == 0){ - if(ABS(gp - rp) > stepthresh) { + if(ABS(gp - rp) > 2.*constthresh) { flagstep = 1; // have observed step change. counter = 3; // setup 3 frame counter } else { @@ -420,16 +418,18 @@ void aubio_beattracking_checkstate(aubio_beattracking_t * bt) { /* if tempo is > 206 bpm, half it */ while (bp < 25) { - AUBIO_DBG("warning, halving the tempo from %f\n", 5168./bp); + //while (bp < fact/206.) { + AUBIO_DBG("warning, doubling the beat period from %d\n", bp); + //AUBIO_DBG("warning, halving the tempo from %f\n", 60.*samplerate/hopsize/bp); bp = bp*2; } - AUBIO_DBG("tempo:\t%3.5f bpm | ", 5168./bp); + //AUBIO_DBG("tempo:\t%3.5f bpm | ", 5168./bp); /* smoothing */ //bp = (uint_t) (0.8 * (smpl_t)bp + 0.2 * (smpl_t)bp2); //AUBIO_DBG("tempo:\t%3.5f bpm smoothed | bp2 %d | bp %d | ", 5168./bp, bp2, bp); //bp2 = bp; - AUBIO_DBG("time signature: %d \n", timesig); + //AUBIO_DBG("time signature: %d \n", timesig); } diff --git a/src/beattracking.h b/src/beattracking.h index f7175ad3..90afd741 100644 --- a/src/beattracking.h +++ b/src/beattracking.h @@ -36,9 +36,6 @@ typedef struct _aubio_beattracking_t aubio_beattracking_t; * \param parameter for rayleigh weight vector - sets preferred tempo to 120bpm [43] * \param channel number (not functionnal) [1] */ aubio_beattracking_t * new_aubio_beattracking(uint_t winlen, - uint_t step, - uint_t laglen, - uint_t rayparam, uint_t channels); /** * track the beat