TempoTrack.cpp
Go to the documentation of this file.
1 /* -*- c-basic-offset: 4 indent-tabs-mode: nil -*- vi:set ts=8 sts=4 sw=4: */
2 
3 /*
4  QM DSP Library
5 
6  Centre for Digital Music, Queen Mary, University of London.
7  This file copyright 2005-2006 Christian Landone.and Matthew Davies.
8 
9  This program is free software; you can redistribute it and/or
10  modify it under the terms of the GNU General Public License as
11  published by the Free Software Foundation; either version 2 of the
12  License, or (at your option) any later version. See the file
13  COPYING included with this distribution for more information.
14 */
15 
16 #include "TempoTrack.h"
17 
18 #include "maths/MathAliases.h"
19 #include "maths/MathUtilities.h"
20 
21 #include <iostream>
22 
23 #include <cassert>
24 #include <cmath>
25 #include <cstdlib>
26 
27 using std::vector;
28 
29 //#define DEBUG_TEMPO_TRACK 1
30 
32 // Construction/Destruction
34 
36 {
37  m_tempoScratch = NULL;
38  m_rawDFFrame = NULL;
39  m_smoothDFFrame = NULL;
40  m_frameACF = NULL;
41  m_smoothRCF = NULL;
42 
43  m_dataLength = 0;
44  m_winLength = 0;
45  m_lagLength = 0;
46 
47  m_rayparam = 0;
48  m_sigma = 0;
49  m_DFWVNnorm = 0;
50 
51  initialise( Params );
52 }
53 
55 {
56  deInitialise();
57 }
58 
60 {
61  m_winLength = Params.winLength;
62  m_lagLength = Params.lagLength;
63 
64  m_rayparam = 43.0;
65  m_sigma = sqrt(3.9017);
66  m_DFWVNnorm = exp( ( log( 2.0 ) / m_rayparam ) * ( m_winLength + 2 ) );
67 
68  m_rawDFFrame = new double[ m_winLength ];
69  m_smoothDFFrame = new double[ m_winLength ];
70  m_frameACF = new double[ m_winLength ];
71  m_tempoScratch = new double[ m_lagLength ];
72  m_smoothRCF = new double[ m_lagLength ];
73 
75 
78  m_DFPParams.LPOrd = Params.LPOrd;
81  m_DFPParams.winPre = Params.WinT.pre;
82  m_DFPParams.winPost = Params.WinT.post;
84 
86 
87  // these are parameters for smoothing m_tempoScratch
90  m_RCFPParams.LPOrd = Params.LPOrd;
93  m_RCFPParams.winPre = Params.WinT.pre;
94  m_RCFPParams.winPost = Params.WinT.post;
96 
98 }
99 
101 {
102  delete [] m_rawDFFrame;
103  delete [] m_smoothDFFrame;
104  delete [] m_smoothRCF;
105  delete [] m_frameACF;
106  delete [] m_tempoScratch;
107  delete m_DFConditioning;
108  delete m_RCFConditioning;
109 }
110 
111 void TempoTrack::createCombFilter(double* Filter, int winLength, int /* TSig */, double beatLag)
112 {
113  int i;
114 
115  if( beatLag == 0 ) {
116  for( i = 0; i < winLength; i++ ) {
117  Filter[ i ] =
118  ( ( i + 1 ) / pow( m_rayparam, 2.0) ) *
119  exp( ( -pow(( i + 1 ),2.0 ) /
120  ( 2.0 * pow( m_rayparam, 2.0))));
121  }
122  } else {
123  m_sigma = beatLag/4;
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) ) /
127  (sqrt(TWO_PI) * m_sigma);
128  }
129  }
130 }
131 
132 double TempoTrack::tempoMM(double* ACF, double* weight, int tsig)
133 {
134  double period = 0;
135  double maxValRCF = 0.0;
136  int maxIndexRCF = 0;
137 
138  double* pdPeaks;
139 
140  int maxIndexTemp;
141  double maxValTemp;
142  int count;
143 
144  int numelem,i,j;
145  int a, b;
146 
147  for( i = 0; i < m_lagLength; i++ ) {
148  m_tempoScratch[ i ] = 0.0;
149  }
150 
151  if( tsig == 0 ) {
152  //if time sig is unknown, use metrically unbiased version of Filterbank
153  numelem = 4;
154  } else {
155  numelem = tsig;
156  }
157 
158 #ifdef DEBUG_TEMPO_TRACK
159  std::cerr << "tempoMM: m_winLength = " << m_winLength << ", m_lagLength = " << m_lagLength << ", numelem = " << numelem << std::endl;
160 #endif
161 
162  for(i=1;i<m_lagLength-1;i++) {
163  //first and last output values are left intentionally as zero
164  for (a=1;a<=numelem;a++) {
165  for(b=(1-a);b<a;b++) {
166  if( tsig == 0 ) {
167  m_tempoScratch[i] += ACF[a*(i+1)+b-1] * (1.0 / (2.0 * (double)a-1)) * weight[i];
168  } else {
169  m_tempoScratch[i] += ACF[a*(i+1)+b-1] * 1 * weight[i];
170  }
171  }
172  }
173  }
174 
175 
177  // MODIFIED BEAT PERIOD EXTRACTION //////////////
179 
180  // find smoothed version of RCF ( as applied to Detection Function)
182 
183  if (tsig != 0) { // i.e. in context dependent state
184 
185 // NOW FIND MAX INDEX OF ACFOUT
186  for( i = 0; i < m_lagLength; i++) {
187  if( m_tempoScratch[ i ] > maxValRCF) {
188  maxValRCF = m_tempoScratch[ i ];
189  maxIndexRCF = i;
190  }
191  }
192 
193  } else { // using rayleigh weighting
194 
195  vector <vector<double> > rcfMat;
196 
197  double sumRcf = 0.;
198 
199  double maxVal = 0.;
200  // now find the two values which minimise rcfMat
201  double minVal = 0.;
202  int p_i = 1; // periodicity for row i;
203  int p_j = 1; //periodicity for column j;
204 
205  for ( i=0; i<m_lagLength; i++) {
207  }
208 
209  // normalise m_tempoScratch so that it sums to zero.
210  for ( i=0; i<m_lagLength; i++) {
211  sumRcf += m_tempoScratch[i];
212  }
213 
214  for( i=0; i<m_lagLength; i++) {
215  m_tempoScratch[i] /= sumRcf;
216  }
217 
218  // create a matrix to store m_tempoScratchValues modified by log2 ratio
219  for ( i=0; i<m_lagLength; i++) {
220  rcfMat.push_back ( vector<double>() ); // adds a new row...
221  }
222 
223  for (i=0; i<m_lagLength; i++) {
224  for (j=0; j<m_lagLength; j++) {
225  rcfMat[i].push_back (0.);
226  }
227  }
228 
229  // the 'i' and 'j' indices deliberately start from '1' and not '0'
230  for ( i=1; i<m_lagLength; i++) {
231  for (j=1; j<m_lagLength; j++) {
232  double log2PeriodRatio = log( static_cast<double>(i)/
233  static_cast<double>(j) ) /
234  log(2.0);
235  rcfMat[i][j] = ( abs(1.0-abs(log2PeriodRatio)) );
236  rcfMat[i][j] += ( 0.01*( 1./(m_tempoScratch[i]+m_tempoScratch[j]) ) );
237  }
238  }
239 
240  // set diagonal equal to maximum value in rcfMat
241  // we don't want to pick one strong middle peak - we need a combination of two peaks.
242 
243  for ( i=1; i<m_lagLength; i++) {
244  for (j=1; j<m_lagLength; j++) {
245  if (rcfMat[i][j] > maxVal) {
246  maxVal = rcfMat[i][j];
247  }
248  }
249  }
250 
251  for ( i=1; i<m_lagLength; i++) {
252  rcfMat[i][i] = maxVal;
253  }
254 
255  // now find the row and column number which minimise rcfMat
256  minVal = maxVal;
257 
258  for ( i=1; i<m_lagLength; i++) {
259  for ( j=1; j<m_lagLength; j++) {
260  if (rcfMat[i][j] < minVal) {
261  minVal = rcfMat[i][j];
262  p_i = i;
263  p_j = j;
264  }
265  }
266  }
267 
268 
269  // initially choose p_j (arbitrary) - saves on an else statement
270  int beatPeriod = p_j;
271  if (m_tempoScratch[p_i] > m_tempoScratch[p_j]) {
272  beatPeriod = p_i;
273  }
274 
275  // now write the output
276  maxIndexRCF = static_cast<int>(beatPeriod);
277  }
278 
279 
280  double locked = 5168.f / maxIndexRCF;
281  if (locked >= 30 && locked <= 180) {
282  m_lockedTempo = locked;
283  }
284 
285 #ifdef DEBUG_TEMPO_TRACK
286  std::cerr << "tempoMM: locked tempo = " << m_lockedTempo << std::endl;
287 #endif
288 
289  if( tsig == 0 ) {
290  tsig = 4;
291  }
292 
293 #ifdef DEBUG_TEMPO_TRACK
294  std::cerr << "tempoMM: maxIndexRCF = " << maxIndexRCF << std::endl;
295 #endif
296 
297  if( tsig == 4 ) {
298 
299 #ifdef DEBUG_TEMPO_TRACK
300  std::cerr << "tsig == 4" << std::endl;
301 #endif
302 
303  pdPeaks = new double[ 4 ];
304  for( i = 0; i < 4; i++ ){ pdPeaks[ i ] = 0.0;}
305 
306  pdPeaks[ 0 ] = ( double )maxIndexRCF + 1;
307 
308  maxIndexTemp = 0;
309  maxValTemp = 0.0;
310  count = 0;
311 
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;
316  }
317  count++;
318  }
319  pdPeaks[ 1 ] = (double)( maxIndexTemp + 1 + ( (2 * maxIndexRCF + 1 ) - 2 ) + 1 )/2;
320 
321  maxIndexTemp = 0;
322  maxValTemp = 0.0;
323  count = 0;
324 
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;
329  }
330  count++;
331  }
332  pdPeaks[ 2 ] = (double)( maxIndexTemp + 1 + ( (3 * maxIndexRCF + 2) - 4 ) + 1 )/3;
333 
334  maxIndexTemp = 0;
335  maxValTemp = 0.0;
336  count = 0;
337 
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;
342  }
343  count++;
344  }
345 
346  pdPeaks[ 3 ] = (double)( maxIndexTemp + 1 + ( (4 * maxIndexRCF + 3) - 9 ) + 1 )/4 ;
347 
348 
349  period = MathUtilities::mean( pdPeaks, 4 );
350 
351  } else {
352 
353 #ifdef DEBUG_TEMPO_TRACK
354  std::cerr << "tsig != 4" << std::endl;
355 #endif
356 
357  pdPeaks = new double[ 3 ];
358  for( i = 0; i < 3; i++ ) {
359  pdPeaks[ i ] = 0.0;
360  }
361 
362  pdPeaks[ 0 ] = ( double )maxIndexRCF + 1;
363 
364  maxIndexTemp = 0;
365  maxValTemp = 0.0;
366  count = 0;
367 
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;
372  }
373  count++;
374  }
375  pdPeaks[ 1 ] = (double)( maxIndexTemp + 1 + ( (2 * maxIndexRCF + 1 ) - 2 ) + 1 )/2;
376 
377  maxIndexTemp = 0;
378  maxValTemp = 0.0;
379  count = 0;
380 
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;
385  }
386  count++;
387  }
388  pdPeaks[ 2 ] = (double)( maxIndexTemp + 1 + ( (3 * maxIndexRCF + 2) - 4 ) + 1 )/3;
389 
390 
391  period = MathUtilities::mean( pdPeaks, 3 );
392  }
393 
394  delete [] pdPeaks;
395 
396  return period;
397 }
398 
399 void TempoTrack::stepDetect( double* periodP, double* periodG, int currentIdx, int* flag )
400 {
401  double stepthresh = 1 * 3.9017;
402 
403  if( *flag ) {
404  if(abs(periodG[ currentIdx ] - periodP[ currentIdx ]) > stepthresh) {
405  // do nuffin'
406  }
407  } else {
408  if(fabs(periodG[ currentIdx ]-periodP[ currentIdx ]) > stepthresh) {
409  *flag = 3;
410  }
411  }
412 }
413 
414 void TempoTrack::constDetect( double* periodP, int currentIdx, int* flag )
415 {
416  double constthresh = 2 * 3.9017;
417 
418  if( fabs( 2 * periodP[ currentIdx ] - periodP[ currentIdx - 1] - periodP[ currentIdx - 2] ) < constthresh) {
419  *flag = 1;
420  } else {
421  *flag = 0;
422  }
423 }
424 
425 int TempoTrack::findMeter(double *ACF, int len, double period)
426 {
427  int i;
428  int p = (int)MathUtilities::round( period );
429  int tsig;
430 
431  double Energy_3 = 0.0;
432  double Energy_4 = 0.0;
433 
434  double temp3A = 0.0;
435  double temp3B = 0.0;
436  double temp4A = 0.0;
437  double temp4B = 0.0;
438 
439  double* dbf = new double[ len ]; int t = 0;
440  for( int u = 0; u < len; u++ ){ dbf[ u ] = 0.0; }
441 
442  if( (double)len < 6 * p + 2 ) {
443 
444  for( i = ( 3 * p - 2 ); i < ( 3 * p + 2 ) + 1; i++ ) {
445  temp3A += ACF[ i ];
446  dbf[ t++ ] = ACF[ i ];
447  }
448 
449  for( i = ( 4 * p - 2 ); i < ( 4 * p + 2 ) + 1; i++ ) {
450  temp4A += ACF[ i ];
451  }
452 
453  Energy_3 = temp3A;
454  Energy_4 = temp4A;
455 
456  } else {
457 
458  for( i = ( 3 * p - 2 ); i < ( 3 * p + 2 ) + 1; i++ ) {
459  temp3A += ACF[ i ];
460  }
461 
462  for( i = ( 4 * p - 2 ); i < ( 4 * p + 2 ) + 1; i++ ) {
463  temp4A += ACF[ i ];
464  }
465 
466  for( i = ( 6 * p - 2 ); i < ( 6 * p + 2 ) + 1; i++ ) {
467  temp3B += ACF[ i ];
468  }
469 
470  for( i = ( 2 * p - 2 ); i < ( 2 * p + 2 ) + 1; i++ ) {
471  temp4B += ACF[ i ];
472  }
473 
474  Energy_3 = temp3A + temp3B;
475  Energy_4 = temp4A + temp4B;
476  }
477 
478  if (Energy_3 > Energy_4) {
479  tsig = 3;
480  } else {
481  tsig = 4;
482  }
483 
484  return tsig;
485 }
486 
487 void TempoTrack::createPhaseExtractor(double *Filter, int /* winLength */, double period, int fsp, int lastBeat)
488 {
489  int p = (int)MathUtilities::round( period );
490  int predictedOffset = 0;
491 
492 #ifdef DEBUG_TEMPO_TRACK
493  std::cerr << "TempoTrack::createPhaseExtractor: period = " << period << ", p = " << p << std::endl;
494 #endif
495 
496  if (p > 10000) {
497  std::cerr << "TempoTrack::createPhaseExtractor: WARNING! Highly implausible period value " << p << "!" << std::endl;
498  period = 5168 / 120;
499  }
500 
501  double* phaseScratch = new double[ p*2 + 2 ];
502  for (int i = 0; i < p*2 + 2; ++i) phaseScratch[i] = 0.0;
503 
504 
505  if ( lastBeat != 0 ) {
506 
507  lastBeat = (int)MathUtilities::round((double)lastBeat );
508 
509  predictedOffset = lastBeat + p - fsp;
510 
511  if (predictedOffset < 0) {
512  lastBeat = 0;
513  }
514  }
515 
516  if ( lastBeat != 0 ) {
517 
518  int mu = p;
519  double sigma = (double)p/8;
520  double PhaseMin = 0.0;
521  double PhaseMax = 0.0;
522  int scratchLength = p*2;
523  double temp = 0.0;
524 
525  for( int i = 0; i < scratchLength; i++ ) {
526  phaseScratch[ i ] = exp( -0.5 * pow( ( i - mu ) / sigma, 2 ) ) / ( sqrt(TWO_PI) *sigma );
527  }
528 
529  MathUtilities::getFrameMinMax( phaseScratch, scratchLength, &PhaseMin, &PhaseMax );
530 
531  for(int i = 0; i < scratchLength; i ++) {
532  temp = phaseScratch[ i ];
533  phaseScratch[ i ] = (temp - PhaseMin)/PhaseMax;
534  }
535 
536 #ifdef DEBUG_TEMPO_TRACK
537  std::cerr << "predictedOffset = " << predictedOffset << std::endl;
538 #endif
539 
540  int index = 0;
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;
544 #endif
545  Filter[ index++ ] = phaseScratch[ i ];
546  }
547  } else {
548  for( int i = 0; i < p; i ++) {
549  Filter[ i ] = 1;
550  }
551  }
552 
553  delete [] phaseScratch;
554 }
555 
556 int TempoTrack::phaseMM(double *DF, double *weighting, int winLength, double period)
557 {
558  int alignment = 0;
559  int p = (int)MathUtilities::round( period );
560 
561  double temp = 0.0;
562 
563  double* y = new double[ winLength ];
564  double* align = new double[ p ];
565 
566  for( int i = 0; i < winLength; i++ ) {
567  y[ i ] = (double)( -i + winLength )/(double)winLength;
568  y[ i ] = pow(y [i ],2.0); // raise to power 2.
569  }
570 
571  for( int o = 0; o < p; o++ ) {
572  temp = 0.0;
573  for (int i = 1 + (o - 1); i < winLength; i += (p + 1)) {
574  temp = temp + DF[ i ] * y[ i ];
575  }
576  align[ o ] = temp * weighting[ o ];
577  }
578 
579 
580  double valTemp = 0.0;
581  for(int i = 0; i < p; i++) {
582  if( align[ i ] > valTemp ) {
583  valTemp = align[ i ];
584  alignment = i;
585  }
586  }
587 
588  delete [] y;
589  delete [] align;
590 
591  return alignment;
592 }
593 
594 int TempoTrack::beatPredict(int FSP0, double alignment, double period, int step )
595 {
596  int beat = 0;
597 
598  int p = (int)MathUtilities::round( period );
599  int align = (int)MathUtilities::round( alignment );
600  int FSP = (int)MathUtilities::round( FSP0 );
601 
602  int FEP = FSP + ( step );
603 
604  beat = FSP + align;
605 
606  m_beats.push_back( beat );
607 
608  while( beat + p < FEP ) {
609  beat += p;
610  m_beats.push_back( beat );
611  }
612 
613  return beat;
614 }
615 
616 
617 
618 vector<int> TempoTrack::process( vector <double> DF,
619  vector <double> *tempoReturn )
620 {
621  m_dataLength = DF.size();
622 
623  m_lockedTempo = 0.0;
624 
625  double period = 0.0;
626  int stepFlag = 0;
627  int constFlag = 0;
628  int FSP = 0;
629  int tsig = 0;
630  int lastBeat = 0;
631 
632  vector <double> causalDF;
633 
634  causalDF = DF;
635 
636  //Prepare Causal Extension DFData
637 // int DFCLength = m_dataLength + m_winLength;
638 
639  for( int j = 0; j < m_winLength; j++ ) {
640  causalDF.push_back( 0 );
641  }
642 
643 
644  double* RW = new double[ m_lagLength ];
645  for (int clear = 0; clear < m_lagLength; clear++){ RW[ clear ] = 0.0;}
646 
647  double* GW = new double[ m_lagLength ];
648  for (int clear = 0; clear < m_lagLength; clear++){ GW[ clear ] = 0.0;}
649 
650  double* PW = new double[ m_lagLength ];
651  for(int clear = 0; clear < m_lagLength; clear++){ PW[ clear ] = 0.0;}
652 
653  m_DFFramer.setSource( &causalDF[0], m_dataLength );
654 
655  int TTFrames = m_DFFramer.getMaxNoFrames();
656 
657 #ifdef DEBUG_TEMPO_TRACK
658  std::cerr << "TTFrames = " << TTFrames << std::endl;
659 #endif
660 
661  double* periodP = new double[ TTFrames ];
662  for(int clear = 0; clear < TTFrames; clear++){ periodP[ clear ] = 0.0;}
663 
664  double* periodG = new double[ TTFrames ];
665  for(int clear = 0; clear < TTFrames; clear++){ periodG[ clear ] = 0.0;}
666 
667  double* alignment = new double[ TTFrames ];
668  for(int clear = 0; clear < TTFrames; clear++){ alignment[ clear ] = 0.0;}
669 
670  m_beats.clear();
671 
672  createCombFilter( RW, m_lagLength, 0, 0 );
673 
674  int TTLoopIndex = 0;
675 
676  for( int i = 0; i < TTFrames; i++ ) {
677 
679 
681 
683 
684  periodP[ TTLoopIndex ] = tempoMM( m_frameACF, RW, 0 );
685 
686  if( GW[ 0 ] != 0 ) {
687  periodG[ TTLoopIndex ] = tempoMM( m_frameACF, GW, tsig );
688  } else {
689  periodG[ TTLoopIndex ] = 0.0;
690  }
691 
692  stepDetect( periodP, periodG, TTLoopIndex, &stepFlag );
693 
694  if( stepFlag == 1) {
695  constDetect( periodP, TTLoopIndex, &constFlag );
696  stepFlag = 0;
697  } else {
698  stepFlag -= 1;
699  }
700 
701  if( stepFlag < 0 ) {
702  stepFlag = 0;
703  }
704 
705  if( constFlag != 0) {
706 
707  tsig = findMeter( m_frameACF, m_winLength, periodP[ TTLoopIndex ] );
708 
709  createCombFilter( GW, m_lagLength, tsig, periodP[ TTLoopIndex ] );
710 
711  periodG[ TTLoopIndex ] = tempoMM( m_frameACF, GW, tsig );
712 
713  period = periodG[ TTLoopIndex ];
714 
715 #ifdef DEBUG_TEMPO_TRACK
716  std::cerr << "TempoTrack::process: constFlag == " << constFlag << ", TTLoopIndex = " << TTLoopIndex << ", period from periodG = " << period << std::endl;
717 #endif
718 
719  createPhaseExtractor( PW, m_winLength, period, FSP, 0 );
720 
721  constFlag = 0;
722 
723  } else {
724 
725  if( GW[ 0 ] != 0 ) {
726  period = periodG[ TTLoopIndex ];
727 
728 #ifdef DEBUG_TEMPO_TRACK
729  std::cerr << "TempoTrack::process: GW[0] == " << GW[0] << ", TTLoopIndex = " << TTLoopIndex << ", period from periodG = " << period << std::endl;
730 #endif
731 
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;
737  }
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;
741  }
742  period = 5168 / 120;
743  }
744 
745  createPhaseExtractor( PW, m_winLength, period, FSP, lastBeat );
746 
747  }
748  else
749  {
750  period = periodP[ TTLoopIndex ];
751 
752 #ifdef DEBUG_TEMPO_TRACK
753  std::cerr << "TempoTrack::process: GW[0] == " << GW[0] << ", TTLoopIndex = " << TTLoopIndex << ", period from periodP = " << period << std::endl;
754 #endif
755 
756  createPhaseExtractor( PW, m_winLength, period, FSP, 0 );
757  }
758  }
759 
760  alignment[ TTLoopIndex ] = phaseMM( m_rawDFFrame, PW, m_winLength, period );
761 
762  lastBeat = beatPredict(FSP, alignment[ TTLoopIndex ], period, m_lagLength );
763 
764  FSP += (m_lagLength);
765 
766  if (tempoReturn) tempoReturn->push_back(m_lockedTempo);
767 
768  TTLoopIndex++;
769  }
770 
771 
772  delete [] periodP;
773  delete [] periodG;
774  delete [] alignment;
775 
776  delete [] RW;
777  delete [] GW;
778  delete [] PW;
779 
780  return m_beats;
781 }
782 
void getFrame(double *dst)
Definition: Framer.cpp:53
virtual ~TempoTrack()
Definition: TempoTrack.cpp:54
void constDetect(double *periodP, int currentIdx, int *flag)
Definition: TempoTrack.cpp:414
DFProcess * m_RCFConditioning
Definition: TempoTrack.h:100
int winLength
Definition: TempoTrack.h:35
double * m_smoothDFFrame
Definition: TempoTrack.h:85
void configure(int frameLength, int hop)
Definition: Framer.cpp:39
int lagLength
Definition: TempoTrack.h:36
int m_winLength
Definition: TempoTrack.h:69
DFProcConfig m_RCFPParams
Definition: TempoTrack.h:102
double * LPBCoeffs
Definition: DFProcess.h:36
std::vector< int > m_beats
Definition: TempoTrack.h:76
int LPOrd
Definition: TempoTrack.h:38
int beatPredict(int FSP, double alignment, double period, int step)
Definition: TempoTrack.cpp:594
int post
Definition: TempoTrack.h:30
void stepDetect(double *periodP, double *periodG, int currentIdx, int *flag)
Definition: TempoTrack.cpp:399
void initialise(TTParams Params)
Definition: TempoTrack.cpp:59
Definition: Filter.h:22
int m_dataLength
Definition: TempoTrack.h:68
Correlation m_correlator
Definition: TempoTrack.h:95
DFProcConfig m_DFPParams
Definition: TempoTrack.h:97
int getMaxNoFrames()
Definition: Framer.cpp:87
int alpha
Definition: TempoTrack.h:37
double * LPACoeffs
Definition: TempoTrack.h:39
Framer m_DFFramer
Definition: TempoTrack.h:93
std::vector< int > process(std::vector< double > DF, std::vector< double > *tempoReturn=0)
Definition: TempoTrack.cpp:618
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)
Definition: Correlation.cpp:34
void process(double *src, double *dst)
Definition: DFProcess.cpp:85
WinThresh WinT
Definition: TempoTrack.h:41
double m_DFWVNnorm
Definition: TempoTrack.h:74
double tempoMM(double *ACF, double *weight, int sig)
Definition: TempoTrack.cpp:132
void setSource(double *src, int64_t length)
Definition: Framer.cpp:92
#define TWO_PI
Definition: MathAliases.h:21
int findMeter(double *ACF, int len, double period)
Definition: TempoTrack.cpp:425
int phaseMM(double *DF, double *weighting, int winLength, double period)
Definition: TempoTrack.cpp:556
double AlphaNormParam
Definition: DFProcess.h:39
double * m_smoothRCF
Definition: TempoTrack.h:81
double * m_rawDFFrame
Definition: TempoTrack.h:84
int m_lagLength
Definition: TempoTrack.h:70
double m_sigma
Definition: TempoTrack.h:73
void deInitialise()
Definition: TempoTrack.cpp:100
double * LPBCoeffs
Definition: TempoTrack.h:40
bool isMedianPositive
Definition: DFProcess.h:40
DFProcess * m_DFConditioning
Definition: TempoTrack.h:94
double * LPACoeffs
Definition: DFProcess.h:35
double * m_tempoScratch
Definition: TempoTrack.h:80
double m_rayparam
Definition: TempoTrack.h:72
TempoTrack(TTParams Params)
Definition: TempoTrack.cpp:35
static double round(double x)
Round x to the nearest integer.
void createCombFilter(double *Filter, int winLength, int TSig, double beatLag)
Definition: TempoTrack.cpp:111
void createPhaseExtractor(double *Filter, int winLength, double period, int fsp, int lastBeat)
Definition: TempoTrack.cpp:487
static double mean(const double *src, int len)
Return the mean of the given array of the given length.
double m_lockedTempo
Definition: TempoTrack.h:78
double * m_frameACF
Definition: TempoTrack.h:86