comparison dsp/tempotracking/TempoTrack.cpp @ 479:7e52c034cf62

Untabify, indent, tidy
author Chris Cannam <cannam@all-day-breakfast.com>
date Fri, 31 May 2019 10:35:08 +0100
parents 7e8d1f26b098
children 5998ee1042d3
comparison
equal deleted inserted replaced
478:c92718cc6ef1 479:7e52c034cf62
22 22
23 #include <cassert> 23 #include <cassert>
24 24
25 //#define DEBUG_TEMPO_TRACK 1 25 //#define DEBUG_TEMPO_TRACK 1
26 26
27
28 #define RAY43VAL
29
30 ////////////////////////////////////////////////////////////////////// 27 //////////////////////////////////////////////////////////////////////
31 // Construction/Destruction 28 // Construction/Destruction
32 ////////////////////////////////////////////////////////////////////// 29 //////////////////////////////////////////////////////////////////////
33 30
34 TempoTrack::TempoTrack( TTParams Params ) 31 TempoTrack::TempoTrack( TTParams Params )
35 { 32 {
36 m_tempoScratch = NULL; 33 m_tempoScratch = NULL;
37 m_rawDFFrame = NULL; 34 m_rawDFFrame = NULL;
38 m_smoothDFFrame = NULL; 35 m_smoothDFFrame = NULL;
39 m_frameACF = NULL; 36 m_frameACF = NULL;
40 m_smoothRCF = NULL; 37 m_smoothRCF = NULL;
41 38
42 m_dataLength = 0; 39 m_dataLength = 0;
43 m_winLength = 0; 40 m_winLength = 0;
44 m_lagLength = 0; 41 m_lagLength = 0;
45 42
54 { 51 {
55 deInitialise(); 52 deInitialise();
56 } 53 }
57 54
58 void TempoTrack::initialise( TTParams Params ) 55 void TempoTrack::initialise( TTParams Params )
59 { 56 {
60 m_winLength = Params.winLength; 57 m_winLength = Params.winLength;
61 m_lagLength = Params.lagLength; 58 m_lagLength = Params.lagLength;
62 59
63 m_rayparam = 43.0; 60 m_rayparam = 43.0;
64 m_sigma = sqrt(3.9017); 61 m_sigma = sqrt(3.9017);
65 m_DFWVNnorm = exp( ( log( 2.0 ) / m_rayparam ) * ( m_winLength + 2 ) ); 62 m_DFWVNnorm = exp( ( log( 2.0 ) / m_rayparam ) * ( m_winLength + 2 ) );
66 63
67 m_rawDFFrame = new double[ m_winLength ]; 64 m_rawDFFrame = new double[ m_winLength ];
68 m_smoothDFFrame = new double[ m_winLength ]; 65 m_smoothDFFrame = new double[ m_winLength ];
69 m_frameACF = new double[ m_winLength ]; 66 m_frameACF = new double[ m_winLength ];
70 m_tempoScratch = new double[ m_lagLength ]; 67 m_tempoScratch = new double[ m_lagLength ];
71 m_smoothRCF = new double[ m_lagLength ]; 68 m_smoothRCF = new double[ m_lagLength ];
72 69
73 m_DFFramer.configure( m_winLength, m_lagLength ); 70 m_DFFramer.configure( m_winLength, m_lagLength );
74 71
75 m_DFPParams.length = m_winLength; 72 m_DFPParams.length = m_winLength;
76 m_DFPParams.AlphaNormParam = Params.alpha; 73 m_DFPParams.AlphaNormParam = Params.alpha;
77 m_DFPParams.LPOrd = Params.LPOrd; 74 m_DFPParams.LPOrd = Params.LPOrd;
78 m_DFPParams.LPACoeffs = Params.LPACoeffs; 75 m_DFPParams.LPACoeffs = Params.LPACoeffs;
79 m_DFPParams.LPBCoeffs = Params.LPBCoeffs; 76 m_DFPParams.LPBCoeffs = Params.LPBCoeffs;
80 m_DFPParams.winPre = Params.WinT.pre; 77 m_DFPParams.winPre = Params.WinT.pre;
81 m_DFPParams.winPost = Params.WinT.post; 78 m_DFPParams.winPost = Params.WinT.post;
82 m_DFPParams.isMedianPositive = true; 79 m_DFPParams.isMedianPositive = true;
83 80
84 m_DFConditioning = new DFProcess( m_DFPParams ); 81 m_DFConditioning = new DFProcess( m_DFPParams );
85 82
86 83 // these are parameters for smoothing m_tempoScratch
87 // these are parameters for smoothing m_tempoScratch
88 m_RCFPParams.length = m_lagLength; 84 m_RCFPParams.length = m_lagLength;
89 m_RCFPParams.AlphaNormParam = Params.alpha; 85 m_RCFPParams.AlphaNormParam = Params.alpha;
90 m_RCFPParams.LPOrd = Params.LPOrd; 86 m_RCFPParams.LPOrd = Params.LPOrd;
91 m_RCFPParams.LPACoeffs = Params.LPACoeffs; 87 m_RCFPParams.LPACoeffs = Params.LPACoeffs;
92 m_RCFPParams.LPBCoeffs = Params.LPBCoeffs; 88 m_RCFPParams.LPBCoeffs = Params.LPBCoeffs;
93 m_RCFPParams.winPre = Params.WinT.pre; 89 m_RCFPParams.winPre = Params.WinT.pre;
94 m_RCFPParams.winPost = Params.WinT.post; 90 m_RCFPParams.winPost = Params.WinT.post;
95 m_RCFPParams.isMedianPositive = true; 91 m_RCFPParams.isMedianPositive = true;
96 92
97 m_RCFConditioning = new DFProcess( m_RCFPParams ); 93 m_RCFConditioning = new DFProcess( m_RCFPParams );
98
99 } 94 }
100 95
101 void TempoTrack::deInitialise() 96 void TempoTrack::deInitialise()
102 { 97 {
103 delete [] m_rawDFFrame; 98 delete [] m_rawDFFrame;
104
105 delete [] m_smoothDFFrame; 99 delete [] m_smoothDFFrame;
106 100 delete [] m_smoothRCF;
107 delete [] m_smoothRCF;
108
109 delete [] m_frameACF; 101 delete [] m_frameACF;
110
111 delete [] m_tempoScratch; 102 delete [] m_tempoScratch;
112
113 delete m_DFConditioning; 103 delete m_DFConditioning;
114 104 delete m_RCFConditioning;
115 delete m_RCFConditioning;
116
117 } 105 }
118 106
119 void TempoTrack::createCombFilter(double* Filter, int winLength, int /* TSig */, double beatLag) 107 void TempoTrack::createCombFilter(double* Filter, int winLength, int /* TSig */, double beatLag)
120 { 108 {
121 int i; 109 int i;
122 110
123 if( beatLag == 0 ) 111 if( beatLag == 0 ) {
124 { 112 for( i = 0; i < winLength; i++ ) {
125 for( i = 0; i < winLength; i++ ) 113 Filter[ i ] =
126 { 114 ( ( i + 1 ) / pow( m_rayparam, 2.0) ) *
127 Filter[ i ] = ( ( i + 1 ) / pow( m_rayparam, 2.0) ) * exp( ( -pow(( i + 1 ),2.0 ) / ( 2.0 * pow( m_rayparam, 2.0)))); 115 exp( ( -pow(( i + 1 ),2.0 ) /
128 } 116 ( 2.0 * pow( m_rayparam, 2.0))));
129 } 117 }
130 else 118 } else {
131 { 119 m_sigma = beatLag/4;
132 m_sigma = beatLag/4; 120 for( i = 0; i < winLength; i++ ) {
133 for( i = 0; i < winLength; i++ ) 121 double dlag = (double)(i+1) - beatLag;
134 { 122 Filter[ i ] = exp(-0.5 * pow(( dlag / m_sigma), 2.0) ) /
135 double dlag = (double)(i+1) - beatLag; 123 (sqrt( 2 * PI) * m_sigma);
136 Filter[ i ] = exp(-0.5 * pow(( dlag / m_sigma), 2.0) ) / (sqrt( 2 * PI) * m_sigma); 124 }
137 }
138 } 125 }
139 } 126 }
140 127
141 double TempoTrack::tempoMM(double* ACF, double* weight, int tsig) 128 double TempoTrack::tempoMM(double* ACF, double* weight, int tsig)
142 { 129 {
143
144 double period = 0; 130 double period = 0;
145 double maxValRCF = 0.0; 131 double maxValRCF = 0.0;
146 int maxIndexRCF = 0; 132 int maxIndexRCF = 0;
147 133
148 double* pdPeaks; 134 double* pdPeaks;
149 135
150 int maxIndexTemp; 136 int maxIndexTemp;
151 double maxValTemp; 137 double maxValTemp;
152 int count; 138 int count;
153 139
154 int numelem,i,j; 140 int numelem,i,j;
155 int a, b; 141 int a, b;
156 142
157 for( i = 0; i < m_lagLength; i++ ) 143 for( i = 0; i < m_lagLength; i++ ) {
158 m_tempoScratch[ i ] = 0.0; 144 m_tempoScratch[ i ] = 0.0;
159 145 }
160 if( tsig == 0 ) 146
161 { 147 if( tsig == 0 ) {
162 //if time sig is unknown, use metrically unbiased version of Filterbank 148 //if time sig is unknown, use metrically unbiased version of Filterbank
163 numelem = 4; 149 numelem = 4;
164 } 150 } else {
165 else 151 numelem = tsig;
166 {
167 numelem = tsig;
168 } 152 }
169 153
170 #ifdef DEBUG_TEMPO_TRACK 154 #ifdef DEBUG_TEMPO_TRACK
171 std::cerr << "tempoMM: m_winLength = " << m_winLength << ", m_lagLength = " << m_lagLength << ", numelem = " << numelem << std::endl; 155 std::cerr << "tempoMM: m_winLength = " << m_winLength << ", m_lagLength = " << m_lagLength << ", numelem = " << numelem << std::endl;
172 #endif 156 #endif
173 157
174 for(i=1;i<m_lagLength-1;i++) 158 for(i=1;i<m_lagLength-1;i++) {
175 { 159 //first and last output values are left intentionally as zero
176 //first and last output values are left intentionally as zero 160 for (a=1;a<=numelem;a++) {
177 for (a=1;a<=numelem;a++) 161 for(b=(1-a);b<a;b++) {
178 { 162 if( tsig == 0 ) {
179 for(b=(1-a);b<a;b++) 163 m_tempoScratch[i] += ACF[a*(i+1)+b-1] * (1.0 / (2.0 * (double)a-1)) * weight[i];
180 { 164 } else {
181 if( tsig == 0 ) 165 m_tempoScratch[i] += ACF[a*(i+1)+b-1] * 1 * weight[i];
182 { 166 }
183 m_tempoScratch[i] += ACF[a*(i+1)+b-1] * (1.0 / (2.0 * (double)a-1)) * weight[i]; 167 }
184 } 168 }
185 else 169 }
186 { 170
187 m_tempoScratch[i] += ACF[a*(i+1)+b-1] * 1 * weight[i]; 171
188 } 172 //////////////////////////////////////////////////
189 } 173 // MODIFIED BEAT PERIOD EXTRACTION //////////////
190 } 174 /////////////////////////////////////////////////
191 } 175
192 176 // find smoothed version of RCF ( as applied to Detection Function)
193 177 m_RCFConditioning->process( m_tempoScratch, m_smoothRCF);
194 ////////////////////////////////////////////////// 178
195 // MODIFIED BEAT PERIOD EXTRACTION ////////////// 179 if (tsig != 0) { // i.e. in context dependent state
196 ///////////////////////////////////////////////// 180
197
198 // find smoothed version of RCF ( as applied to Detection Function)
199 m_RCFConditioning->process( m_tempoScratch, m_smoothRCF);
200
201 if (tsig != 0) // i.e. in context dependent state
202 {
203 // NOW FIND MAX INDEX OF ACFOUT 181 // NOW FIND MAX INDEX OF ACFOUT
204 for( i = 0; i < m_lagLength; i++) 182 for( i = 0; i < m_lagLength; i++) {
205 { 183 if( m_tempoScratch[ i ] > maxValRCF) {
206 if( m_tempoScratch[ i ] > maxValRCF) 184 maxValRCF = m_tempoScratch[ i ];
207 { 185 maxIndexRCF = i;
208 maxValRCF = m_tempoScratch[ i ]; 186 }
209 maxIndexRCF = i; 187 }
188
189 } else { // using rayleigh weighting
190
191 vector <vector<double> > rcfMat;
192
193 double sumRcf = 0.;
194
195 double maxVal = 0.;
196 // now find the two values which minimise rcfMat
197 double minVal = 0.;
198 int p_i = 1; // periodicity for row i;
199 int p_j = 1; //periodicity for column j;
200
201 for ( i=0; i<m_lagLength; i++) {
202 m_tempoScratch[i] =m_smoothRCF[i];
203 }
204
205 // normalise m_tempoScratch so that it sums to zero.
206 for ( i=0; i<m_lagLength; i++) {
207 sumRcf += m_tempoScratch[i];
208 }
209
210 for( i=0; i<m_lagLength; i++) {
211 m_tempoScratch[i] /= sumRcf;
212 }
213
214 // create a matrix to store m_tempoScratchValues modified by log2 ratio
215 for ( i=0; i<m_lagLength; i++) {
216 rcfMat.push_back ( vector<double>() ); // adds a new row...
217 }
218
219 for (i=0; i<m_lagLength; i++) {
220 for (j=0; j<m_lagLength; j++) {
221 rcfMat[i].push_back (0.);
222 }
223 }
224
225 // the 'i' and 'j' indices deliberately start from '1' and not '0'
226 for ( i=1; i<m_lagLength; i++) {
227 for (j=1; j<m_lagLength; j++) {
228 double log2PeriodRatio = log( static_cast<double>(i)/
229 static_cast<double>(j) ) /
230 log(2.0);
231 rcfMat[i][j] = ( abs(1.0-abs(log2PeriodRatio)) );
232 rcfMat[i][j] += ( 0.01*( 1./(m_tempoScratch[i]+m_tempoScratch[j]) ) );
233 }
234 }
235
236 // set diagonal equal to maximum value in rcfMat
237 // we don't want to pick one strong middle peak - we need a combination of two peaks.
238
239 for ( i=1; i<m_lagLength; i++) {
240 for (j=1; j<m_lagLength; j++) {
241 if (rcfMat[i][j] > maxVal) {
242 maxVal = rcfMat[i][j];
210 } 243 }
211 } 244 }
212 } 245 }
213 else // using rayleigh weighting 246
214 { 247 for ( i=1; i<m_lagLength; i++) {
215 vector <vector<double> > rcfMat; 248 rcfMat[i][i] = maxVal;
216 249 }
217 double sumRcf = 0.; 250
218 251 // now find the row and column number which minimise rcfMat
219 double maxVal = 0.; 252 minVal = maxVal;
220 // now find the two values which minimise rcfMat 253
221 double minVal = 0.; 254 for ( i=1; i<m_lagLength; i++) {
222 int p_i = 1; // periodicity for row i; 255 for ( j=1; j<m_lagLength; j++) {
223 int p_j = 1; //periodicity for column j; 256 if (rcfMat[i][j] < minVal) {
224 257 minVal = rcfMat[i][j];
225 258 p_i = i;
226 for ( i=0; i<m_lagLength; i++) 259 p_j = j;
227 { 260 }
228 m_tempoScratch[i] =m_smoothRCF[i]; 261 }
229 } 262 }
230 263
231 // normalise m_tempoScratch so that it sums to zero. 264
232 for ( i=0; i<m_lagLength; i++) 265 // initially choose p_j (arbitrary) - saves on an else statement
233 { 266 int beatPeriod = p_j;
234 sumRcf += m_tempoScratch[i]; 267 if (m_tempoScratch[p_i] > m_tempoScratch[p_j]) {
235 } 268 beatPeriod = p_i;
236 269 }
237 for( i=0; i<m_lagLength; i++) 270
238 { 271 // now write the output
239 m_tempoScratch[i] /= sumRcf; 272 maxIndexRCF = static_cast<int>(beatPeriod);
240 } 273 }
241
242 // create a matrix to store m_tempoScratchValues modified by log2 ratio
243 for ( i=0; i<m_lagLength; i++)
244 {
245 rcfMat.push_back ( vector<double>() ); // adds a new row...
246 }
247
248 for (i=0; i<m_lagLength; i++)
249 {
250 for (j=0; j<m_lagLength; j++)
251 {
252 rcfMat[i].push_back (0.);
253 }
254 }
255
256 // the 'i' and 'j' indices deliberately start from '1' and not '0'
257 for ( i=1; i<m_lagLength; i++)
258 {
259 for (j=1; j<m_lagLength; j++)
260 {
261 double log2PeriodRatio = log( static_cast<double>(i)/static_cast<double>(j) ) / log(2.0);
262 rcfMat[i][j] = ( abs(1.0-abs(log2PeriodRatio)) );
263 rcfMat[i][j] += ( 0.01*( 1./(m_tempoScratch[i]+m_tempoScratch[j]) ) );
264 }
265 }
266
267 // set diagonal equal to maximum value in rcfMat
268 // we don't want to pick one strong middle peak - we need a combination of two peaks.
269
270 for ( i=1; i<m_lagLength; i++)
271 {
272 for (j=1; j<m_lagLength; j++)
273 {
274 if (rcfMat[i][j] > maxVal)
275 {
276 maxVal = rcfMat[i][j];
277 }
278 }
279 }
280
281 for ( i=1; i<m_lagLength; i++)
282 {
283 rcfMat[i][i] = maxVal;
284 }
285
286 // now find the row and column number which minimise rcfMat
287 minVal = maxVal;
288
289 for ( i=1; i<m_lagLength; i++)
290 {
291 for ( j=1; j<m_lagLength; j++)
292 {
293 if (rcfMat[i][j] < minVal)
294 {
295 minVal = rcfMat[i][j];
296 p_i = i;
297 p_j = j;
298 }
299 }
300 }
301
302
303 // initially choose p_j (arbitrary) - saves on an else statement
304 int beatPeriod = p_j;
305 if (m_tempoScratch[p_i] > m_tempoScratch[p_j])
306 {
307 beatPeriod = p_i;
308 }
309
310 // now write the output
311 maxIndexRCF = static_cast<int>(beatPeriod);
312 }
313 274
314 275
315 double locked = 5168.f / maxIndexRCF; 276 double locked = 5168.f / maxIndexRCF;
316 if (locked >= 30 && locked <= 180) { 277 if (locked >= 30 && locked <= 180) {
317 m_lockedTempo = locked; 278 m_lockedTempo = locked;
319 280
320 #ifdef DEBUG_TEMPO_TRACK 281 #ifdef DEBUG_TEMPO_TRACK
321 std::cerr << "tempoMM: locked tempo = " << m_lockedTempo << std::endl; 282 std::cerr << "tempoMM: locked tempo = " << m_lockedTempo << std::endl;
322 #endif 283 #endif
323 284
324 if( tsig == 0 ) 285 if( tsig == 0 ) {
325 tsig = 4; 286 tsig = 4;
326 287 }
327 288
328 #ifdef DEBUG_TEMPO_TRACK 289 #ifdef DEBUG_TEMPO_TRACK
329 std::cerr << "tempoMM: maxIndexRCF = " << maxIndexRCF << std::endl; 290 std::cerr << "tempoMM: maxIndexRCF = " << maxIndexRCF << std::endl;
330 #endif 291 #endif
331 292
332 if( tsig == 4 ) 293 if( tsig == 4 ) {
333 { 294
334 #ifdef DEBUG_TEMPO_TRACK 295 #ifdef DEBUG_TEMPO_TRACK
335 std::cerr << "tsig == 4" << std::endl; 296 std::cerr << "tsig == 4" << std::endl;
336 #endif 297 #endif
337 298
338 pdPeaks = new double[ 4 ]; 299 pdPeaks = new double[ 4 ];
339 for( i = 0; i < 4; i++ ){ pdPeaks[ i ] = 0.0;} 300 for( i = 0; i < 4; i++ ){ pdPeaks[ i ] = 0.0;}
340 301
341 pdPeaks[ 0 ] = ( double )maxIndexRCF + 1; 302 pdPeaks[ 0 ] = ( double )maxIndexRCF + 1;
342 303
343 maxIndexTemp = 0; 304 maxIndexTemp = 0;
344 maxValTemp = 0.0; 305 maxValTemp = 0.0;
345 count = 0; 306 count = 0;
346 307
347 for( i = (2 * maxIndexRCF + 1) - 1; i < (2 * maxIndexRCF + 1) + 2; i++ ) 308 for( i = (2 * maxIndexRCF + 1) - 1; i < (2 * maxIndexRCF + 1) + 2; i++ ) {
348 { 309 if( ACF[ i ] > maxValTemp ) {
349 if( ACF[ i ] > maxValTemp ) 310 maxValTemp = ACF[ i ];
350 { 311 maxIndexTemp = count;
351 maxValTemp = ACF[ i ]; 312 }
352 maxIndexTemp = count; 313 count++;
353 } 314 }
354 count++; 315 pdPeaks[ 1 ] = (double)( maxIndexTemp + 1 + ( (2 * maxIndexRCF + 1 ) - 2 ) + 1 )/2;
355 } 316
356 pdPeaks[ 1 ] = (double)( maxIndexTemp + 1 + ( (2 * maxIndexRCF + 1 ) - 2 ) + 1 )/2; 317 maxIndexTemp = 0;
357 318 maxValTemp = 0.0;
358 maxIndexTemp = 0; 319 count = 0;
359 maxValTemp = 0.0; 320
360 count = 0; 321 for( i = (3 * maxIndexRCF + 2 ) - 2; i < (3 * maxIndexRCF + 2 ) + 3; i++ ) {
361 322 if( ACF[ i ] > maxValTemp ) {
362 for( i = (3 * maxIndexRCF + 2 ) - 2; i < (3 * maxIndexRCF + 2 ) + 3; i++ ) 323 maxValTemp = ACF[ i ];
363 { 324 maxIndexTemp = count;
364 if( ACF[ i ] > maxValTemp ) 325 }
365 { 326 count++;
366 maxValTemp = ACF[ i ]; 327 }
367 maxIndexTemp = count; 328 pdPeaks[ 2 ] = (double)( maxIndexTemp + 1 + ( (3 * maxIndexRCF + 2) - 4 ) + 1 )/3;
368 } 329
369 count++; 330 maxIndexTemp = 0;
370 } 331 maxValTemp = 0.0;
371 pdPeaks[ 2 ] = (double)( maxIndexTemp + 1 + ( (3 * maxIndexRCF + 2) - 4 ) + 1 )/3; 332 count = 0;
372 333
373 maxIndexTemp = 0; 334 for( i = ( 4 * maxIndexRCF + 3) - 3; i < ( 4 * maxIndexRCF + 3) + 4; i++ ) {
374 maxValTemp = 0.0; 335 if( ACF[ i ] > maxValTemp ) {
375 count = 0; 336 maxValTemp = ACF[ i ];
376 337 maxIndexTemp = count;
377 for( i = ( 4 * maxIndexRCF + 3) - 3; i < ( 4 * maxIndexRCF + 3) + 4; i++ ) 338 }
378 { 339 count++;
379 if( ACF[ i ] > maxValTemp ) 340 }
380 { 341
381 maxValTemp = ACF[ i ]; 342 pdPeaks[ 3 ] = (double)( maxIndexTemp + 1 + ( (4 * maxIndexRCF + 3) - 9 ) + 1 )/4 ;
382 maxIndexTemp = count; 343
383 } 344
384 count++; 345 period = MathUtilities::mean( pdPeaks, 4 );
385 } 346
386 pdPeaks[ 3 ] = (double)( maxIndexTemp + 1 + ( (4 * maxIndexRCF + 3) - 9 ) + 1 )/4 ; 347 } else {
387 348
388 349 #ifdef DEBUG_TEMPO_TRACK
389 period = MathUtilities::mean( pdPeaks, 4 ); 350 std::cerr << "tsig != 4" << std::endl;
390 } 351 #endif
391 else 352
392 { 353 pdPeaks = new double[ 3 ];
393 #ifdef DEBUG_TEMPO_TRACK 354 for( i = 0; i < 3; i++ ) {
394 std::cerr << "tsig != 4" << std::endl; 355 pdPeaks[ i ] = 0.0;
395 #endif 356 }
396 357
397 pdPeaks = new double[ 3 ]; 358 pdPeaks[ 0 ] = ( double )maxIndexRCF + 1;
398 for( i = 0; i < 3; i++ ){ pdPeaks[ i ] = 0.0;} 359
399 360 maxIndexTemp = 0;
400 pdPeaks[ 0 ] = ( double )maxIndexRCF + 1; 361 maxValTemp = 0.0;
401 362 count = 0;
402 maxIndexTemp = 0; 363
403 maxValTemp = 0.0; 364 for( i = (2 * maxIndexRCF + 1) - 1; i < (2 * maxIndexRCF + 1) + 2; i++ ) {
404 count = 0; 365 if( ACF[ i ] > maxValTemp ) {
405 366 maxValTemp = ACF[ i ];
406 for( i = (2 * maxIndexRCF + 1) - 1; i < (2 * maxIndexRCF + 1) + 2; i++ ) 367 maxIndexTemp = count;
407 { 368 }
408 if( ACF[ i ] > maxValTemp ) 369 count++;
409 { 370 }
410 maxValTemp = ACF[ i ]; 371 pdPeaks[ 1 ] = (double)( maxIndexTemp + 1 + ( (2 * maxIndexRCF + 1 ) - 2 ) + 1 )/2;
411 maxIndexTemp = count; 372
412 } 373 maxIndexTemp = 0;
413 count++; 374 maxValTemp = 0.0;
414 } 375 count = 0;
415 pdPeaks[ 1 ] = (double)( maxIndexTemp + 1 + ( (2 * maxIndexRCF + 1 ) - 2 ) + 1 )/2; 376
416 377 for( i = (3 * maxIndexRCF + 2 ) - 2; i < (3 * maxIndexRCF + 2 ) + 3; i++ ) {
417 maxIndexTemp = 0; 378 if( ACF[ i ] > maxValTemp ) {
418 maxValTemp = 0.0; 379 maxValTemp = ACF[ i ];
419 count = 0; 380 maxIndexTemp = count;
420 381 }
421 for( i = (3 * maxIndexRCF + 2 ) - 2; i < (3 * maxIndexRCF + 2 ) + 3; i++ ) 382 count++;
422 { 383 }
423 if( ACF[ i ] > maxValTemp ) 384 pdPeaks[ 2 ] = (double)( maxIndexTemp + 1 + ( (3 * maxIndexRCF + 2) - 4 ) + 1 )/3;
424 { 385
425 maxValTemp = ACF[ i ]; 386
426 maxIndexTemp = count; 387 period = MathUtilities::mean( pdPeaks, 3 );
427 }
428 count++;
429 }
430 pdPeaks[ 2 ] = (double)( maxIndexTemp + 1 + ( (3 * maxIndexRCF + 2) - 4 ) + 1 )/3;
431
432
433 period = MathUtilities::mean( pdPeaks, 3 );
434 } 388 }
435 389
436 delete [] pdPeaks; 390 delete [] pdPeaks;
437 391
438 return period; 392 return period;
440 394
441 void TempoTrack::stepDetect( double* periodP, double* periodG, int currentIdx, int* flag ) 395 void TempoTrack::stepDetect( double* periodP, double* periodG, int currentIdx, int* flag )
442 { 396 {
443 double stepthresh = 1 * 3.9017; 397 double stepthresh = 1 * 3.9017;
444 398
445 if( *flag ) 399 if( *flag ) {
446 { 400 if(abs(periodG[ currentIdx ] - periodP[ currentIdx ]) > stepthresh) {
447 if(abs(periodG[ currentIdx ] - periodP[ currentIdx ]) > stepthresh) 401 // do nuffin'
448 { 402 }
449 // do nuffin' 403 } else {
450 } 404 if(fabs(periodG[ currentIdx ]-periodP[ currentIdx ]) > stepthresh) {
451 } 405 *flag = 3;
452 else 406 }
453 {
454 if(fabs(periodG[ currentIdx ]-periodP[ currentIdx ]) > stepthresh)
455 {
456 *flag = 3;
457 }
458 } 407 }
459 } 408 }
460 409
461 void TempoTrack::constDetect( double* periodP, int currentIdx, int* flag ) 410 void TempoTrack::constDetect( double* periodP, int currentIdx, int* flag )
462 { 411 {
463 double constthresh = 2 * 3.9017; 412 double constthresh = 2 * 3.9017;
464 413
465 if( fabs( 2 * periodP[ currentIdx ] - periodP[ currentIdx - 1] - periodP[ currentIdx - 2] ) < constthresh) 414 if( fabs( 2 * periodP[ currentIdx ] - periodP[ currentIdx - 1] - periodP[ currentIdx - 2] ) < constthresh) {
466 { 415 *flag = 1;
467 *flag = 1; 416 } else {
468 } 417 *flag = 0;
469 else
470 {
471 *flag = 0;
472 } 418 }
473 } 419 }
474 420
475 int TempoTrack::findMeter(double *ACF, int len, double period) 421 int TempoTrack::findMeter(double *ACF, int len, double period)
476 { 422 {
487 double temp4B = 0.0; 433 double temp4B = 0.0;
488 434
489 double* dbf = new double[ len ]; int t = 0; 435 double* dbf = new double[ len ]; int t = 0;
490 for( int u = 0; u < len; u++ ){ dbf[ u ] = 0.0; } 436 for( int u = 0; u < len; u++ ){ dbf[ u ] = 0.0; }
491 437
492 if( (double)len < 6 * p + 2 ) 438 if( (double)len < 6 * p + 2 ) {
493 { 439
494 for( i = ( 3 * p - 2 ); i < ( 3 * p + 2 ) + 1; i++ ) 440 for( i = ( 3 * p - 2 ); i < ( 3 * p + 2 ) + 1; i++ ) {
495 { 441 temp3A += ACF[ i ];
496 temp3A += ACF[ i ]; 442 dbf[ t++ ] = ACF[ i ];
497 dbf[ t++ ] = ACF[ i ]; 443 }
498 } 444
499 445 for( i = ( 4 * p - 2 ); i < ( 4 * p + 2 ) + 1; i++ ) {
500 for( i = ( 4 * p - 2 ); i < ( 4 * p + 2 ) + 1; i++ ) 446 temp4A += ACF[ i ];
501 { 447 }
502 temp4A += ACF[ i ]; 448
503 } 449 Energy_3 = temp3A;
504 450 Energy_4 = temp4A;
505 Energy_3 = temp3A; 451
506 Energy_4 = temp4A; 452 } else {
507 } 453
508 else 454 for( i = ( 3 * p - 2 ); i < ( 3 * p + 2 ) + 1; i++ ) {
509 { 455 temp3A += ACF[ i ];
510 for( i = ( 3 * p - 2 ); i < ( 3 * p + 2 ) + 1; i++ ) 456 }
511 { 457
512 temp3A += ACF[ i ]; 458 for( i = ( 4 * p - 2 ); i < ( 4 * p + 2 ) + 1; i++ ) {
513 } 459 temp4A += ACF[ i ];
514 460 }
515 for( i = ( 4 * p - 2 ); i < ( 4 * p + 2 ) + 1; i++ ) 461
516 { 462 for( i = ( 6 * p - 2 ); i < ( 6 * p + 2 ) + 1; i++ ) {
517 temp4A += ACF[ i ]; 463 temp3B += ACF[ i ];
518 } 464 }
519 465
520 for( i = ( 6 * p - 2 ); i < ( 6 * p + 2 ) + 1; i++ ) 466 for( i = ( 2 * p - 2 ); i < ( 2 * p + 2 ) + 1; i++ ) {
521 { 467 temp4B += ACF[ i ];
522 temp3B += ACF[ i ]; 468 }
523 } 469
524 470 Energy_3 = temp3A + temp3B;
525 for( i = ( 2 * p - 2 ); i < ( 2 * p + 2 ) + 1; i++ ) 471 Energy_4 = temp4A + temp4B;
526 { 472 }
527 temp4B += ACF[ i ]; 473
528 } 474 if (Energy_3 > Energy_4) {
529 475 tsig = 3;
530 Energy_3 = temp3A + temp3B; 476 } else {
531 Energy_4 = temp4A + temp4B; 477 tsig = 4;
532 } 478 }
533
534 if (Energy_3 > Energy_4)
535 {
536 tsig = 3;
537 }
538 else
539 {
540 tsig = 4;
541 }
542
543 479
544 return tsig; 480 return tsig;
545 } 481 }
546 482
547 void TempoTrack::createPhaseExtractor(double *Filter, int /* winLength */, double period, int fsp, int lastBeat) 483 void TempoTrack::createPhaseExtractor(double *Filter, int /* winLength */, double period, int fsp, int lastBeat)
548 { 484 {
549 int p = (int)MathUtilities::round( period ); 485 int p = (int)MathUtilities::round( period );
550 int predictedOffset = 0; 486 int predictedOffset = 0;
551 487
552 #ifdef DEBUG_TEMPO_TRACK 488 #ifdef DEBUG_TEMPO_TRACK
553 std::cerr << "TempoTrack::createPhaseExtractor: period = " << period << ", p = " << p << std::endl; 489 std::cerr << "TempoTrack::createPhaseExtractor: period = " << period << ", p = " << p << std::endl;
559 } 495 }
560 496
561 double* phaseScratch = new double[ p*2 + 2 ]; 497 double* phaseScratch = new double[ p*2 + 2 ];
562 for (int i = 0; i < p*2 + 2; ++i) phaseScratch[i] = 0.0; 498 for (int i = 0; i < p*2 + 2; ++i) phaseScratch[i] = 0.0;
563 499
564 500
565 if( lastBeat != 0 ) 501 if ( lastBeat != 0 ) {
566 { 502
567 lastBeat = (int)MathUtilities::round((double)lastBeat );///(double)winLength); 503 lastBeat = (int)MathUtilities::round((double)lastBeat );///(double)winLength);
568 504
569 predictedOffset = lastBeat + p - fsp; 505 predictedOffset = lastBeat + p - fsp;
570 506
571 if (predictedOffset < 0) 507 if (predictedOffset < 0) {
572 {
573 lastBeat = 0; 508 lastBeat = 0;
574 } 509 }
575 } 510 }
576 511
577 if( lastBeat != 0 ) 512 if ( lastBeat != 0 ) {
578 { 513
579 int mu = p; 514 int mu = p;
580 double sigma = (double)p/8; 515 double sigma = (double)p/8;
581 double PhaseMin = 0.0; 516 double PhaseMin = 0.0;
582 double PhaseMax = 0.0; 517 double PhaseMax = 0.0;
583 int scratchLength = p*2; 518 int scratchLength = p*2;
584 double temp = 0.0; 519 double temp = 0.0;
585 520
586 for( int i = 0; i < scratchLength; i++ ) 521 for( int i = 0; i < scratchLength; i++ ) {
587 { 522 phaseScratch[ i ] = exp( -0.5 * pow( ( i - mu ) / sigma, 2 ) ) / ( sqrt( 2*PI ) *sigma );
588 phaseScratch[ i ] = exp( -0.5 * pow( ( i - mu ) / sigma, 2 ) ) / ( sqrt( 2*PI ) *sigma ); 523 }
589 } 524
590 525 MathUtilities::getFrameMinMax( phaseScratch, scratchLength, &PhaseMin, &PhaseMax );
591 MathUtilities::getFrameMinMax( phaseScratch, scratchLength, &PhaseMin, &PhaseMax ); 526
592 527 for(int i = 0; i < scratchLength; i ++) {
593 for(int i = 0; i < scratchLength; i ++) 528 temp = phaseScratch[ i ];
594 { 529 phaseScratch[ i ] = (temp - PhaseMin)/PhaseMax;
595 temp = phaseScratch[ i ]; 530 }
596 phaseScratch[ i ] = (temp - PhaseMin)/PhaseMax;
597 }
598 531
599 #ifdef DEBUG_TEMPO_TRACK 532 #ifdef DEBUG_TEMPO_TRACK
600 std::cerr << "predictedOffset = " << predictedOffset << std::endl; 533 std::cerr << "predictedOffset = " << predictedOffset << std::endl;
601 #endif 534 #endif
602 535
603 int index = 0; 536 int index = 0;
604 for (int i = p - ( predictedOffset - 1); i < p + ( p - predictedOffset) + 1; i++) 537 for (int i = p - ( predictedOffset - 1); i < p + ( p - predictedOffset) + 1; i++) {
605 {
606 #ifdef DEBUG_TEMPO_TRACK 538 #ifdef DEBUG_TEMPO_TRACK
607 std::cerr << "assigning to filter index " << index << " (size = " << p*2 << ")" << " value " << phaseScratch[i] << " from scratch index " << i << std::endl; 539 std::cerr << "assigning to filter index " << index << " (size = " << p*2 << ")" << " value " << phaseScratch[i] << " from scratch index " << i << std::endl;
608 #endif 540 #endif
609 Filter[ index++ ] = phaseScratch[ i ]; 541 Filter[ index++ ] = phaseScratch[ i ];
610 } 542 }
611 } 543 } else {
612 else 544 for( int i = 0; i < p; i ++) {
613 { 545 Filter[ i ] = 1;
614 for( int i = 0; i < p; i ++) 546 }
615 { 547 }
616 Filter[ i ] = 1; 548
617 }
618 }
619
620 delete [] phaseScratch; 549 delete [] phaseScratch;
621 } 550 }
622 551
623 int TempoTrack::phaseMM(double *DF, double *weighting, int winLength, double period) 552 int TempoTrack::phaseMM(double *DF, double *weighting, int winLength, double period)
624 { 553 {
628 double temp = 0.0; 557 double temp = 0.0;
629 558
630 double* y = new double[ winLength ]; 559 double* y = new double[ winLength ];
631 double* align = new double[ p ]; 560 double* align = new double[ p ];
632 561
633 for( int i = 0; i < winLength; i++ ) 562 for( int i = 0; i < winLength; i++ ) {
634 { 563 y[ i ] = (double)( -i + winLength )/(double)winLength;
635 y[ i ] = (double)( -i + winLength )/(double)winLength; 564 y[ i ] = pow(y [i ],2.0); // raise to power 2.
636 y[ i ] = pow(y [i ],2.0); // raise to power 2. 565 }
637 } 566
638 567 for( int o = 0; o < p; o++ ) {
639 for( int o = 0; o < p; o++ ) 568 temp = 0.0;
640 { 569 for (int i = 1 + (o - 1); i < winLength; i += (p + 1)) {
641 temp = 0.0; 570 temp = temp + DF[ i ] * y[ i ];
642 for(int i = 1 + (o - 1); i< winLength; i += (p + 1)) 571 }
643 { 572 align[ o ] = temp * weighting[ o ];
644 temp = temp + DF[ i ] * y[ i ];
645 }
646 align[ o ] = temp * weighting[ o ];
647 } 573 }
648 574
649 575
650 double valTemp = 0.0; 576 double valTemp = 0.0;
651 for(int i = 0; i < p; i++) 577 for(int i = 0; i < p; i++) {
652 { 578 if( align[ i ] > valTemp ) {
653 if( align[ i ] > valTemp ) 579 valTemp = align[ i ];
654 { 580 alignment = i;
655 valTemp = align[ i ]; 581 }
656 alignment = i;
657 }
658 } 582 }
659 583
660 delete [] y; 584 delete [] y;
661 delete [] align; 585 delete [] align;
662 586
675 599
676 beat = FSP + align; 600 beat = FSP + align;
677 601
678 m_beats.push_back( beat ); 602 m_beats.push_back( beat );
679 603
680 while( beat + p < FEP ) 604 while( beat + p < FEP ) {
681 { 605 beat += p;
682 beat += p; 606 m_beats.push_back( beat );
683
684 m_beats.push_back( beat );
685 } 607 }
686 608
687 return beat; 609 return beat;
688 } 610 }
689 611
691 613
692 vector<int> TempoTrack::process( vector <double> DF, 614 vector<int> TempoTrack::process( vector <double> DF,
693 vector <double> *tempoReturn ) 615 vector <double> *tempoReturn )
694 { 616 {
695 m_dataLength = DF.size(); 617 m_dataLength = DF.size();
696 618
697 m_lockedTempo = 0.0; 619 m_lockedTempo = 0.0;
698 620
699 double period = 0.0; 621 double period = 0.0;
700 int stepFlag = 0; 622 int stepFlag = 0;
701 int constFlag = 0; 623 int constFlag = 0;
702 int FSP = 0; 624 int FSP = 0;
703 int tsig = 0; 625 int tsig = 0;
704 int lastBeat = 0; 626 int lastBeat = 0;
707 629
708 causalDF = DF; 630 causalDF = DF;
709 631
710 //Prepare Causal Extension DFData 632 //Prepare Causal Extension DFData
711 // int DFCLength = m_dataLength + m_winLength; 633 // int DFCLength = m_dataLength + m_winLength;
712 634
713 for( int j = 0; j < m_winLength; j++ ) 635 for( int j = 0; j < m_winLength; j++ ) {
714 { 636 causalDF.push_back( 0 );
715 causalDF.push_back( 0 ); 637 }
716 } 638
717 639
718
719 double* RW = new double[ m_lagLength ]; 640 double* RW = new double[ m_lagLength ];
720 for (int clear = 0; clear < m_lagLength; clear++){ RW[ clear ] = 0.0;} 641 for (int clear = 0; clear < m_lagLength; clear++){ RW[ clear ] = 0.0;}
721 642
722 double* GW = new double[ m_lagLength ]; 643 double* GW = new double[ m_lagLength ];
723 for (int clear = 0; clear < m_lagLength; clear++){ GW[ clear ] = 0.0;} 644 for (int clear = 0; clear < m_lagLength; clear++){ GW[ clear ] = 0.0;}
730 int TTFrames = m_DFFramer.getMaxNoFrames(); 651 int TTFrames = m_DFFramer.getMaxNoFrames();
731 652
732 #ifdef DEBUG_TEMPO_TRACK 653 #ifdef DEBUG_TEMPO_TRACK
733 std::cerr << "TTFrames = " << TTFrames << std::endl; 654 std::cerr << "TTFrames = " << TTFrames << std::endl;
734 #endif 655 #endif
735 656
736 double* periodP = new double[ TTFrames ]; 657 double* periodP = new double[ TTFrames ];
737 for(int clear = 0; clear < TTFrames; clear++){ periodP[ clear ] = 0.0;} 658 for(int clear = 0; clear < TTFrames; clear++){ periodP[ clear ] = 0.0;}
738 659
739 double* periodG = new double[ TTFrames ]; 660 double* periodG = new double[ TTFrames ];
740 for(int clear = 0; clear < TTFrames; clear++){ periodG[ clear ] = 0.0;} 661 for(int clear = 0; clear < TTFrames; clear++){ periodG[ clear ] = 0.0;}
741 662
742 double* alignment = new double[ TTFrames ]; 663 double* alignment = new double[ TTFrames ];
743 for(int clear = 0; clear < TTFrames; clear++){ alignment[ clear ] = 0.0;} 664 for(int clear = 0; clear < TTFrames; clear++){ alignment[ clear ] = 0.0;}
744 665
745 m_beats.clear(); 666 m_beats.clear();
746 667
747 createCombFilter( RW, m_lagLength, 0, 0 ); 668 createCombFilter( RW, m_lagLength, 0, 0 );
748 669
749 int TTLoopIndex = 0; 670 int TTLoopIndex = 0;
750 671
751 for( int i = 0; i < TTFrames; i++ ) 672 for( int i = 0; i < TTFrames; i++ ) {
752 { 673
753 m_DFFramer.getFrame( m_rawDFFrame ); 674 m_DFFramer.getFrame( m_rawDFFrame );
754 675
755 m_DFConditioning->process( m_rawDFFrame, m_smoothDFFrame ); 676 m_DFConditioning->process( m_rawDFFrame, m_smoothDFFrame );
756 677
757 m_correlator.doAutoUnBiased( m_smoothDFFrame, m_frameACF, m_winLength ); 678 m_correlator.doAutoUnBiased( m_smoothDFFrame, m_frameACF, m_winLength );
758 679
759 periodP[ TTLoopIndex ] = tempoMM( m_frameACF, RW, 0 ); 680 periodP[ TTLoopIndex ] = tempoMM( m_frameACF, RW, 0 );
760 681
761 if( GW[ 0 ] != 0 ) 682 if( GW[ 0 ] != 0 ) {
762 { 683 periodG[ TTLoopIndex ] = tempoMM( m_frameACF, GW, tsig );
763 periodG[ TTLoopIndex ] = tempoMM( m_frameACF, GW, tsig ); 684 } else {
764 } 685 periodG[ TTLoopIndex ] = 0.0;
765 else 686 }
766 { 687
767 periodG[ TTLoopIndex ] = 0.0; 688 stepDetect( periodP, periodG, TTLoopIndex, &stepFlag );
768 } 689
769 690 if( stepFlag == 1) {
770 stepDetect( periodP, periodG, TTLoopIndex, &stepFlag ); 691 constDetect( periodP, TTLoopIndex, &constFlag );
771 692 stepFlag = 0;
772 if( stepFlag == 1) 693 } else {
773 { 694 stepFlag -= 1;
774 constDetect( periodP, TTLoopIndex, &constFlag ); 695 }
775 stepFlag = 0; 696
776 } 697 if( stepFlag < 0 ) {
777 else 698 stepFlag = 0;
778 { 699 }
779 stepFlag -= 1; 700
780 } 701 if( constFlag != 0) {
781 702
782 if( stepFlag < 0 ) 703 tsig = findMeter( m_frameACF, m_winLength, periodP[ TTLoopIndex ] );
783 { 704
784 stepFlag = 0; 705 createCombFilter( GW, m_lagLength, tsig, periodP[ TTLoopIndex ] );
785 } 706
786 707 periodG[ TTLoopIndex ] = tempoMM( m_frameACF, GW, tsig );
787 if( constFlag != 0) 708
788 { 709 period = periodG[ TTLoopIndex ];
789 tsig = findMeter( m_frameACF, m_winLength, periodP[ TTLoopIndex ] );
790
791 createCombFilter( GW, m_lagLength, tsig, periodP[ TTLoopIndex ] );
792
793 periodG[ TTLoopIndex ] = tempoMM( m_frameACF, GW, tsig );
794
795 period = periodG[ TTLoopIndex ];
796 710
797 #ifdef DEBUG_TEMPO_TRACK 711 #ifdef DEBUG_TEMPO_TRACK
798 std::cerr << "TempoTrack::process: constFlag == " << constFlag << ", TTLoopIndex = " << TTLoopIndex << ", period from periodG = " << period << std::endl; 712 std::cerr << "TempoTrack::process: constFlag == " << constFlag << ", TTLoopIndex = " << TTLoopIndex << ", period from periodG = " << period << std::endl;
799 #endif 713 #endif
800 714
801 createPhaseExtractor( PW, m_winLength, period, FSP, 0 ); 715 createPhaseExtractor( PW, m_winLength, period, FSP, 0 );
802 716
803 constFlag = 0; 717 constFlag = 0;
804 718
805 } 719 } else {
806 else 720
807 { 721 if( GW[ 0 ] != 0 ) {
808 if( GW[ 0 ] != 0 ) 722 period = periodG[ TTLoopIndex ];
809 {
810 period = periodG[ TTLoopIndex ];
811 723
812 #ifdef DEBUG_TEMPO_TRACK 724 #ifdef DEBUG_TEMPO_TRACK
813 std::cerr << "TempoTrack::process: GW[0] == " << GW[0] << ", TTLoopIndex = " << TTLoopIndex << ", period from periodG = " << period << std::endl; 725 std::cerr << "TempoTrack::process: GW[0] == " << GW[0] << ", TTLoopIndex = " << TTLoopIndex << ", period from periodG = " << period << std::endl;
814 #endif 726 #endif
815 727
824 std::cerr << i << " -> " << periodP[i] << std::endl; 736 std::cerr << i << " -> " << periodP[i] << std::endl;
825 } 737 }
826 period = 5168 / 120; 738 period = 5168 / 120;
827 } 739 }
828 740
829 createPhaseExtractor( PW, m_winLength, period, FSP, lastBeat ); 741 createPhaseExtractor( PW, m_winLength, period, FSP, lastBeat );
830 742
831 } 743 }
832 else 744 else
833 { 745 {
834 period = periodP[ TTLoopIndex ]; 746 period = periodP[ TTLoopIndex ];
835 747
836 #ifdef DEBUG_TEMPO_TRACK 748 #ifdef DEBUG_TEMPO_TRACK
837 std::cerr << "TempoTrack::process: GW[0] == " << GW[0] << ", TTLoopIndex = " << TTLoopIndex << ", period from periodP = " << period << std::endl; 749 std::cerr << "TempoTrack::process: GW[0] == " << GW[0] << ", TTLoopIndex = " << TTLoopIndex << ", period from periodP = " << period << std::endl;
838 #endif 750 #endif
839 751
840 createPhaseExtractor( PW, m_winLength, period, FSP, 0 ); 752 createPhaseExtractor( PW, m_winLength, period, FSP, 0 );
841 } 753 }
842 } 754 }
843 755
844 alignment[ TTLoopIndex ] = phaseMM( m_rawDFFrame, PW, m_winLength, period ); 756 alignment[ TTLoopIndex ] = phaseMM( m_rawDFFrame, PW, m_winLength, period );
845 757
846 lastBeat = beatPredict(FSP, alignment[ TTLoopIndex ], period, m_lagLength ); 758 lastBeat = beatPredict(FSP, alignment[ TTLoopIndex ], period, m_lagLength );
847 759
848 FSP += (m_lagLength); 760 FSP += (m_lagLength);
849 761
850 if (tempoReturn) tempoReturn->push_back(m_lockedTempo); 762 if (tempoReturn) tempoReturn->push_back(m_lockedTempo);
851 763
852 TTLoopIndex++; 764 TTLoopIndex++;
853 } 765 }
854 766
855 767
856 delete [] periodP; 768 delete [] periodP;
857 delete [] periodG; 769 delete [] periodG;