Beispiel #1
0
        private Complex[] FFT(Complex[] input)
        {
            if (input.Length < 2)
            {
                return(new Complex[0]);
            }

            var arr    = new fftwf_complexarray(input);
            var outArr = new fftwf_complexarray(input.Length);

            var plan = fftwf_plan.dft_1d(input.Length, arr, outArr, fftw_direction.Forward, fftw_flags.Estimate);

            plan.Execute();

            return(outArr.GetData_Complex());
        }
        protected override void OnSettingsChanged(SettingsChangedEventArgs e)
        {
            while (isProcessing)
            {
                Thread.Sleep(100);
            }

            int n = settings.FFTSampleCount;

            timeDomainData      = new float[settings.FFTSampleCount];
            frequencyDomainData = new float[settings.FFTSampleCount];

            // n*2 because we are dealing with complex numbers
            complexInput  = new float[n * 2];
            complexOutput = new float[n * 2];

            try
            {
                mfin  = new fftwf_complexarray(complexInput);
                mfout = new fftwf_complexarray(complexOutput);
            }
            catch (DllNotFoundException)
            {
                Console.WriteLine("DllNotFoundException: You must copy the native FFTW DLLs (libfftw3-3.dll, libfftw3f-3.dll, libfftw3l-3.dll) into the working directory.");
                throw;
            }
            catch (BadImageFormatException)
            {
                Console.WriteLine("BadImageFormatException: This normally means, that you're loading a 32bit DLL into a 64bit process or vice versa.");
                throw;
            }

            plan = fftwf_plan.dft_1d(n, mfin, mfout,
                                     settings.IsBackward ? fftw_direction.Backward : fftw_direction.Forward,
                                     settings.PlanningRigor == FFTPlanningRigor.Estimate ? fftw_flags.Estimate :
                                     settings.PlanningRigor == FFTPlanningRigor.Measure ? fftw_flags.Measure :
                                     settings.PlanningRigor == FFTPlanningRigor.Patient ? fftw_flags.Patient :
                                     fftw_flags.Estimate);

            switch (settings.OutputFormat)
            {
            case FFTOutputFormat.Raw:
                this.OutputBlockSize = settings.FFTSampleCount * 2;
                break;

            case FFTOutputFormat.RealImaginaryPair:
                this.OutputBlockSize = settings.FFTSampleCount;
                break;

            case FFTOutputFormat.RealOnly:
                this.OutputBlockSize = settings.FFTSampleCount / 2;
                break;

            case FFTOutputFormat.Magnitude:
                this.OutputBlockSize = settings.FFTSampleCount / 2;
                break;

            case FFTOutputFormat.FrequencyMagnitudePair:
                this.OutputBlockSize = settings.FFTSampleCount;
                break;

            default:
                throw new ArgumentException("The FFT's output format is not supported.", "FFTOutputFormat");
            }
        }
Beispiel #3
0
        // Initializes FFTW and all arrays
        // n: Logical size of the transform
        public FFTWtest(int n)
        {
            Console.WriteLine($"Start testing with n = {n.ToString("#,0")} complex numbers. All plans will be executed {repeatPlan.ToString("#,0")} times on a single thread.");
            Console.WriteLine("Please wait, creating plans...");
            fftLength = n;

            // create two unmanaged arrays, properly aligned
            pin  = fftwf.malloc(n * 8);
            pout = fftwf.malloc(n * 8);

            // create two managed arrays, possibly misalinged
            // n*2 because we are dealing with complex numbers
            fin  = new float[n * 2];
            fout = new float[n * 2];
            // and two more for double FFTW
            din  = new double[n * 2];
            dout = new double[n * 2];

            // get handles and pin arrays so the GC doesn't move them
            hin   = GCHandle.Alloc(fin, GCHandleType.Pinned);
            hout  = GCHandle.Alloc(fout, GCHandleType.Pinned);
            hdin  = GCHandle.Alloc(din, GCHandleType.Pinned);
            hdout = GCHandle.Alloc(dout, GCHandleType.Pinned);

            // create a few test transforms
            fplan1 = fftwf.dft_1d(n, pin, pout, fftw_direction.Forward, fftw_flags.Estimate);
            fplan2 = fftwf.dft_1d(n, hin.AddrOfPinnedObject(), hout.AddrOfPinnedObject(), fftw_direction.Forward, fftw_flags.Estimate);
            fplan3 = fftwf.dft_1d(n, hout.AddrOfPinnedObject(), pin, fftw_direction.Backward, fftw_flags.Measure);
            // end with transforming back to original array
            fplan4 = fftwf.dft_1d(n, hout.AddrOfPinnedObject(), hin.AddrOfPinnedObject(), fftw_direction.Backward, fftw_flags.Estimate);
            // and check a quick one with doubles, just to be sure
            fplan5 = fftw.dft_1d(n, hdin.AddrOfPinnedObject(), hdout.AddrOfPinnedObject(), fftw_direction.Backward, fftw_flags.Measure);

            // create a managed plan as well
            mfin  = new fftwf_complexarray(fin);
            mfout = new fftwf_complexarray(fout);
            mdin  = new fftw_complexarray(din);
            mdout = new fftw_complexarray(dout);

            mplan1 = fftwf_plan.dft_1d(n, mfin, mfout, fftw_direction.Forward, fftw_flags.Estimate);
            mplan2 = fftwf_plan.dft_1d(n, mfin, mfout, fftw_direction.Forward, fftw_flags.Measure);
            mplan3 = fftwf_plan.dft_1d(n, mfin, mfout, fftw_direction.Forward, fftw_flags.Patient);

            mplan4 = fftwf_plan.dft_1d(n, mfout, mfin, fftw_direction.Backward, fftw_flags.Measure);

            mplan5 = fftw_plan.dft_1d(n, mdin, mdout, fftw_direction.Forward, fftw_flags.Measure);


            // fill our arrays with an arbitrary complex sawtooth-like signal
            for (int i = 0; i < n * 2; i++)
            {
                fin[i] = i % 50;
            }
            for (int i = 0; i < n * 2; i++)
            {
                fout[i] = i % 50;
            }
            for (int i = 0; i < n * 2; i++)
            {
                din[i] = i % 50;
            }

            // copy managed arrays to unmanaged arrays
            Marshal.Copy(fin, 0, pin, n * 2);
            Marshal.Copy(fout, 0, pout, n * 2);

            Console.WriteLine();
        }