示例#1
2
文件: FFT.cs 项目: leon196/WJ
    void Start()
    {
        Instance = this;

        crossovers[0] = 30; //guesstimating sample lengths for frequency bands
        crossovers[1] = 50;
        crossovers[2] = 600;
        crossovers[3] = freqData.Length;

        band = new float[BANDS];
        output = new float[BANDS];

        for (int i = 0; i < audioObj.Length; i++)
        {
          audioObj[i].player = (GameObject)Instantiate(playerPrefab);
          audioObj[i].player.transform.parent = transform;
          audioObj[i].player.transform.position = Vector3.zero;
          audioObj[i].clip = new AudioClip();
        }

        inputDevices = new string[Microphone.devices.Length];
        deviceNum = Microphone.devices.Length - 1;

        for (int i = 0; i < Microphone.devices.Length; i++)
        inputDevices[i] = Microphone.devices[i].ToString();

        CurrentAudioInput = Microphone.devices[deviceNum].ToString();

        InvokeRepeating("Check", 0, 1.0f / 15.0f);
        StartCoroutine(StartRecord());
    }
示例#2
0
    /**
     * Constructor, sets the {@link Decoder}, the sample window size and the
     * hop size for the spectra returned. Say the sample window size is 1024
     * samples. To get an overlapp of 50% you specify a hop size of 512 samples,
     * for 25% overlap you specify a hopsize of 256 and so on. Hop sizes are of
     * course not limited to powers of 2.
     *
     * @param decoder The decoder to get the samples from.
     * @param sampleWindowSize The sample window size.
     * @param hopSize The hop size.
     * @param useHamming Wheter to use hamming smoothing or not.
     */
    public SpectrumProvider( DecoderInterface decoder, int sampleWindowSize, int hopSize, bool useHamming )
    {
        if( decoder == null )
            throw new ArgumentException( "Decoder must be != null" );

        if( sampleWindowSize <= 0 )
            throw new ArgumentException( "Sample window size must be > 0" );
        if( hopSize <= 0 )
            throw new ArgumentException( "Hop size must be > 0" );

        if( sampleWindowSize < hopSize )
            throw new ArgumentException( "Hop size must be <= sampleSize" );

        this.sampleWindowSize = sampleWindowSize;

        this.decoder = decoder;
        this.samples = new float[sampleWindowSize];
        this.nextSamples = new float[sampleWindowSize];
        this.tempSamples = new float[sampleWindowSize];
        this.hopSize = hopSize;
        fft = new FFT( sampleWindowSize, AudioManager.frequency );
        if( useHamming )
            fft.window(FFT.HAMMING);

        decoder.readSamples( ref samples );
        decoder.readSamples( ref nextSamples );
    }
示例#3
0
    void Start()
    {
        _texPw = new Texture2D(n, n, TextureFormat.RGBA32, false, true);
        _texEtaX = new Texture2D(n, n, TextureFormat.RGBA32, false, true);
        _texEtaY = new Texture2D(n, n , TextureFormat.RGBA32, false, true);
        _cPw = _texPw.GetPixels();
        _cEtaX = _texEtaX.GetPixels();
        _cEtaY = _texEtaY.GetPixels();
        displacementMat.SetFloat("_L", L);
        floatDecoderMat.SetFloat("_L", L);
        floatDecoderMat.SetTexture("_XTex", _texEtaX);
        floatDecoderMat.SetTexture("_YTex", _texEtaY);
        floatDecoderMat.SetTexture("_ZTex", _texPw);

        _texUvw = new RenderTexture(n, n, 0, RenderTextureFormat.ARGBFloat, RenderTextureReadWrite.Linear);
        displacementMat.mainTexture = _texUvw;

        _k = new K(n, L);
        _phillips = new Phillips(_k, wind.magnitude, wind.normalized);
        _h0 = new H0(_phillips);
        _w = new W(_k);
        _h = new H(_h0, _w);
        _eta = new Eta(n, _k, _h);

        _fft = new FFT(n);
        _pw = new float[2 * n * n];
        _etaX = new float[_pw.Length];
        _etaY = new float[_pw.Length];
    }
示例#4
0
 void Start()
 {
     thi = this;
     prevTime = Time.time;
     int n = freqData.Length;
     int k = 3;
     band = new float[k];
 }
示例#5
0
		public MFCC(int samplePerFrame, int samplingRate, int numCepstra)
		{
			this.samplePerFrame = samplePerFrame;
			this.samplingRate = samplingRate;
			this.numCepstra = numCepstra;
			upperFilterFreq = samplingRate / 2.0;
			
			fft = new FFT();
			dct = new DCT(this.numCepstra, numMelFilters);
		}
        private dynamic GenerateSpecifiedHarmonic(double systemFrequency, DataSeries dataSeries, int specifiedHarmonic)
        {
            int samplesPerCycle = Transform.CalculateSamplesPerCycle(dataSeries.SampleRate, systemFrequency);

            double[][] dataArrHarm  = new double[(dataSeries.DataPoints.Count - samplesPerCycle)][];
            double[][] dataArrAngle = new double[(dataSeries.DataPoints.Count - samplesPerCycle)][];

            Parallel.For(0, dataSeries.DataPoints.Count - samplesPerCycle, i =>
            {
                double[] points           = dataSeries.DataPoints.Skip(i).Take(samplesPerCycle).Select(point => point.Value / samplesPerCycle).ToArray();
                double specifiedFrequency = systemFrequency * specifiedHarmonic;

                FFT fft = new FFT(systemFrequency * samplesPerCycle, points);

                int index = Array.FindIndex(fft.Frequency, value => Math.Round(value) == specifiedFrequency);

                dataArrHarm[i]  = new double[] { dataSeries.DataPoints[i].Time.Subtract(m_epoch).TotalMilliseconds, fft.Magnitude[index] / Math.Sqrt(2) };
                dataArrAngle[i] = new double[] { dataSeries.DataPoints[i].Time.Subtract(m_epoch).TotalMilliseconds, fft.Angle[index] * 180 / Math.PI };
            });

            return(new { Magnitude = dataArrHarm.ToList(), Angle = dataArrAngle.ToList() });
        }
示例#7
0
        static async Task Main(string[] args)
        {
            //Generator generator1 = new Generator();
            //while (true)
            //{
            //    Thread.Sleep(50);
            //    await generator1.Generate();
            //}
            HubConnection connection = new HubConnectionBuilder()
                                       .WithUrl("https://localhost:5001/Chat")
                                       .Build();

            connection.Closed += async exception =>
            {
                Console.WriteLine("Connection is closed.");
                await Task.Delay(new Random().Next(0, 5) * 1000);

                // await connection.StartAsync();
            };
            await connection.StartAsync();

            HttpClient client = new HttpClient();
            var        data   = await client
                                .GetAsync("https://localhost:44388/api/app/book?SkipCount=0&MaxResultCount=512");

            var str = await data.Content.ReadAsStringAsync();

            //JObject jo = (JObject)JsonConvert.DeserializeObject(str);
            //var array = jo.Value<JToken>("items");
            //foreach(var e in jo.Value<JToken>("datas"))
            Point m        = JsonConvert.DeserializeObject <Point>(str);
            var   points   = m.items.Select(x => x.datas).ToArray();
            FFT   analy    = new FFT();
            var   sepctrum = analy.PowerSpectrum(ref points, 512);
            await connection.SendAsync("SendMessage", points);

            // await connection.SendAsync("SendMessageBy");
            Console.WriteLine();
        }
示例#8
0
        /// <summary>
        /// Execution function for Day 16
        /// </summary>
        public void Execute16()
        {
            UserActionAsync(() =>
            {
                WriteToConsole("Start execution of Day16");
                var parser = GetInputParser("Day16Input.txt");
                var data   = parser.GetInputData();

                var fft = new FFT(data.First());
                fft.Run(100);

                var first8 = fft.Signal.Substring(0, 8);

                WriteToConsole($"The first 8 digits after 100 iteration are {first8}");

                fft = new FFT(data.First());
                fft.RepeatSignal(10_000);
                fft.RunForMessage(100);

                WriteToConsole($"The final message is {fft.Message}");
            });
        }
示例#9
0
        public void Run()
        {
            const int n = 4;
            var       x = new Complex[n];

            var random = new Random();

            // original data
            for (var i = 0; i < n; i++)
            {
                x[i] = new Complex(i, 0);
                x[i] = new Complex(-2 * random.NextDouble() + 1, 0);
            }
            FFT.Show(x, "x");

            // FFT of original data
            var y = FFT.Fft(x);

            FFT.Show(y, "y = fft(x)");

            // take inverse FFT
            var z = FFT.Ifft(y);

            FFT.Show(z, "z = ifft(y)");

            // circular convolution of x with itself
            var c = FFT.Cconvolve(x, x);

            FFT.Show(c, "c = cconvolve(x, x)");

            // linear convolution of x with itself
            var d = FFT.Convolve(x, x);

            FFT.Show(d, "d = convolve(x, x)");


            Console.ReadLine();
        }
示例#10
0
        public void PhaseUnwrap()
        {
            // Generate a Phase Ramp between two signals
            double[] resultPhase = new double[600];
            double[] unwrapPhase = new double[600];

            UInt32 length = 2048;

            double[] wCoeff = mdsplib.DSP.Window.Coefficients(mdsplib.DSP.Window.Type.FTHP, length);

            // Instantiate & Initialize a new DFT
            FFT fft = new FFT();

            fft.Initialize(length, 3 * length);

            for (Int32 phase = 0; phase < 600; phase++)
            {
                double[] inputSignalRef   = mdsplib.DSP.Generate.ToneCycles(7.0, 128, length, phaseDeg: 45.0);
                double[] inputSignalPhase = mdsplib.DSP.Generate.ToneCycles(7.0, 128, length, phaseDeg: phase);

                inputSignalRef   = inputSignalRef.Multiply(wCoeff);
                inputSignalPhase = inputSignalPhase.Multiply(wCoeff);

                // Call the DFT and get the scaled spectrum back of a reference and a phase shifted signal.
                Complex[] cSpectrumRef   = fft.Direct(inputSignalRef);
                Complex[] cSpectrumPhase = fft.Direct(inputSignalPhase);

                // Magnitude Format - Just as a test point
                double[] lmSpectrumTest = cSpectrumRef.Magnitude();
                UInt32   peakLocation   = mdsplib.DSP.Analyze.FindMaxPosition(lmSpectrumTest);

                // Extract the phase of 'peak value' bin
                double[] resultArrayRef   = cSpectrumRef.PhaseDegrees();
                double[] resultArrayPhase = cSpectrumPhase.PhaseDegrees();
                resultPhase[phase] = resultArrayPhase[peakLocation] - resultArrayRef[peakLocation];
            }
            unwrapPhase = mdsplib.DSP.Analyze.UnwrapPhaseDegrees(resultPhase);
        }
