comparison src/OnsetDetectionFunction.cpp @ 22:a8e3e95d14e4 develop

Renamed many variables, functions and arguments so they have more sensible names. Also removed an apparently redundant variable in OnsetDetectionFunction called wframe
author Adam <adamstark.uk@gmail.com>
date Fri, 24 Jan 2014 21:45:55 +0000
parents baf35f208814
children 98f7a54faa0c
comparison
equal deleted inserted replaced
21:ef4721e7466c 22:a8e3e95d14e4
21 21
22 #include <math.h> 22 #include <math.h>
23 #include "OnsetDetectionFunction.h" 23 #include "OnsetDetectionFunction.h"
24 24
25 //======================================================================= 25 //=======================================================================
26 OnsetDetectionFunction :: OnsetDetectionFunction(int arg_hsize,int arg_fsize,int arg_df_type,int arg_win_type) 26 OnsetDetectionFunction::OnsetDetectionFunction(int hopSize_,int frameSize_,int onsetDetectionFunctionType_,int windowType)
27 { 27 {
28 // indicate that we have not initialised yet 28 // indicate that we have not initialised yet
29 initialised = 0; 29 initialised = 0;
30 30
31 // set pi 31 // set pi
32 pi = 3.14159265358979; 32 pi = 3.14159265358979;
33 33
34 // initialise with arguments to constructor 34 // initialise with arguments to constructor
35 initialise(arg_hsize,arg_fsize,arg_df_type,arg_win_type); 35 initialise(hopSize_,frameSize_,onsetDetectionFunctionType_,windowType);
36 } 36 }
37 37
38 38
39 //======================================================================= 39 //=======================================================================
40 OnsetDetectionFunction :: ~OnsetDetectionFunction() 40 OnsetDetectionFunction::~OnsetDetectionFunction()
41 { 41 {
42 // destroy fft plan 42 // destroy fft plan
43 fftw_destroy_plan(p); 43 fftw_destroy_plan(p);
44 fftw_free(in); 44 fftw_free(complexIn);
45 fftw_free(out); 45 fftw_free(complexOut);
46 46
47 // deallocate memory 47 // deallocate memory
48 delete [] frame; 48 delete [] frame;
49 frame = NULL; 49 frame = NULL;
50 delete [] window; 50 delete [] window;
51 window = NULL; 51 window = NULL;
52 delete [] wframe; 52 delete [] magSpec;
53 wframe = NULL; 53 magSpec = NULL;
54 delete [] mag; 54 delete [] prevMagSpec;
55 mag = NULL; 55 prevMagSpec = NULL;
56 delete [] mag_old;
57 mag_old = NULL;
58 delete [] phase; 56 delete [] phase;
59 phase = NULL; 57 phase = NULL;
60 delete [] phase_old; 58 delete [] prevPhase;
61 phase_old = NULL; 59 prevPhase = NULL;
62 delete [] phase_old_2; 60 delete [] prevPhase2;
63 phase_old_2 = NULL; 61 prevPhase2 = NULL;
64 } 62 }
65 63
66 //======================================================================= 64 //=======================================================================
67 void OnsetDetectionFunction :: initialise(int arg_hsize,int arg_fsize,int arg_df_type,int arg_win_type) 65 void OnsetDetectionFunction::initialise(int hopSize_,int frameSize_,int onsetDetectionFunctionType_,int windowType)
68 { 66 {
69 if (initialised == 1) // if we have already initialised some buffers and an FFT plan 67 if (initialised == 1) // if we have already initialised some buffers and an FFT plan
70 { 68 {
71 ////////////////////////////////// 69 //////////////////////////////////
72 // TIDY UP FIRST - If initialise is called after the class has been initialised 70 // TIDY UP FIRST - If initialise is called after the class has been initialised
73 // then we want to free up memory and cancel existing FFT plans 71 // then we want to free up memory and cancel existing FFT plans
74 72
75 // destroy fft plan 73 // destroy fft plan
76 fftw_destroy_plan(p); 74 fftw_destroy_plan(p);
77 fftw_free(in); 75 fftw_free(complexIn);
78 fftw_free(out); 76 fftw_free(complexOut);
79 77
80 78
81 // deallocate memory 79 // deallocate memory
82 delete [] frame; 80 delete [] frame;
83 frame = NULL; 81 frame = NULL;
84 delete [] window; 82 delete [] window;
85 window = NULL; 83 window = NULL;
86 delete [] wframe; 84 delete [] magSpec;
87 wframe = NULL; 85 magSpec = NULL;
88 delete [] mag; 86 delete [] prevMagSpec;
89 mag = NULL; 87 prevMagSpec = NULL;
90 delete [] mag_old;
91 mag_old = NULL;
92 delete [] phase; 88 delete [] phase;
93 phase = NULL; 89 phase = NULL;
94 delete [] phase_old; 90 delete [] prevPhase;
95 phase_old = NULL; 91 prevPhase = NULL;
96 delete [] phase_old_2; 92 delete [] prevPhase2;
97 phase_old_2 = NULL; 93 prevPhase2 = NULL;
98 94
99 ////// END TIDY UP /////////////// 95 ////// END TIDY UP ///////////////
100 ////////////////////////////////// 96 //////////////////////////////////
101 } 97 }
102 98
103 hopsize = arg_hsize; // set hopsize 99 hopSize = hopSize_; // set hopsize
104 framesize = arg_fsize; // set framesize 100 frameSize = frameSize_; // set framesize
105 101
106 df_type = arg_df_type; // set detection function type 102 onsetDetectionFunctionType = onsetDetectionFunctionType_; // set detection function type
107 103
108 // initialise buffers 104 // initialise buffers
109 frame = new double[framesize]; 105 frame = new double[frameSize];
110 window = new double[framesize]; 106 window = new double[frameSize];
111 wframe = new double[framesize]; 107
112 108 magSpec = new double[frameSize];
113 mag = new double[framesize]; 109 prevMagSpec = new double[frameSize];
114 mag_old = new double[framesize]; 110
115 111 phase = new double[frameSize];
116 phase = new double[framesize]; 112 prevPhase = new double[frameSize];
117 phase_old = new double[framesize]; 113 prevPhase2 = new double[frameSize];
118 phase_old_2 = new double[framesize];
119 114
120 115
121 // set the window to the specified type 116 // set the window to the specified type
122 switch (arg_win_type){ 117 switch (windowType){
123 case RectangularWindow: 118 case RectangularWindow:
124 set_win_rectangular(); // Rectangular window 119 calculateRectangularWindow(); // Rectangular window
125 break; 120 break;
126 case HanningWindow: 121 case HanningWindow:
127 set_win_hanning(); // Hanning Window 122 calculateHanningWindow(); // Hanning Window
128 break; 123 break;
129 case HammingWindow: 124 case HammingWindow:
130 set_win_hamming(); // Hamming Window 125 calclulateHammingWindow(); // Hamming Window
131 break; 126 break;
132 case BlackmanWindow: 127 case BlackmanWindow:
133 set_win_blackman(); // Blackman Window 128 calculateBlackmanWindow(); // Blackman Window
134 break; 129 break;
135 case TukeyWindow: 130 case TukeyWindow:
136 set_win_tukey(); // Tukey Window 131 calculateTukeyWindow(); // Tukey Window
137 break; 132 break;
138 default: 133 default:
139 set_win_hanning(); // DEFAULT: Hanning Window 134 calculateHanningWindow(); // DEFAULT: Hanning Window
140 } 135 }
141 136
142 137
143 138
144 139
145 // initialise previous magnitude spectrum to zero 140 // initialise previous magnitude spectrum to zero
146 for (int i = 0;i < framesize;i++) 141 for (int i = 0;i < frameSize;i++)
147 { 142 {
148 mag_old[i] = 0.0; 143 prevMagSpec[i] = 0.0;
149 phase_old[i] = 0.0; 144 prevPhase[i] = 0.0;
150 phase_old_2[i] = 0.0; 145 prevPhase2[i] = 0.0;
151 frame[i] = 0.0; 146 frame[i] = 0.0;
152 } 147 }
153 148
154 energy_sum_old = 0.0; // initialise previous energy sum value to zero 149 prevEnergySum = 0.0; // initialise previous energy sum value to zero
155 150
156 /* Init fft */ 151 /* Init fft */
157 in = (fftw_complex*) fftw_malloc(sizeof(fftw_complex) * framesize); // complex array to hold fft data 152 complexIn = (fftw_complex*) fftw_malloc(sizeof(fftw_complex) * frameSize); // complex array to hold fft data
158 out = (fftw_complex*) fftw_malloc(sizeof(fftw_complex) * framesize); // complex array to hold fft data 153 complexOut = (fftw_complex*) fftw_malloc(sizeof(fftw_complex) * frameSize); // complex array to hold fft data
159 p = fftw_plan_dft_1d(framesize, in, out, FFTW_FORWARD, FFTW_ESTIMATE); // FFT plan initialisation 154 p = fftw_plan_dft_1d(frameSize, complexIn, complexOut, FFTW_FORWARD, FFTW_ESTIMATE); // FFT plan initialisation
160 155
161 initialised = 1; 156 initialised = 1;
162 } 157 }
163 158
164 //======================================================================= 159 //=======================================================================
165 void OnsetDetectionFunction :: set_df_type(int arg_df_type) 160 void OnsetDetectionFunction :: setOnsetDetectionFunctionType(int onsetDetectionFunctionType_)
166 { 161 {
167 df_type = arg_df_type; // set detection function type 162 onsetDetectionFunctionType = onsetDetectionFunctionType_; // set detection function type
168 } 163 }
169 164
170 //======================================================================= 165 //=======================================================================
171 double OnsetDetectionFunction :: getDFsample(double *inputbuffer) 166 double OnsetDetectionFunction :: calculateOnsetDetectionFunctionSample(double *buffer)
172 { 167 {
173 double df_sample; 168 double odfSample;
174 169
175 // shift audio samples back in frame by hop size 170 // shift audio samples back in frame by hop size
176 for (int i = 0; i < (framesize-hopsize);i++) 171 for (int i = 0; i < (frameSize-hopSize);i++)
177 { 172 {
178 frame[i] = frame[i+hopsize]; 173 frame[i] = frame[i+hopSize];
179 } 174 }
180 175
181 // add new samples to frame from input buffer 176 // add new samples to frame from input buffer
182 int j = 0; 177 int j = 0;
183 for (int i = (framesize-hopsize);i < framesize;i++) 178 for (int i = (frameSize-hopSize);i < frameSize;i++)
184 { 179 {
185 frame[i] = inputbuffer[j]; 180 frame[i] = buffer[j];
186 j++; 181 j++;
187 } 182 }
188 183
189 switch (df_type){ 184 switch (onsetDetectionFunctionType){
190 case EnergyEnvelope: 185 case EnergyEnvelope:
191 { 186 {
192 // calculate energy envelope detection function sample 187 // calculate energy envelope detection function sample
193 df_sample = energy_envelope(); 188 odfSample = energyEnvelope();
194 break; 189 break;
195 } 190 }
196 case EnergyDifference: 191 case EnergyDifference:
197 { 192 {
198 // calculate half-wave rectified energy difference detection function sample 193 // calculate half-wave rectified energy difference detection function sample
199 df_sample = energy_difference(); 194 odfSample = energyDifference();
200 break; 195 break;
201 } 196 }
202 case SpectralDifference: 197 case SpectralDifference:
203 { 198 {
204 // calculate spectral difference detection function sample 199 // calculate spectral difference detection function sample
205 df_sample = spectral_difference(); 200 odfSample = spectralDifference();
206 break; 201 break;
207 } 202 }
208 case SpectralDifferenceHWR: 203 case SpectralDifferenceHWR:
209 { 204 {
210 // calculate spectral difference detection function sample (half wave rectified) 205 // calculate spectral difference detection function sample (half wave rectified)
211 df_sample = spectral_difference_hwr(); 206 odfSample = spectralDifferenceHWR();
212 break; 207 break;
213 } 208 }
214 case PhaseDeviation: 209 case PhaseDeviation:
215 { 210 {
216 // calculate phase deviation detection function sample (half wave rectified) 211 // calculate phase deviation detection function sample (half wave rectified)
217 df_sample = phase_deviation(); 212 odfSample = phaseDeviation();
218 break; 213 break;
219 } 214 }
220 case ComplexSpectralDifference: 215 case ComplexSpectralDifference:
221 { 216 {
222 // calcualte complex spectral difference detection function sample 217 // calcualte complex spectral difference detection function sample
223 df_sample = complex_spectral_difference(); 218 odfSample = complexSpectralDifference();
224 break; 219 break;
225 } 220 }
226 case ComplexSpectralDifferenceHWR: 221 case ComplexSpectralDifferenceHWR:
227 { 222 {
228 // calcualte complex spectral difference detection function sample (half-wave rectified) 223 // calcualte complex spectral difference detection function sample (half-wave rectified)
229 df_sample = complex_spectral_difference_hwr(); 224 odfSample = complexSpectralDifferenceHWR();
230 break; 225 break;
231 } 226 }
232 case HighFrequencyContent: 227 case HighFrequencyContent:
233 { 228 {
234 // calculate high frequency content detection function sample 229 // calculate high frequency content detection function sample
235 df_sample = high_frequency_content(); 230 odfSample = highFrequencyContent();
236 break; 231 break;
237 } 232 }
238 case HighFrequencySpectralDifference: 233 case HighFrequencySpectralDifference:
239 { 234 {
240 // calculate high frequency spectral difference detection function sample 235 // calculate high frequency spectral difference detection function sample
241 df_sample = high_frequency_spectral_difference(); 236 odfSample = highFrequencySpectralDifference();
242 break; 237 break;
243 } 238 }
244 case HighFrequencySpectralDifferenceHWR: 239 case HighFrequencySpectralDifferenceHWR:
245 { 240 {
246 // calculate high frequency spectral difference detection function (half-wave rectified) 241 // calculate high frequency spectral difference detection function (half-wave rectified)
247 df_sample = high_frequency_spectral_difference_hwr(); 242 odfSample = highFrequencySpectralDifferenceHWR();
248 break; 243 break;
249 } 244 }
250 default: 245 default:
251 { 246 {
252 df_sample = 1.0; 247 odfSample = 1.0;
253 } 248 }
254 } 249 }
255 250
256 return df_sample; 251 return odfSample;
257 } 252 }
258 253
259 254
260 //======================================================================= 255 //=======================================================================
261 void OnsetDetectionFunction :: perform_FFT() 256 void OnsetDetectionFunction :: performFFT()
262 { 257 {
263 int fsize2 = (framesize/2); 258 int fsize2 = (frameSize/2);
264 259
265 // window frame and copy to complex array, swapping the first and second half of the signal 260 // window frame and copy to complex array, swapping the first and second half of the signal
266 for (int i = 0;i < fsize2;i++) 261 for (int i = 0;i < fsize2;i++)
267 { 262 {
268 in[i][0] = frame[i+fsize2] * window[i+fsize2]; 263 complexIn[i][0] = frame[i+fsize2] * window[i+fsize2];
269 in[i][1] = 0.0; 264 complexIn[i][1] = 0.0;
270 in[i+fsize2][0] = frame[i] * window[i]; 265 complexIn[i+fsize2][0] = frame[i] * window[i];
271 in[i+fsize2][1] = 0.0; 266 complexIn[i+fsize2][1] = 0.0;
272 } 267 }
273 268
274 // perform the fft 269 // perform the fft
275 fftw_execute(p); 270 fftw_execute(p);
276 } 271 }
278 //////////////////////////////////////////////////////////////////////////////////////////////// 273 ////////////////////////////////////////////////////////////////////////////////////////////////
279 //////////////////////////////////////////////////////////////////////////////////////////////// 274 ////////////////////////////////////////////////////////////////////////////////////////////////
280 ////////////////////////////// Methods for Detection Functions ///////////////////////////////// 275 ////////////////////////////// Methods for Detection Functions /////////////////////////////////
281 276
282 //======================================================================= 277 //=======================================================================
283 double OnsetDetectionFunction :: energy_envelope() 278 double OnsetDetectionFunction :: energyEnvelope()
284 { 279 {
285 double sum; 280 double sum;
286 281
287 sum = 0; // initialise sum 282 sum = 0; // initialise sum
288 283
289 // sum the squares of the samples 284 // sum the squares of the samples
290 for (int i = 0;i < framesize;i++) 285 for (int i = 0;i < frameSize;i++)
291 { 286 {
292 sum = sum + (frame[i]*frame[i]); 287 sum = sum + (frame[i]*frame[i]);
293 } 288 }
294 289
295 return sum; // return sum 290 return sum; // return sum
296 } 291 }
297 292
298 //======================================================================= 293 //=======================================================================
299 double OnsetDetectionFunction :: energy_difference() 294 double OnsetDetectionFunction :: energyDifference()
300 { 295 {
301 double sum; 296 double sum;
302 double sample; 297 double sample;
303 298
304 sum = 0; // initialise sum 299 sum = 0; // initialise sum
305 300
306 // sum the squares of the samples 301 // sum the squares of the samples
307 for (int i = 0;i < framesize;i++) 302 for (int i = 0;i < frameSize;i++)
308 { 303 {
309 sum = sum + (frame[i]*frame[i]); 304 sum = sum + (frame[i]*frame[i]);
310 } 305 }
311 306
312 sample = sum - energy_sum_old; // sample is first order difference in energy 307 sample = sum - prevEnergySum; // sample is first order difference in energy
313 308
314 energy_sum_old = sum; // store energy value for next calculation 309 prevEnergySum = sum; // store energy value for next calculation
315 310
316 if (sample > 0) 311 if (sample > 0)
317 { 312 {
318 return sample; // return difference 313 return sample; // return difference
319 } 314 }
322 return 0; 317 return 0;
323 } 318 }
324 } 319 }
325 320
326 //======================================================================= 321 //=======================================================================
327 double OnsetDetectionFunction :: spectral_difference() 322 double OnsetDetectionFunction :: spectralDifference()
328 { 323 {
329 double diff; 324 double diff;
330 double sum; 325 double sum;
331 326
332 // perform the FFT 327 // perform the FFT
333 perform_FFT(); 328 performFFT();
334 329
335 // compute first (N/2)+1 mag values 330 // compute first (N/2)+1 mag values
336 for (int i = 0;i < (framesize/2)+1;i++) 331 for (int i = 0;i < (frameSize/2)+1;i++)
337 { 332 {
338 mag[i] = sqrt(pow(out[i][0],2) + pow(out[i][1],2)); 333 magSpec[i] = sqrt(pow(complexOut[i][0],2) + pow(complexOut[i][1],2));
339 } 334 }
340 // mag spec symmetric above (N/2)+1 so copy previous values 335 // mag spec symmetric above (N/2)+1 so copy previous values
341 for (int i = (framesize/2)+1;i < framesize;i++) 336 for (int i = (frameSize/2)+1;i < frameSize;i++)
342 { 337 {
343 mag[i] = mag[framesize-i]; 338 magSpec[i] = magSpec[frameSize-i];
344 } 339 }
345 340
346 sum = 0; // initialise sum to zero 341 sum = 0; // initialise sum to zero
347 342
348 for (int i = 0;i < framesize;i++) 343 for (int i = 0;i < frameSize;i++)
349 { 344 {
350 // calculate difference 345 // calculate difference
351 diff = mag[i] - mag_old[i]; 346 diff = magSpec[i] - prevMagSpec[i];
352 347
353 // ensure all difference values are positive 348 // ensure all difference values are positive
354 if (diff < 0) 349 if (diff < 0)
355 { 350 {
356 diff = diff*-1; 351 diff = diff*-1;
358 353
359 // add difference to sum 354 // add difference to sum
360 sum = sum+diff; 355 sum = sum+diff;
361 356
362 // store magnitude spectrum bin for next detection function sample calculation 357 // store magnitude spectrum bin for next detection function sample calculation
363 mag_old[i] = mag[i]; 358 prevMagSpec[i] = magSpec[i];
364 } 359 }
365 360
366 return sum; 361 return sum;
367 } 362 }
368 363
369 //======================================================================= 364 //=======================================================================
370 double OnsetDetectionFunction :: spectral_difference_hwr() 365 double OnsetDetectionFunction :: spectralDifferenceHWR()
371 { 366 {
372 double diff; 367 double diff;
373 double sum; 368 double sum;
374 369
375 // perform the FFT 370 // perform the FFT
376 perform_FFT(); 371 performFFT();
377 372
378 // compute first (N/2)+1 mag values 373 // compute first (N/2)+1 mag values
379 for (int i = 0;i < (framesize/2)+1;i++) 374 for (int i = 0;i < (frameSize/2)+1;i++)
380 { 375 {
381 mag[i] = sqrt(pow(out[i][0],2) + pow(out[i][1],2)); 376 magSpec[i] = sqrt(pow(complexOut[i][0],2) + pow(complexOut[i][1],2));
382 } 377 }
383 // mag spec symmetric above (N/2)+1 so copy previous values 378 // mag spec symmetric above (N/2)+1 so copy previous values
384 for (int i = (framesize/2)+1;i < framesize;i++) 379 for (int i = (frameSize/2)+1;i < frameSize;i++)
385 { 380 {
386 mag[i] = mag[framesize-i]; 381 magSpec[i] = magSpec[frameSize-i];
387 } 382 }
388 383
389 sum = 0; // initialise sum to zero 384 sum = 0; // initialise sum to zero
390 385
391 for (int i = 0;i < framesize;i++) 386 for (int i = 0;i < frameSize;i++)
392 { 387 {
393 // calculate difference 388 // calculate difference
394 diff = mag[i] - mag_old[i]; 389 diff = magSpec[i] - prevMagSpec[i];
395 390
396 // only add up positive differences 391 // only add up positive differences
397 if (diff > 0) 392 if (diff > 0)
398 { 393 {
399 // add difference to sum 394 // add difference to sum
401 } 396 }
402 397
403 398
404 399
405 // store magnitude spectrum bin for next detection function sample calculation 400 // store magnitude spectrum bin for next detection function sample calculation
406 mag_old[i] = mag[i]; 401 prevMagSpec[i] = magSpec[i];
407 } 402 }
408 403
409 return sum; 404 return sum;
410 } 405 }
411 406
412 407
413 //======================================================================= 408 //=======================================================================
414 double OnsetDetectionFunction :: phase_deviation() 409 double OnsetDetectionFunction :: phaseDeviation()
415 { 410 {
416 double dev,pdev; 411 double dev,pdev;
417 double sum; 412 double sum;
418 413
419 // perform the FFT 414 // perform the FFT
420 perform_FFT(); 415 performFFT();
421 416
422 sum = 0; // initialise sum to zero 417 sum = 0; // initialise sum to zero
423 418
424 // compute phase values from fft output and sum deviations 419 // compute phase values from fft output and sum deviations
425 for (int i = 0;i < framesize;i++) 420 for (int i = 0;i < frameSize;i++)
426 { 421 {
427 // calculate phase value 422 // calculate phase value
428 phase[i] = atan2(out[i][1],out[i][0]); 423 phase[i] = atan2(complexOut[i][1],complexOut[i][0]);
429 424
430 // calculate magnitude value 425 // calculate magnitude value
431 mag[i] = sqrt(pow(out[i][0],2) + pow(out[i][1],2)); 426 magSpec[i] = sqrt(pow(complexOut[i][0],2) + pow(complexOut[i][1],2));
432 427
433 428
434 // if bin is not just a low energy bin then examine phase deviation 429 // if bin is not just a low energy bin then examine phase deviation
435 if (mag[i] > 0.1) 430 if (magSpec[i] > 0.1)
436 { 431 {
437 dev = phase[i] - (2*phase_old[i]) + phase_old_2[i]; // phase deviation 432 dev = phase[i] - (2*prevPhase[i]) + prevPhase2[i]; // phase deviation
438 pdev = princarg(dev); // wrap into [-pi,pi] range 433 pdev = princarg(dev); // wrap into [-pi,pi] range
439 434
440 // make all values positive 435 // make all values positive
441 if (pdev < 0) 436 if (pdev < 0)
442 { 437 {
446 // add to sum 441 // add to sum
447 sum = sum + pdev; 442 sum = sum + pdev;
448 } 443 }
449 444
450 // store values for next calculation 445 // store values for next calculation
451 phase_old_2[i] = phase_old[i]; 446 prevPhase2[i] = prevPhase[i];
452 phase_old[i] = phase[i]; 447 prevPhase[i] = phase[i];
453 } 448 }
454 449
455 return sum; 450 return sum;
456 } 451 }
457 452
458 //======================================================================= 453 //=======================================================================
459 double OnsetDetectionFunction :: complex_spectral_difference() 454 double OnsetDetectionFunction :: complexSpectralDifference()
460 { 455 {
461 double dev,pdev; 456 double dev,pdev;
462 double sum; 457 double sum;
463 double mag_diff,phase_diff; 458 double mag_diff,phase_diff;
464 double value; 459 double value;
465 460
466 // perform the FFT 461 // perform the FFT
467 perform_FFT(); 462 performFFT();
468 463
469 sum = 0; // initialise sum to zero 464 sum = 0; // initialise sum to zero
470 465
471 // compute phase values from fft output and sum deviations 466 // compute phase values from fft output and sum deviations
472 for (int i = 0;i < framesize;i++) 467 for (int i = 0;i < frameSize;i++)
473 { 468 {
474 // calculate phase value 469 // calculate phase value
475 phase[i] = atan2(out[i][1],out[i][0]); 470 phase[i] = atan2(complexOut[i][1],complexOut[i][0]);
476 471
477 // calculate magnitude value 472 // calculate magnitude value
478 mag[i] = sqrt(pow(out[i][0],2) + pow(out[i][1],2)); 473 magSpec[i] = sqrt(pow(complexOut[i][0],2) + pow(complexOut[i][1],2));
479 474
480 475
481 // phase deviation 476 // phase deviation
482 dev = phase[i] - (2*phase_old[i]) + phase_old_2[i]; 477 dev = phase[i] - (2*prevPhase[i]) + prevPhase2[i];
483 478
484 // wrap into [-pi,pi] range 479 // wrap into [-pi,pi] range
485 pdev = princarg(dev); 480 pdev = princarg(dev);
486 481
487 482
488 // calculate magnitude difference (real part of Euclidean distance between complex frames) 483 // calculate magnitude difference (real part of Euclidean distance between complex frames)
489 mag_diff = mag[i] - mag_old[i]; 484 mag_diff = magSpec[i] - prevMagSpec[i];
490 485
491 // calculate phase difference (imaginary part of Euclidean distance between complex frames) 486 // calculate phase difference (imaginary part of Euclidean distance between complex frames)
492 phase_diff = -mag[i]*sin(pdev); 487 phase_diff = -magSpec[i]*sin(pdev);
493 488
494 489
495 490
496 // square real and imaginary parts, sum and take square root 491 // square real and imaginary parts, sum and take square root
497 value = sqrt(pow(mag_diff,2) + pow(phase_diff,2)); 492 value = sqrt(pow(mag_diff,2) + pow(phase_diff,2));
500 // add to sum 495 // add to sum
501 sum = sum + value; 496 sum = sum + value;
502 497
503 498
504 // store values for next calculation 499 // store values for next calculation
505 phase_old_2[i] = phase_old[i]; 500 prevPhase2[i] = prevPhase[i];
506 phase_old[i] = phase[i]; 501 prevPhase[i] = phase[i];
507 mag_old[i] = mag[i]; 502 prevMagSpec[i] = magSpec[i];
508 } 503 }
509 504
510 return sum; 505 return sum;
511 } 506 }
512 507
513 //======================================================================= 508 //=======================================================================
514 double OnsetDetectionFunction :: complex_spectral_difference_hwr() 509 double OnsetDetectionFunction :: complexSpectralDifferenceHWR()
515 { 510 {
516 double dev,pdev; 511 double dev,pdev;
517 double sum; 512 double sum;
518 double mag_diff,phase_diff; 513 double mag_diff,phase_diff;
519 double value; 514 double value;
520 515
521 // perform the FFT 516 // perform the FFT
522 perform_FFT(); 517 performFFT();
523 518
524 sum = 0; // initialise sum to zero 519 sum = 0; // initialise sum to zero
525 520
526 // compute phase values from fft output and sum deviations 521 // compute phase values from fft output and sum deviations
527 for (int i = 0;i < framesize;i++) 522 for (int i = 0;i < frameSize;i++)
528 { 523 {
529 // calculate phase value 524 // calculate phase value
530 phase[i] = atan2(out[i][1],out[i][0]); 525 phase[i] = atan2(complexOut[i][1],complexOut[i][0]);
531 526
532 // calculate magnitude value 527 // calculate magnitude value
533 mag[i] = sqrt(pow(out[i][0],2) + pow(out[i][1],2)); 528 magSpec[i] = sqrt(pow(complexOut[i][0],2) + pow(complexOut[i][1],2));
534 529
535 530
536 // phase deviation 531 // phase deviation
537 dev = phase[i] - (2*phase_old[i]) + phase_old_2[i]; 532 dev = phase[i] - (2*prevPhase[i]) + prevPhase2[i];
538 533
539 // wrap into [-pi,pi] range 534 // wrap into [-pi,pi] range
540 pdev = princarg(dev); 535 pdev = princarg(dev);
541 536
542 537
543 // calculate magnitude difference (real part of Euclidean distance between complex frames) 538 // calculate magnitude difference (real part of Euclidean distance between complex frames)
544 mag_diff = mag[i] - mag_old[i]; 539 mag_diff = magSpec[i] - prevMagSpec[i];
545 540
546 // if we have a positive change in magnitude, then include in sum, otherwise ignore (half-wave rectification) 541 // if we have a positive change in magnitude, then include in sum, otherwise ignore (half-wave rectification)
547 if (mag_diff > 0) 542 if (mag_diff > 0)
548 { 543 {
549 // calculate phase difference (imaginary part of Euclidean distance between complex frames) 544 // calculate phase difference (imaginary part of Euclidean distance between complex frames)
550 phase_diff = -mag[i]*sin(pdev); 545 phase_diff = -magSpec[i]*sin(pdev);
551 546
552 // square real and imaginary parts, sum and take square root 547 // square real and imaginary parts, sum and take square root
553 value = sqrt(pow(mag_diff,2) + pow(phase_diff,2)); 548 value = sqrt(pow(mag_diff,2) + pow(phase_diff,2));
554 549
555 // add to sum 550 // add to sum
556 sum = sum + value; 551 sum = sum + value;
557 } 552 }
558 553
559 // store values for next calculation 554 // store values for next calculation
560 phase_old_2[i] = phase_old[i]; 555 prevPhase2[i] = prevPhase[i];
561 phase_old[i] = phase[i]; 556 prevPhase[i] = phase[i];
562 mag_old[i] = mag[i]; 557 prevMagSpec[i] = magSpec[i];
563 } 558 }
564 559
565 return sum; 560 return sum;
566 } 561 }
567 562
568 563
569 //======================================================================= 564 //=======================================================================
570 double OnsetDetectionFunction :: high_frequency_content() 565 double OnsetDetectionFunction :: highFrequencyContent()
571 { 566 {
572 double sum; 567 double sum;
573 568
574 // perform the FFT 569 // perform the FFT
575 perform_FFT(); 570 performFFT();
576 571
577 sum = 0; // initialise sum to zero 572 sum = 0; // initialise sum to zero
578 573
579 // compute phase values from fft output and sum deviations 574 // compute phase values from fft output and sum deviations
580 for (int i = 0;i < framesize;i++) 575 for (int i = 0;i < frameSize;i++)
581 { 576 {
582 // calculate magnitude value 577 // calculate magnitude value
583 mag[i] = sqrt(pow(out[i][0],2) + pow(out[i][1],2)); 578 magSpec[i] = sqrt(pow(complexOut[i][0],2) + pow(complexOut[i][1],2));
584 579
585 580
586 sum = sum + (mag[i]*((double) (i+1))); 581 sum = sum + (magSpec[i]*((double) (i+1)));
587 582
588 // store values for next calculation 583 // store values for next calculation
589 mag_old[i] = mag[i]; 584 prevMagSpec[i] = magSpec[i];
590 } 585 }
591 586
592 return sum; 587 return sum;
593 } 588 }
594 589
595 //======================================================================= 590 //=======================================================================
596 double OnsetDetectionFunction :: high_frequency_spectral_difference() 591 double OnsetDetectionFunction :: highFrequencySpectralDifference()
597 { 592 {
598 double sum; 593 double sum;
599 double mag_diff; 594 double mag_diff;
600 595
601 // perform the FFT 596 // perform the FFT
602 perform_FFT(); 597 performFFT();
603 598
604 sum = 0; // initialise sum to zero 599 sum = 0; // initialise sum to zero
605 600
606 // compute phase values from fft output and sum deviations 601 // compute phase values from fft output and sum deviations
607 for (int i = 0;i < framesize;i++) 602 for (int i = 0;i < frameSize;i++)
608 { 603 {
609 // calculate magnitude value 604 // calculate magnitude value
610 mag[i] = sqrt(pow(out[i][0],2) + pow(out[i][1],2)); 605 magSpec[i] = sqrt(pow(complexOut[i][0],2) + pow(complexOut[i][1],2));
611 606
612 // calculate difference 607 // calculate difference
613 mag_diff = mag[i] - mag_old[i]; 608 mag_diff = magSpec[i] - prevMagSpec[i];
614 609
615 if (mag_diff < 0) 610 if (mag_diff < 0)
616 { 611 {
617 mag_diff = -mag_diff; 612 mag_diff = -mag_diff;
618 } 613 }
619 614
620 sum = sum + (mag_diff*((double) (i+1))); 615 sum = sum + (mag_diff*((double) (i+1)));
621 616
622 // store values for next calculation 617 // store values for next calculation
623 mag_old[i] = mag[i]; 618 prevMagSpec[i] = magSpec[i];
624 } 619 }
625 620
626 return sum; 621 return sum;
627 } 622 }
628 623
629 //======================================================================= 624 //=======================================================================
630 double OnsetDetectionFunction :: high_frequency_spectral_difference_hwr() 625 double OnsetDetectionFunction :: highFrequencySpectralDifferenceHWR()
631 { 626 {
632 double sum; 627 double sum;
633 double mag_diff; 628 double mag_diff;
634 629
635 // perform the FFT 630 // perform the FFT
636 perform_FFT(); 631 performFFT();
637 632
638 sum = 0; // initialise sum to zero 633 sum = 0; // initialise sum to zero
639 634
640 // compute phase values from fft output and sum deviations 635 // compute phase values from fft output and sum deviations
641 for (int i = 0;i < framesize;i++) 636 for (int i = 0;i < frameSize;i++)
642 { 637 {
643 // calculate magnitude value 638 // calculate magnitude value
644 mag[i] = sqrt(pow(out[i][0],2) + pow(out[i][1],2)); 639 magSpec[i] = sqrt(pow(complexOut[i][0],2) + pow(complexOut[i][1],2));
645 640
646 // calculate difference 641 // calculate difference
647 mag_diff = mag[i] - mag_old[i]; 642 mag_diff = magSpec[i] - prevMagSpec[i];
648 643
649 if (mag_diff > 0) 644 if (mag_diff > 0)
650 { 645 {
651 sum = sum + (mag_diff*((double) (i+1))); 646 sum = sum + (mag_diff*((double) (i+1)));
652 } 647 }
653 648
654 // store values for next calculation 649 // store values for next calculation
655 mag_old[i] = mag[i]; 650 prevMagSpec[i] = magSpec[i];
656 } 651 }
657 652
658 return sum; 653 return sum;
659 } 654 }
660 655
662 //////////////////////////////////////////////////////////////////////////////////////////////// 657 ////////////////////////////////////////////////////////////////////////////////////////////////
663 //////////////////////////////////////////////////////////////////////////////////////////////// 658 ////////////////////////////////////////////////////////////////////////////////////////////////
664 ////////////////////////////// Methods to Calculate Windows //////////////////////////////////// 659 ////////////////////////////// Methods to Calculate Windows ////////////////////////////////////
665 660
666 //======================================================================= 661 //=======================================================================
667 void OnsetDetectionFunction :: set_win_hanning() 662 void OnsetDetectionFunction :: calculateHanningWindow()
668 { 663 {
669 double N; // variable to store framesize minus 1 664 double N; // variable to store framesize minus 1
670 665
671 N = (double) (framesize-1); // framesize minus 1 666 N = (double) (frameSize-1); // framesize minus 1
672 667
673 // Hanning window calculation 668 // Hanning window calculation
674 for (int n = 0;n < framesize;n++) 669 for (int n = 0;n < frameSize;n++)
675 { 670 {
676 window[n] = 0.5*(1-cos(2*pi*(n/N))); 671 window[n] = 0.5*(1-cos(2*pi*(n/N)));
677 } 672 }
678 } 673 }
679 674
680 //======================================================================= 675 //=======================================================================
681 void OnsetDetectionFunction :: set_win_hamming() 676 void OnsetDetectionFunction :: calclulateHammingWindow()
682 { 677 {
683 double N; // variable to store framesize minus 1 678 double N; // variable to store framesize minus 1
684 double n_val; // double version of index 'n' 679 double n_val; // double version of index 'n'
685 680
686 N = (double) (framesize-1); // framesize minus 1 681 N = (double) (frameSize-1); // framesize minus 1
687 n_val = 0; 682 n_val = 0;
688 683
689 // Hamming window calculation 684 // Hamming window calculation
690 for (int n = 0;n < framesize;n++) 685 for (int n = 0;n < frameSize;n++)
691 { 686 {
692 window[n] = 0.54 - (0.46*cos(2*pi*(n_val/N))); 687 window[n] = 0.54 - (0.46*cos(2*pi*(n_val/N)));
693 n_val = n_val+1; 688 n_val = n_val+1;
694 } 689 }
695 } 690 }
696 691
697 //======================================================================= 692 //=======================================================================
698 void OnsetDetectionFunction :: set_win_blackman() 693 void OnsetDetectionFunction :: calculateBlackmanWindow()
699 { 694 {
700 double N; // variable to store framesize minus 1 695 double N; // variable to store framesize minus 1
701 double n_val; // double version of index 'n' 696 double n_val; // double version of index 'n'
702 697
703 N = (double) (framesize-1); // framesize minus 1 698 N = (double) (frameSize-1); // framesize minus 1
704 n_val = 0; 699 n_val = 0;
705 700
706 // Blackman window calculation 701 // Blackman window calculation
707 for (int n = 0;n < framesize;n++) 702 for (int n = 0;n < frameSize;n++)
708 { 703 {
709 window[n] = 0.42 - (0.5*cos(2*pi*(n_val/N))) + (0.08*cos(4*pi*(n_val/N))); 704 window[n] = 0.42 - (0.5*cos(2*pi*(n_val/N))) + (0.08*cos(4*pi*(n_val/N)));
710 n_val = n_val+1; 705 n_val = n_val+1;
711 } 706 }
712 } 707 }
713 708
714 //======================================================================= 709 //=======================================================================
715 void OnsetDetectionFunction :: set_win_tukey() 710 void OnsetDetectionFunction :: calculateTukeyWindow()
716 { 711 {
717 double N; // variable to store framesize minus 1 712 double N; // variable to store framesize minus 1
718 double n_val; // double version of index 'n' 713 double n_val; // double version of index 'n'
719 double alpha; // alpha [default value = 0.5]; 714 double alpha; // alpha [default value = 0.5];
720 715
721 alpha = 0.5; 716 alpha = 0.5;
722 717
723 N = (double) (framesize-1); // framesize minus 1 718 N = (double) (frameSize-1); // framesize minus 1
724 719
725 // Tukey window calculation 720 // Tukey window calculation
726 721
727 n_val = (double) (-1*((framesize/2)))+1; 722 n_val = (double) (-1*((frameSize/2)))+1;
728 723
729 for (int n = 0;n < framesize;n++) // left taper 724 for (int n = 0;n < frameSize;n++) // left taper
730 { 725 {
731 if ((n_val >= 0) && (n_val <= (alpha*(N/2)))) 726 if ((n_val >= 0) && (n_val <= (alpha*(N/2))))
732 { 727 {
733 window[n] = 1.0; 728 window[n] = 1.0;
734 } 729 }
745 } 740 }
746 741
747 } 742 }
748 743
749 //======================================================================= 744 //=======================================================================
750 void OnsetDetectionFunction :: set_win_rectangular() 745 void OnsetDetectionFunction :: calculateRectangularWindow()
751 { 746 {
752 // Rectangular window calculation 747 // Rectangular window calculation
753 for (int n = 0;n < framesize;n++) 748 for (int n = 0;n < frameSize;n++)
754 { 749 {
755 window[n] = 1.0; 750 window[n] = 1.0;
756 } 751 }
757 } 752 }
758 753
761 //////////////////////////////////////////////////////////////////////////////////////////////// 756 ////////////////////////////////////////////////////////////////////////////////////////////////
762 //////////////////////////////////////////////////////////////////////////////////////////////// 757 ////////////////////////////////////////////////////////////////////////////////////////////////
763 ///////////////////////////////// Other Handy Methods ////////////////////////////////////////// 758 ///////////////////////////////// Other Handy Methods //////////////////////////////////////////
764 759
765 //======================================================================= 760 //=======================================================================
766 double OnsetDetectionFunction :: princarg(double phaseval) 761 double OnsetDetectionFunction :: princarg(double phaseVal)
767 { 762 {
768 // if phase value is less than or equal to -pi then add 2*pi 763 // if phase value is less than or equal to -pi then add 2*pi
769 while (phaseval <= (-pi)) 764 while (phaseVal <= (-pi))
770 { 765 {
771 phaseval = phaseval + (2*pi); 766 phaseVal = phaseVal + (2*pi);
772 } 767 }
773 768
774 // if phase value is larger than pi, then subtract 2*pi 769 // if phase value is larger than pi, then subtract 2*pi
775 while (phaseval > pi) 770 while (phaseVal > pi)
776 { 771 {
777 phaseval = phaseval - (2*pi); 772 phaseVal = phaseVal - (2*pi);
778 } 773 }
779 774
780 return phaseval; 775 return phaseVal;
781 } 776 }
782 777
783 778
784 779
785 780
786 781
787 782
788 783
789 784
790 785
791 786
792 787
793 788
794 789