/// <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(); }
/// <summary> /// Create a new filter base on existing data /// </summary> /// <param name="A_Data">Feedback filter coefficients</param /// <param name="B_Data">Feedforward filter coefficients</param> public IIR_GenericFilter(FxVectorF A_Data,FxVectorF B_Data) { // create copy of the data for internal use this.A_Data = A_Data.GetCopy() as FxVectorF; this.B_Data = B_Data.GetCopy() as FxVectorF; // normalize base on a0 coefficients this.A_Data.Divide(this.A_Data[0]); this.B_Data.Divide(this.A_Data[0]); // set the max offset maxOffset = (A_Data.Size > B_Data.Size) ? A_Data.Size : B_Data.Size; float maxManhattan = (float)this.A_Data.Norms(NormVectorType.Manhattan); if (maxManhattan < (float)this.B_Data.Norms(NormVectorType.Manhattan)) { maxManhattan = (float)this.B_Data.Norms(NormVectorType.Manhattan); } // normalize base on a0 coefficients this.A_Data.Divide(maxManhattan); this.B_Data.Divide(maxManhattan); }
/// <summary> /// FFT algorithm with internal padding to power of 2 /// </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_Safe_F( FxVectorF real, FxVectorF imag, Boolean Forward, out FxVectorF resultReal, out FxVectorF resultImag ) { // copy local the inputs FxVectorF real_local = real.GetCopy() as FxVectorF; FxVectorF imag_local = ( imag != null ) ? imag.GetCopy() as FxVectorF : null; // get the max size from A,B int maxSize; if ( imag_local != null ) maxSize = ( real_local.Size > imag_local.Size ) ? real_local.Size : imag_local.Size; else maxSize = real_local.Size; // check that is power of 2 if ( Math.Pow( 2, Math.Floor( Math.Log( maxSize, 2 ) ) ) != maxSize ) { // calc the size of log2 extence int sizeLog2 = (int)Math.Floor( Math.Log( maxSize, 2 ) ) + 1; // calc the new maxSize maxSize = (int)Math.Pow( 2, sizeLog2 ); // increase the size of A,B real_local.Padding( maxSize - real_local.Size, true, 0 ); if ( imag_local != null ) imag_local.Padding( maxSize - imag_local.Size, true, 0 ); } // call the unsafe fft FFT_F( real_local, imag_local, Forward, out resultReal, out resultImag ); }
/// <summary> /// Result = A (*) B /// By using FFT for calculations /// The second vector is allready in fft form /// The two vectors must have the same size and be power of 2 /// </summary> /// <param name="A"></param> /// <param name="B_dftReal"></param> /// <param name="B_dftImag"></param> /// <param name="Result"></param> public static void Convolution_FFT_F( FxVectorF A, FxVectorF B_dftReal, FxVectorF B_dftImag, out FxVectorF Result ) { FxVectorF A_dftReal,A_dftImag; // copy local the inputs FxVectorF A_local = A.GetCopy() as FxVectorF; // get the max size from A,B int maxSize = ( A_local.Size > B_dftReal.Size ) ? A_local.Size : B_dftReal.Size; // calc the DFT of the signal SignalTools.FFT_F( A_local, null, true, out A_dftReal, out A_dftImag ); // allocate result vector Result = new FxVectorF( maxSize ); float real,imag; // do the multiplication for ( int i=0; i < maxSize; i++ ) { // complex multiplication real = A_dftReal[i] * B_dftReal[i] - A_dftImag[i] * B_dftImag[i]; imag = A_dftReal[i] * B_dftImag[i] + A_dftImag[i] * B_dftReal[i]; // set the new values A_dftReal[i] = real; A_dftImag[i] = imag; } // calc the DFT of the signal SignalTools.FFT_F( A_dftReal, A_dftImag, false, out Result, out B_dftImag ); // cat the padding int maxInputSize = ( A.Size > B_dftReal.Size ) ? A.Size : B_dftReal.Size; Result = Result.GetSubVector( maxSize - maxInputSize, Result.Size ) as FxVectorF; }
/// <summary> /// Result = A (*) B /// By using FFT for calculations /// </summary> /// <param name="A"></param> /// <param name="B"></param> /// <param name="Result"></param> public static void Convolution_FFT_F( FxVectorF A, FxVectorF B, out FxVectorF Result ) { FxVectorF A_dftReal,A_dftImag,B_dftReal,B_dftImag; // copy local the inputs FxVectorF A_local = A.GetCopy() as FxVectorF; FxVectorF B_local = B.GetCopy() as FxVectorF; // get the max size from A,B int maxSize = ( A_local.Size > B_local.Size ) ? A_local.Size : B_local.Size; // check that is power of 2 if ( Math.Pow( 2, Math.Log( maxSize, 2 ) ) != maxSize ) { // calc the size of log2 extence int sizeLog2 = (int)Math.Floor( Math.Log( maxSize, 2 ) ) + 1; // calc the new maxSize maxSize = (int)Math.Pow( 2, sizeLog2 ); // increase the size of A,B A_local.Padding( maxSize - A_local.Size, true, 0 ); B_local.Padding( maxSize - B_local.Size, true, 0 ); } // allocate temp file FxVectorF tmp = new FxVectorF( maxSize ); // check for padding if ( A_local.Size == maxSize && B_local.Size != maxSize ) { // increase the size of B B_local.Padding( maxSize - B_local.Size, true, 0 ); } else if ( B_local.Size == maxSize && A_local.Size != maxSize ) { A_local.Padding( maxSize - A_local.Size, true, 0 ); } // calc the DFT of the signal SignalTools.FFT_F( A_local, tmp, true, out A_dftReal, out A_dftImag ); // calc the DFT of the signal SignalTools.FFT_F( B_local, tmp, true, out B_dftReal, out B_dftImag ); // allocate result vector Result = new FxVectorF( maxSize ); float real,imag; // do the multiplication for ( int i=0; i < maxSize; i++ ) { // complex multiplication real = A_dftReal[i] * B_dftReal[i] - A_dftImag[i] * B_dftImag[i]; imag = A_dftReal[i] * B_dftImag[i] + A_dftImag[i] * B_dftReal[i]; // set the new values A_dftReal[i] = real; A_dftImag[i] = imag; } // calc the DFT of the signal SignalTools.FFT_F( A_dftReal, A_dftImag, false, out Result, out B_dftImag ); // cat the padding int maxInputSize = ( A.Size > B.Size ) ? A.Size : B.Size; Result = Result.GetSubVector( maxSize - maxInputSize, Result.Size) as FxVectorF; }
public void Transform( FxVectorF inBuffer, FxVectorF outBuffer ) { FxVectorF outBufferTmp; FxVectorF inBuffer_local = inBuffer; if ( inBuffer.Size > p_Impulse.Size ) { // add zeros to the end of the impulse p_Impulse.Padding( inBuffer.Size - p_Impulse.Size, true, 0 ); // update fft TransformImpulseToFFT(); } if ( inBuffer.Size < p_Impulse.Size ) { // copy the input buffer local inBuffer_local = inBuffer.GetCopy() as FxVectorF; // add zero sto teh end of the input buffer inBuffer_local.Padding( p_Impulse.Size - inBuffer_local.Size, true, 0 ); } // make the convolution SignalTools.Convolution_FFT_F( inBuffer_local, p_ImpulseFFT_Real, p_ImpulseFFT_Imag, out outBufferTmp ); if ( inBuffer_local != inBuffer ) { // copy the result to the data outBuffer.SetValue( outBufferTmp.GetSubVector( inBuffer_local.Size - inBuffer.Size, outBufferTmp.Size ) ); } else { // copy the result to the data outBuffer.SetValue( outBufferTmp ); } }