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