示例#11
0
        public MainView()
        {
            InitializeComponent();
            this.ImuDebugData           = new InertialMeasurementUnit();
            this.CustomerIMU            = new IMUCustomer();
            this.Altimeter              = new Altimeter();
            this.Ethernet               = new UDP();
            this.FFTData                = new FFT();
            this.GNSSData               = new GNSS();
            this.NewDebugImuData        = false;
            this.NewCustomerData        = false;
            this.NewProximitySensorData = false;
            this.NewAltimeterData       = false;
            this.NewFFTData             = false;
            counter = 0;

            loadDebugIMU(this.Ethernet);
            loadCustomerData(this.Ethernet);
            LoadProximitySensor(this.Ethernet);
            LoadAltimeterData(this.Ethernet);
            LoadFFTData(this.Ethernet);
            LoadGNSSData(this.Ethernet);
            this.EthernetRecvThread = new Thread(this.Ethernet.Start);
            this.EthernetRecvThread.IsBackground = true;
            this.EthernetRecvThread.Start();

            DataFpsTimer.Interval   = 500;
            DataFpsTimer.Tick      += new EventHandler(dataFpsTick);
            GraphsFpsTimer.Interval = 1;
            GraphsFpsTimer.Tick    += new EventHandler(graphFpsTick);
            GraphsFpsTimer.Start();
            DataFpsTimer.Start();



            this.fftChart.ChartAreas["ChartArea1"].AxisX.Maximum = this.FFTData.N;
            CreateMap();
        }
示例#12
0
    // Use this for initialization
    void Start()
    {
        n = testMatrix.GetLength(0);
        m = testMatrix.GetLength(1);


        cloneArr      = new GameObject[n, m];
        ftCloneArr    = new GameObject[n, m];
        iftCloneArr   = new GameObject[n, m];
        ftTestMatrix  = FFT.FFT2D(testMatrix, n, m, 1);
        iftTestMatrix = FFT.FFT2D(ftTestMatrix, n, m, -1);

        //Display the test matrix and its FFT
        for (int i = 0; i < n; i++)
        {
            for (int j = 0; j < m; j++)
            {
                Vector3 pos   = new Vector3(startPos.x + i, startPos.y + ((float)testMatrix[i, j].real) / 2, startPos.z + j);
                Vector3 ftPos = new Vector3(ftStartPos.x + i,
                                            ftStartPos.y + (System.Math.Abs((float)ftTestMatrix[i, j].real)) / 2,
                                            ftStartPos.z + j);
                Vector3    iftPos   = new Vector3(iftStartPos.x + i, iftStartPos.y + ((float)iftTestMatrix[i, j].real) / 2, iftStartPos.z + j);
                Quaternion rotation = new Quaternion(0, 0, 0, 0);

                GameObject clone    = Instantiate(barPrefab, pos, rotation);
                GameObject ftClone  = Instantiate(fftBarPrefab, ftPos, rotation);
                GameObject iftClone = Instantiate(iftBarPrefab, iftPos, rotation);

                cloneArr[i, j]    = clone;
                ftCloneArr[i, j]  = ftClone;
                iftCloneArr[i, j] = iftClone;

                clone.transform.localScale    = new Vector3(1f, (float)testMatrix[i, j].real, 1f);
                ftClone.transform.localScale  = new Vector3(1f, System.Math.Abs((float)ftTestMatrix[i, j].real), 1f);
                iftClone.transform.localScale = new Vector3(1f, (float)iftTestMatrix[i, j].real, 1f);
            }
        }
    }
示例#13
0
    static void Main()
    {
        var h = Console.ReadLine().Split();

        char[] sa = h[0].ToCharArray(), sb = h[1].ToCharArray();

        var neg_a  = sa[0] == '-';
        var neg_b  = sb[0] == '-';
        var neg_ab = neg_a ^ neg_b;

        var a = Array.ConvertAll(sa, c => (long)(c - '0'));
        var b = Array.ConvertAll(sb, c => (long)(c - '0'));

        Array.Reverse(a);
        Array.Reverse(b);
        if (neg_a)
        {
            Array.Resize(ref a, a.Length - 1);
        }
        if (neg_b)
        {
            Array.Resize(ref b, b.Length - 1);
        }

        var ab = FFT.Convolution(a, b);

        for (int i = 0; i < ab.Length - 1; i++)
        {
            if (ab[i] < 10)
            {
                continue;
            }
            ab[i + 1] += ab[i] / 10;
            ab[i]     %= 10;
        }

        Console.WriteLine(ToString(ab, neg_ab));
    }
    public static float[] GetFrequencySpectrum(float[] soundData)
    {
        int grainSize = soundData.Length;

        if (!Mathf.IsPowerOfTwo(grainSize))
        {
            throw new System.ArgumentException("Grain Size needs to be a power of 2");
        }

        Complex[] complexData = new Complex[grainSize];
        for (int i = 0; i < grainSize; i++)
        {
            complexData[i] = new Complex(soundData[i], 0);
        }

        FFT.CalculateFFT(complexData, false);
        for (int i = 0; i < grainSize; i++)
        {
            soundData[i] = (float)complexData[i].magnitude;
        }

        return(soundData);
    }
示例#15
0
        public void FFT2()
        {
            double[] realPoints = { 1, 2.34, 78.94, 432987746, 3.14159, -32, -99932, 1, 0, 0 };
            double[] imgPoints  = { 0, 0, 0, 323, -32, 43.32234, 3.163, 832, -0.003, 0 };

            var fValues = new Complex[realPoints.Length / 2][];
            var fResult = new Complex[realPoints.Length / 2][];

            for (int i = 0; i < fValues.GetLength(0); i++)
            {
                fValues[i]    = new Complex[2];
                fValues[i][0] = new Complex(realPoints[2 * i], imgPoints[2 * i]);
                fValues[i][1] = new Complex(realPoints[2 * i + 1], imgPoints[2 * i + 1]);

                fResult[i] = FFT.PerformFFT(fValues[i]);
            }

            for (int i = 0; i < fValues.Length; i++)
            {
                Assert.AreEqual(fValues[i][0] + fValues[i][1], fResult[i][0]);
                Assert.AreEqual(fValues[i][0] - fValues[i][1], fResult[i][1]);
            }
        }
    // Fast Fourier Transform (FFT) of an audio buffer. This provides an array of frequency strength.
    float[] ProcessAudioBufferFFT(float[] buffer)
    {
        // Because the FFT process is processor intensive, order of operation matters for these commands

        // Initialize the FFT
        uint log2 = 0;

        uint.TryParse(Mathf.Log(buffer.Length, 2).ToString(), out log2);
        FFT fftAnalysis = new FFT();

        fftAnalysis.Init(log2);

        // Create the arrays holding our data
        double[] spectrumReal = new double[buffer.Length];
        for (int i = 0; i < buffer.Length; i++)
        {
            spectrumReal[i] = (double)buffer[i];
        }
        double[] spectrumImaginary = new double[buffer.Length];

        // Run the FFT and modify the array values in place
        fftAnalysis.Run(spectrumReal, spectrumImaginary);

        // Cast HALF the spectrum into float that is further processed using root mean square
        int pointCount = (int)(spectrumReal.Length * 0.5f);

        float[] fftSpectrum = new float[pointCount - SPECTRUM_INDEX_CUTOFF];
        for (int i = 0; i < fftSpectrum.Length; i++)
        {
            float imaginary = (float)spectrumImaginary[i + SPECTRUM_INDEX_CUTOFF];
            float real      = (float)spectrumReal[i + SPECTRUM_INDEX_CUTOFF];
            float value     = Mathf.Sqrt((imaginary * imaginary) + (real * real));
            fftSpectrum[i] = Mathf.Abs(value);
        }

        return(fftSpectrum);
    }
示例#17
0
    void TakeTestN(Vector3Int N)
    {
        isf.N = N;


        isf.InitISF();

        psi1 = FFT.CreateRenderTexture3D(N[0], N[1], N[2], RenderTextureFormat.RGFloat);
        psi2 = FFT.CreateRenderTexture3D(N[0], N[1], N[2], RenderTextureFormat.RGFloat);
        isf.InitializePsi(ref psi1, ref psi2);

        var watch = new System.Diagnostics.Stopwatch();

        watch.Start();

        for (int i = 0; i < 5; ++i)
        {
            isf.current_tick += 1;

            isf.ShroedingerIntegration(ref psi1, ref psi2);
            isf.Normalize(ref psi1, ref psi2);
            isf.PressureProject(ref psi1, ref psi2);
            fft.ExportComplex3D(psi1, null);
            Debug.Log("  At: " + i.ToString());
        }

        watch.Stop();
        BenchmarkSingleResult ben = new BenchmarkSingleResult();

        ben.milli = watch.ElapsedMilliseconds / 5.0;
        ben.Nx    = N.x;
        ben.Ny    = N.y;
        ben.Nz    = N.z;
        ben.scale = N.x * N.y * N.z;

        result.results.Add(ben);
    }
