Mercurial > hg > btrack
comparison src/OnsetDetectionFunction.cpp @ 93:4aa362058011
Added Kiss FFT option
author | Adam Stark <adamstark.uk@gmail.com> |
---|---|
date | Sat, 18 Jun 2016 09:24:13 +0100 |
parents | f6708e4c69f1 |
children | 6aea5918992d |
comparison
equal
deleted
inserted
replaced
92:f6708e4c69f1 | 93:4aa362058011 |
---|---|
54 //======================================================================= | 54 //======================================================================= |
55 OnsetDetectionFunction::~OnsetDetectionFunction() | 55 OnsetDetectionFunction::~OnsetDetectionFunction() |
56 { | 56 { |
57 if (initialised) | 57 if (initialised) |
58 { | 58 { |
59 // destroy fft plan | 59 freeFFT(); |
60 fftw_destroy_plan (p); | |
61 fftw_free (complexIn); | |
62 fftw_free (complexOut); | |
63 } | 60 } |
64 } | 61 } |
65 | 62 |
66 //======================================================================= | 63 //======================================================================= |
67 void OnsetDetectionFunction::initialise (int hopSize_, int frameSize_) | 64 void OnsetDetectionFunction::initialise (int hopSize_, int frameSize_) |
72 } | 69 } |
73 | 70 |
74 //======================================================================= | 71 //======================================================================= |
75 void OnsetDetectionFunction::initialise(int hopSize_,int frameSize_,int onsetDetectionFunctionType_,int windowType_) | 72 void OnsetDetectionFunction::initialise(int hopSize_,int frameSize_,int onsetDetectionFunctionType_,int windowType_) |
76 { | 73 { |
77 if (initialised) // if we have already initialised FFT plan | |
78 { | |
79 // destroy fft plan | |
80 fftw_destroy_plan (p); | |
81 fftw_free (complexIn); | |
82 fftw_free (complexOut); | |
83 } | |
84 | |
85 hopSize = hopSize_; // set hopsize | 74 hopSize = hopSize_; // set hopsize |
86 frameSize = frameSize_; // set framesize | 75 frameSize = frameSize_; // set framesize |
87 | 76 |
88 onsetDetectionFunctionType = onsetDetectionFunctionType_; // set detection function type | 77 onsetDetectionFunctionType = onsetDetectionFunctionType_; // set detection function type |
89 windowType = windowType_; // set window type | 78 windowType = windowType_; // set window type |
129 frame[i] = 0.0; | 118 frame[i] = 0.0; |
130 } | 119 } |
131 | 120 |
132 prevEnergySum = 0.0; // initialise previous energy sum value to zero | 121 prevEnergySum = 0.0; // initialise previous energy sum value to zero |
133 | 122 |
134 /* Init fft */ | 123 initialiseFFT(); |
135 complexIn = (fftw_complex*) fftw_malloc(sizeof(fftw_complex) * frameSize); // complex array to hold fft data | 124 } |
136 complexOut = (fftw_complex*) fftw_malloc(sizeof(fftw_complex) * frameSize); // complex array to hold fft data | 125 |
137 p = fftw_plan_dft_1d (frameSize, complexIn, complexOut, FFTW_FORWARD, FFTW_ESTIMATE); // FFT plan initialisation | 126 //======================================================================= |
138 | 127 void OnsetDetectionFunction::initialiseFFT() |
139 initialised = true; | 128 { |
129 if (initialised) // if we have already initialised FFT plan | |
130 { | |
131 freeFFT(); | |
132 } | |
133 | |
134 #ifdef USE_FFTW | |
135 complexIn = (fftw_complex*) fftw_malloc (sizeof(fftw_complex) * frameSize); // complex array to hold fft data | |
136 complexOut = (fftw_complex*) fftw_malloc (sizeof(fftw_complex) * frameSize); // complex array to hold fft data | |
137 p = fftw_plan_dft_1d (frameSize, complexIn, complexOut, FFTW_FORWARD, FFTW_ESTIMATE); // FFT plan initialisation | |
138 #endif | |
139 | |
140 #ifdef USE_KISS_FFT | |
141 complexOut.resize (frameSize); | |
142 | |
143 for (int i = 0; i < frameSize;i++) | |
144 { | |
145 complexOut[i].resize(2); | |
146 } | |
147 | |
148 fftIn = new kiss_fft_cpx[frameSize]; | |
149 fftOut = new kiss_fft_cpx[frameSize]; | |
150 cfg = kiss_fft_alloc (frameSize, 0, 0, 0); | |
151 #endif | |
152 | |
153 initialised = true; | |
154 } | |
155 | |
156 //======================================================================= | |
157 void OnsetDetectionFunction::freeFFT() | |
158 { | |
159 #ifdef USE_FFTW | |
160 fftw_destroy_plan (p); | |
161 fftw_free (complexIn); | |
162 fftw_free (complexOut); | |
163 #endif | |
164 | |
165 #ifdef USE_KISS_FFT | |
166 free (cfg); | |
167 delete [] fftIn; | |
168 delete [] fftOut; | |
169 #endif | |
140 } | 170 } |
141 | 171 |
142 //======================================================================= | 172 //======================================================================= |
143 void OnsetDetectionFunction::setOnsetDetectionFunctionType (int onsetDetectionFunctionType_) | 173 void OnsetDetectionFunction::setOnsetDetectionFunctionType (int onsetDetectionFunctionType_) |
144 { | 174 { |
237 | 267 |
238 | 268 |
239 //======================================================================= | 269 //======================================================================= |
240 void OnsetDetectionFunction::performFFT() | 270 void OnsetDetectionFunction::performFFT() |
241 { | 271 { |
242 int fsize2 = (frameSize/2); | 272 int fsize2 = (frameSize/2); |
243 | 273 |
274 #ifdef USE_FFTW | |
244 // window frame and copy to complex array, swapping the first and second half of the signal | 275 // window frame and copy to complex array, swapping the first and second half of the signal |
245 for (int i = 0;i < fsize2;i++) | 276 for (int i = 0;i < fsize2;i++) |
246 { | 277 { |
247 complexIn[i][0] = frame[i+fsize2] * window[i+fsize2]; | 278 complexIn[i][0] = frame[i + fsize2] * window[i + fsize2]; |
248 complexIn[i][1] = 0.0; | 279 complexIn[i][1] = 0.0; |
249 complexIn[i+fsize2][0] = frame[i] * window[i]; | 280 complexIn[i+fsize2][0] = frame[i] * window[i]; |
250 complexIn[i+fsize2][1] = 0.0; | 281 complexIn[i+fsize2][1] = 0.0; |
251 } | 282 } |
252 | 283 |
253 // perform the fft | 284 // perform the fft |
254 fftw_execute (p); | 285 fftw_execute (p); |
286 #endif | |
287 | |
288 #ifdef USE_KISS_FFT | |
289 for (int i = 0; i < fsize2; i++) | |
290 { | |
291 fftIn[i].r = frame[i + fsize2] * window[i + fsize2]; | |
292 fftIn[i].i = 0.0; | |
293 fftIn[i + fsize2].r = frame[i] * window[i]; | |
294 fftIn[i + fsize2].i = 0.0; | |
295 } | |
296 | |
297 // execute kiss fft | |
298 kiss_fft (cfg, fftIn, fftOut); | |
299 | |
300 // store real and imaginary parts of FFT | |
301 for (int i = 0; i < frameSize; i++) | |
302 { | |
303 complexOut[i][0] = fftOut[i].r; | |
304 complexOut[i][1] = fftOut[i].i; | |
305 } | |
306 #endif | |
255 } | 307 } |
256 | 308 |
257 //////////////////////////////////////////////////////////////////////////////////////////////// | 309 //////////////////////////////////////////////////////////////////////////////////////////////// |
258 //////////////////////////////////////////////////////////////////////////////////////////////// | 310 //////////////////////////////////////////////////////////////////////////////////////////////// |
259 ////////////////////////////// Methods for Detection Functions ///////////////////////////////// | 311 ////////////////////////////// Methods for Detection Functions ///////////////////////////////// |
312 performFFT(); | 364 performFFT(); |
313 | 365 |
314 // compute first (N/2)+1 mag values | 366 // compute first (N/2)+1 mag values |
315 for (int i = 0;i < (frameSize/2)+1;i++) | 367 for (int i = 0;i < (frameSize/2)+1;i++) |
316 { | 368 { |
317 magSpec[i] = sqrt (pow (complexOut[i][0],2) + pow (complexOut[i][1],2)); | 369 magSpec[i] = sqrt (pow (complexOut[i][0], 2) + pow (complexOut[i][1], 2)); |
318 } | 370 } |
319 // mag spec symmetric above (N/2)+1 so copy previous values | 371 // mag spec symmetric above (N/2)+1 so copy previous values |
320 for (int i = (frameSize/2)+1; i < frameSize; i++) | 372 for (int i = (frameSize/2)+1; i < frameSize; i++) |
321 { | 373 { |
322 magSpec[i] = magSpec[frameSize-i]; | 374 magSpec[i] = magSpec[frameSize-i]; |
400 | 452 |
401 // compute phase values from fft output and sum deviations | 453 // compute phase values from fft output and sum deviations |
402 for (int i = 0;i < frameSize;i++) | 454 for (int i = 0;i < frameSize;i++) |
403 { | 455 { |
404 // calculate phase value | 456 // calculate phase value |
405 phase[i] = atan2 (complexOut[i][1],complexOut[i][0]); | 457 phase[i] = atan2 (complexOut[i][1], complexOut[i][0]); |
406 | 458 |
407 // calculate magnitude value | 459 // calculate magnitude value |
408 magSpec[i] = sqrt (pow (complexOut[i][0],2) + pow (complexOut[i][1],2)); | 460 magSpec[i] = sqrt (pow (complexOut[i][0],2) + pow (complexOut[i][1],2)); |
409 | 461 |
410 | 462 |
446 | 498 |
447 // compute phase values from fft output and sum deviations | 499 // compute phase values from fft output and sum deviations |
448 for (int i = 0;i < frameSize;i++) | 500 for (int i = 0;i < frameSize;i++) |
449 { | 501 { |
450 // calculate phase value | 502 // calculate phase value |
451 phase[i] = atan2 (complexOut[i][1],complexOut[i][0]); | 503 phase[i] = atan2 (complexOut[i][1], complexOut[i][0]); |
452 | 504 |
453 // calculate magnitude value | 505 // calculate magnitude value |
454 magSpec[i] = sqrt (pow (complexOut[i][0],2) + pow(complexOut[i][1],2)); | 506 magSpec[i] = sqrt (pow (complexOut[i][0],2) + pow(complexOut[i][1],2)); |
455 | 507 |
456 // phase deviation | 508 // phase deviation |
486 | 538 |
487 // compute phase values from fft output and sum deviations | 539 // compute phase values from fft output and sum deviations |
488 for (int i = 0;i < frameSize;i++) | 540 for (int i = 0;i < frameSize;i++) |
489 { | 541 { |
490 // calculate phase value | 542 // calculate phase value |
491 phase[i] = atan2 (complexOut[i][1],complexOut[i][0]); | 543 phase[i] = atan2 (complexOut[i][1], complexOut[i][0]); |
492 | 544 |
493 // calculate magnitude value | 545 // calculate magnitude value |
494 magSpec[i] = sqrt (pow (complexOut[i][0],2) + pow(complexOut[i][1],2)); | 546 magSpec[i] = sqrt (pow (complexOut[i][0],2) + pow(complexOut[i][1],2)); |
495 | 547 |
496 // phase deviation | 548 // phase deviation |