/// <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; }
/// <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; }
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(); } } }