Exemplo n.º 1
0
static int ifft(fixed fr[], fixed fi[], int m)
{
  int mr, nn, i, j, l, k, istep, n, scale, shift;
  fixed qr, qi, tr, ti, wr, wi;

  n = 1 << m;

  if (n > N_WAVE)
    return -1;

  mr = 0;
  nn = n - 1;
  scale = 0;

  /* decimation in time - re-order data */
  for (m = 1; m <= nn; ++m) {
    l = n;
    do {
      l >>= 1;
    } while (mr + l > nn);
    mr = (mr & (l - 1)) + l;

    if (mr <= m)
      continue;
    tr = fr[m];
    fr[m] = fr[mr];
    fr[mr] = tr;
    ti = fi[m];
    fi[m] = fi[mr];
    fi[mr] = ti;
  }

  l = 1;
  k = LOG2_N_WAVE - 1;
  while (l < n) {
    /* variable scaling, depending upon data */
    shift = 0;
    for (i = 0; i < n; ++i) {
      j = fr[i];
      if (j < 0)
	j = -j;
      m = fi[i];
      if (m < 0)
	m = -m;
      if (j > 16383 || m > 16383) {
	shift = 1;
	break;
      }
    }
    if (shift)
      ++scale;
    /* it may not be obvious, but the shift will be performed
       on each data point exactly once, during this pass. */
    istep = l << 1;
    for (m = 0; m < l; ++m) {
      j = m << k;
      /* 0 <= j < N_WAVE/2 */
      wr = Sinewave[j + N_WAVE / 4];
      wi = -Sinewave[j];
      wi = -wi;
      if (shift) {
	wr >>= 1;
	wi >>= 1;
      }
      for (i = m; i < n; i += istep) {
	j = i + l;
	tr = fix_mpy(wr, fr[j]) - fix_mpy(wi, fi[j]);
	ti = fix_mpy(wr, fi[j]) + fix_mpy(wi, fr[j]);
	qr = fr[i];
	qi = fi[i];
	if (shift) {
	  qr >>= 1;
	  qi >>= 1;
	}
	fr[j] = qr - tr;
	fi[j] = qi - ti;
	fr[i] = qr + tr;
	fi[i] = qi + ti;
      }
    }
    --k;
    l = istep;
  }

  return scale;
}
Exemplo n.º 2
0
__IRAM_CODE static int fft(fixed fr[], fixed fi[], int m)
{
  int mr, nn, i, j, l, k, istep, n;
  fixed qr, qi, wr, wi;

  n = 1 << m;

  if (n > N_WAVE)
    return -1;

  mr = 0;
  nn = n - 1;

  /* decimation in time - re-order data */
  for (m = 1; m <= nn; ++m) {
    fixed tmp;
    l = n;
    do {
      l >>= 1;
    } while (mr + l > nn);
    mr = (mr & (l - 1)) + l;

    if (mr <= m)
      continue;
    tmp = fr[m];
    fr[m] = fr[mr];
    fr[mr] = tmp;
    tmp = fi[m];
    fi[m] = fi[mr];
    fi[mr] = tmp;
  }

  l = 1;
  k = LOG2_N_WAVE - 1;
  while (l < n) {
    /* fixed scaling, for proper normalization -
       there will be log2(n) passes, so this
       results in an overall factor of 1/n,
       distributed to maximize arithmetic accuracy. */
    istep = l << 1;
    for (m = 0; m < l; ++m) {
      j = m << k;
      /* 0 <= j < N_WAVE/2 */
      wr = Sinewave[j + N_WAVE / 4];
      wi = -Sinewave[j];
      wr >>= 1;
      wi >>= 1;
      for (i = m; i < n; i += istep) {
	fixed tr,ti;
	j = i + l;
	tr = fix_mpy(wr, fr[j]) - fix_mpy(wi, fi[j]);
	ti = fix_mpy(wr, fi[j]) + fix_mpy(wi, fr[j]);
	qr = fr[i];
	qi = fi[i];
	qr >>= 1;
	qi >>= 1;
	fr[j] = qr - tr;
	fi[j] = qi - ti;
	fr[i] = qr + tr;
	fi[i] = qi + ti;
      }
    }
    --k;
    l = istep;
  }
  return 0;
}
Exemplo n.º 3
0
/*
        fix_fft() - perform fast Fourier transform.

        if n>0 FFT is done, if n<0 inverse FFT is done
        f[n] is a complex array, INPUT AND RESULT.
        size of data = 2**m
        set inverse to 0=dft, 1=idft
*/
int fix_fft(fixed f[], int m, int inverse)
{
        int mr,nn,i,j,l,k,istep, n, scale, shift;
        fixed qr,qi,tr,ti,wr,wi,t;

                n = 1<<m;

        if(n > N_WAVE)
                return -1;

        mr = 0;
        nn = n - 1;
        scale = 0;

        /* decimation in time - re-order data */
        for(m=1; m<=nn; ++m) {
                l = n;
                do {
                        l >>= 1;
                } while(mr+l > nn);
                mr = (mr & (l-1)) + l;

                if(mr <= m) continue;
                tr = f[m<<1];
                f[m<<1] = f[mr<<1];
                f[mr<<1] = tr;
                ti = f[1+(m<<1)];
                f[1+(m<<1)] = f[1+(mr<<1)];
                f[1+(mr<<1)] = ti;
        }

        l = 1;
        k = LOG2_N_WAVE-1;
        while(l < n) {
                if(inverse) {
                        /* variable scaling, depending upon data */
                        shift = 0;
                        for(i=0; i<n; ++i) {
                                j = f[i<<1];
                                if(j < 0)
                                        j = -j;
                                m = f[1+(i<<1)];
                                if(m < 0)
                                        m = -m;
                                if(j > 16383 || m > 16383) {
                                        shift = 1;
                                        break;
                                }
                        }
                        if(shift)
                                ++scale;
                } else {
                        /* fixed scaling, for proper normalization -
                           there will be log2(n) passes, so this
                           results in an overall factor of 1/n,
                           distributed to maximize arithmetic accuracy. */
                        shift = 1;
                }
                /* it may not be obvious, but the shift will be performed
                   on each data point exactly once, during this pass. */
                istep = l << 1;
                for(m=0; m<l; ++m) {
                        j = m << k;
                        /* 0 <= j < N_WAVE/2 */
                        wr =  Sinewave[j+N_WAVE/4];
                        wi = -Sinewave[j];
                        if(inverse)
                                wi = -wi;
                        if(shift) {
                                wr >>= 1;
                                wi >>= 1;
                        }
                        for(i=m; i<n; i+=istep) {
                                j = i + l;
                                        tr = fix_mpy(wr,f[j<<1]) -
fix_mpy(wi,f[1+(j<<1)]);
                                        ti = fix_mpy(wr,f[1+(j<<1)]) +
fix_mpy(wi,f[j<<1]);
                                qr = f[i<<1];
                                qi = f[1+(i<<1)];
                                if(shift) {
                                        qr >>= 1;
                                        qi >>= 1;
                                }
                                f[j<<1] = qr - tr;
                                f[1+(j<<1)] = qi - ti;
                                f[i<<1] = qr + tr;
                                f[1+(i<<1)] = qi + ti;
                        }
                }
                --k;
                l = istep;
        }

        return scale;
}