示例#18
0
        internal static void GetMinimumPhaseSpectrum(MinimumPhaseAnalysis minimumPhase)
        {
            var fftSize = minimumPhase.FFTSize;

            for (var i = fftSize / 2 + 1; i < fftSize; i++)
            {
                minimumPhase.LogSpectrum[i] = minimumPhase.LogSpectrum[fftSize - i];
            }

            FFT.Execute(minimumPhase.InverseFFT);
            var cepstrum = minimumPhase.Cepstrum;

            cepstrum[0] = new Complex(cepstrum[0].Real, cepstrum[0].Imaginary);
            for (int i = 1, limit = fftSize / 2; i < limit; i++)
            {
                cepstrum[i] = new Complex(cepstrum[i].Real * 2.0, cepstrum[i].Imaginary * -2.0);
            }
            cepstrum[fftSize / 2] = new Complex(cepstrum[fftSize / 2].Real, cepstrum[fftSize / 2].Imaginary * -1.0);
            for (var i = fftSize / 2 + 1; i < fftSize; i++)
            {
                cepstrum[i] = new Complex();
            }

            FFT.Execute(minimumPhase.ForwardFFT);

            // Since x is complex number, calculation of exp(x) is as following.
            // Note: This FFT library does not keep the aliasing.
            var mininimumPhaseSpectrum = minimumPhase.MinimumPhaseSpectrum;

            for (int i = 0, limit = fftSize / 2; i <= limit; i++)
            {
                var tmp       = Math.Exp(mininimumPhaseSpectrum[i].Real / fftSize);
                var real      = tmp * Math.Cos(mininimumPhaseSpectrum[i].Imaginary / fftSize);
                var imaginary = tmp * Math.Sin(mininimumPhaseSpectrum[i].Imaginary / fftSize);
                mininimumPhaseSpectrum[i] = new Complex(real, imaginary);
            }
        }
示例#19
0
        public static void Main(String[] args)
        {
            //var a = new Matrix<int, IntegerRing>(new int[,] { { 1, 2 }, { 3, 4 }, { 5, 6 } });
            //var b = new Matrix<int, IntegerRing>(new int[,] { { 1, 2, 3 }, { 4, 5, 6 } });

            //Console.WriteLine(a);
            //Console.WriteLine(b);
            //Console.WriteLine(a * b);
            //Polynomial<Complex, ComplexRing> p = new Polynomial<Complex, ComplexRing>(1, 2, 3, 4, 5);
            //Polynomial<Complex, ComplexRing> q = new Polynomial<Complex, ComplexRing>(1, 2, 3, 4, 5);
            Polynomial <Complex, ComplexRing> p = new Polynomial <Complex, ComplexRing>(1, 2, 1);

            Console.WriteLine(p);


            var q = FFT.Transform(p, false);

            Console.WriteLine(q);
            var k = FFT.Transform(q, true);

            Console.WriteLine(k);

            Console.ReadKey();
        }
示例#20
0
        static void Main()
        {
            FFT fft = new FFT();

            fft.Initialize(4096);

            double Fs = 1000;

            double[] d = new double[4096];
            for (int i = 0; i < 4096; i++)
            {
                double t = i / Fs;

                d[i] = Math.Sin(Math.PI * 2.0 * t * 200.0) + 0.2 * Math.Sin(Math.PI * 2.0 * t * 90.0);
            }

            var c = fft.Execute(d);



            Application.EnableVisualStyles();
            Application.SetCompatibleTextRenderingDefault(false);
            Application.Run(new MainForm());
        }
示例#21
0
    public void InitISF()
    {
        int[] res = GetGrids();

        SchroedingerMul = FFT.CreateRenderTexture3D(N[0], N[1], N[2], RenderTextureFormat.RGFloat);
        PossionMul      = FFT.CreateRenderTexture3D(N[0], N[1], N[2], RenderTextureFormat.RFloat);
        Velocity        = FFT.CreateRenderTexture3D(N[0], N[1], N[2], RenderTextureFormat.ARGBFloat);
        Divergence      = FFT.CreateRenderTexture3D(N[0], N[1], N[2], RenderTextureFormat.RGFloat);
        TempRT          = FFT.CreateRenderTexture3D(N[0], N[1], N[2], RenderTextureFormat.RGFloat);

        fft.OutputRT = TempRT;
        fft.SetN(N);

        ISFCS.SetVector("size", size);
        ISFCS.SetInts("res", res);
        ISFCS.SetFloat("hbar", hbar);
        ISFCS.SetFloat("dt", estimate_dt);

        ISFCS.SetTexture(kernelInitBuffer, "SchroedingerMul", SchroedingerMul);
        ISFCS.SetTexture(kernelInitBuffer, "PossionMul", PossionMul);
        DispatchISFCS(kernelInitBuffer);

        fft.fftshift(ref SchroedingerMul, ref TempRT);
    }
示例#22
0
        private Complex[][] transformToFFT(byte[] audio, int chunkSize)
        {
            int totalSize = audio.Length;

            int amountPossible = totalSize / chunkSize;

            //When turning into frequency domain we'll need complex numbers:
            Complex[][] results = new Complex[amountPossible][];

            //For all the chunks:
            for (int times = 0; times < amountPossible; times++)
            {
                Complex[] complex = new Complex[chunkSize];
                for (int i = 0; i < chunkSize; i++)
                {
                    //Put the time domain data into a complex number with imaginary part as 0:
                    complex[i] = new Complex(audio[(times * chunkSize) + i], 0);
                }
                //Perform FFT analysis on the chunk:
                results[times] = FFT.fft(hamming(complex));
            }

            return(results);
        }
示例#23
0
        public void RealFFT8()
        {
            var values = new Complex[8];

            for (int i = 0; i < values.Length; i++)
            {
                values[i] = new Complex(i, 0);
            }

            double[] expectedReal =
                Enumerable.Repeat(28.0, 1)
                .Concat(Enumerable.Repeat(-4.0, values.Length - 1))
                .ToArray();

            double[] expectedImg = { 0, 9.656854, 4, 1.656854, 0, -1.656854, -4, -9.656854 };

            var result = FFT.PerformFFT(values);

            for (int i = 0; i < result.Length; i++)
            {
                Assert.AreEqual(expectedReal[i], result[i].Real, delta: Math.Pow(10, -5));
                Assert.AreEqual(expectedImg[i], result[i].Imaginary, delta: Math.Pow(10, -5));
            }
        }
        public static Image AnalyseLocation(double[] signal, int sr, double startTimeInSeconds, int windowWidth)
        {
            int binCount = windowWidth / 2;

            int location = (int)Math.Round(startTimeInSeconds * sr); //assume location points to start of grunt

            if (location >= signal.Length)
            {
                LoggedConsole.WriteErrorLine("WARNING: Location is beyond end of signal.");
                return(null);
            }

            int nyquist = sr / 2;

            FFT.WindowFunc wf               = FFT.Hamming;
            var            fft              = new FFT(windowWidth, wf);
            int            maxHz            = 1000; // max frequency to display in fft image
            double         hzPerBin         = nyquist / (double)binCount;
            int            requiredBinCount = (int)Math.Round(maxHz / hzPerBin);

            double[] subsampleWav = DataTools.Subarray(signal, location, windowWidth);
            var      spectrum     = fft.Invoke(subsampleWav);

            // convert to power
            spectrum = DataTools.SquareValues(spectrum);
            spectrum = DataTools.filterMovingAverageOdd(spectrum, 3);
            spectrum = DataTools.normalise(spectrum);
            var subBandSpectrum = DataTools.Subarray(spectrum, 1, requiredBinCount); // ignore DC in bin zero.

            var startTime = TimeSpan.FromSeconds(startTimeInSeconds);

            double[] scoreArray = CalculateScores(subBandSpectrum, windowWidth);
            Image    image4     = GraphsAndCharts.DrawWaveAndFft(subsampleWav, sr, startTime, spectrum, maxHz * 2, scoreArray);

            return(image4);
        }
示例#25
0
    public static Complex[] convolve(Complex[] carr1, Complex[] carr2)
    {
        Complex complex = new Complex((double)0f, (double)0f);

        Complex[] array = new Complex[2 * carr1.Length];
        for (int i = 0; i < carr1.Length; i++)
        {
            array[i] = carr1[i];
        }
        for (int i = carr1.Length; i < 2 * carr1.Length; i++)
        {
            array[i] = complex;
        }
        Complex[] array2 = new Complex[2 * carr2.Length];
        for (int j = 0; j < carr2.Length; j++)
        {
            array2[j] = carr2[j];
        }
        for (int j = carr2.Length; j < 2 * carr2.Length; j++)
        {
            array2[j] = complex;
        }
        return(FFT.cconvolve(array, array2));
    }
示例#26
0
        static void FastFFTFilt(double[] x, double[] h, int fftSize, ForwardRealFFT forwardRealFFT, InverseRealFFT inverseRealFFT, double[] y)
        {
            for (var i = 0; i < x.Length; i++)
            {
                forwardRealFFT.Waveform[i] = x[i] / fftSize;
            }
            if (x.Length < fftSize)
            {
                Array.Clear(forwardRealFFT.Waveform, x.Length, fftSize - x.Length);
            }
            FFT.Execute(forwardRealFFT.ForwardFFT);
            var xSpectrum = new Complex[fftSize];

            Array.Copy(forwardRealFFT.Spectrum, xSpectrum, fftSize / 2 + 1);

            for (var i = 0; i < h.Length; i++)
            {
                forwardRealFFT.Waveform[i] = h[i] / fftSize;
            }
            if (h.Length < fftSize)
            {
                Array.Clear(forwardRealFFT.Waveform, h.Length, fftSize - h.Length);
            }
            FFT.Execute(forwardRealFFT.ForwardFFT);

            for (var i = fftSize / 2 + 1; i > -1; i--)
            {
                inverseRealFFT.Spectrum[i] = new Complex(
                    xSpectrum[i].Real * forwardRealFFT.Spectrum[i].Real - xSpectrum[i].Imaginary * forwardRealFFT.Spectrum[i].Imaginary,
                    xSpectrum[i].Real * forwardRealFFT.Spectrum[i].Imaginary + xSpectrum[i].Imaginary * forwardRealFFT.Spectrum[i].Real
                    );
            }
            FFT.Execute(inverseRealFFT.InverseFFT);

            inverseRealFFT.Waveform.BlockCopy(0, y, 0, fftSize);
        }
示例#27
0
        double D4CLoveTrainSub(double[] x, int fs, double currentF0, double currentPosition, int f0Length, int fftSize, int boundary0, int boundary1, int boundary2, ForwardRealFFT forwardRealFFT)
        {
            var powerSpectrum = new double[fftSize];

            var windowLength = MatlabFunctions.MatlabRound(1.5 * fs / currentF0) * 2 + 1;

            GetWindowedWaveform(x, fs, currentF0, currentPosition, WindowType.Blackman, 3.0, forwardRealFFT.Waveform);

            Array.Clear(forwardRealFFT.Waveform, windowLength, fftSize - windowLength);
            FFT.Execute(forwardRealFFT.ForwardFFT);

            var spectrum = forwardRealFFT.Spectrum;

            for (int i = boundary0 + 1, limit = fftSize / 2 + 1; i < limit; i++)
            {
                powerSpectrum[i] = spectrum[i].Real * spectrum[i].Real + spectrum[i].Imaginary * spectrum[i].Imaginary;
            }
            for (var i = boundary0; i <= boundary2; i++)
            {
                powerSpectrum[i] += powerSpectrum[i - 1];
            }

            return(powerSpectrum[boundary1] / powerSpectrum[boundary2]);
        }
