コード例 #1
0
ファイル: noisered.c プロジェクト: Emisense/eTracks
static void FFT(unsigned NumSamples,
         int InverseTransform,
         const float *RealIn, float *ImagIn, float *RealOut, float *ImagOut)
{
  unsigned i;
  double * work = malloc(2 * NumSamples * sizeof(*work));
  for (i = 0; i < 2 * NumSamples; i += 2) {
    work[i] = RealIn[i >> 1];
    work[i + 1] = ImagIn? ImagIn[i >> 1] : 0;
  }
  lsx_safe_cdft(2 * (int)NumSamples, InverseTransform? -1 : 1, work);
  if (InverseTransform) for (i = 0; i < 2 * NumSamples; i += 2) {
    RealOut[i >> 1] = work[i] / NumSamples;
    ImagOut[i >> 1] = work[i + 1] / NumSamples;
  }
  else for (i = 0; i < 2 * NumSamples; i += 2) {
コード例 #2
0
ファイル: bend.c プロジェクト: CaptainHayashi/sox
static int flow(sox_effect_t * effp, const sox_sample_t * ibuf,
                sox_sample_t * obuf, size_t * isamp, size_t * osamp)
{
  priv_t *p = (priv_t *) effp->priv;
  size_t i, len = *isamp = *osamp = min(*isamp, *osamp);
  double magn, phase, tmp, window, real, imag;
  double freqPerBin, expct;
  long k, qpd, index, inFifoLatency, stepSize, fftFrameSize2;
  float pitchShift = p->shift;

  /* set up some handy variables */
  fftFrameSize2 = p->fftFrameSize / 2;
  stepSize = p->fftFrameSize / p->ovsamp;
  freqPerBin = effp->in_signal.rate / p->fftFrameSize;
  expct = 2. * M_PI * (double) stepSize / (double) p->fftFrameSize;
  inFifoLatency = p->fftFrameSize - stepSize;
  if (!p->gRover)
    p->gRover = inFifoLatency;

  /* main processing loop */
  for (i = 0; i < len; i++) {
    SOX_SAMPLE_LOCALS;
    ++p->in_pos;

    /* As long as we have not yet collected enough data just read in */
    p->gInFIFO[p->gRover] = SOX_SAMPLE_TO_FLOAT_32BIT(ibuf[i], effp->clips);
    obuf[i] = SOX_FLOAT_32BIT_TO_SAMPLE(
        p->gOutFIFO[p->gRover - inFifoLatency], effp->clips);
    p->gRover++;

    /* now we have enough data for processing */
    if (p->gRover >= p->fftFrameSize) {
      if (p->bends_pos != p->nbends && p->in_pos >=
          p->bends[p->bends_pos].start + p->bends[p->bends_pos].duration) {
        pitchShift = p->shift *= pow(2., p->bends[p->bends_pos].cents / 1200);
        ++p->bends_pos;
      }
      if (p->bends_pos != p->nbends && p->in_pos >= p->bends[p->bends_pos].start) {
        double progress = (double)(p->in_pos - p->bends[p->bends_pos].start) /
             p->bends[p->bends_pos].duration;
        progress = 1 - cos(M_PI * progress);
        progress *= p->bends[p->bends_pos].cents * (.5 / 1200);
        pitchShift = p->shift * pow(2., progress);
      }

      p->gRover = inFifoLatency;

      /* do windowing and re,im interleave */
      for (k = 0; k < p->fftFrameSize; k++) {
        window = -.5 * cos(2 * M_PI * k / (double) p->fftFrameSize) + .5;
        p->gFFTworksp[2 * k] = p->gInFIFO[k] * window;
        p->gFFTworksp[2 * k + 1] = 0.;
      }

      /* ***************** ANALYSIS ******************* */
      lsx_safe_cdft(2 * p->fftFrameSize, 1, p->gFFTworksp);

      /* this is the analysis step */
      for (k = 0; k <= fftFrameSize2; k++) {
        /* de-interlace FFT buffer */
        real = p->gFFTworksp[2 * k];
        imag = - p->gFFTworksp[2 * k + 1];

        /* compute magnitude and phase */
        magn = 2. * sqrt(real * real + imag * imag);
        phase = atan2(imag, real);

        /* compute phase difference */
        tmp = phase - p->gLastPhase[k];
        p->gLastPhase[k] = phase;

        tmp -= (double) k *expct; /* subtract expected phase difference */

        /* map delta phase into +/- Pi interval */
        qpd = tmp / M_PI;
        if (qpd >= 0)
          qpd += qpd & 1;
        else qpd -= qpd & 1;
        tmp -= M_PI * (double) qpd;

        /* get deviation from bin frequency from the +/- Pi interval */
        tmp = p->ovsamp * tmp / (2. * M_PI);

        /* compute the k-th partials' true frequency */
        tmp = (double) k *freqPerBin + tmp * freqPerBin;

        /* store magnitude and true frequency in analysis arrays */
        p->gAnaMagn[k] = magn;
        p->gAnaFreq[k] = tmp;

      }

      /* this does the actual pitch shifting */
      memset(p->gSynMagn, 0, p->fftFrameSize * sizeof(float));
      memset(p->gSynFreq, 0, p->fftFrameSize * sizeof(float));
      for (k = 0; k <= fftFrameSize2; k++) {
        index = k * pitchShift;
        if (index <= fftFrameSize2) {
          p->gSynMagn[index] += p->gAnaMagn[k];
          p->gSynFreq[index] = p->gAnaFreq[k] * pitchShift;
        }
      }

      for (k = 0; k <= fftFrameSize2; k++) { /* SYNTHESIS */
        /* get magnitude and true frequency from synthesis arrays */
        magn = p->gSynMagn[k], tmp = p->gSynFreq[k];
        tmp -= (double) k *freqPerBin; /* subtract bin mid frequency */
        tmp /= freqPerBin; /* get bin deviation from freq deviation */
        tmp = 2. * M_PI * tmp / p->ovsamp; /* take p->ovsamp into account */
        tmp += (double) k *expct; /* add the overlap phase advance back in */
        p->gSumPhase[k] += tmp; /* accumulate delta phase to get bin phase */
        phase = p->gSumPhase[k];
        /* get real and imag part and re-interleave */
        p->gFFTworksp[2 * k] = magn * cos(phase);
        p->gFFTworksp[2 * k + 1] = - magn * sin(phase);
      }

      for (k = p->fftFrameSize + 2; k < 2 * p->fftFrameSize; k++)
        p->gFFTworksp[k] = 0.; /* zero negative frequencies */

      lsx_safe_cdft(2 * p->fftFrameSize, -1, p->gFFTworksp);

      /* do windowing and add to output accumulator */
      for (k = 0; k < p->fftFrameSize; k++) {
        window =
            -.5 * cos(2. * M_PI * (double) k / (double) p->fftFrameSize) + .5;
        p->gOutputAccum[k] +=
            2. * window * p->gFFTworksp[2 * k] / (fftFrameSize2 * p->ovsamp);
      }
      for (k = 0; k < stepSize; k++)
        p->gOutFIFO[k] = p->gOutputAccum[k];

      memmove(p->gOutputAccum, /* shift accumulator */
          p->gOutputAccum + stepSize, p->fftFrameSize * sizeof(float));

      for (k = 0; k < inFifoLatency; k++) /* move input FIFO */
        p->gInFIFO[k] = p->gInFIFO[k + stepSize];
    }
  }
  return SOX_SUCCESS;
}