/// <summary> /// Create a new filter base on existing data /// </summary> /// <param name="filter"></param> public FIR_GenericFilter( FxVectorF filter ) { p_Impulse = filter.GetCopy() as FxVectorF; // normalize the filter p_Impulse.Divide( (float)p_Impulse.Norms( NormVectorType.Manhattan ) ); // check that is power of 2 ( we do that for speed ) if ( Math.Pow( 2, Math.Log( p_Impulse.Size, 2 ) ) != p_Impulse.Size ) { // calc the size of log2 extence int sizeLog2 = (int)Math.Floor( Math.Log( p_Impulse.Size, 2 ) ) + 1; // calc the new maxSize int newSize = (int)Math.Pow( 2, sizeLog2 ); // increase the size of Impulse p_Impulse.Padding( newSize - p_Impulse.Size, true, 0 ); } // calc the fft of impulse TransformImpulseToFFT(); }
public FxVectorF GetFrequencyResponse(int resolution) { FxVectorF inFilter = new FxVectorF(4096); FxVectorF FreqResponse = new FxVectorF(resolution); FxVectorF tmpImag, tmpReal, power; FxVectorF filter; // calc the sinc for the size of the filter for (int i = 0; i < inFilter.Size; i++) { if (i == inFilter.Size / 2) inFilter[i] = 1; else inFilter[i] = 0; } // calc the impulse of the filter this.Transform(inFilter,out filter); power = new FxVectorF(256); int mod = (int)Math.Ceiling(filter.Size / ((double)power.Size * 2)); // calc the fft of the filter SignalTools.FFT_Safe_F(filter, null, true, out tmpReal, out tmpImag); for (int i = 0; i < mod; i++) { // calc the power of the filter for (int j = 0; j < power.Size; j++) { FreqResponse[j] += (float)(Math.Sqrt(tmpReal[j * mod + i] * tmpReal[j * mod + i] + tmpImag[j * mod + i] * tmpImag[j * mod + i])); } } // normalize FreqResponse.Divide((float)(mod*Math.Sqrt(2))); return FreqResponse; }
/// <summary> /// FFT algorithm /// </summary> /// <param name="real">The real part of input</param> /// <param name="imag">The imag part of input</param> /// <param name="Forward">The </param> /// <param name="resultReal">The real part of the result</param> /// <param name="resultImag">The real imag of the result</param> public static void FFT_F( FxVectorF real, FxVectorF imag, Boolean Forward, out FxVectorF resultReal, out FxVectorF resultImag ) { // find the size and log2(size) int size = real.Size; int sizeLog2 = (int)Math.Log( size, 2 ); // allocate result FxVectorF resultRealTmp = new FxVectorF( size ); FxVectorF resultImagTmp = new FxVectorF( size ); // Do the bit reversal int i2 = size >> 1; var j = 0; for ( var i = 0; i < size - 1; i++ ) { if ( i < j ) { resultRealTmp[i] = real[j]; resultRealTmp[j] = real[i]; if ( imag == null ) { resultImagTmp[i] = 0; resultImagTmp[j] = 0; } else { resultImagTmp[i] = imag[j]; resultImagTmp[j] = imag[i]; } } var m = size; do { m >>= 1; j ^= m; } while ( ( j & m ) == 0 ); } // set the sign of exponents int exponentSign = ( Forward ) ? 1 : -1; // pass all the level of fft tree and compute the fourier for ( var levelSize = 1; levelSize < size; levelSize *= 2 ) { Parallel.For( 0, levelSize, index => Radix2Step( resultRealTmp, resultImagTmp, exponentSign, levelSize, index ) ); } // set the out result resultReal = resultRealTmp; resultImag = resultImagTmp; // normalize when we have reverce if ( !Forward ) { resultReal.Divide( size ); resultImag.Divide( size ); } }
/// <summary> /// DFT /// </summary> /// <param name="real"></param> /// <param name="imag"></param> /// <param name="Forward"></param> /// <param name="resultReal"></param> /// <param name="resultImag"></param> public static void DFT_F( FxVectorF real, FxVectorF imag, Boolean Forward, out FxVectorF resultReal, out FxVectorF resultImag ) { // set the direction of the DFT double dir = ( Forward ) ? -1 : 1; double arg, cosarg,sinarg; int size = real.Size; // allocate result FxVectorF resultRealTmp = new FxVectorF( size ); FxVectorF resultImagTmp = new FxVectorF( size ); // pass all the datas Parallel.For( 0, size, ( i ) => { arg = -dir * 2.0 * Math.PI * (double)i / size; for ( int k = 0; k < size; k++ ) { cosarg = Math.Cos( k * arg ); sinarg = Math.Sin( k * arg ); resultRealTmp[i] += (float)( real[k] * cosarg - imag[k] * sinarg ); resultImagTmp[i] += (float)( real[k] * sinarg + imag[k] * cosarg ); } } ); // pass the result to the output resultReal = resultRealTmp; resultImag = resultImagTmp; // normalize when we have reverce if ( !Forward ) { resultReal.Divide( size ); resultImag.Divide( size ); } }