示例#28
0
    static object Solve()
    {
        var n = int.Parse(Console.ReadLine());
        var a = ReadL();

        // g^{p-1} == 1
        var pg    = new long[p - 1];
        var pgMap = new long[p];

        pg[0] = 1;
        for (int i = 1; i < pg.Length; i++)
        {
            pg[i]        = pg[i - 1] * g % p;
            pgMap[pg[i]] = i;
        }

        var r = 0L;
        var c = new long[p - 1];

        foreach (var x in a)
        {
            if (x == 0)
            {
                continue;
            }
            c[pgMap[x]]++;
            r -= x * x % p;
        }
        var conv = FFT.Convolution(c, c);

        for (int i = 0; i < conv.Length; i++)
        {
            r += conv[i] * pg[i % (p - 1)];
        }
        return(r / 2);
    }
示例#29
0
        public static void Run()
        {
            //var frequencies = FitsIO.ReadFrequencies(@"C:\Users\Jon\github\p9-data\small\fits\simulation_point\freq.fits");
            //var uvw = FitsIO.ReadUVW(@"C:\Users\Jon\github\p9-data\small\fits\simulation_point\uvw.fits");
            var frequencies = FitsIO.ReadFrequencies(@"C:\dev\GitHub\p9-data\small\fits\simulation_point\freq.fits");
            var uvw         = FitsIO.ReadUVW(@"C:\dev\GitHub\p9-data\small\fits\simulation_point\uvw.fits");
            var flags       = new bool[uvw.GetLength(0), uvw.GetLength(1), frequencies.Length]; //completely unflagged dataset

            var    visibilitiesCount = flags.Length;
            int    gridSize          = 64;
            int    subgridsize       = 16;
            int    kernelSize        = 8;
            int    max_nr_timesteps  = 64;
            double cellSize          = 2.0 / 3600.0 * PI / 180.0;
            var    c = new GriddingConstants(visibilitiesCount, gridSize, subgridsize, kernelSize, max_nr_timesteps, (float)cellSize, 1, 0.0f);

            var metadata = Partitioner.CreatePartition(c, uvw, frequencies);

            var psfGrid = IDG.GridPSF(c, metadata, uvw, flags, frequencies);
            var psf     = FFT.Backward(psfGrid, c.VisibilitiesCount);

            FFT.Shift(psf);
            var maxPsf = psf[gridSize / 2, gridSize / 2];

            for (int i = 0; i < psf.GetLength(0); i++)
            {
                for (int j = 0; j < psf.GetLength(1); j++)
                {
                    psf[i, j] = psf[i, j] / maxPsf;
                }
            }
            FitsIO.Write(psf, "psf.fits");

            var truth = new double[64, 64];

            //truth[40, 50] = 1.5;
            truth[0, 0] = 1.7;
            var dirty = ConvolveFFTPadded(truth, psf);

            FitsIO.Write(truth, "truth.fits");
            FitsIO.Write(dirty, "dirty.fits");

            var psf2 = ConvolveFFT(psf, psf);
            var b    = ConvolveFFTPadded(dirty, psf);
            var a    = psf2[gridSize / 2, gridSize / 2];

            /*
             * var integral = CalcPSf2Integral(psf);
             * FitsIO.Write(integral, "psfIntegral.fits");
             * var c0 = new double[64, 64];
             * var qY = 0;
             * var qX = 0;
             * c0[qY, qX] = 1.0;
             * c0 = Convolve(c0, psf);
             * FitsIO.Write(c0, "cx0.fits");
             * var cx = ConvolveFFT(c0, psf);
             * FitsIO.Write(cx, "cx1.fits");
             * var a2 = cx[qY, qX];
             * var res = QueryIntegral(integral, qY, qX);*/

            var x = new double[gridSize, gridSize];
            //Deconv(x, dirty, psf, psf2, a, 0.0);

            var dCopy = new double[gridSize, gridSize];

            for (int i = 0; i < b.GetLength(0); i++)
            {
                for (int j = 0; j < b.GetLength(1); j++)
                {
                    dCopy[i, j] = dirty[i, j];
                }
            }
            var x2        = new double[gridSize, gridSize];
            var converged = GreedyCD.Deconvolve2(x2, dirty, psf, 0.0, 1.0, 500, dCopy);
        }
示例#30
0
        static void Main(string[] args)
        {
            const int FFTSize        = 240;
            const int FFTComplexSize = FFTSize / 2 + 1;
            var       fft            = new FFT(FFTSize, fftw_direction.Forward);
            var       input          = new Complex[FFTSize];
            var       input2         = new Complex[FFTSize];
            var       output         = new Complex[FFTSize];
            const int RectWaveWidth  = 40;
            const int RectWaveWidth2 = 30;
            var       conv           = new Convolver(Kernel);

            for (int i = 0; i < FFTSize; i++)
            {
                //input[i] = i / RectWaveWidth % 2 == 0 ? 1 : 0;
                //input[i] += i / RectWaveWidth2 % 2 == 0 ? 1 : 0;
                input[i] = 1000 + 50000 * Math.Sin(2 * Math.PI / FFTSize * 20.1 * i) + 40000 * Math.Sin(2 * Math.PI / FFTSize * 7 * i) + 9000 * Math.Sin(2 * Math.PI / FFTSize * 119 * i);
                // input[i] = 1 * Math.Sin(2 * Math.PI / FFTSize * 7 * i);
                // input[i] *= 2 * Math.Cos(2 * Math.PI / FFTSize * 5 * i);
            }

            var filter = new Complex[FFTSize];

            for (int i = 0; i < FFTSize; i++)
            {
                filter[i] = Filter(i, FFTSize);
            }

            //fixed (double* kernel = Kernel) {
            //	int len = conv.Convolve(input, FFTSize, input2, FFTSize);
            //	len = conv.ConvolveFinal(input2 + len, FFTSize - len);
            //}

            //input[0] = 1;
            //for (int i = 1; i < FFTSize; i++) {
            //	input[i] = 0;
            //}
            //for (int i = 0; i < FFTSize; i++) {
            //	input[i] = i % 2 == 0 ? 1 : 0;
            //}
            fft.WriteInput(input);
            fft.Execute();
            fft.ReadOutput(output);

            {
                var sum = 0d;
                for (int i = 0; i < output.Length; i++)
                {
                    var c   = output[i] / (i > 0 ? fft.FFTSize / 2 : FFTSize);
                    var abs = Complex.Abs(c);
                    sum += abs;
                    Console.WriteLine($"{i}=abs({c.Real:N6},{c.Imaginary:N6})={abs:N6}");
                }
                Console.WriteLine($"sum={sum:N6}");
            }

            //output[0] = 100 * FFTSize;
            //for (int i = 1; i < 50; i++) {
            //	output[i] = output[FFTSize - i] = 100 * FFTSize / 2;
            //}

            for (int i = 0; i < FFTSize; i++)
            {
                output[i] *= filter[i];
            }

            var ifft = new FFT(FFTSize, fftw_direction.Backward);

            ifft.WriteInput(output);
            ifft.Execute();
            ifft.ReadOutput(input2);

            for (int i = 0; i < input2.Length; i++)
            {
                input2[i] /= FFTSize;
            }

            fft.WriteInput(input2);
            fft.Execute();
            fft.ReadOutput(output);

            {
                var sum = 0d;
                for (int i = 0; i < output.Length; i++)
                {
                    var c   = output[i] / (i > 0 ? fft.FFTSize / 2 : FFTSize);
                    var abs = Complex.Abs(c);
                    sum += abs;
                    Console.WriteLine($"{i}=abs({c.Real:N6},{c.Imaginary:N6})={abs:N6}");
                }
                Console.WriteLine($"sum={sum:N6}");
            }
        }
示例#31
0
    void AnalyzeAudio()
    {
        if (soundFile)
        {
            //The array for the averaged sample data. (L,R,L,R,L,R are averaged into (L+R)/2, (L+R)/2, (L+R)/2)
            float[] preprocessedSamples = new float[numSamples];

            int   numberOfSamplesProcessed = 0;
            float combinedChannelAverage   = 0f;

            Debug.Log("Starting sample processing...");
            for (int i = 0; i < allChannelsSamples.Length; i++)
            {
                combinedChannelAverage += allChannelsSamples[i];
                //for(int j = 0; j < numChannels; j++)
                //{
                //	combinedChannelAverage += allChannelsSamples[i + j];
                //	numberOfSamplesProcessed++;
                //}
                //preprecessedSamples[i/numChannels] = combinedChannelAverage / (float)numChannels;
                //combinedChannelAverage = 0;

                // Each time we have processed all channels samples for a point in time, we will store the average of the channels combined
                if ((i + 1) % numChannels == 0)
                {
                    preprocessedSamples[numberOfSamplesProcessed] = combinedChannelAverage / numChannels;
                    numberOfSamplesProcessed++;
                    combinedChannelAverage = 0f;
                }
            }

            int      specSampSize = 1024;
            int      iterations   = preprocessedSamples.Length / specSampSize;
            double[] sampleChunk  = new double[specSampSize];

            //LomFFT fft = new LomFFT();
            FFT fft = new FFT();
            fft.Initialize((System.UInt32)specSampSize);

            SpectralFluxAnalyzer preproAnalyzer = new SpectralFluxAnalyzer();

            for (int i = 0; i < iterations; ++i)
            {
                System.Array.Copy(preprocessedSamples, i * specSampSize, sampleChunk, 0, specSampSize);

                double[] windowCoefs         = DSP.Window.Coefficients(DSP.Window.Type.Hanning, (uint)specSampSize);
                double[] scaledSpectrumChunk = DSP.Math.Multiply(sampleChunk, windowCoefs);
                double   scaleFactor         = DSP.Window.ScaleFactor.Signal(windowCoefs);

                // Perform the FFT and convert output (complex numbers) to Magnitude
                System.Numerics.Complex[] fftSpectrum = fft.Execute(scaledSpectrumChunk);
                double[] scaledFFTSpectrum            = DSP.ConvertComplex.ToMagnitude(fftSpectrum);
                scaledFFTSpectrum = DSP.Math.Multiply(scaledFFTSpectrum, scaleFactor);

                //old
                //fft.FFT(sampleChunk);



                float currTime = getTimeFromIndex(i) * specSampSize;
                preproAnalyzer.analyzeSpectrum(System.Array.ConvertAll(scaledFFTSpectrum, x => (float)x), currTime);                 //AnalyzeSpectrum(data...);
            }

            //foreach(SpectralFluxAnalyzer.SpectralFluxInfo specInfo in preproAnalyzer.spectralFluxSamples)
            //{
            //	if(specInfo.isPeak)
            //	{
            //		Debug.Log("Peak at: " + specInfo.time);
            //	}
            //}

            importantMoments = null;
            importantMoments = new AnimationCurve();
            freqCurve        = null;
            freqCurve        = new AnimationCurve();

            Debug.Log("Starting graph processing...");
            for (int i = 0; i < preproAnalyzer.spectralFluxSamples.Count; i++)
            {
                if (preproAnalyzer.spectralFluxSamples[i].isPeak)
                {
                    importantMoments.AddKey(preproAnalyzer.spectralFluxSamples[i].time, 1);
                    freqCurve.AddKey(preproAnalyzer.spectralFluxSamples[i].time, preproAnalyzer.spectralFluxSamples[i].spectralFlux);
                }
            }

            Debug.Log("Done!");
            Debug.Log(numberOfSamplesProcessed);


            //AudioListener.GetSpectrumData(spectrums, 0, FFTWindow.BlackmanHarris);
            //Debug.Log(AudioSettings.outputSampleRate);
        }
    }
