Changeset bfbfafa for src/spectral


Ignore:
Timestamp:
Oct 3, 2017, 10:31:12 PM (7 years ago)
Author:
Paul Brossier <piem@piem.org>
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.
Message:

Merge branch 'master' into dct

File:
1 edited

Legend:

Unmodified
Added
Removed
  • src/spectral/fft.c

    r7b7a58e rbfbfafa  
    7878pthread_mutex_t aubio_fftw_mutex = PTHREAD_MUTEX_INITIALIZER;
    7979
    80 #else
    81 #ifdef HAVE_ACCELERATE        // using ACCELERATE
     80#elif defined HAVE_ACCELERATE        // using ACCELERATE
    8281// https://developer.apple.com/library/mac/#documentation/Accelerate/Reference/vDSPRef/Reference/reference.html
    8382#include <Accelerate/Accelerate.h>
     
    113112#endif /* HAVE_AUBIO_DOUBLE */
    114113
    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
    116140// let's use ooura instead
    117141extern void aubio_ooura_rdft(int, int, smpl_t *, int *, smpl_t *);
    118142
    119 #endif /* HAVE_ACCELERATE */
    120 #endif /* HAVE_FFTW3 */
     143#endif
    121144
    122145struct _aubio_fft_t {
    123146  uint_t winsize;
    124147  uint_t fft_size;
     148
    125149#ifdef HAVE_FFTW3             // using FFTW3
    126150  real_t *in, *out;
    127151  fftw_plan pfw, pbw;
    128   fft_data_t * specdata;      /* complex spectral data */
    129 #else
    130 #ifdef HAVE_ACCELERATE        // using ACCELERATE
     152  fft_data_t * specdata; /* complex spectral data */
     153
     154#elif defined HAVE_ACCELERATE  // using ACCELERATE
    131155  int log2fftsize;
    132156  aubio_FFTSetup fftSetup;
    133157  aubio_DSPSplitComplex spec;
    134158  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;
    135167#else                         // using OOURA
    136168  smpl_t *in, *out;
    137169  smpl_t *w;
    138170  int *ip;
    139 #endif /* HAVE_ACCELERATE */
    140 #endif /* HAVE_FFTW3 */
     171#endif /* using OOURA */
     172
    141173  fvec_t * compspec;
    142174};
     
    148180    goto beach;
    149181  }
     182
    150183#ifdef HAVE_FFTW3
    151184  uint_t i;
     
    176209    s->specdata[i] = 0.;
    177210  }
    178 #else
    179 #ifdef HAVE_ACCELERATE        // using ACCELERATE
     211
     212#elif defined HAVE_ACCELERATE  // using ACCELERATE
    180213  s->winsize = winsize;
    181214  s->fft_size = winsize;
    182215  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);
    184217  s->in = AUBIO_ARRAY(smpl_t, s->fft_size);
    185218  s->out = AUBIO_ARRAY(smpl_t, s->fft_size);
     
    187220  s->spec.imagp = AUBIO_ARRAY(smpl_t, s->fft_size/2);
    188221  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
    189260#else                         // using OOURA
    190261  if (aubio_is_power_of_two(winsize) != 1) {
     
    201272  s->w     = AUBIO_ARRAY(smpl_t, s->fft_size);
    202273  s->ip[0] = 0;
    203 #endif /* HAVE_ACCELERATE */
    204 #endif /* HAVE_FFTW3 */
     274#endif /* using OOURA */
     275
    205276  return s;
     277
    206278beach:
    207279  AUBIO_FREE(s);
     
    211283void del_aubio_fft(aubio_fft_t * s) {
    212284  /* destroy data */
    213   del_fvec(s->compspec);
    214285#ifdef HAVE_FFTW3             // using FFTW3
    215286  pthread_mutex_lock(&aubio_fftw_mutex);
     
    218289  fftw_free(s->specdata);
    219290  pthread_mutex_unlock(&aubio_fftw_mutex);
    220 #else /* HAVE_FFTW3 */
    221 #ifdef HAVE_ACCELERATE        // using ACCELERATE
     291
     292#elif defined HAVE_ACCELERATE // using ACCELERATE
    222293  AUBIO_FREE(s->spec.realp);
    223294  AUBIO_FREE(s->spec.imagp);
    224295  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
    225303#else                         // using OOURA
    226304  AUBIO_FREE(s->w);
    227305  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);
    230310  AUBIO_FREE(s->out);
    231   AUBIO_FREE(s->in);
    232311  AUBIO_FREE(s);
    233312}
     
    252331  memcpy(s->in, input->data, s->winsize * sizeof(smpl_t));
    253332#endif /* HAVE_MEMCPY_HACKS */
     333
    254334#ifdef HAVE_FFTW3             // using FFTW3
    255335  fftw_execute(s->pfw);
     
    266346  }
    267347#endif /* HAVE_COMPLEX_H */
    268 #else /* HAVE_FFTW3 */
    269 #ifdef HAVE_ACCELERATE        // using ACCELERATE
     348
     349#elif defined HAVE_ACCELERATE // using ACCELERATE
    270350  // convert real data to even/odd format used in vDSP
    271351  aubio_vDSP_ctoz((aubio_DSPComplex*)s->in, 2, &s->spec, 1, s->fft_size/2);
     
    282362  smpl_t scale = 1./2.;
    283363  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
    284377#else                         // using OOURA
    285378  aubio_ooura_rdft(s->winsize, 1, s->in, s->ip, s->w);
     
    290383    compspec->data[s->winsize - i] = - s->in[2 * i + 1];
    291384  }
    292 #endif /* HAVE_ACCELERATE */
    293 #endif /* HAVE_FFTW3 */
     385#endif /* using OOURA */
    294386}
    295387
     
    314406    output->data[i] = s->out[i]*renorm;
    315407  }
    316 #else /* HAVE_FFTW3 */
    317 #ifdef HAVE_ACCELERATE        // using ACCELERATE
     408
     409#elif defined HAVE_ACCELERATE // using ACCELERATE
    318410  // convert from real imag  [ r0, r1, ..., rN, iN-1, .., i2, i1]
    319411  // to vDSP packed format   [ r0, rN, r1, i1, ..., rN-1, iN-1 ]
     
    333425  smpl_t scale = 1.0 / s->winsize;
    334426  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
    335444#else                         // using OOURA
    336445  smpl_t scale = 2.0 / s->winsize;
     
    345454    output->data[i] = s->out[i] * scale;
    346455  }
    347 #endif /* HAVE_ACCELERATE */
    348 #endif /* HAVE_FFTW3 */
     456#endif
    349457}
    350458
     
    366474    spectrum->phas[0] = 0.;
    367475  }
     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
    368491  for (i=1; i < spectrum->length - 1; i++) {
    369492    spectrum->phas[i] = ATAN2(compspec->data[compspec->length-i],
    370493        compspec->data[i]);
    371494  }
     495#endif
    372496  if (compspec->data[compspec->length/2] < 0) {
    373497    spectrum->phas[spectrum->length - 1] = PI;
Note: See TracChangeset for help on using the changeset viewer.