void FFT(int NumSamples,
         bool InverseTransform,
         float *RealIn, float *ImagIn, float *RealOut, float *ImagOut)
{
	int NumBits;                 /* Number of bits needed to store indices */
	int i, j, k, n;
	int BlockSize, BlockEnd;
	
	double angle_numerator = 2.0 * M_PI;
	float tr, ti;                /* temp real, temp imaginary */
	
	if (!IsPowerOfTwo(NumSamples)) {
		fprintf(stderr, "%d is not a power of two\n", NumSamples);
		exit(1);
	}
	
	if (!gFFTBitTable)
		InitFFT();
	
	if (InverseTransform)
		angle_numerator = -angle_numerator;
	
	NumBits = NumberOfBitsNeeded(NumSamples);
	
	/*
	 **   Do simultaneous data copy and bit-reversal ordering into outputs...
	 */
	
	for (i = 0; i < NumSamples; i++) {
		j = FastReverseBits(i, NumBits);
		RealOut[j] = RealIn[i];
		ImagOut[j] = (ImagIn == NULL) ? 0.0 : ImagIn[i];
	}
	
	/*
	 **   Do the FFT itself...
	 */
	
	BlockEnd = 1;
	for (BlockSize = 2; BlockSize <= NumSamples; BlockSize <<= 1) {
		
		double delta_angle = angle_numerator / (double) BlockSize;
		
		float sm2 = sin(-2 * delta_angle);
		float sm1 = sin(-delta_angle);
		float cm2 = cos(-2 * delta_angle);
		float cm1 = cos(-delta_angle);
		float w = 2 * cm1;
		float ar0, ar1, ar2, ai0, ai1, ai2;
		
		for (i = 0; i < NumSamples; i += BlockSize) {
			ar2 = cm2;
			ar1 = cm1;
			
			ai2 = sm2;
			ai1 = sm1;
			
			for (j = i, n = 0; n < BlockEnd; j++, n++) {
				ar0 = w * ar1 - ar2;
				ar2 = ar1;
				ar1 = ar0;
				
				ai0 = w * ai1 - ai2;
				ai2 = ai1;
				ai1 = ai0;
				
				k = j + BlockEnd;
				tr = ar0 * RealOut[k] - ai0 * ImagOut[k];
				ti = ar0 * ImagOut[k] + ai0 * RealOut[k];
				
				RealOut[k] = RealOut[j] - tr;
				ImagOut[k] = ImagOut[j] - ti;
				
				RealOut[j] += tr;
				ImagOut[j] += ti;
			}
		}
		
		BlockEnd = BlockSize;
	}
	
	/*
	 **   Need to normalize if inverse transform...
	 */
	
	if (InverseTransform) {
		float denom = (float) NumSamples;
		
		for (i = 0; i < NumSamples; i++) {
			RealOut[i] /= denom;
			ImagOut[i] /= denom;
		}
	}
}
예제 #2
0
void fft_double (unsigned int p_nSamples, bool p_bInverseTransform, double *p_lpRealIn, double *p_lpImagIn, double *p_lpRealOut, double *p_lpImagOut)
{

	if(!p_lpRealIn || !p_lpRealOut || !p_lpImagOut) return;


	unsigned int NumBits;
	unsigned int i, j, k, n;
	unsigned int BlockSize, BlockEnd;

	double angle_numerator = 2.0 * PI;
	double tr, ti;

	if( !IsPowerOfTwo(p_nSamples) )
	{
		return;
	}

	if( p_bInverseTransform ) angle_numerator = -angle_numerator;

	NumBits = NumberOfBitsNeeded ( p_nSamples );


	for( i=0; i < p_nSamples; i++ )
	{
		j = ReverseBits ( i, NumBits );
		p_lpRealOut[j] = p_lpRealIn[i];
		p_lpImagOut[j] = (p_lpImagIn == NULL) ? 0.0 : p_lpImagIn[i];
	}


	BlockEnd = 1;
	for( BlockSize = 2; BlockSize <= p_nSamples; BlockSize <<= 1 )
	{
		double delta_angle = angle_numerator / (double)BlockSize;
		double sm2 = sin ( -2 * delta_angle );
		double sm1 = sin ( -delta_angle );
		double cm2 = cos ( -2 * delta_angle );
		double cm1 = cos ( -delta_angle );
		double w = 2 * cm1;
		double ar[3], ai[3];

		for( i=0; i < p_nSamples; i += BlockSize )
		{

			ar[2] = cm2;
			ar[1] = cm1;

			ai[2] = sm2;
			ai[1] = sm1;

			for ( j=i, n=0; n < BlockEnd; j++, n++ )
			{

				ar[0] = w*ar[1] - ar[2];
				ar[2] = ar[1];
				ar[1] = ar[0];

				ai[0] = w*ai[1] - ai[2];
				ai[2] = ai[1];
				ai[1] = ai[0];

				k = j + BlockEnd;
				tr = ar[0]*p_lpRealOut[k] - ai[0]*p_lpImagOut[k];
				ti = ar[0]*p_lpImagOut[k] + ai[0]*p_lpRealOut[k];

				p_lpRealOut[k] = p_lpRealOut[j] - tr;
				p_lpImagOut[k] = p_lpImagOut[j] - ti;

				p_lpRealOut[j] += tr;
				p_lpImagOut[j] += ti;

			}
		}

		BlockEnd = BlockSize;

	}


	if( p_bInverseTransform )
	{
		double denom = (double)p_nSamples;

		for ( i=0; i < p_nSamples; i++ )
		{
			p_lpRealOut[i] /= denom;
			p_lpImagOut[i] /= denom;
		}
	}

}
예제 #3
0
파일: Fft.cpp 프로젝트: crespo2014/cpp-lib
void CFft::FftDouble(unsigned int NumSamples, int InverseTransform, double *RealIn, double *ImagIn, double *RealOut, double *ImagOut)
{

	double PI=3.14;
    unsigned int NumBits;    /* Number of bits needed to store indices */
    unsigned int i, j, k, n;
    unsigned int BlockSize, BlockEnd;

    double angle_numerator = 2.0 * PI;
    double tr, ti;     /* temp real, temp imaginary */

    if ( !IsPowerOfTwo(NumSamples) )
    {
        fprintf (
            stderr,
            "Error in fft():  NumSamples=%u is not power of two\n",
            NumSamples );

        exit(1);
    }

    if ( InverseTransform )
        angle_numerator = -angle_numerator;

    
NumBits = NumberOfBitsNeeded ( NumSamples );

    /*
    **   Do simultaneous data copy and bit-reversal ordering into outputs...
    */

    for ( i=0; i < NumSamples; i++ )
    {
        j = ReverseBits ( i, NumBits );
        RealOut[j] = RealIn[i];
        ImagOut[j] = (ImagIn == NULL) ? 0.0 : ImagIn[i];
    }

    /*
    **   Do the FFT itself...
    */

    BlockEnd = 1;
    for ( BlockSize = 2; BlockSize <= NumSamples; BlockSize <<= 1 )
    {
        double delta_angle = angle_numerator / (double)BlockSize;
        double sm2 = sin ( -2 * delta_angle );
        double sm1 = sin ( -delta_angle );
        double cm2 = cos ( -2 * delta_angle );
        double cm1 = cos ( -delta_angle );
        double w = 2 * cm1;
        double ar[3], ai[3];

        for ( i=0; i < NumSamples; i += BlockSize )
        {
            ar[2] = cm2;
            ar[1] = cm1;

            ai[2] = sm2;
            ai[1] = sm1;

            for ( j=i, n=0; n < BlockEnd; j++, n++ )
            {
                ar[0] = w*ar[1] - ar[2];
                ar[2] = ar[1];
                ar[1] = ar[0];

                ai[0] = w*ai[1] - ai[2];
                ai[2] = ai[1];
                ai[1] = ai[0];

                k = j + BlockEnd;
                tr = ar[0]*RealOut[k] - ai[0]*ImagOut[k];
                ti = ar[0]*ImagOut[k] + ai[0]*RealOut[k];

                RealOut[k] = RealOut[j] - tr;
                ImagOut[k] = ImagOut[j] - ti;

                RealOut[j] += tr;
                ImagOut[j] += ti;
            }
        }

        BlockEnd = BlockSize;
    }

    /*
    **   Need to normalize if inverse transform...
    */

    if ( InverseTransform )
    {
        double denom = (double)NumSamples;

        for ( i=0; i < NumSamples; i++ )
        {
            RealOut[i] /= denom;
            ImagOut[i] /= denom;
        }
    }
	
}
예제 #4
0
파일: fft.cpp 프로젝트: Azpidatziak/Aegisub
/// @brief Transform
/// @param n_samples
/// @param input
/// @param output_r
/// @param output_i
/// @param inverse
///
void FFT::DoTransform (size_t n_samples,float *input,float *output_r,float *output_i,bool inverse) {
	// Check if it's power of two
	if (!IsPowerOfTwo(n_samples)) {
		throw "FFT requires power of two input.";
	}

	// Inverse transform
	float angle_num = 2.0f * 3.1415926535897932384626433832795f;
	if (inverse) angle_num = -angle_num;

	// Variables
	unsigned int i, j, k, n;
	float tr, ti;

	// Calculate needed bits
	unsigned int NumBits;
	NumBits = NumberOfBitsNeeded(n_samples);

	// Copy samples to output buffers
	for (i=0;i<n_samples;i++) {
		j = ReverseBits (i,NumBits);
		output_r[j] = input[i];
		output_i[j] = 0.0f;
	}

	unsigned int BlockEnd = 1;
	unsigned int BlockSize;
	for (BlockSize = 2;BlockSize<=n_samples;BlockSize<<=1) {
		// Calculate variables for this iteration
		float delta_angle = angle_num / (float)BlockSize;
		float sm2 = sin (-2 * delta_angle);
		float sm1 = sin (-delta_angle);
		float cm2 = cos (-2 * delta_angle);
		float cm1 = cos (-delta_angle);
		float w = 2 * cm1;
		float ar0, ar1, ar2, ai0, ai1, ai2;

		// Apply for every sample
		for(i=0;i<n_samples;i+=BlockSize) {
			ar1 = cm1;
			ar2 = cm2;
			ai1 = sm1;
			ai2 = sm2;

			for (j=i,n=0;n<BlockEnd;j++,n++) {
				k = j + BlockEnd;

				ar0 = w*ar1 - ar2;
				ai0 = w*ai1 - ai2;
				ar2 = ar1;
				ai2 = ai1;
				ar1 = ar0;
				ai1 = ai0;

				tr = ar0*output_r[k] - ai0*output_i[k];
				ti = ar0*output_i[k] + ai0*output_r[k];

				output_r[k] = output_r[j] - tr;
				output_i[k] = output_i[j] - ti;

				output_r[j] += tr;
				output_i[j] += ti;
			}
		}

		// Set next block end to current size
		BlockEnd = BlockSize;
	}

	// Divide everything by number of samples if it's an inverse transform
	if (inverse) {
		float denom = 1.0f/(float)n_samples;
		for (i=0;i<n_samples;i++) {
			output_r[i] *= denom;
			output_i[i] *= denom;
		}
	}
}
예제 #5
0
extern void fft_float(
  _UINT32 __NumSamples,
  _INT32 __InverseTransform,
  _IEEE32 * __RealIn,
  _IEEE32 * __ImagIn,
  _IEEE32 * __RealOut,
  _IEEE32 * __ImagOut)
{
  
  register _INT32 _w2c___comma;
  register _UINT32 _w2c___comma0;
  register _INT32 _w2c___ompv_ok_to_fork;
  register _UINT64 _w2c_reg3;
  register _UINT32 _w2c___comma1;
  register _IEEE32 _w2c___cselect;
  register _IEEE64 _w2c___comma2;
  register _IEEE64 _w2c___comma3;
  register _IEEE64 _w2c___comma4;
  register _INT32 _w2c_trip_count;
  register _INT32 _w2c___ompv_ok_to_fork0;
  _IEEE64 delta_angle;
  _IEEE64 denom;
  _INT32 __localized_common_i;
  _INT32 __localized_common_j;
  _INT32 _w2c___localized_common_i0;
  _IEEE64 __localized_common_ar[3LL];
  _IEEE64 __localized_common_ai[3LL];
  _INT32 _w2c___localized_common_j0;
  _INT32 __localized_common_n;
  _INT32 __ompv_gtid_s1;
  
  /*Begin_of_nested_PU(s)*/
  
  NumSamples = __NumSamples;
  InverseTransform = __InverseTransform;
  * RealIn = *__RealIn;
  * ImagIn = *__ImagIn;
  * RealOut = *__RealOut;
  * ImagOut = *__ImagOut;
  _w2c___comma = IsPowerOfTwo(NumSamples);
  if(_w2c___comma == 0)
  {
    printf("Error in fft():  NumSamples=%u is not power of two\n", NumSamples);
    exit(1);
  }
  if(InverseTransform != 0)
  {
    angle_numerator = -angle_numerator;
  }
  CheckPointer(RealIn, "RealIn");
  CheckPointer(RealOut, "RealOut");
  CheckPointer(ImagOut, "ImagOut");
  _w2c___comma0 = NumberOfBitsNeeded(NumSamples);
  NumBits = _w2c___comma0;
  _w2c___ompv_ok_to_fork = 1;
  if(_w2c___ompv_ok_to_fork)
  {
    _w2c___ompv_ok_to_fork = __ompc_can_fork();
  }
  if(_w2c___ompv_ok_to_fork)
  {
    __ompc_fork(0, &__omprg_fft_float_1, _w2c_reg3);
  }
  else
  {
    __ompv_gtid_s1 = __ompc_get_local_thread_num();
    __ompc_serialized_parallel();
    for(__localized_common_i = 0; __localized_common_i < (_INT32) NumSamples; __localized_common_i = __localized_common_i + 1)
    {
      _w2c___comma1 = ReverseBits((_UINT32) __localized_common_i, NumBits);
      __localized_common_j = (_INT32)(_w2c___comma1);
      * (RealOut + (_UINT64)((_UINT64) __localized_common_j)) = *(RealIn + (_UINT64)((_UINT64) __localized_common_i));
      if((_UINT64)(ImagIn) != 0ULL)
      {
        _w2c___cselect = *(ImagIn + (_UINT64)((_UINT64) __localized_common_i));
      }
      else
      {
        _w2c___cselect = 0.0F;
      }
      * (ImagOut + (_UINT64)((_UINT64) __localized_common_j)) = _w2c___cselect;
    }
    __ompc_end_serialized_parallel();
  }
  _w2c___comma2 = log2((_IEEE64)(NumSamples));
  NumIter = _U4F8TRUNC(_w2c___comma2);
  m = 1;
  while(NumIter >= (_UINT32) m)
  {
    _514 :;
    _w2c___comma3 = pow(2.0, (_IEEE64)(m));
    BlockSize = _U4F8TRUNC(_w2c___comma3);
    _w2c___comma4 = pow(2.0, (_IEEE64)(m + -1));
    BlockEnd = _U4F8TRUNC(_w2c___comma4);
    delta_angle = angle_numerator / (_IEEE64)(BlockSize);
    sm2 = sin(delta_angle * -2.0);
    sm1 = sin(-delta_angle);
    cm2 = cos(delta_angle * -2.0);
    cm1 = cos(delta_angle);
    w = cm1 * 2.0;
    _w2c_trip_count = (((_INT32) NumSamples + (_INT32) BlockSize) + -1) / (_INT32) BlockSize;
    _w2c___ompv_ok_to_fork0 = _w2c_trip_count > 1;
    if(_w2c___ompv_ok_to_fork0)
    {
      _w2c___ompv_ok_to_fork0 = __ompc_can_fork();
    }
    if(_w2c___ompv_ok_to_fork0)
    {
      __ompc_fork(0, &__ompdo_fft_float_11, _w2c_reg3);
    }
    else
    {
      __ompv_gtid_s1 = __ompc_get_local_thread_num();
      __ompc_serialized_parallel();
      for(_w2c___localized_common_i0 = 0; _w2c___localized_common_i0 < (_INT32) NumSamples; _w2c___localized_common_i0 = _w2c___localized_common_i0 + (_INT32) BlockSize)
      {
        (__localized_common_ar)[2] = cm2;
        (__localized_common_ar)[1] = cm1;
        (__localized_common_ai)[2] = sm2;
        (__localized_common_ai)[1] = sm1;
        _w2c___localized_common_j0 = _w2c___localized_common_i0;
        __localized_common_n = 0;
        while((_UINT32) __localized_common_n < BlockEnd)
        {
          _1026 :;
          (__localized_common_ar)[0] = ((__localized_common_ar)[1] * w) - (__localized_common_ar)[2];
          (__localized_common_ar)[2] = (__localized_common_ar)[1];
          (__localized_common_ar)[1] = (__localized_common_ar)[0];
          (__localized_common_ai)[0] = ((__localized_common_ai)[1] * w) - (__localized_common_ai)[2];
          (__localized_common_ai)[2] = (__localized_common_ai)[1];
          (__localized_common_ai)[1] = (__localized_common_ai)[0];
          k = (_INT32)((_UINT32) _w2c___localized_common_j0 + BlockEnd);
          tr = ((_IEEE64)(*(RealOut + (_UINT64)((_UINT64) k))) * (__localized_common_ar)[0]) - ((_IEEE64)(*(ImagOut + (_UINT64)((_UINT64) k))) * (__localized_common_ai)[0]);
          ti = ((_IEEE64)(*(RealOut + (_UINT64)((_UINT64) k))) * (__localized_common_ai)[0]) + ((_IEEE64)(*(ImagOut + (_UINT64)((_UINT64) k))) * (__localized_common_ar)[0]);
          * (RealOut + (_UINT64)((_UINT64) k)) = (_IEEE32)((_IEEE64)(*(RealOut + (_UINT64)((_UINT64) _w2c___localized_common_j0))) - tr);
          * (ImagOut + (_UINT64)((_UINT64) k)) = (_IEEE32)((_IEEE64)(*(ImagOut + (_UINT64)((_UINT64) _w2c___localized_common_j0))) - ti);
          * (RealOut + (_UINT64)((_UINT64) _w2c___localized_common_j0)) = (_IEEE32)((_IEEE64)(*(RealOut + (_UINT64)((_UINT64) _w2c___localized_common_j0))) + tr);
          * (ImagOut + (_UINT64)((_UINT64) _w2c___localized_common_j0)) = (_IEEE32)((_IEEE64)(*(ImagOut + (_UINT64)((_UINT64) _w2c___localized_common_j0))) + ti);
          _w2c___localized_common_j0 = _w2c___localized_common_j0 + 1;
          __localized_common_n = __localized_common_n + 1;
          _770 :;
        }
        goto _1282;
        _1282 :;
      }
      __ompc_end_serialized_parallel();
    }
    m = m + 1;
    _258 :;
  }
  goto _1538;
  _1538 :;
  if(InverseTransform != 0)
  {
    denom = (_IEEE64)(NumSamples);
    i = 0;
    while(NumSamples > (_UINT32) i)
    {
      _2050 :;
      * (RealOut + (_UINT64)((_UINT64) i)) = (_IEEE32)((_IEEE64)(*(RealOut + (_UINT64)((_UINT64) i))) / denom);
      * (ImagOut + (_UINT64)((_UINT64) i)) = (_IEEE32)((_IEEE64)(*(ImagOut + (_UINT64)((_UINT64) i))) / denom);
      i = i + 1;
      _1794 :;
    }
    _2306 :;
  }
  return;
} /* fft_float */
예제 #6
0
void anim_fft_double (unsigned  NofSamples,
		      int       InverseTransform,
		      double   *RealIn,
		      double   *ImagIn,
		      double   *RealOut,
		      double   *ImagOut )
{
  unsigned NofBits;    /* Number of bits needed to store indices */
  unsigned LSample, j, k, n;
  unsigned BlockSize, BlockEnd;
  double AngleNumerator = 2.0 * M_PI;
  double TempReal, TempImagin;     /* temp real, temp imaginary */
  
  if ( !IsPowerOfTwo(NofSamples) ) {
    PrintError(("Error in fft():  NofSamples=%u is not power of two\n", NofSamples) );
    exit(1);
  }
  if ( InverseTransform ) AngleNumerator = -AngleNumerator;
  
  CHECKPOINTER ( RealIn );
  CHECKPOINTER ( RealOut );
  CHECKPOINTER ( ImagOut );

  NofBits = NumberOfBitsNeeded ( NofSamples );

  /*
  **   Do simultaneous data copy and bit-reversal ordering into outputs...
  */
  
  for ( LSample=0; LSample < NofSamples; LSample++ ) {
    j = ReverseBits ( LSample, NofBits );
    RealOut[j] = RealIn[LSample];
    ImagOut[j] = (ImagIn == NULL) ? 0.0 : ImagIn[LSample];
  }
  
  /*
  **   Do the FFT itself...
  */
  
  BlockEnd = 1;
  for ( BlockSize = 2; BlockSize <= NofSamples; BlockSize <<= 1 ) {
    double delta_angle = AngleNumerator / (double)BlockSize;
    double sm2 = sin ( -2 * delta_angle );
    double sm1 = sin ( -delta_angle );
    double cm2 = cos ( -2 * delta_angle );
    double cm1 = cos ( -delta_angle );
    double w = 2 * cm1;
    double ar[3], ai[3];
    
    for ( LSample=0; LSample < NofSamples; LSample += BlockSize ) {
      ar[2] = cm2;
      ar[1] = cm1;
      
      ai[2] = sm2;
      ai[1] = sm1;
      
      for ( j=LSample, n=0; n < BlockEnd; j++, n++ ) {
	ar[0] = w*ar[1] - ar[2];
	ar[2] = ar[1];
	ar[1] = ar[0];
	  
	ai[0] = w*ai[1] - ai[2];
	ai[2] = ai[1];
	ai[1] = ai[0];
	
	k = j + BlockEnd;
	TempReal = ar[0]*RealOut[k] - ai[0]*ImagOut[k];
	TempImagin = ar[0]*ImagOut[k] + ai[0]*RealOut[k];
	
	RealOut[k] = RealOut[j] - TempReal;
	ImagOut[k] = ImagOut[j] - TempImagin;
	
	RealOut[j] += TempReal;
	ImagOut[j] += TempImagin;
      }
    }
    BlockEnd = BlockSize;
  }
  
  /*
  **   Need to normalize if inverse transform...
  */
    
  if ( InverseTransform ) {
    double denom = (double)NofSamples;
    
    for ( LSample=0; LSample < NofSamples; LSample++ ) {
      RealOut[LSample] /= denom;
      ImagOut[LSample] /= denom;
    }
  }
}