示例#32
0
 public DSPLibFFTProvider(int binSize)
 {
     fft = new FFT();
     fft.Initialize((UInt32)binSize);
     this.binSize = binSize;
 }
示例#33
0
        public static bool Deconvolve2(double[,] xImage, double[,] res, double[,] psf, double lambda, double alpha, Rectangle rec, int maxIteration = 100, double[,] dirtyCopy = null)
        {
            var yPsfHalf  = psf.GetLength(0) / 2;
            var xPsfHalf  = psf.GetLength(1) / 2;
            var integral  = CommonDeprecated.PSF.CalcPSFScan(psf);
            var resPadded = new double[res.GetLength(0) + psf.GetLength(0), res.GetLength(1) + psf.GetLength(1)];

            for (int y = 0; y < res.GetLength(0); y++)
            {
                for (int x = 0; x < res.GetLength(1); x++)
                {
                    resPadded[y + yPsfHalf, x + xPsfHalf] = res[y, x];
                }
            }

            //invert the PSF, since we actually do want to correlate the psf with the residuals. (The FFT already inverts the psf, so we need to invert it again to not invert it. Trust me.)
            var psfPadded  = new double[res.GetLength(0) + psf.GetLength(0), res.GetLength(1) + psf.GetLength(1)];
            var psfYOffset = res.GetLength(0) / 2;
            var psfXOffset = res.GetLength(1) / 2;

            for (int y = 0; y < psf.GetLength(0); y++)
            {
                for (int x = 0; x < psf.GetLength(1); x++)
                {
                    psfPadded[y + psfYOffset + 1, x + psfXOffset + 1] = psf[psf.GetLength(0) - y - 1, psf.GetLength(1) - x - 1];
                }
            }
            FFT.Shift(psfPadded);
            var PSFPadded = FFT.Forward(psfPadded, 1.0);

            DeconvolveGreedy2(xImage, resPadded, res, psf, PSFPadded, integral, lambda, alpha, rec, 100);

            var    xCummulatedDiff = new double[xImage.GetLength(0), xImage.GetLength(1)];
            int    iter            = 0;
            bool   converged       = false;
            double epsilon         = 1e-4;
            double objective       = double.MaxValue;

            while (!converged & iter < maxIteration)
            {
                var oOld = objective;
                objective  = GreedyCD.CalcElasticNetObjective(xImage, res, integral, lambda, alpha, rec.Y, rec.X);
                objective += GreedyCD.CalcDataObjective(resPadded, res, yPsfHalf, yPsfHalf);
                Console.WriteLine("Objective \t" + objective);

                if (oOld < objective)
                {
                    Console.Write("error");
                }
                var RES = FFT.Forward(resPadded, 1.0);
                var B   = Common.Fourier2D.Multiply(RES, PSFPadded);
                var b   = FFT.Backward(B, (double)(B.GetLength(0) * B.GetLength(1)));

                var activeSet = new List <Tuple <int, int> >();
                for (int y = rec.Y; y < rec.YLength; y++)
                {
                    for (int x = rec.X; x < rec.XLength; x++)
                    {
                        var yLocal   = y - rec.Y;
                        var xLocal   = x - rec.X;
                        var currentA = CommonDeprecated.PSF.QueryScan(integral, y, x, res.GetLength(0), res.GetLength(1));
                        var old      = xImage[yLocal, xLocal];
                        var xTmp     = old + b[y + yPsfHalf, x + xPsfHalf] / currentA;
                        xTmp = CommonDeprecated.ShrinkElasticNet(xTmp, lambda, alpha);
                        var xDiff = old - xTmp;

                        if (Math.Abs(xDiff) > epsilon)
                        {
                            activeSet.Add(new Tuple <int, int>(y, x));
                        }
                    }
                }

                //active set iterations
                Console.WriteLine("--------------------count:" + activeSet.Count + "------------------");
                converged = activeSet.Count == 0;
                bool activeSetConverged = activeSet.Count == 0;
                var  innerMax           = 40;
                var  innerIter          = 0;
                while (!activeSetConverged & innerIter <= innerMax)
                {
                    var oTest = GreedyCD.CalcElasticNetObjective(xImage, res, integral, lambda, alpha, rec.Y, rec.X);
                    oTest += GreedyCD.CalcDataObjective(resPadded, res, yPsfHalf, yPsfHalf);

                    activeSetConverged = true;
                    var delete = new List <Tuple <int, int> >();
                    foreach (var pixel in activeSet)
                    {
                        var y        = pixel.Item1;
                        var x        = pixel.Item2;
                        var yLocal   = y - rec.Y;
                        var xLocal   = x - rec.X;
                        var xOld     = xImage[yLocal, xLocal];
                        var currentB = CalculateB(resPadded, res, psf, y, x);

                        //calculate minimum of parabola, eg -2b/a
                        var xTmp = xOld + currentB / CommonDeprecated.PSF.QueryScan(integral, y, x, res.GetLength(0), res.GetLength(1));
                        xTmp = GreedyCD.ShrinkPositive(xTmp, lambda * alpha) / (1 + lambda * (1 - alpha));
                        var xDiff = xOld - xTmp;

                        if (Math.Abs(xDiff) > epsilon)
                        {
                            activeSetConverged = false;
                            //Console.WriteLine(Math.Abs(xOld - xTmp) + "\t" + y + "\t" + x);
                            xImage[yLocal, xLocal]           = xTmp;
                            xCummulatedDiff[yLocal, xLocal] += xDiff;
                            GreedyCD.UpdateResiduals2(resPadded, res, psf, y, x, xDiff, yPsfHalf, xPsfHalf);
                        }
                        else if (xTmp == 0.0)
                        {
                            // zero, remove from active set
                            activeSetConverged               = false;
                            xImage[yLocal, xLocal]           = 0.0;
                            xCummulatedDiff[yLocal, xLocal] += xOld;
                            GreedyCD.UpdateResiduals2(resPadded, res, psf, y, x, xDiff, yPsfHalf, xPsfHalf);
                            delete.Add(pixel);
                            //Console.WriteLine("drop pixel \t" + xTmp + "\t" + y + "\t" + x);
                        }
                    }
                    innerIter++;
                }

                /*
                 * foreach (var pixel in delete)
                 *  activeSet.Remove(pixel);
                 *
                 * //exchange with other nodes
                 * var allXDiff = new List<PixelExchange>();
                 * for (int y = 0; y < xCummulatedDiff.GetLength(0); y++)
                 *  for (int x = 0; x < xCummulatedDiff.GetLength(1); x++)
                 *  {
                 *      if (xCummulatedDiff[y, x] > 0.0)
                 *      {
                 *          var p = new PixelExchange();
                 *          p.Rank = comm.Rank;
                 *          p.Y = rec.Y + y;
                 *          p.X = rec.X + x;
                 *          p.Value = xCummulatedDiff[y, x];
                 *          allXDiff.Add(p);
                 *          xCummulatedDiff[y, x] = 0.0;
                 *      }
                 *  }
                 *
                 * var allNonZeros = comm.Allreduce(allXDiff, (aC, bC) =>
                 * {
                 *  aC.AddRange(bC);
                 *  return aC;
                 * });
                 *
                 * foreach (var p in allXDiff)
                 *  if (p.Rank != comm.Rank)
                 *      GreedyCD.UpdateResiduals2(resPadded, res, psf, p.Y, p.X, p.Value, yPsfHalf, xPsfHalf);*/

                RES = FFT.Forward(resPadded, 1.0);
                B   = Common.Fourier2D.Multiply(RES, PSFPadded);
                b   = FFT.Backward(B, (double)(B.GetLength(0) * B.GetLength(1)));

                iter++;
            }

            //copy back the residuals
            for (int y = 0; y < res.GetLength(0); y++)
            {
                for (int x = 0; x < res.GetLength(1); x++)
                {
                    res[y, x] = resPadded[y + yPsfHalf, x + xPsfHalf];
                }
            }

            return(converged);
        }
示例#34
0
	// ************************************************************************ //
	// Initialization
	// ************************************************************************ //	

	/**
	 * 
	 */
	void Start() 
	{
		this.m_dispertion 	= new OceanDispertion( this.settings );
		this.m_spectrum 	= new OceanSpectrum( this.settings );
		this.m_fourier 		= new FFT();
	}
