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