예제 #1
0
파일: SignalTools.cs 프로젝트: fxbit/FxMath
        /// <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;
        }
예제 #2
0
파일: SignalTools.cs 프로젝트: fxbit/FxMath
        /// <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;
        }
예제 #3
0
파일: Form1.cs 프로젝트: fxbit/FxMath
        private void button13_Click( object sender, EventArgs e )
        {
            // process the white noise data with the dsp
            if ( wn != null ) {

                tmpWn = new FxVectorF( wn.Size );

                // create the signal spectrum graphs
                if ( plot_signal_spectrum == null ) {

                    power = new FxVectorF( 256 );

                    #region Plot Creation

                    signal_spectrum = new FxVectorF( 256 );

                    // insert the plot of the time filter
                    filterPlot = new PloterElement( signal_spectrum );
                    filterPlot.Position.X = 0;
                    filterPlot.Position.Y = 410;
                    filterPlot.Origin = new FxVector2f(10, 100);
                    filterPlot.FitPlots();
                    canvas_audio.AddElements( filterPlot );

                    // create the plot for the spectrum
                    plot_signal_spectrum = new PloterElement( signal_spectrum );
                    plot_signal_spectrum.Position.X = 0;
                    plot_signal_spectrum.Position.Y = 10;
                    plot_signal_spectrum.Origin = new FxVector2f(10, 100);
                    plot_signal_spectrum.FitPlots();
                    plot_signal_spectrum.AddPlot( signal_spectrum, PlotType.Lines, Color.Aqua );

                    // add the signal to canva
                    canvas_audio.AddElements( plot_signal_spectrum );

                    // create the plot for the spectrum
                    plot_signal_spectrum_original = new PloterElement( signal_spectrum );
                    plot_signal_spectrum_original.Position.X = 600;
                    plot_signal_spectrum_original.Position.Y = 10;
                    plot_signal_spectrum_original.Origin = new FxVector2f(10, 100);
                    plot_signal_spectrum_original.FitPlots();

                    // add the signal to canva
                    canvas_audio.AddElements( plot_signal_spectrum_original );

                    // create the plot for the spectrum
                    plot_filter_spectrum = new PloterElement( signal_spectrum );
                    plot_filter_spectrum.Position.X = 600;
                    plot_filter_spectrum.Position.Y = 410;
                    plot_filter_spectrum.Origin = new FxVector2f(10, 100);
                    plot_filter_spectrum.FitPlots();

                    // add the signal to canva
                    canvas_audio.AddElements( plot_filter_spectrum );
                    #endregion

                    // add filter
                    UpdateFilter( BiQuadFilter.BandPassFilterConstantPeakGain( 44100, 20000, 0.5f ) );

                }

                if ( this.fil != null ) {
                    // use the filter directly
                    this.fil.Transform( wn, tmpWn );
                }

                FxVectorF tmpImag,tmpReal;

                // calc spectrum
                int mod = (int)Math.Ceiling( tmpWn.Size / ( (double)power.Size * 2 ) );

                // ===============================================================================================

                if ( ShowOutputAudioSpectrum ) {
                    power.SetValue( 0.0f );
                    FxVectorF local=tmpWn;
                    if ( Math.Pow( 2, Math.Floor( Math.Log( local.Size, 2 ) ) ) != local.Size ) {
                        int newSize;

                        // calc the size of log2
                        int sizeLog2 = (int)Math.Floor( Math.Log( local.Size, 2 ) ) - 1;

                        // calc the new size
                        newSize = (int)Math.Pow( 2, sizeLog2 );
                        if ( newSize < 512 )
                            newSize = 512;

                        local = tmpWn.GetSubVector( 0, newSize ) as FxVectorF;
                    }

                    mod = (int)Math.Ceiling( local.Size / ( (double)power.Size * 2 ) );

                    // calc the fft
                    SignalTools.FFT_F( local, null, true, out tmpReal, out tmpImag );

                    // pass all the data in form of blocks
                    for ( int i = 0; i < mod; i++ ) {
                        for ( int j = 0; j < power.Size; j++ ) {
                            power[j] += (float)( Math.Sqrt( tmpReal[j * mod + i] * tmpReal[j * mod + i] + tmpImag[j * mod + i] * tmpImag[j * mod + i] ) );
                        }
                    }

                    // normalize the result
                    power.Divide( power.Max() );

                    // refresh the plot
                    plot_signal_spectrum.RefreshPlot( power, 0 );
                    plot_signal_spectrum.FitPlots();

                    // redraw canvas if we are not going to show output spectrum
                    if ( !ShowInputAudioSpectrum )
                        canvas_audio.ReDraw();
                }

                // ===============================================================================================

                if ( ShowInputAudioSpectrum ) {
                    // calc spectrum

                    // reset the power
                    power.SetValue( 0.0f );
                    FxVectorF local=wn;

                    if ( Math.Pow( 2, Math.Floor( Math.Log( local.Size, 2 ) ) ) != local.Size ) {
                        int newSize;

                        // calc the size of log2
                        int sizeLog2 = (int)Math.Floor( Math.Log( local.Size, 2 ) ) - 1;

                        // calc the new size
                        newSize = (int)Math.Pow( 2, sizeLog2 );
                        if ( newSize < 512 )
                            newSize = 512;

                        local = wn.GetSubVector( 0, newSize ) as FxVectorF;
                    }

                    mod = (int)Math.Ceiling( local.Size / ( (double)power.Size * 2 ) );

                    // calc the fft
                    SignalTools.FFT_Safe_F( local, null, true, out tmpReal, out tmpImag );

                    // pass all the data in form of blocks
                    for ( int i = 0; i < mod; i++ ) {
                        for ( int j = 0; j < power.Size; j++ ) {
                            power[j] += (float)( Math.Sqrt( tmpReal[j * mod + i] * tmpReal[j * mod + i] + tmpImag[j * mod + i] * tmpImag[j * mod + i] ) );
                        }

                    }

                    // normalize the result
                    power.Divide( power.Max() );

                    // refresh the plot
                    plot_signal_spectrum_original.RefreshPlot( power, 0 );
                    plot_signal_spectrum_original.FitPlots();

                    // redraw canvas
                    canvas_audio.ReDraw();
                }
            }
        }