示例#35
0
    private IEnumerator _AnalyseClip(AudioClip clip)
    {
        _clip = clip;

        _sampleRate = (int)sampleRate;
        _spectrumSamples = (int)(_clip.frequency * _clip.length / _sampleRate);
        _lastSpectrum = new float[_sampleRate / 2 + 1];
        _thresholdWindowSize = thresholdRadius * 2 + 1;

        _fft = new FFT(_sampleRate, _clip.frequency);

        //if(subBandFrequencies.Length > 1)
        {
            _fft.CustomAverages( subBands.ToArray() );
        //			_fft.CustomAverages(subBandFrequencies);
        //			subBands = subBandFrequencies.Length - 1;
        }
        //		else if(subBands > 1)
        //		_fft.LogAverages(subBands.Count);

        if(storeSpectrumData)
            _spectrumData = new List<float[]>(_spectrumSamples);

        _subBandWidth = _sampleRate / (subBands.Count * 2);

        _spectralFlux = new List< List <float> >(subBands.Count);
        _beats  = new List<List <float>>(subBands.Count);
        _nextBeatVals = new List<float>(subBands.Count);

        for(int i = 0 ; i < subBands.Count ; i++)
        {
            _spectralFlux.Add( new List<float>(_spectrumSamples) );
            _beats.Add( new List<float>(_spectrumSamples) );
            _nextBeatVals.Add(0);
        }

        _bpmCurve = new List<float>(_spectrumSamples);
        _summedSpectrum = new List<int>(_spectrumSamples);

        yield return StartCoroutine(_GetSpectrumData());
    }
示例#36
0
    public void getFullSpectrumThreaded(Action <float> callback)
    {
        try
        {
            // We only need to retain the samples for combined channels over the time domain
            float[] preProcessedSamples = new float[this._numTotalSamples];

            int   numProcessed           = 0;
            float combinedChannelAverage = 0f;
            for (int i = 0; i < _multiChannelSamples.Length; i++)
            {
                combinedChannelAverage += _multiChannelSamples[i];

                // Each time we have processed all channels samples for a point in time, we will store the average of the channels combined
                if ((i + 1) % this._numChannels == 0)
                {
                    preProcessedSamples[numProcessed] = combinedChannelAverage / this._numChannels;
                    numProcessed++;
                    combinedChannelAverage = 0f;
                }
            }

            //Debug.Log("Combine Channels done");
            //Debug.Log(preProcessedSamples.Length);

            // Once we have our audio sample data prepared, we can execute an FFT to return the spectrum data over the time domain
            int spectrumSampleSize = 1024;
            int iterations         = preProcessedSamples.Length / spectrumSampleSize;

            FFT fft = new FFT();
            fft.Initialize((UInt32)spectrumSampleSize);

            //Debug.Log(string.Format("Processing {0} time domain samples for FFT", iterations));
            double[] sampleChunk = new double[spectrumSampleSize];
            for (int i = 0; i < iterations; i++)
            {
                // Grab the current 1024 chunk of audio sample data
                Array.Copy(preProcessedSamples, i * spectrumSampleSize, sampleChunk, 0, spectrumSampleSize);

                // Apply our chosen FFT Window
                double[] windowCoefs         = DSP.Window.Coefficients(DSP.Window.Type.Hanning, (uint)spectrumSampleSize);
                double[] scaledSpectrumChunk = DSP.Math.Multiply(sampleChunk, windowCoefs);
                double   scaleFactor         = DSP.Window.ScaleFactor.Signal(windowCoefs);

                // Perform the FFT and convert output (complex numbers) to Magnitude
                Complex[] fftSpectrum       = fft.Execute(scaledSpectrumChunk);
                double[]  scaledFFTSpectrum = DSPLib.DSP.ConvertComplex.ToMagnitude(fftSpectrum);
                scaledFFTSpectrum = DSP.Math.Multiply(scaledFFTSpectrum, scaleFactor);

                // These 1024 magnitude values correspond (roughly) to a single point in the audio timeline
                float curSongTime = getTimeFromIndex(i) * spectrumSampleSize;

                // Send our magnitude data off to our Spectral Flux Analyzer to be analyzed for peaks
                _preProcessedSpectralFluxAnalyzer.analyzeSpectrum(Array.ConvertAll(scaledFFTSpectrum, x => (float)x), curSongTime);
                callback((i * 100) / iterations);
            }

            callback(100);
            //Debug.Log("Spectrum Analysis done");
            //Debug.Log("Background Thread Completed");
            _loadComplete = true;
        }
        catch (Exception e)
        {
            // Catch exceptions here since the background thread won't always surface the exception to the main thread
            Debug.Log(e.ToString());
        }
    }
 void StartAnalysis()
 {
     spectogramTexture = new Texture2D(textureWidth, textureHeight, TextureFormat.ARGB32, false);
     currentXCoord = 0;
     textureUpdateCount = 0;
     fft = new FFT(fftSampleRate, currentClip.frequency);
 }
示例#38
0
文件: Main.cs 项目: ptaa32/ARDOP
        private void UpdateWaterfall(ref byte[] bytNewSamples)
        {
            lock (static_UpdateWaterfall_dblI_Init)
            {
                try
                {
                    if (InitStaticVariableHelper(static_UpdateWaterfall_dblI_Init))
                    {
                        static_UpdateWaterfall_dblI = new double[1024];
                    }
                }
                finally
                {
                    static_UpdateWaterfall_dblI_Init.State = 1;
                }
            }
            lock (static_UpdateWaterfall_dblQ_Init)
            {
                try
                {
                    if (InitStaticVariableHelper(static_UpdateWaterfall_dblQ_Init))
                    {
                        static_UpdateWaterfall_dblQ = new double[1024];
                    }
                }
                finally
                {
                    static_UpdateWaterfall_dblQ_Init.State = 1;
                }
            }
            lock (static_UpdateWaterfall_dblReF_Init)
            {
                try
                {
                    if (InitStaticVariableHelper(static_UpdateWaterfall_dblReF_Init))
                    {
                        static_UpdateWaterfall_dblReF = new double[1024];
                    }
                }
                finally
                {
                    static_UpdateWaterfall_dblReF_Init.State = 1;
                }
            }
            lock (static_UpdateWaterfall_dblImF_Init)
            {
                try
                {
                    if (InitStaticVariableHelper(static_UpdateWaterfall_dblImF_Init))
                    {
                        static_UpdateWaterfall_dblImF = new double[1024];
                    }
                }
                finally
                {
                    static_UpdateWaterfall_dblImF_Init.State = 1;
                }
            }
            lock (static_UpdateWaterfall_aryLastY_Init)
            {
                try
                {
                    if (InitStaticVariableHelper(static_UpdateWaterfall_aryLastY_Init))
                    {
                        static_UpdateWaterfall_aryLastY = new int[256];
                    }
                }
                finally
                {
                    static_UpdateWaterfall_aryLastY_Init.State = 1;
                }
            }
            lock (static_UpdateWaterfall_intPtr_Init)
            {
                try
                {
                    if (InitStaticVariableHelper(static_UpdateWaterfall_intPtr_Init))
                    {
                        static_UpdateWaterfall_intPtr = 0;
                    }
                }
                finally
                {
                    static_UpdateWaterfall_intPtr_Init.State = 1;
                }
            }
            lock (static_UpdateWaterfall_dblMag_Init)
            {
                try
                {
                    if (InitStaticVariableHelper(static_UpdateWaterfall_dblMag_Init))
                    {
                        static_UpdateWaterfall_dblMag = new double[207];
                    }
                }
                finally
                {
                    static_UpdateWaterfall_dblMag_Init.State = 1;
                }
            }
            lock (static_UpdateWaterfall_FFT_Init)
            {
                try
                {
                    if (InitStaticVariableHelper(static_UpdateWaterfall_FFT_Init))
                    {
                        static_UpdateWaterfall_FFT = new FFT();
                    }
                }
                finally
                {
                    static_UpdateWaterfall_FFT_Init.State = 1;
                }
            }

            double dblMagAvg = 0;
            int intTrace = 0;
            Int32 intTuneLineLow = default(Int32);
            Int32 intTuneLineHi = default(Int32);
            Int32 intDelta = default(Int32);
            System.Drawing.Color clrTLC = Color.Chartreuse;
            int intBusyStatus = 0;
            for (int i = 0; i <= bytNewSamples.Length - 1; i += 2)
            {
                static_UpdateWaterfall_dblI(static_UpdateWaterfall_intPtr) = Convert.ToDouble(System.BitConverter.ToInt16(bytNewSamples, i));
                static_UpdateWaterfall_intPtr += 1;
                if (static_UpdateWaterfall_intPtr > 1023)
                    break; // TODO: might not be correct. Was : Exit For
            }
            if (static_UpdateWaterfall_intPtr < 1024)
                return;
            static_UpdateWaterfall_intPtr = 0;
            static_UpdateWaterfall_FFT.FourierTransform(1024, static_UpdateWaterfall_dblI, static_UpdateWaterfall_dblQ, static_UpdateWaterfall_dblReF, static_UpdateWaterfall_dblImF, false);
            for (int i = 0; i <= static_UpdateWaterfall_dblMag.Length - 1; i++)
            {
                //starting at ~300 Hz to ~2700 Hz Which puts the center of the signal in the center of the window (~1500Hz)
                static_UpdateWaterfall_dblMag(i) = (Math.Pow(static_UpdateWaterfall_dblReF(i + 25), 2) + Math.Pow(static_UpdateWaterfall_dblImF(i + 25), 2));
                // first pass
                dblMagAvg += static_UpdateWaterfall_dblMag(i);
            }
            intDelta = (stcConnection.intSessionBW / 2 + MCB.TuningRange) / 11.719;
            intTuneLineLow = Max((103 - intDelta), 3);
            intTuneLineHi = Min((103 + intDelta), 203);

            intBusyStatus = objBusy.BusyDetect(static_UpdateWaterfall_dblMag, intTuneLineLow, intTuneLineHi);
            if (intBusyStatus == 1)
            {
                clrTLC = Color.Fuchsia;

            }
            else if (intBusyStatus == 2)
            {
                clrTLC = Color.Gold;
            }
            if (static_UpdateWaterfall_intLastBusyStatus == 0 & intBusyStatus > 0)
            {
                objHI.QueueCommandToHost("BUSY TRUE");
                Debug.WriteLine("BUSY TRUE");
                static_UpdateWaterfall_intLastBusyStatus = intBusyStatus;
            }
            else if (intBusyStatus == 0 & static_UpdateWaterfall_intLastBusyStatus > 0)
            {
                objHI.QueueCommandToHost("BUSY FALSE");
                Debug.WriteLine("BUSY FALSE");
                static_UpdateWaterfall_intLastBusyStatus = intBusyStatus;
            }

            try
            {
                dblMagAvg = Math.Log10(dblMagAvg / 5000);
                for (int i = 0; i <= static_UpdateWaterfall_dblMag.Length - 1; i++)
                {
                    // The following provides some AGC over the waterfall to compensate for avg input level.
                    double y1 = (0.25 + 2.5 / dblMagAvg) * Math.Log10(0.01 + static_UpdateWaterfall_dblMag(i));
                    System.Drawing.Color objColor = default(System.Drawing.Color);
                    //  Set the pixel color based on the intensity (log) of the spectral line
                    if (y1 > 6.5)
                    {
                        objColor = Color.Orange;
                        // Strongest spectral line
                    }
                    else if (y1 > 6)
                    {
                        objColor = Color.Khaki;
                    }
                    else if (y1 > 5.5)
                    {
                        objColor = Color.Cyan;
                    }
                    else if (y1 > 5)
                    {
                        objColor = Color.DeepSkyBlue;
                    }
                    else if (y1 > 4.5)
                    {
                        objColor = Color.RoyalBlue;
                    }
                    else if (y1 > 4)
                    {
                        objColor = Color.Navy;
                    }
                    else
                    {
                        objColor = Color.Black;
                        // Weakest spectral line
                    }
                    if (i == 103)
                    {
                        bmpSpectrum.SetPixel(i, static_UpdateWaterfall_intWaterfallRow, Color.Tomato);
                        // 1500 Hz line (center)
                    }
                    else if ((i == intTuneLineLow | i == intTuneLineLow - 1 | i == intTuneLineHi | i == intTuneLineHi + 1))
                    {
                        bmpSpectrum.SetPixel(i, static_UpdateWaterfall_intWaterfallRow, clrTLC);
                    }
                    else
                    {
                        bmpSpectrum.SetPixel(i, static_UpdateWaterfall_intWaterfallRow, objColor);
                        // Else plot the pixel as received
                    }
                }
                // Using a new bit map allows merging the two parts of bmpSpectrum and plotting all at one time to eliminate GDI+ fault.
                intTrace = 1;
                bmpNewSpectrum = new Bitmap(bmpSpectrum.Width, bmpSpectrum.Height);
                // Top rectangle of the waterfall is Waterfall Row to bottom of bmpSpectrum
                intTrace = 2;
                Rectangle destRect1 = new Rectangle(0, 0, bmpSpectrum.Width, bmpSpectrum.Height - static_UpdateWaterfall_intWaterfallRow);
                // Now create rectangle for the bottom part of the waterfall. Top of bmpSpectrum to intWaterfallRow -1
                intTrace = 3;
                Rectangle destRect2 = new Rectangle(0, bmpSpectrum.Height - static_UpdateWaterfall_intWaterfallRow, bmpSpectrum.Width, static_UpdateWaterfall_intWaterfallRow);
                // Create a new graphics area to draw into the new bmpNewSpectrum
                intTrace = 4;
                Graphics graComposit = Graphics.FromImage(bmpNewSpectrum);
                // add the two rectangles to the graComposit
                intTrace = 5;
                graComposit.DrawImage(bmpSpectrum, destRect1, 0, static_UpdateWaterfall_intWaterfallRow, bmpSpectrum.Width, bmpSpectrum.Height - static_UpdateWaterfall_intWaterfallRow, GraphicsUnit.Pixel);
                intTrace = 6;
                graComposit.DrawImage(bmpSpectrum, destRect2, 0, 0, bmpSpectrum.Width, static_UpdateWaterfall_intWaterfallRow, GraphicsUnit.Pixel);
                intTrace = 7;
                graComposit.Dispose();
                //  the new composit bitmap has been constructed
                intTrace = 8;
                if ((graFrequency != null))
                {
                    intTrace = 9;
                    graFrequency.Dispose();
                    // this permits writing back to the graFrequency without a GDI+ fault.
                }
                intTrace = 10;
                graFrequency = pnlWaterfall.CreateGraphics;
                intTrace = 11;
                graFrequency.DrawImage(bmpNewSpectrum, 0, 0);
                // Draw the new bitmap in one update to avoid a possible GDI+ fault
                static_UpdateWaterfall_intWaterfallRow -= 1;
                // Move the WaterFallRow back to point to the oldest received spectrum
                intTrace = 12;
                if (static_UpdateWaterfall_intWaterfallRow < 0)
                    static_UpdateWaterfall_intWaterfallRow = bmpSpectrum.Height - 1;
                // Makes the bitmap a circular buffer
            }
            catch (Exception ex)
            {
                Logs.Exception("[Main.UpdateWaterfall] Err #: " + Err.Number.ToString + "  Exception: " + ex.ToString + "  intTrace=" + intTrace.ToString);
            }
        }
