Changeset bfbfafa for src/spectral
- Timestamp:
- Oct 3, 2017, 10:31:12 PM (7 years ago)
- Branches:
- feature/autosink, feature/cnn, feature/cnn_org, feature/constantq, feature/crepe, feature/crepe_org, feature/pitchshift, feature/pydocstrings, feature/timestretch, fix/ffmpeg5, master
- Children:
- 2e5c52e
- Parents:
- 7b7a58e (diff), 25db68c (diff)
Note: this is a merge changeset, the changes displayed below correspond to the merge itself.
Use the(diff)
links above to see all the changes relative to each parent. - File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
src/spectral/fft.c
r7b7a58e rbfbfafa 78 78 pthread_mutex_t aubio_fftw_mutex = PTHREAD_MUTEX_INITIALIZER; 79 79 80 #else 81 #ifdef HAVE_ACCELERATE // using ACCELERATE 80 #elif defined HAVE_ACCELERATE // using ACCELERATE 82 81 // https://developer.apple.com/library/mac/#documentation/Accelerate/Reference/vDSPRef/Reference/reference.html 83 82 #include <Accelerate/Accelerate.h> … … 113 112 #endif /* HAVE_AUBIO_DOUBLE */ 114 113 115 #else // using OOURA 114 #elif defined HAVE_INTEL_IPP // using INTEL IPP 115 116 #if !HAVE_AUBIO_DOUBLE 117 #define aubio_IppFloat Ipp32f 118 #define aubio_IppComplex Ipp32fc 119 #define aubio_FFTSpec FFTSpec_R_32f 120 #define aubio_ippsMalloc_complex ippsMalloc_32fc 121 #define aubio_ippsFFTInit_R ippsFFTInit_R_32f 122 #define aubio_ippsFFTGetSize_R ippsFFTGetSize_R_32f 123 #define aubio_ippsFFTInv_CCSToR ippsFFTInv_CCSToR_32f 124 #define aubio_ippsFFTFwd_RToCCS ippsFFTFwd_RToCCS_32f 125 #define aubio_ippsAtan2 ippsAtan2_32f_A21 126 #else /* HAVE_AUBIO_DOUBLE */ 127 #define aubio_IppFloat Ipp64f 128 #define aubio_IppComplex Ipp64fc 129 #define aubio_FFTSpec FFTSpec_R_64f 130 #define aubio_ippsMalloc_complex ippsMalloc_64fc 131 #define aubio_ippsFFTInit_R ippsFFTInit_R_64f 132 #define aubio_ippsFFTGetSize_R ippsFFTGetSize_R_64f 133 #define aubio_ippsFFTInv_CCSToR ippsFFTInv_CCSToR_64f 134 #define aubio_ippsFFTFwd_RToCCS ippsFFTFwd_RToCCS_64f 135 #define aubio_ippsAtan2 ippsAtan2_64f_A50 136 #endif 137 138 139 #else // using OOURA 116 140 // let's use ooura instead 117 141 extern void aubio_ooura_rdft(int, int, smpl_t *, int *, smpl_t *); 118 142 119 #endif /* HAVE_ACCELERATE */ 120 #endif /* HAVE_FFTW3 */ 143 #endif 121 144 122 145 struct _aubio_fft_t { 123 146 uint_t winsize; 124 147 uint_t fft_size; 148 125 149 #ifdef HAVE_FFTW3 // using FFTW3 126 150 real_t *in, *out; 127 151 fftw_plan pfw, pbw; 128 fft_data_t * specdata; 129 #else 130 # ifdef HAVE_ACCELERATE// using ACCELERATE152 fft_data_t * specdata; /* complex spectral data */ 153 154 #elif defined HAVE_ACCELERATE // using ACCELERATE 131 155 int log2fftsize; 132 156 aubio_FFTSetup fftSetup; 133 157 aubio_DSPSplitComplex spec; 134 158 smpl_t *in, *out; 159 160 #elif defined HAVE_INTEL_IPP // using Intel IPP 161 smpl_t *in, *out; 162 Ipp8u* memSpec; 163 Ipp8u* memInit; 164 Ipp8u* memBuffer; 165 struct aubio_FFTSpec* fftSpec; 166 aubio_IppComplex* complexOut; 135 167 #else // using OOURA 136 168 smpl_t *in, *out; 137 169 smpl_t *w; 138 170 int *ip; 139 #endif /* HAVE_ACCELERATE*/140 #endif /* HAVE_FFTW3 */ 171 #endif /* using OOURA */ 172 141 173 fvec_t * compspec; 142 174 }; … … 148 180 goto beach; 149 181 } 182 150 183 #ifdef HAVE_FFTW3 151 184 uint_t i; … … 176 209 s->specdata[i] = 0.; 177 210 } 178 #else 179 # ifdef HAVE_ACCELERATE// using ACCELERATE211 212 #elif defined HAVE_ACCELERATE // using ACCELERATE 180 213 s->winsize = winsize; 181 214 s->fft_size = winsize; 182 215 s->compspec = new_fvec(winsize); 183 s->log2fftsize = (uint_t)log2f(s->fft_size);216 s->log2fftsize = aubio_power_of_two_order(s->fft_size); 184 217 s->in = AUBIO_ARRAY(smpl_t, s->fft_size); 185 218 s->out = AUBIO_ARRAY(smpl_t, s->fft_size); … … 187 220 s->spec.imagp = AUBIO_ARRAY(smpl_t, s->fft_size/2); 188 221 s->fftSetup = aubio_vDSP_create_fftsetup(s->log2fftsize, FFT_RADIX2); 222 223 #elif defined HAVE_INTEL_IPP // using Intel IPP 224 const IppHintAlgorithm qualityHint = ippAlgHintAccurate; // OR ippAlgHintFast; 225 const int flags = IPP_FFT_NODIV_BY_ANY; // we're scaling manually afterwards 226 int order = aubio_power_of_two_order(winsize); 227 int sizeSpec, sizeInit, sizeBuffer; 228 IppStatus status; 229 230 if (winsize <= 4 || aubio_is_power_of_two(winsize) != 1) 231 { 232 AUBIO_ERR("intel IPP fft: can only create with sizes > 4 and power of two, requested %d," 233 " try recompiling aubio with --enable-fftw3\n", winsize); 234 goto beach; 235 } 236 237 status = aubio_ippsFFTGetSize_R(order, flags, qualityHint, 238 &sizeSpec, &sizeInit, &sizeBuffer); 239 if (status != ippStsNoErr) { 240 AUBIO_ERR("fft: failed to initialize fft. IPP error: %d\n", status); 241 goto beach; 242 } 243 s->fft_size = s->winsize = winsize; 244 s->compspec = new_fvec(winsize); 245 s->in = AUBIO_ARRAY(smpl_t, s->winsize); 246 s->out = AUBIO_ARRAY(smpl_t, s->winsize); 247 s->memSpec = ippsMalloc_8u(sizeSpec); 248 s->memBuffer = ippsMalloc_8u(sizeBuffer); 249 if (sizeInit > 0 ) { 250 s->memInit = ippsMalloc_8u(sizeInit); 251 } 252 s->complexOut = aubio_ippsMalloc_complex(s->fft_size / 2 + 1); 253 status = aubio_ippsFFTInit_R( 254 &s->fftSpec, order, flags, qualityHint, s->memSpec, s->memInit); 255 if (status != ippStsNoErr) { 256 AUBIO_ERR("fft: failed to initialize. IPP error: %d\n", status); 257 goto beach; 258 } 259 189 260 #else // using OOURA 190 261 if (aubio_is_power_of_two(winsize) != 1) { … … 201 272 s->w = AUBIO_ARRAY(smpl_t, s->fft_size); 202 273 s->ip[0] = 0; 203 #endif /* HAVE_ACCELERATE*/204 #endif /* HAVE_FFTW3 */ 274 #endif /* using OOURA */ 275 205 276 return s; 277 206 278 beach: 207 279 AUBIO_FREE(s); … … 211 283 void del_aubio_fft(aubio_fft_t * s) { 212 284 /* destroy data */ 213 del_fvec(s->compspec);214 285 #ifdef HAVE_FFTW3 // using FFTW3 215 286 pthread_mutex_lock(&aubio_fftw_mutex); … … 218 289 fftw_free(s->specdata); 219 290 pthread_mutex_unlock(&aubio_fftw_mutex); 220 #else /* HAVE_FFTW3 */ 221 # ifdef HAVE_ACCELERATE// using ACCELERATE291 292 #elif defined HAVE_ACCELERATE // using ACCELERATE 222 293 AUBIO_FREE(s->spec.realp); 223 294 AUBIO_FREE(s->spec.imagp); 224 295 aubio_vDSP_destroy_fftsetup(s->fftSetup); 296 297 #elif defined HAVE_INTEL_IPP // using Intel IPP 298 ippFree(s->memSpec); 299 ippFree(s->memInit); 300 ippFree(s->memBuffer); 301 ippFree(s->complexOut); 302 225 303 #else // using OOURA 226 304 AUBIO_FREE(s->w); 227 305 AUBIO_FREE(s->ip); 228 #endif /* HAVE_ACCELERATE */ 229 #endif /* HAVE_FFTW3 */ 306 #endif 307 308 del_fvec(s->compspec); 309 AUBIO_FREE(s->in); 230 310 AUBIO_FREE(s->out); 231 AUBIO_FREE(s->in);232 311 AUBIO_FREE(s); 233 312 } … … 252 331 memcpy(s->in, input->data, s->winsize * sizeof(smpl_t)); 253 332 #endif /* HAVE_MEMCPY_HACKS */ 333 254 334 #ifdef HAVE_FFTW3 // using FFTW3 255 335 fftw_execute(s->pfw); … … 266 346 } 267 347 #endif /* HAVE_COMPLEX_H */ 268 #else /* HAVE_FFTW3 */ 269 # ifdef HAVE_ACCELERATE// using ACCELERATE348 349 #elif defined HAVE_ACCELERATE // using ACCELERATE 270 350 // convert real data to even/odd format used in vDSP 271 351 aubio_vDSP_ctoz((aubio_DSPComplex*)s->in, 2, &s->spec, 1, s->fft_size/2); … … 282 362 smpl_t scale = 1./2.; 283 363 aubio_vDSP_vsmul(compspec->data, 1, &scale, compspec->data, 1, s->fft_size); 364 365 #elif defined HAVE_INTEL_IPP // using Intel IPP 366 367 // apply fft 368 aubio_ippsFFTFwd_RToCCS(s->in, (aubio_IppFloat*)s->complexOut, s->fftSpec, s->memBuffer); 369 // convert complex buffer to [ r0, r1, ..., rN, iN-1, .., i2, i1] 370 compspec->data[0] = s->complexOut[0].re; 371 compspec->data[s->fft_size / 2] = s->complexOut[s->fft_size / 2].re; 372 for (i = 1; i < s->fft_size / 2; i++) { 373 compspec->data[i] = s->complexOut[i].re; 374 compspec->data[s->fft_size - i] = s->complexOut[i].im; 375 } 376 284 377 #else // using OOURA 285 378 aubio_ooura_rdft(s->winsize, 1, s->in, s->ip, s->w); … … 290 383 compspec->data[s->winsize - i] = - s->in[2 * i + 1]; 291 384 } 292 #endif /* HAVE_ACCELERATE */ 293 #endif /* HAVE_FFTW3 */ 385 #endif /* using OOURA */ 294 386 } 295 387 … … 314 406 output->data[i] = s->out[i]*renorm; 315 407 } 316 #else /* HAVE_FFTW3 */ 317 # ifdef HAVE_ACCELERATE// using ACCELERATE408 409 #elif defined HAVE_ACCELERATE // using ACCELERATE 318 410 // convert from real imag [ r0, r1, ..., rN, iN-1, .., i2, i1] 319 411 // to vDSP packed format [ r0, rN, r1, i1, ..., rN-1, iN-1 ] … … 333 425 smpl_t scale = 1.0 / s->winsize; 334 426 aubio_vDSP_vsmul(output->data, 1, &scale, output->data, 1, s->fft_size); 427 428 #elif defined HAVE_INTEL_IPP // using Intel IPP 429 430 // convert from real imag [ r0, 0, ..., rN, iN-1, .., i2, i1, iN-1] to complex format 431 s->complexOut[0].re = compspec->data[0]; 432 s->complexOut[0].im = 0; 433 s->complexOut[s->fft_size / 2].re = compspec->data[s->fft_size / 2]; 434 s->complexOut[s->fft_size / 2].im = 0.0; 435 for (i = 1; i < s->fft_size / 2; i++) { 436 s->complexOut[i].re = compspec->data[i]; 437 s->complexOut[i].im = compspec->data[s->fft_size - i]; 438 } 439 // apply fft 440 aubio_ippsFFTInv_CCSToR((const aubio_IppFloat *)s->complexOut, output->data, s->fftSpec, s->memBuffer); 441 // apply scaling 442 aubio_ippsMulC(output->data, 1.0 / s->winsize, output->data, s->fft_size); 443 335 444 #else // using OOURA 336 445 smpl_t scale = 2.0 / s->winsize; … … 345 454 output->data[i] = s->out[i] * scale; 346 455 } 347 #endif /* HAVE_ACCELERATE */ 348 #endif /* HAVE_FFTW3 */ 456 #endif 349 457 } 350 458 … … 366 474 spectrum->phas[0] = 0.; 367 475 } 476 #if defined(HAVE_INTEL_IPP) 477 // convert from real imag [ r0, r1, ..., rN, iN-1, ..., i2, i1, i0] 478 // to [ r0, r1, ..., rN, i0, i1, i2, ..., iN-1] 479 for (i = 1; i < spectrum->length / 2; i++) { 480 ELEM_SWAP(compspec->data[compspec->length - i], 481 compspec->data[spectrum->length + i - 1]); 482 } 483 aubio_ippsAtan2(compspec->data + spectrum->length, 484 compspec->data + 1, spectrum->phas + 1, spectrum->length - 1); 485 // revert the imaginary part back again 486 for (i = 1; i < spectrum->length / 2; i++) { 487 ELEM_SWAP(compspec->data[spectrum->length + i - 1], 488 compspec->data[compspec->length - i]); 489 } 490 #else 368 491 for (i=1; i < spectrum->length - 1; i++) { 369 492 spectrum->phas[i] = ATAN2(compspec->data[compspec->length-i], 370 493 compspec->data[i]); 371 494 } 495 #endif 372 496 if (compspec->data[compspec->length/2] < 0) { 373 497 spectrum->phas[spectrum->length - 1] = PI;
Note: See TracChangeset
for help on using the changeset viewer.