annotate dsp/tempotracking/TempoTrack.cpp @ 229:0e42bf10f29a

* fix compile error with gcc-4.1
author Chris Cannam <c.cannam@qmul.ac.uk>
date Wed, 26 Jul 2006 20:22:43 +0000
parents 49844bc8a895
children a9bf0cfe9383
rev   line source
c@225 1 /* -*- c-basic-offset: 4 indent-tabs-mode: nil -*- vi:set ts=8 sts=4 sw=4: */
c@225 2
c@225 3 /*
c@225 4 QM DSP Library
c@225 5
c@225 6 Centre for Digital Music, Queen Mary, University of London.
c@225 7 This file copyright 2005-2006 Christian Landone.
c@225 8 All rights reserved.
c@225 9 */
c@225 10
c@225 11 #include "TempoTrack.h"
c@225 12
c@225 13 #include "dsp/maths/MathAliases.h"
c@225 14 #include "dsp/maths/MathUtilities.h"
c@225 15
c@225 16
c@225 17 //////////////////////////////////////////////////////////////////////
c@225 18 // Construction/Destruction
c@225 19 //////////////////////////////////////////////////////////////////////
c@225 20
c@225 21 TempoTrack::TempoTrack( TTParams Params )
c@225 22 {
c@225 23 m_tempoScratch = NULL;
c@225 24 m_rawDFFrame = NULL;
c@225 25 m_smoothDFFrame = NULL;
c@225 26 m_frameACF = NULL;
c@225 27
c@225 28 m_dataLength = 0;
c@225 29 m_winLength = 0;
c@225 30 m_lagLength = 0;
c@225 31
c@225 32 m_rayparam = 0;
c@225 33 m_sigma = 0;
c@225 34 m_DFWVNnorm = 0;
c@225 35
c@225 36 initialise( Params );
c@225 37 }
c@225 38
c@225 39 TempoTrack::~TempoTrack()
c@225 40 {
c@225 41 deInitialise();
c@225 42 }
c@225 43
c@225 44 void TempoTrack::initialise( TTParams Params )
c@225 45 {
c@225 46 m_winLength = Params.winLength;
c@225 47 m_lagLength = Params.lagLength;
c@225 48
c@225 49 m_rayparam = 43.0;
c@225 50 m_sigma = sqrt(3.9017);
c@225 51 m_DFWVNnorm = exp( ( log( 2.0 ) / m_rayparam ) * ( m_winLength + 2 ) );
c@225 52
c@225 53 m_rawDFFrame = new double[ m_winLength ];
c@225 54 m_smoothDFFrame = new double[ m_winLength ];
c@225 55 m_frameACF = new double[ m_winLength ];
c@225 56 m_tempoScratch = new double[ m_lagLength ];
c@225 57
c@225 58 unsigned int winPre = Params.WinT.pre;
c@225 59 unsigned int winPost = Params.WinT.post;
c@225 60
c@225 61 m_DFFramer.configure( m_winLength, m_lagLength );
c@225 62
c@225 63 m_DFPParams.length = m_winLength;
c@225 64 m_DFPParams.AlphaNormParam = Params.alpha;
c@225 65 m_DFPParams.LPOrd = Params.LPOrd;
c@225 66 m_DFPParams.LPACoeffs = Params.LPACoeffs;
c@225 67 m_DFPParams.LPBCoeffs = Params.LPBCoeffs;
c@225 68 m_DFPParams.winPre = Params.WinT.pre;
c@225 69 m_DFPParams.winPost = Params.WinT.post;
c@225 70 m_DFPParams.isMedianPositive = true;
c@225 71
c@225 72 m_DFConditioning = new DFProcess( m_DFPParams );
c@225 73
c@225 74 }
c@225 75
c@225 76 void TempoTrack::deInitialise()
c@225 77 {
c@225 78 delete [] m_rawDFFrame;
c@225 79
c@225 80 delete [] m_smoothDFFrame;
c@225 81
c@225 82 delete [] m_frameACF;
c@225 83
c@225 84 delete [] m_tempoScratch;
c@225 85
c@225 86 delete m_DFConditioning;
c@225 87 }
c@225 88
c@225 89 void TempoTrack::createCombFilter(double* Filter, unsigned int winLength, unsigned int TSig, double beatLag)
c@225 90 {
c@225 91 unsigned int i;
c@225 92
c@225 93 if( beatLag == 0 )
c@225 94 {
c@225 95 for( i = 0; i < winLength; i++ )
c@225 96 {
c@225 97 Filter[ i ] = ( ( i + 1 ) / pow( m_rayparam, 2.0) ) * exp( ( -pow(( i + 1 ),2.0 ) / ( 2.0 * pow( m_rayparam, 2.0))));
c@225 98 }
c@225 99 }
c@225 100 else
c@225 101 {
c@225 102 m_sigma = beatLag/8;
c@225 103 for( i = 0; i < winLength; i++ )
c@225 104 {
c@225 105 double dlag = (double)(i+1) - beatLag;
c@225 106 Filter[ i ] = exp(-0.5 * pow(( dlag / m_sigma), 2.0) ) / (sqrt( 2 * PI) * m_sigma);
c@225 107 }
c@225 108 }
c@225 109 }
c@225 110
c@225 111 double TempoTrack::tempoMM(double* ACF, double* weight, int tsig)
c@225 112 {
c@225 113
c@225 114 double period = 0;
c@225 115 double maxValRCF = 0.0;
c@225 116 unsigned int maxIndexRCF = 0;
c@225 117
c@225 118 double* pdPeaks;
c@225 119
c@225 120 unsigned int maxIndexTemp;
c@225 121 double maxValTemp;
c@225 122 unsigned int count;
c@225 123
c@225 124 unsigned int numelem;
c@225 125 int i, a, b;
c@225 126
c@225 127 for( i = 0; i < m_lagLength; i++ )
c@225 128 m_tempoScratch[ i ] = 0.0;
c@225 129
c@225 130 if( tsig == 0 )
c@225 131 {
c@225 132 //if time sig is unknown, use metrically unbiased version of Filterbank
c@225 133 numelem = 4;
c@225 134 }
c@225 135 else
c@225 136 {
c@225 137 numelem = tsig;
c@225 138 }
c@225 139
c@225 140 for(i=1;i<m_lagLength-1;i++)
c@225 141 {
c@225 142 //first and last output values are left intentionally as zero
c@225 143 for (a=1;a<=numelem;a++)
c@225 144 {
c@225 145 for(b=(1-a);b<a;b++)
c@225 146 {
c@225 147 if( tsig == 0 )
c@225 148 {
c@225 149 m_tempoScratch[i] += ACF[a*(i+1)+b-1] * (1.0 / (2.0 * (double)a-1)) * weight[i];
c@225 150 }
c@225 151 else
c@225 152 {
c@225 153 m_tempoScratch[i] += ACF[a*(i+1)+b-1] * 1 * weight[i];
c@225 154 }
c@225 155 }
c@225 156 }
c@225 157 }
c@225 158
c@225 159
c@225 160 //NOW FIND MAX INDEX OF ACFOUT
c@225 161 for( i = 0; i < m_lagLength; i++)
c@225 162 {
c@225 163 if( m_tempoScratch[ i ] > maxValRCF)
c@225 164 {
c@225 165 maxValRCF = m_tempoScratch[ i ];
c@225 166 maxIndexRCF = i;
c@225 167 }
c@225 168 }
c@225 169
c@225 170 if( tsig == 0 )
c@225 171 tsig = 4;
c@225 172
c@225 173
c@225 174 if( tsig == 4 )
c@225 175 {
c@225 176 pdPeaks = new double[ 4 ];
c@225 177 for( i = 0; i < 4; i++ ){ pdPeaks[ i ] = 0.0;}
c@225 178
c@225 179 pdPeaks[ 0 ] = ( double )maxIndexRCF + 1;
c@225 180
c@225 181 maxIndexTemp = 0;
c@225 182 maxValTemp = 0.0;
c@225 183 count = 0;
c@225 184
c@225 185 for( i = (2 * maxIndexRCF + 1) - 1; i < (2 * maxIndexRCF + 1) + 2; i++ )
c@225 186 {
c@225 187 if( ACF[ i ] > maxValTemp )
c@225 188 {
c@225 189 maxValTemp = ACF[ i ];
c@225 190 maxIndexTemp = count;
c@225 191 }
c@225 192 count++;
c@225 193 }
c@225 194 pdPeaks[ 1 ] = (double)( maxIndexTemp + 1 + ( (2 * maxIndexRCF + 1 ) - 2 ) + 1 )/2;
c@225 195
c@225 196 maxIndexTemp = 0;
c@225 197 maxValTemp = 0.0;
c@225 198 count = 0;
c@225 199
c@225 200 for( i = (3 * maxIndexRCF + 2 ) - 2; i < (3 * maxIndexRCF + 2 ) + 3; i++ )
c@225 201 {
c@225 202 if( ACF[ i ] > maxValTemp )
c@225 203 {
c@225 204 maxValTemp = ACF[ i ];
c@225 205 maxIndexTemp = count;
c@225 206 }
c@225 207 count++;
c@225 208 }
c@225 209 pdPeaks[ 2 ] = (double)( maxIndexTemp + 1 + ( (3 * maxIndexRCF + 2) - 4 ) + 1 )/3;
c@225 210
c@225 211 maxIndexTemp = 0;
c@225 212 maxValTemp = 0.0;
c@225 213 count = 0;
c@225 214
c@225 215 for( i = ( 4 * maxIndexRCF + 3) - 3; i < ( 4 * maxIndexRCF + 3) + 4; i++ )
c@225 216 {
c@225 217 if( ACF[ i ] > maxValTemp )
c@225 218 {
c@225 219 maxValTemp = ACF[ i ];
c@225 220 maxIndexTemp = count;
c@225 221 }
c@225 222 count++;
c@225 223 }
c@225 224 pdPeaks[ 3 ] = (double)( maxIndexTemp + 1 + ( (4 * maxIndexRCF + 3) - 9 ) + 1 )/4 ;
c@225 225
c@225 226
c@225 227 period = MathUtilities::mean( pdPeaks, 4 );
c@225 228 }
c@225 229 else
c@225 230 {
c@225 231 pdPeaks = new double[ 3 ];
c@225 232 for( i = 0; i < 3; i++ ){ pdPeaks[ i ] = 0.0;}
c@225 233
c@225 234 pdPeaks[ 0 ] = ( double )maxIndexRCF + 1;
c@225 235
c@225 236 maxIndexTemp = 0;
c@225 237 maxValTemp = 0.0;
c@225 238 count = 0;
c@225 239
c@225 240 for( i = (2 * maxIndexRCF + 1) - 1; i < (2 * maxIndexRCF + 1) + 2; i++ )
c@225 241 {
c@225 242 if( ACF[ i ] > maxValTemp )
c@225 243 {
c@225 244 maxValTemp = ACF[ i ];
c@225 245 maxIndexTemp = count;
c@225 246 }
c@225 247 count++;
c@225 248 }
c@225 249 pdPeaks[ 1 ] = (double)( maxIndexTemp + 1 + ( (2 * maxIndexRCF + 1 ) - 2 ) + 1 )/2;
c@225 250
c@225 251 maxIndexTemp = 0;
c@225 252 maxValTemp = 0.0;
c@225 253 count = 0;
c@225 254
c@225 255 for( i = (3 * maxIndexRCF + 2 ) - 2; i < (3 * maxIndexRCF + 2 ) + 3; i++ )
c@225 256 {
c@225 257 if( ACF[ i ] > maxValTemp )
c@225 258 {
c@225 259 maxValTemp = ACF[ i ];
c@225 260 maxIndexTemp = count;
c@225 261 }
c@225 262 count++;
c@225 263 }
c@225 264 pdPeaks[ 2 ] = (double)( maxIndexTemp + 1 + ( (3 * maxIndexRCF + 2) - 4 ) + 1 )/3;
c@225 265
c@225 266
c@225 267 period = MathUtilities::mean( pdPeaks, 3 );
c@225 268 }
c@225 269
c@225 270 delete [] pdPeaks;
c@225 271
c@225 272 return period;
c@225 273 }
c@225 274
c@225 275 void TempoTrack::stepDetect( double* periodP, double* periodG, int currentIdx, int* flag )
c@225 276 {
c@225 277 double stepthresh = 1 * 3.9017;
c@225 278
c@225 279 if( *flag )
c@225 280 {
c@225 281 if(abs(periodG[ currentIdx ] - periodP[ currentIdx ]) > stepthresh)
c@225 282 {
c@225 283 // do nuffin'
c@225 284 }
c@225 285 }
c@225 286 else
c@225 287 {
c@225 288 if(fabs(periodG[ currentIdx ]-periodP[ currentIdx ]) > stepthresh)
c@225 289 {
c@225 290 *flag = 3;
c@225 291 }
c@225 292 }
c@225 293 }
c@225 294
c@225 295 void TempoTrack::constDetect( double* periodP, int currentIdx, int* flag )
c@225 296 {
c@225 297 double constthresh = 2 * 3.9017;
c@225 298
c@225 299 if( fabs( 2 * periodP[ currentIdx ] - periodP[ currentIdx - 1] - periodP[ currentIdx - 2] ) < constthresh)
c@225 300 {
c@225 301 *flag = 1;
c@225 302 }
c@225 303 else
c@225 304 {
c@225 305 *flag = 0;
c@225 306 }
c@225 307 }
c@225 308
c@225 309 int TempoTrack::findMeter(double *ACF, unsigned int len, double period)
c@225 310 {
c@225 311 int i;
c@225 312 int p = (int)MathUtilities::round( period );
c@225 313 int tsig;
c@225 314
c@225 315 double Energy_3 = 0.0;
c@225 316 double Energy_4 = 0.0;
c@225 317
c@225 318 double temp3A = 0.0;
c@225 319 double temp3B = 0.0;
c@225 320 double temp4A = 0.0;
c@225 321 double temp4B = 0.0;
c@225 322
c@225 323 double* dbf = new double[ len ]; int t = 0;
c@225 324 for( unsigned int u = 0; u < len; u++ ){ dbf[ u ] = 0.0; }
c@225 325
c@225 326 if( (double)len < 6 * p + 2 )
c@225 327 {
c@225 328 for( i = ( 3 * p - 2 ); i < ( 3 * p + 2 ) + 1; i++ )
c@225 329 {
c@225 330 temp3A += ACF[ i ];
c@225 331 dbf[ t++ ] = ACF[ i ];
c@225 332 }
c@225 333
c@225 334 for( i = ( 4 * p - 2 ); i < ( 4 * p + 2 ) + 1; i++ )
c@225 335 {
c@225 336 temp4A += ACF[ i ];
c@225 337 }
c@225 338
c@225 339 Energy_3 = temp3A;
c@225 340 Energy_4 = temp4A;
c@225 341 }
c@225 342 else
c@225 343 {
c@225 344 for( i = ( 3 * p - 2 ); i < ( 3 * p + 2 ) + 1; i++ )
c@225 345 {
c@225 346 temp3A += ACF[ i ];
c@225 347 }
c@225 348
c@225 349 for( i = ( 4 * p - 2 ); i < ( 4 * p + 2 ) + 1; i++ )
c@225 350 {
c@225 351 temp4A += ACF[ i ];
c@225 352 }
c@225 353
c@225 354 for( i = ( 6 * p - 2 ); i < ( 6 * p + 2 ) + 1; i++ )
c@225 355 {
c@225 356 temp3B += ACF[ i ];
c@225 357 }
c@225 358
c@225 359 for( i = ( 2 * p - 2 ); i < ( 2 * p + 2 ) + 1; i++ )
c@225 360 {
c@225 361 temp4B += ACF[ i ];
c@225 362 }
c@225 363
c@225 364 Energy_3 = temp3A + temp3B;
c@225 365 Energy_4 = temp4A + temp4B;
c@225 366 }
c@225 367
c@225 368 if (Energy_3 > Energy_4)
c@225 369 {
c@225 370 tsig = 3;
c@225 371 }
c@225 372 else
c@225 373 {
c@225 374 tsig = 4;
c@225 375 }
c@225 376
c@225 377
c@225 378 return tsig;
c@225 379 }
c@225 380
c@225 381 void TempoTrack::createPhaseExtractor(double *Filter, unsigned int winLength, double period, unsigned int fsp, unsigned int lastBeat)
c@225 382 {
c@225 383 int p = (int)MathUtilities::round( period );
c@225 384 int predictedOffset = 0;
c@225 385
c@225 386 double* phaseScratch = new double[ p*2 ];
c@225 387
c@225 388
c@225 389 if( lastBeat != 0 )
c@225 390 {
c@225 391 lastBeat = (int)MathUtilities::round((double)lastBeat );///(double)winLength);
c@225 392
c@225 393 predictedOffset = lastBeat + p - fsp;
c@225 394
c@225 395 if (predictedOffset < 0)
c@225 396 {
c@225 397 lastBeat = 0;
c@225 398 }
c@225 399 }
c@225 400
c@225 401 if( lastBeat != 0 )
c@225 402 {
c@225 403 int mu = p;
c@225 404 double sigma = (double)p/4;
c@225 405 double PhaseMin = 0.0;
c@225 406 double PhaseMax = 0.0;
c@225 407 unsigned int scratchLength = p*2;
c@225 408 double temp = 0.0;
c@225 409
c@225 410 for( int i = 0; i < scratchLength; i++ )
c@225 411 {
c@225 412 phaseScratch[ i ] = exp( -0.5 * pow( ( i - mu ) / sigma, 2 ) ) / ( sqrt( 2*PI ) *sigma );
c@225 413 }
c@225 414
c@225 415 MathUtilities::getFrameMinMax( phaseScratch, scratchLength, &PhaseMin, &PhaseMax );
c@225 416
c@225 417 for(int i = 0; i < scratchLength; i ++)
c@225 418 {
c@225 419 temp = phaseScratch[ i ];
c@225 420 phaseScratch[ i ] = (temp - PhaseMin)/PhaseMax;
c@225 421 }
c@225 422
c@225 423 unsigned int index = 0;
c@225 424 for(int i = p - ( predictedOffset - 1); i < p + ( p - predictedOffset) + 1; i++)
c@225 425 {
c@225 426 Filter[ index++ ] = phaseScratch[ i ];
c@225 427 }
c@225 428 }
c@225 429 else
c@225 430 {
c@225 431 for( int i = 0; i < p; i ++)
c@225 432 {
c@225 433 Filter[ i ] = 1;
c@225 434 }
c@225 435 }
c@225 436
c@225 437 delete [] phaseScratch;
c@225 438 }
c@225 439
c@225 440 int TempoTrack::phaseMM(double *DF, double *weighting, unsigned int winLength, double period)
c@225 441 {
c@225 442 int alignment = 0;
c@225 443 int p = (int)MathUtilities::round( period );
c@225 444
c@225 445 double temp = 0.0;
c@225 446
c@225 447 double* y = new double[ winLength ];
c@225 448 double* align = new double[ p ];
c@225 449
c@225 450 for( int i = 0; i < winLength; i++ )
c@225 451 {
c@225 452 y[ i ] = (double)( -i + winLength )/(double)winLength;
c@225 453 }
c@225 454
c@225 455 for( int o = 0; o < p; o++ )
c@225 456 {
c@225 457 temp = 0.0;
c@225 458 for(int i = 1 + (o - 1); i< winLength; i += (p + 1))
c@225 459 {
c@225 460 temp = temp + DF[ i ] * y[ i ];
c@225 461 }
c@225 462 align[ o ] = temp * weighting[ o ];
c@225 463 }
c@225 464
c@225 465
c@225 466 double valTemp = 0.0;
c@225 467 for(int i = 0; i < p; i++)
c@225 468 {
c@225 469 if( align[ i ] > valTemp )
c@225 470 {
c@225 471 valTemp = align[ i ];
c@225 472 alignment = i;
c@225 473 }
c@225 474 }
c@225 475
c@225 476 delete [] y;
c@225 477 delete [] align;
c@225 478
c@225 479 return alignment;
c@225 480 }
c@225 481
c@225 482 int TempoTrack::beatPredict(unsigned int FSP0, double alignment, double period, unsigned int step )
c@225 483 {
c@225 484 int beat = 0;
c@225 485
c@225 486 int p = (int)MathUtilities::round( period );
c@225 487 int align = (int)MathUtilities::round( alignment );
c@225 488 int FSP = (int)MathUtilities::round( FSP0 );
c@225 489
c@225 490 int FEP = FSP + ( step );
c@225 491
c@225 492 beat = FSP + align;
c@225 493
c@225 494 m_beats.push_back( beat );
c@225 495
c@225 496 while( beat + p < FEP )
c@225 497 {
c@225 498 beat += p;
c@225 499
c@225 500 m_beats.push_back( beat );
c@225 501 }
c@225 502
c@225 503 return beat;
c@225 504 }
c@225 505
c@225 506 vector<int> TempoTrack::process(double *DF, unsigned int length)
c@225 507 {
c@225 508 m_dataLength = length;
c@225 509
c@225 510 double period = 0.0;
c@225 511 int stepFlag = 0;
c@225 512 int constFlag = 0;
c@225 513 int FSP = 0;
c@225 514 int tsig = 0;
c@225 515 int lastBeat = 0;
c@225 516
c@225 517
c@225 518 double* RW = new double[ m_lagLength ];
c@225 519 for( unsigned int clear = 0; clear < m_lagLength; clear++){ RW[ clear ] = 0.0;}
c@225 520
c@225 521 double* GW = new double[ m_lagLength ];
c@225 522 for(unsigned int clear = 0; clear < m_lagLength; clear++){ GW[ clear ] = 0.0;}
c@225 523
c@225 524 double* PW = new double[ m_lagLength ];
c@225 525 for(unsigned int clear = 0; clear < m_lagLength; clear++){ PW[ clear ] = 0.0;}
c@225 526
c@225 527 m_DFFramer.setSource( DF, m_dataLength );
c@225 528
c@225 529 unsigned int TTFrames = m_DFFramer.getMaxNoFrames();
c@225 530
c@225 531 double* periodP = new double[ TTFrames ];
c@225 532 for(unsigned int clear = 0; clear < TTFrames; clear++){ periodP[ clear ] = 0.0;}
c@225 533
c@225 534 double* periodG = new double[ TTFrames ];
c@225 535 for(unsigned int clear = 0; clear < TTFrames; clear++){ periodG[ clear ] = 0.0;}
c@225 536
c@225 537 double* alignment = new double[ TTFrames ];
c@225 538 for(unsigned int clear = 0; clear < TTFrames; clear++){ alignment[ clear ] = 0.0;}
c@225 539
c@225 540 m_beats.clear();
c@225 541
c@225 542 createCombFilter( RW, m_lagLength, 0, 0 );
c@225 543
c@225 544 int TTLoopIndex = 0;
c@225 545
c@225 546 for( unsigned int i = 0; i < TTFrames; i++ )
c@225 547 {
c@225 548 m_DFFramer.getFrame( m_rawDFFrame );
c@225 549
c@225 550 m_DFConditioning->process( m_rawDFFrame, m_smoothDFFrame );
c@225 551
c@225 552 m_correlator.doAutoUnBiased( m_smoothDFFrame, m_frameACF, m_winLength );
c@225 553
c@225 554 periodP[ TTLoopIndex ] = tempoMM( m_frameACF, RW, 0 );
c@225 555
c@225 556 if( GW[ 0 ] != 0 )
c@225 557 {
c@225 558 periodG[ TTLoopIndex ] = tempoMM( m_frameACF, GW, tsig );
c@225 559 }
c@225 560 else
c@225 561 {
c@225 562 periodG[ TTLoopIndex ] = 0.0;
c@225 563 }
c@225 564
c@225 565 stepDetect( periodP, periodG, TTLoopIndex, &stepFlag );
c@225 566
c@225 567 if( stepFlag == 1)
c@225 568 {
c@225 569 constDetect( periodP, TTLoopIndex, &constFlag );
c@225 570 stepFlag = 0;
c@225 571 }
c@225 572 else
c@225 573 {
c@225 574 stepFlag -= 1;
c@225 575 }
c@225 576
c@225 577 if( stepFlag < 0 )
c@225 578 {
c@225 579 stepFlag = 0;
c@225 580 }
c@225 581
c@225 582 if( constFlag != 0)
c@225 583 {
c@225 584 tsig = findMeter( m_frameACF, m_winLength, periodP[ TTLoopIndex ] );
c@225 585
c@225 586 createCombFilter( GW, m_lagLength, tsig, periodP[ TTLoopIndex ] );
c@225 587
c@225 588 periodG[ TTLoopIndex ] = tempoMM( m_frameACF, GW, tsig );
c@225 589
c@225 590 period = periodG[ TTLoopIndex ];
c@225 591
c@225 592 createPhaseExtractor( PW, m_winLength, period, FSP, 0 );
c@225 593
c@225 594 constFlag = 0;
c@225 595
c@225 596 }
c@225 597 else
c@225 598 {
c@225 599 if( GW[ 0 ] != 0 )
c@225 600 {
c@225 601 period = periodG[ TTLoopIndex ];
c@225 602 createPhaseExtractor( PW, m_winLength, period, FSP, lastBeat );
c@225 603
c@225 604 }
c@225 605 else
c@225 606 {
c@225 607 period = periodP[ TTLoopIndex ];
c@225 608 createPhaseExtractor( PW, m_winLength, period, FSP, 0 );
c@225 609 }
c@225 610 }
c@225 611
c@225 612 alignment[ TTLoopIndex ] = phaseMM( m_rawDFFrame, PW, m_winLength, period );
c@225 613
c@225 614 lastBeat = beatPredict(FSP, alignment[ TTLoopIndex ], period, m_lagLength );
c@225 615
c@225 616 FSP += (m_lagLength);
c@225 617
c@225 618 TTLoopIndex++;
c@225 619 }
c@225 620
c@225 621
c@225 622 delete [] periodP;
c@225 623 delete [] periodG;
c@225 624 delete [] alignment;
c@225 625
c@225 626 delete [] RW;
c@225 627 delete [] GW;
c@225 628 delete [] PW;
c@225 629
c@225 630 return m_beats;
c@225 631 }
c@225 632
c@225 633
c@225 634
c@225 635
c@225 636
c@225 637 vector<int> TempoTrack::process( vector <double> DF )
c@225 638 {
c@225 639 m_dataLength = DF.size();
c@225 640
c@225 641 double period = 0.0;
c@225 642 int stepFlag = 0;
c@225 643 int constFlag = 0;
c@225 644 int FSP = 0;
c@225 645 int tsig = 0;
c@225 646 int lastBeat = 0;
c@225 647
c@225 648 vector <double> causalDF;
c@225 649
c@225 650 causalDF = DF;
c@225 651
c@225 652 //Prepare Causal Extension DFData
c@225 653 unsigned int DFCLength = m_dataLength + m_winLength;
c@225 654
c@225 655 for( unsigned int j = 0; j < m_winLength; j++ )
c@225 656 {
c@225 657 causalDF.push_back( 0 );
c@225 658 }
c@225 659
c@225 660
c@225 661 double* RW = new double[ m_lagLength ];
c@225 662 for( unsigned int clear = 0; clear < m_lagLength; clear++){ RW[ clear ] = 0.0;}
c@225 663
c@225 664 double* GW = new double[ m_lagLength ];
c@225 665 for(unsigned int clear = 0; clear < m_lagLength; clear++){ GW[ clear ] = 0.0;}
c@225 666
c@225 667 double* PW = new double[ m_lagLength ];
c@225 668 for(unsigned clear = 0; clear < m_lagLength; clear++){ PW[ clear ] = 0.0;}
c@225 669
c@225 670 m_DFFramer.setSource( &causalDF[0], m_dataLength );
c@225 671
c@225 672 unsigned int TTFrames = m_DFFramer.getMaxNoFrames();
c@225 673
c@225 674 double* periodP = new double[ TTFrames ];
c@225 675 for(unsigned clear = 0; clear < TTFrames; clear++){ periodP[ clear ] = 0.0;}
c@225 676
c@225 677 double* periodG = new double[ TTFrames ];
c@225 678 for(unsigned clear = 0; clear < TTFrames; clear++){ periodG[ clear ] = 0.0;}
c@225 679
c@225 680 double* alignment = new double[ TTFrames ];
c@225 681 for(unsigned clear = 0; clear < TTFrames; clear++){ alignment[ clear ] = 0.0;}
c@225 682
c@225 683 m_beats.clear();
c@225 684
c@225 685 createCombFilter( RW, m_lagLength, 0, 0 );
c@225 686
c@225 687 int TTLoopIndex = 0;
c@225 688
c@225 689 for( unsigned int i = 0; i < TTFrames; i++ )
c@225 690 {
c@225 691 m_DFFramer.getFrame( m_rawDFFrame );
c@225 692
c@225 693 m_DFConditioning->process( m_rawDFFrame, m_smoothDFFrame );
c@225 694
c@225 695 m_correlator.doAutoUnBiased( m_smoothDFFrame, m_frameACF, m_winLength );
c@225 696
c@225 697 periodP[ TTLoopIndex ] = tempoMM( m_frameACF, RW, 0 );
c@225 698
c@225 699 if( GW[ 0 ] != 0 )
c@225 700 {
c@225 701 periodG[ TTLoopIndex ] = tempoMM( m_frameACF, GW, tsig );
c@225 702 }
c@225 703 else
c@225 704 {
c@225 705 periodG[ TTLoopIndex ] = 0.0;
c@225 706 }
c@225 707
c@225 708 stepDetect( periodP, periodG, TTLoopIndex, &stepFlag );
c@225 709
c@225 710 if( stepFlag == 1)
c@225 711 {
c@225 712 constDetect( periodP, TTLoopIndex, &constFlag );
c@225 713 stepFlag = 0;
c@225 714 }
c@225 715 else
c@225 716 {
c@225 717 stepFlag -= 1;
c@225 718 }
c@225 719
c@225 720 if( stepFlag < 0 )
c@225 721 {
c@225 722 stepFlag = 0;
c@225 723 }
c@225 724
c@225 725 if( constFlag != 0)
c@225 726 {
c@225 727 tsig = findMeter( m_frameACF, m_winLength, periodP[ TTLoopIndex ] );
c@225 728
c@225 729 createCombFilter( GW, m_lagLength, tsig, periodP[ TTLoopIndex ] );
c@225 730
c@225 731 periodG[ TTLoopIndex ] = tempoMM( m_frameACF, GW, tsig );
c@225 732
c@225 733 period = periodG[ TTLoopIndex ];
c@225 734
c@225 735 createPhaseExtractor( PW, m_winLength, period, FSP, 0 );
c@225 736
c@225 737 constFlag = 0;
c@225 738
c@225 739 }
c@225 740 else
c@225 741 {
c@225 742 if( GW[ 0 ] != 0 )
c@225 743 {
c@225 744 period = periodG[ TTLoopIndex ];
c@225 745 createPhaseExtractor( PW, m_winLength, period, FSP, lastBeat );
c@225 746
c@225 747 }
c@225 748 else
c@225 749 {
c@225 750 period = periodP[ TTLoopIndex ];
c@225 751 createPhaseExtractor( PW, m_winLength, period, FSP, 0 );
c@225 752 }
c@225 753 }
c@225 754
c@225 755 alignment[ TTLoopIndex ] = phaseMM( m_rawDFFrame, PW, m_winLength, period );
c@225 756
c@225 757 lastBeat = beatPredict(FSP, alignment[ TTLoopIndex ], period, m_lagLength );
c@225 758
c@225 759 FSP += (m_lagLength);
c@225 760
c@225 761 TTLoopIndex++;
c@225 762 }
c@225 763
c@225 764
c@225 765 delete [] periodP;
c@225 766 delete [] periodG;
c@225 767 delete [] alignment;
c@225 768
c@225 769 delete [] RW;
c@225 770 delete [] GW;
c@225 771 delete [] PW;
c@225 772
c@225 773 return m_beats;
c@225 774 }