示例#39
0
        public static bool Deconvolve(double[,] xImage, double[,] residuals, double[,] psf, double lambda, double alpha, int maxIteration = 100, double epsilon = 1e-4)
        {
            FitsIO.Write(residuals, "res.fits");
            var yBlockSize = 2;
            var xBlockSize = 2;

            var PSFCorrelated = CommonDeprecated.PSF.CalculateFourierCorrelation(psf, psf.GetLength(0), psf.GetLength(1));
            var RES           = FFT.Forward(residuals);
            var BMAPFourier   = Common.Fourier2D.Multiply(RES, PSFCorrelated);
            var bMap          = FFT.Backward(BMAPFourier, BMAPFourier.Length);

            //FFT.Shift(bMap);
            FitsIO.Write(bMap, "bMap.fits");
            var PSF = FFT.Forward(CommonDeprecated.Residuals.Pad(psf, psf.GetLength(0), psf.GetLength(1)), 1.0);

            var PSF2Fourier = Common.Fourier2D.Multiply(PSF, PSFCorrelated);

            var xDiff = new double[xImage.GetLength(0), xImage.GetLength(1)];
            //var blockInversion = CalcBlock(psf, yBlockSize, xBlockSize).Inverse();
            var random = new Random(123);

            var lipschitz = ApproximateLipschitz(psf, yBlockSize, xBlockSize);
            var startL2   = NaiveGreedyCD.CalcDataObjective(residuals);

            var iter = 0;

            while (iter < maxIteration)
            {
                /*
                 * var yB = random.Next(xImage.GetLength(0) / yBlockSize);
                 * var xB = random.Next(xImage.GetLength(1) / xBlockSize);
                 * yB = 64 / yBlockSize;
                 * xB = 64 / xBlockSize;
                 * var block = CopyFrom(bMap, yB, xB, yBlockSize, xBlockSize);
                 *
                 * //var optimized = block * blockInversion;
                 *
                 * var optimized = block / lipschitz /4;
                 * var xOld = CopyFrom(xImage, yB, xB, yBlockSize, xBlockSize);
                 * optimized = xOld + optimized;
                 *
                 * //shrink
                 * for (int i = 0; i < optimized.Count; i++)
                 *  optimized[i] = Common.ShrinkElasticNet(optimized[i], lambda, alpha);
                 * var optDiff = optimized - xOld;
                 * //AddInto(xDiff, optDiff, yB, xB, yBlockSize, xBlockSize);
                 * AddInto(xImage, optDiff, yB, xB, yBlockSize, xBlockSize);
                 * FitsIO.Write(xImage, "xImageBlock.fits");
                 * FitsIO.Write(xDiff, "xDiff.fits");
                 * xDiff[64, 64] = 1.0;
                 *
                 * //update b-map
                 * var XDIFF = FFT.Forward(xDiff);
                 * XDIFF = Common.Fourier2D.Multiply(XDIFF, PSF2Fourier);
                 * Common.Fourier2D.SubtractInPlace(BMAPFourier, XDIFF);
                 * bMap = FFT.Backward(BMAPFourier, BMAPFourier.Length);
                 * //FFT.Shift(bMap);
                 * FitsIO.Write(bMap, "bMap2.fits");
                 *
                 * //calc residuals for debug purposes
                 * var XDIFF2 = FFT.Forward(xDiff);
                 * XDIFF2 = Common.Fourier2D.Multiply(XDIFF2, PSF);
                 * var RES2 = Common.Fourier2D.Subtract(RES, XDIFF2);
                 * var resDebug = FFT.Backward(RES2, RES2.Length);
                 * var L2 = NaiveGreedyCD.CalcDataObjective(resDebug);
                 * FitsIO.Write(resDebug, "resDebug.fits");
                 * var xDiff3 = FFT.Backward(XDIFF2, XDIFF2.Length);
                 * FitsIO.Write(xDiff3, "recDebug.fits");
                 *
                 * //clear from xDiff
                 * AddInto(xDiff, -optDiff, yB, xB, yBlockSize, xBlockSize);*/
                iter++;
            }

            return(false);
        }
