116 for( i = 0; i < winLength; i++ ) {
119 exp( ( -pow(( i + 1 ),2.0 ) /
124 for( i = 0; i < winLength; i++ ) {
125 double dlag = (double)(i+1) - beatLag;
126 Filter[ i ] = exp(-0.5 * pow(( dlag /
m_sigma), 2.0) ) /
135 double maxValRCF = 0.0;
158 #ifdef DEBUG_TEMPO_TRACK 159 std::cerr <<
"tempoMM: m_winLength = " <<
m_winLength <<
", m_lagLength = " << m_lagLength <<
", numelem = " << numelem << std::endl;
162 for(i=1;i<m_lagLength-1;i++) {
164 for (a=1;a<=numelem;a++) {
165 for(b=(1-a);b<a;b++) {
167 m_tempoScratch[i] += ACF[a*(i+1)+b-1] * (1.0 / (2.0 * (
double)a-1)) * weight[i];
195 vector <vector<double> > rcfMat;
220 rcfMat.push_back ( vector<double>() );
225 rcfMat[i].push_back (0.);
232 double log2PeriodRatio = log( static_cast<double>(i)/
233 static_cast<double>(j) ) /
235 rcfMat[i][j] = ( abs(1.0-abs(log2PeriodRatio)) );
245 if (rcfMat[i][j] > maxVal) {
246 maxVal = rcfMat[i][j];
252 rcfMat[i][i] = maxVal;
260 if (rcfMat[i][j] < minVal) {
261 minVal = rcfMat[i][j];
270 int beatPeriod = p_j;
276 maxIndexRCF =
static_cast<int>(beatPeriod);
280 double locked = 5168.f / maxIndexRCF;
281 if (locked >= 30 && locked <= 180) {
285 #ifdef DEBUG_TEMPO_TRACK 286 std::cerr <<
"tempoMM: locked tempo = " <<
m_lockedTempo << std::endl;
293 #ifdef DEBUG_TEMPO_TRACK 294 std::cerr <<
"tempoMM: maxIndexRCF = " << maxIndexRCF << std::endl;
299 #ifdef DEBUG_TEMPO_TRACK 300 std::cerr <<
"tsig == 4" << std::endl;
303 pdPeaks =
new double[ 4 ];
304 for( i = 0; i < 4; i++ ){ pdPeaks[ i ] = 0.0;}
306 pdPeaks[ 0 ] = ( double )maxIndexRCF + 1;
312 for( i = (2 * maxIndexRCF + 1) - 1; i < (2 * maxIndexRCF + 1) + 2; i++ ) {
313 if( ACF[ i ] > maxValTemp ) {
314 maxValTemp = ACF[ i ];
315 maxIndexTemp = count;
319 pdPeaks[ 1 ] = (double)( maxIndexTemp + 1 + ( (2 * maxIndexRCF + 1 ) - 2 ) + 1 )/2;
325 for( i = (3 * maxIndexRCF + 2 ) - 2; i < (3 * maxIndexRCF + 2 ) + 3; i++ ) {
326 if( ACF[ i ] > maxValTemp ) {
327 maxValTemp = ACF[ i ];
328 maxIndexTemp = count;
332 pdPeaks[ 2 ] = (double)( maxIndexTemp + 1 + ( (3 * maxIndexRCF + 2) - 4 ) + 1 )/3;
338 for( i = ( 4 * maxIndexRCF + 3) - 3; i < ( 4 * maxIndexRCF + 3) + 4; i++ ) {
339 if( ACF[ i ] > maxValTemp ) {
340 maxValTemp = ACF[ i ];
341 maxIndexTemp = count;
346 pdPeaks[ 3 ] = (double)( maxIndexTemp + 1 + ( (4 * maxIndexRCF + 3) - 9 ) + 1 )/4 ;
353 #ifdef DEBUG_TEMPO_TRACK 354 std::cerr <<
"tsig != 4" << std::endl;
357 pdPeaks =
new double[ 3 ];
358 for( i = 0; i < 3; i++ ) {
362 pdPeaks[ 0 ] = ( double )maxIndexRCF + 1;
368 for( i = (2 * maxIndexRCF + 1) - 1; i < (2 * maxIndexRCF + 1) + 2; i++ ) {
369 if( ACF[ i ] > maxValTemp ) {
370 maxValTemp = ACF[ i ];
371 maxIndexTemp = count;
375 pdPeaks[ 1 ] = (double)( maxIndexTemp + 1 + ( (2 * maxIndexRCF + 1 ) - 2 ) + 1 )/2;
381 for( i = (3 * maxIndexRCF + 2 ) - 2; i < (3 * maxIndexRCF + 2 ) + 3; i++ ) {
382 if( ACF[ i ] > maxValTemp ) {
383 maxValTemp = ACF[ i ];
384 maxIndexTemp = count;
388 pdPeaks[ 2 ] = (double)( maxIndexTemp + 1 + ( (3 * maxIndexRCF + 2) - 4 ) + 1 )/3;
401 double stepthresh = 1 * 3.9017;
404 if(abs(periodG[ currentIdx ] - periodP[ currentIdx ]) > stepthresh) {
408 if(fabs(periodG[ currentIdx ]-periodP[ currentIdx ]) > stepthresh) {
416 double constthresh = 2 * 3.9017;
418 if( fabs( 2 * periodP[ currentIdx ] - periodP[ currentIdx - 1] - periodP[ currentIdx - 2] ) < constthresh) {
431 double Energy_3 = 0.0;
432 double Energy_4 = 0.0;
439 double* dbf =
new double[ len ];
int t = 0;
440 for(
int u = 0; u < len; u++ ){ dbf[ u ] = 0.0; }
442 if( (
double)len < 6 * p + 2 ) {
444 for( i = ( 3 * p - 2 ); i < ( 3 * p + 2 ) + 1; i++ ) {
446 dbf[ t++ ] = ACF[ i ];
449 for( i = ( 4 * p - 2 ); i < ( 4 * p + 2 ) + 1; i++ ) {
458 for( i = ( 3 * p - 2 ); i < ( 3 * p + 2 ) + 1; i++ ) {
462 for( i = ( 4 * p - 2 ); i < ( 4 * p + 2 ) + 1; i++ ) {
466 for( i = ( 6 * p - 2 ); i < ( 6 * p + 2 ) + 1; i++ ) {
470 for( i = ( 2 * p - 2 ); i < ( 2 * p + 2 ) + 1; i++ ) {
474 Energy_3 = temp3A + temp3B;
475 Energy_4 = temp4A + temp4B;
478 if (Energy_3 > Energy_4) {
490 int predictedOffset = 0;
492 #ifdef DEBUG_TEMPO_TRACK 493 std::cerr <<
"TempoTrack::createPhaseExtractor: period = " << period <<
", p = " << p << std::endl;
497 std::cerr <<
"TempoTrack::createPhaseExtractor: WARNING! Highly implausible period value " << p <<
"!" << std::endl;
501 double* phaseScratch =
new double[ p*2 + 2 ];
502 for (
int i = 0; i < p*2 + 2; ++i) phaseScratch[i] = 0.0;
505 if ( lastBeat != 0 ) {
509 predictedOffset = lastBeat + p - fsp;
511 if (predictedOffset < 0) {
516 if ( lastBeat != 0 ) {
519 double sigma = (double)p/8;
520 double PhaseMin = 0.0;
521 double PhaseMax = 0.0;
522 int scratchLength = p*2;
525 for(
int i = 0; i < scratchLength; i++ ) {
526 phaseScratch[ i ] = exp( -0.5 * pow( ( i - mu ) / sigma, 2 ) ) / ( sqrt(
TWO_PI) *sigma );
531 for(
int i = 0; i < scratchLength; i ++) {
532 temp = phaseScratch[ i ];
533 phaseScratch[ i ] = (temp - PhaseMin)/PhaseMax;
536 #ifdef DEBUG_TEMPO_TRACK 537 std::cerr <<
"predictedOffset = " << predictedOffset << std::endl;
541 for (
int i = p - ( predictedOffset - 1); i < p + ( p - predictedOffset) + 1; i++) {
542 #ifdef DEBUG_TEMPO_TRACK 543 std::cerr <<
"assigning to filter index " << index <<
" (size = " << p*2 <<
")" <<
" value " << phaseScratch[i] <<
" from scratch index " << i << std::endl;
545 Filter[ index++ ] = phaseScratch[ i ];
548 for(
int i = 0; i < p; i ++) {
553 delete [] phaseScratch;
563 double* y =
new double[ winLength ];
564 double* align =
new double[ p ];
566 for(
int i = 0; i < winLength; i++ ) {
567 y[ i ] = (double)( -i + winLength )/(double)winLength;
568 y[ i ] = pow(y [i ],2.0);
571 for(
int o = 0; o < p; o++ ) {
573 for (
int i = 1 + (o - 1); i < winLength; i += (p + 1)) {
574 temp = temp + DF[ i ] * y[ i ];
576 align[ o ] = temp * weighting[ o ];
580 double valTemp = 0.0;
581 for(
int i = 0; i < p; i++) {
582 if( align[ i ] > valTemp ) {
583 valTemp = align[ i ];
602 int FEP = FSP + ( step );
608 while( beat + p < FEP ) {
619 vector <double> *tempoReturn )
632 vector <double> causalDF;
640 causalDF.push_back( 0 );
645 for (
int clear = 0; clear <
m_lagLength; clear++){ RW[ clear ] = 0.0;}
648 for (
int clear = 0; clear <
m_lagLength; clear++){ GW[ clear ] = 0.0;}
651 for(
int clear = 0; clear <
m_lagLength; clear++){ PW[ clear ] = 0.0;}
657 #ifdef DEBUG_TEMPO_TRACK 658 std::cerr <<
"TTFrames = " << TTFrames << std::endl;
661 double* periodP =
new double[ TTFrames ];
662 for(
int clear = 0; clear < TTFrames; clear++){ periodP[ clear ] = 0.0;}
664 double* periodG =
new double[ TTFrames ];
665 for(
int clear = 0; clear < TTFrames; clear++){ periodG[ clear ] = 0.0;}
667 double* alignment =
new double[ TTFrames ];
668 for(
int clear = 0; clear < TTFrames; clear++){ alignment[ clear ] = 0.0;}
676 for(
int i = 0; i < TTFrames; i++ ) {
689 periodG[ TTLoopIndex ] = 0.0;
692 stepDetect( periodP, periodG, TTLoopIndex, &stepFlag );
705 if( constFlag != 0) {
713 period = periodG[ TTLoopIndex ];
715 #ifdef DEBUG_TEMPO_TRACK 716 std::cerr <<
"TempoTrack::process: constFlag == " << constFlag <<
", TTLoopIndex = " << TTLoopIndex <<
", period from periodG = " << period << std::endl;
726 period = periodG[ TTLoopIndex ];
728 #ifdef DEBUG_TEMPO_TRACK 729 std::cerr <<
"TempoTrack::process: GW[0] == " << GW[0] <<
", TTLoopIndex = " << TTLoopIndex <<
", period from periodG = " << period << std::endl;
732 if (period > 10000) {
733 std::cerr <<
"TempoTrack::process: WARNING! Highly implausible period value " << period <<
"!" << std::endl;
734 std::cerr <<
"periodG contains (of " << TTFrames <<
" frames): " << std::endl;
735 for (
int i = 0; i < TTLoopIndex + 3 && i < TTFrames; ++i) {
736 std::cerr << i <<
" -> " << periodG[i] << std::endl;
738 std::cerr <<
"periodP contains (of " << TTFrames <<
" frames): " << std::endl;
739 for (
int i = 0; i < TTLoopIndex + 3 && i < TTFrames; ++i) {
740 std::cerr << i <<
" -> " << periodP[i] << std::endl;
750 period = periodP[ TTLoopIndex ];
752 #ifdef DEBUG_TEMPO_TRACK 753 std::cerr <<
"TempoTrack::process: GW[0] == " << GW[0] <<
", TTLoopIndex = " << TTLoopIndex <<
", period from periodP = " << period << std::endl;
762 lastBeat =
beatPredict(FSP, alignment[ TTLoopIndex ], period, m_lagLength );
void getFrame(double *dst)
void constDetect(double *periodP, int currentIdx, int *flag)
DFProcess * m_RCFConditioning
void configure(int frameLength, int hop)
DFProcConfig m_RCFPParams
std::vector< int > m_beats
int beatPredict(int FSP, double alignment, double period, int step)
void stepDetect(double *periodP, double *periodG, int currentIdx, int *flag)
void initialise(TTParams Params)
std::vector< int > process(std::vector< double > DF, std::vector< double > *tempoReturn=0)
static void getFrameMinMax(const double *data, int len, double *min, double *max)
Return through min and max pointers the highest and lowest values in the given array of the given len...
void doAutoUnBiased(double *src, double *dst, int length)
void process(double *src, double *dst)
double tempoMM(double *ACF, double *weight, int sig)
void setSource(double *src, int64_t length)
int findMeter(double *ACF, int len, double period)
int phaseMM(double *DF, double *weighting, int winLength, double period)
DFProcess * m_DFConditioning
TempoTrack(TTParams Params)
static double round(double x)
Round x to the nearest integer.
void createCombFilter(double *Filter, int winLength, int TSig, double beatLag)
void createPhaseExtractor(double *Filter, int winLength, double period, int fsp, int lastBeat)
static double mean(const double *src, int len)
Return the mean of the given array of the given length.