Mercurial > hg > qm-dsp
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; |