示例#40
0
文件: Main.cs 项目: ptaa32/ARDOP
        private void UpdateSpectrum(ref byte[] bytNewSamples)
        {
            lock (static_UpdateSpectrum_dblI_Init)
            {
                try
                {
                    if (InitStaticVariableHelper(static_UpdateSpectrum_dblI_Init))
                    {
                        static_UpdateSpectrum_dblI = new double[1024];
                    }
                }
                finally
                {
                    static_UpdateSpectrum_dblI_Init.State = 1;
                }
            }
            lock (static_UpdateSpectrum_dblQ_Init)
            {
                try
                {
                    if (InitStaticVariableHelper(static_UpdateSpectrum_dblQ_Init))
                    {
                        static_UpdateSpectrum_dblQ = new double[1024];
                    }
                }
                finally
                {
                    static_UpdateSpectrum_dblQ_Init.State = 1;
                }
            }
            lock (static_UpdateSpectrum_dblReF_Init)
            {
                try
                {
                    if (InitStaticVariableHelper(static_UpdateSpectrum_dblReF_Init))
                    {
                        static_UpdateSpectrum_dblReF = new double[1024];
                    }
                }
                finally
                {
                    static_UpdateSpectrum_dblReF_Init.State = 1;
                }
            }
            lock (static_UpdateSpectrum_dblImF_Init)
            {
                try
                {
                    if (InitStaticVariableHelper(static_UpdateSpectrum_dblImF_Init))
                    {
                        static_UpdateSpectrum_dblImF = new double[1024];
                    }
                }
                finally
                {
                    static_UpdateSpectrum_dblImF_Init.State = 1;
                }
            }
            lock (static_UpdateSpectrum_aryLastY_Init)
            {
                try
                {
                    if (InitStaticVariableHelper(static_UpdateSpectrum_aryLastY_Init))
                    {
                        static_UpdateSpectrum_aryLastY = new int[256];
                    }
                }
                finally
                {
                    static_UpdateSpectrum_aryLastY_Init.State = 1;
                }
            }
            lock (static_UpdateSpectrum_intPtr_Init)
            {
                try
                {
                    if (InitStaticVariableHelper(static_UpdateSpectrum_intPtr_Init))
                    {
                        static_UpdateSpectrum_intPtr = 0;
                    }
                }
                finally
                {
                    static_UpdateSpectrum_intPtr_Init.State = 1;
                }
            }
            lock (static_UpdateSpectrum_dblMag_Init)
            {
                try
                {
                    if (InitStaticVariableHelper(static_UpdateSpectrum_dblMag_Init))
                    {
                        static_UpdateSpectrum_dblMag = new double[207];
                    }
                }
                finally
                {
                    static_UpdateSpectrum_dblMag_Init.State = 1;
                }
            }
            lock (static_UpdateSpectrum_FFT_Init)
            {
                try
                {
                    if (InitStaticVariableHelper(static_UpdateSpectrum_FFT_Init))
                    {
                        static_UpdateSpectrum_FFT = new FFT();
                    }
                }
                finally
                {
                    static_UpdateSpectrum_FFT_Init.State = 1;
                }
            }
            lock (static_UpdateSpectrum_intPriorY_Init)
            {
                try
                {
                    if (InitStaticVariableHelper(static_UpdateSpectrum_intPriorY_Init))
                    {
                        static_UpdateSpectrum_intPriorY = new int[257];
                    }
                }
                finally
                {
                    static_UpdateSpectrum_intPriorY_Init.State = 1;
                }
            }

            double[] dblMagBusy = new double[207];
            double dblMagMax = 1E-10;
            double dblMagMin = 10000000000.0;
            Int32 intTuneLineLow = default(Int32);
            Int32 intTuneLineHi = default(Int32);
            Int32 intDelta = default(Int32);
            int intBusyStatus = 0;
            int Trace = 0;
            System.Drawing.Color clrTLC = Color.Chartreuse;

            for (int i = 0; i <= bytNewSamples.Length - 1; i += 2)
            {
                static_UpdateSpectrum_dblI(static_UpdateSpectrum_intPtr) = Convert.ToDouble(System.BitConverter.ToInt16(bytNewSamples, i));
                static_UpdateSpectrum_intPtr += 1;
                if (static_UpdateSpectrum_intPtr > 1023)
                    break; // TODO: might not be correct. Was : Exit For
            }

            if (static_UpdateSpectrum_intPtr < 1024)
                return;

            //FFT.FourierTransform(1024, dblI, dblQ, dblReF, dblImF, False)
            //For i As Integer = 0 To dblMag.Length - 1
            //    'starting at ~300 Hz to ~2700 Hz Which puts the center of the signal in the center of the window (~1500Hz)
            //    dblMag(i) = (dblReF(i + 25) ^ 2 + dblImF(i + 25) ^ 2) ' first pass
            //    dblMagAvg += dblMag(i)
            //Next i
            //intDelta = (stcConnection.intSessionBW \ 2 + MCB.TuningRange) / 11.719
            //intTuneLineLow = Max((103 - intDelta), 3)
            //intTuneLineHi = Min((103 + intDelta), 203)

            //intBusyStatus = objBusy.BusyDetect(dblMag, intTuneLineLow, intTuneLineHi)
            //If intBusyStatus = 1 Then
            //    clrTLC = Color.Fuchsia

            //ElseIf intBusyStatus = 2 Then
            //    clrTLC = Color.Orange
            //End If

            // Busy detector call needs work...OK in Waterfall!

            static_UpdateSpectrum_intPtr = 0;
            static_UpdateSpectrum_FFT.FourierTransform(1024, static_UpdateSpectrum_dblI, static_UpdateSpectrum_dblQ, static_UpdateSpectrum_dblReF, static_UpdateSpectrum_dblImF, false);
            Trace = 1;
            intDelta = ((stcConnection.intSessionBW / 2) + MCB.TuningRange) / 11.719;
            intTuneLineLow = Max((103 - intDelta), 3);
            intTuneLineHi = Min((103 + intDelta), 203);

            for (int i = 0; i <= static_UpdateSpectrum_dblMag.Length - 1; i++)
            {
                //starting at ~300 Hz to ~2700 Hz Which puts the center of the window at 1500Hz
                dblMagBusy(i) = (Math.Pow(static_UpdateSpectrum_dblReF(i + 25), 2) + Math.Pow(static_UpdateSpectrum_dblImF(i + 25), 2));
                //dblMag(i) = 0.2 * (dblReF(i + 25) ^ 2 + dblImF(i + 25) ^ 2) + 0.8 * dblMag(i) ' first pass
                static_UpdateSpectrum_dblMag(i) = 0.2 * dblMagBusy(i) + 0.8 * static_UpdateSpectrum_dblMag(i);
                // first pass
                dblMagMax = Math.Max(dblMagMax, static_UpdateSpectrum_dblMag(i));
                dblMagMin = Math.Min(dblMagMin, static_UpdateSpectrum_dblMag(i));
            }
            intBusyStatus = objBusy.BusyDetect(dblMagBusy, intTuneLineLow, intTuneLineHi);
            if (intBusyStatus == 1)
            {
                clrTLC = Color.Fuchsia;
            }
            else if (intBusyStatus == 2)
            {
                clrTLC = Color.Orange;
            }
            if (static_UpdateSpectrum_intLastBusyStatus == 0 & intBusyStatus > 0)
            {
                objHI.QueueCommandToHost("BUSY TRUE");
                Debug.WriteLine("BUSY TRUE");
                static_UpdateSpectrum_intLastBusyStatus = intBusyStatus;
            }
            else if (intBusyStatus == 0 & static_UpdateSpectrum_intLastBusyStatus > 0)
            {
                objHI.QueueCommandToHost("BUSY FALSE");
                Debug.WriteLine("BUSY FALSE");
                static_UpdateSpectrum_intLastBusyStatus = intBusyStatus;
            }
            // This performs an auto scaling mechansim with fast attack and slow release
            // more than 10000:1 difference Max:Min
            if (dblMagMin / dblMagMax < 0.0001)
            {
                static_UpdateSpectrum_dblMaxScale = Max(dblMagMax, static_UpdateSpectrum_dblMaxScale * 0.9);
            }
            else
            {
                static_UpdateSpectrum_dblMaxScale = Max(10000 * dblMagMin, dblMagMax);
            }
            Trace = 2;
            try
            {
                //            'InititializeSpectrum(Color.Black)
                bmpNewSpectrum = new Bitmap(intBMPSpectrumWidth, intBMPSpectrumHeight);
                for (int i = 0; i <= static_UpdateSpectrum_dblMag.Length - 1; i++)
                {
                    // The following provides some AGC over the waterfall to compensate for avg input level.
                    int y1 = Convert.ToInt32(-0.25 * (intBMPSpectrumHeight - 1) * Log10((Max(static_UpdateSpectrum_dblMag(i), static_UpdateSpectrum_dblMaxScale / 10000)) / static_UpdateSpectrum_dblMaxScale));
                    // range should be 0 to bmpSpectrumHeight -1
                    System.Drawing.Color objColor = Color.Yellow;
                    // Redraw center and bandwidth lines if change in display
                    if (intTuneLineLow != intSavedTuneLineLow)
                    {
                        for (int j = 0; j <= intBMPSpectrumHeight - 1; j++)
                        {
                            bmpNewSpectrum.SetPixel(103, j, Color.Tomato);
                            bmpNewSpectrum.SetPixel(intSavedTuneLineLow, j, Color.Black);
                            bmpNewSpectrum.SetPixel(intSavedTuneLineHi, j, Color.Black);
                            bmpNewSpectrum.SetPixel(Max(0, intSavedTuneLineLow - 1), j, Color.Black);
                            bmpNewSpectrum.SetPixel(intSavedTuneLineHi + 1, j, Color.Black);
                            bmpNewSpectrum.SetPixel(intTuneLineLow, j, clrTLC);
                            bmpNewSpectrum.SetPixel(intTuneLineHi, j, clrTLC);
                            bmpNewSpectrum.SetPixel(intTuneLineLow - 1, j, clrTLC);
                            bmpNewSpectrum.SetPixel(intTuneLineHi + 1, j, clrTLC);
                        }
                        intSavedTuneLineHi = intTuneLineHi;
                        intSavedTuneLineLow = intTuneLineLow;
                    }
                    // Clear the old pixels and put in new ones if not on a center or Tuning lines
                    if (!((i == 103) | (i == intTuneLineHi) | (i == intTuneLineLow) | (i == intTuneLineHi + 1) | (i == intTuneLineLow - 1)))
                    {
                        // Set the prior plotted pixels to black
                        bmpNewSpectrum.SetPixel(i, static_UpdateSpectrum_intPriorY(i), Color.Black);
                        if (static_UpdateSpectrum_intPriorY(i) < (intBMPSpectrumHeight - 2))
                            bmpNewSpectrum.SetPixel(i, static_UpdateSpectrum_intPriorY(i) + 1, Color.Black);
                        static_UpdateSpectrum_intPriorY(i) = y1;
                        bmpNewSpectrum.SetPixel(i, y1, Color.Yellow);
                        if (y1 < (intBMPSpectrumHeight - 2))
                            bmpNewSpectrum.SetPixel(i, y1 + 1, Color.Gold);
                    }
                }
                Trace = 10;
                if ((graFrequency != null))
                {
                    Trace = 11;
                    graFrequency.Dispose();
                    // this permits writing back to the graFrequency without a GDI+ fault.
                }
                graFrequency = pnlWaterfall.CreateGraphics;
                graFrequency.DrawImage(bmpNewSpectrum, 0, 0);
                // Draw the new bitmap in one update to avoid a possible GDI+ fault
            }
            catch (Exception ex)
            {
                Logs.Exception("[Main.UpdateSpectrum] Err #: " + Err.Number.ToString + "  Exception: " + ex.ToString + "  Trace=" + Trace.ToString);
            }
        }