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; } } }
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; } } }
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; } } }
/// @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; } } }
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 */
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; } } }