public void ProcessData(byte[] dataBuffer)
        {
            const int bytePerSample = 2;
            const int channels      = 2;

            if (FFTDisplay.EnoughData && WaterfallDisplay.EnoughData)
            {
                return;
            }

            lock (FFTLock)
            {
                int samplePairs = dataBuffer.Length / (channels * bytePerSample);

                for (int samplePair = 0; samplePair < samplePairs; samplePair++)
                {
                    int    samplePairPos = samplePair * bytePerSample * channels;
                    double I             = ByteUtil.getDoubleFromBytes(dataBuffer, samplePairPos);
                    double Q             = ByteUtil.getDoubleFromBytes(dataBuffer, samplePairPos + bytePerSample);


                    FFT.AddSample(I, Q);

                    if (FFT.ResultAvailable)
                    {
                        FFT.GetResultSquared(FFTResult);

                        FFTDisplay.ProcessFFTData(FFTResult);
                        WaterfallDisplay.ProcessFFTData(FFTResult);
                    }
                }
            }
        }
        public void ProcessData(double[] iSamples, double[] qSamples, int spectPart, double baseAmp)
        {
            FpsBlocksReceived++;

            /* TODO: waterfall display sometimes holds "EnoughData" and doesnt reset */
            if (FFTDisplay.EnoughData && WaterfallDisplay.EnoughData)
            {
                return;
            }

            FpsBlocksProcessed++;

            lock (FFTLock)
            {
                int samplePairs = iSamples.Length;

                for (int samplePair = 0; samplePair < samplePairs; samplePair++)
                {
                    double I = iSamples[samplePair];
                    double Q = qSamples[samplePair];

                    FFT.AddSample(I, Q);

                    if (FFT.ResultAvailable)
                    {
                        FFT.GetResultSquared(FFTResult);

                        ReceiverCorrection.ApplyCorrectionTable(FFTResult);
                        FilterCorrection.ApplyCorrectionTable(FFTResult);

                        Remote.ProcessData(FFTResult);

                        if (FitSpectrumEnabled)
                        {
                            CenterCut((int)(FitSpectrumWidth * FFTSize));
                            FFTDisplay.ProcessFFTData(FFTResultPartial, spectPart, baseAmp);
                            WaterfallDisplay.ProcessFFTData(FFTResultPartial, spectPart, baseAmp);
                        }
                        else
                        {
                            FFTDisplay.ProcessFFTData(FFTResult, spectPart, baseAmp);
                            WaterfallDisplay.ProcessFFTData(FFTResult, spectPart, baseAmp);
                        }
                    }
                }
            }
        }
        public void ProcessSample(double I, double Q, int spectPart, int spectParts, double baseAmp)
        {
            lock (FFTLock)
            {
                FFT.AddSample(I, Q);

                if (FFT.ResultAvailable)
                {
                    FFT.GetResultSquared(FFTResult);

                    ReceiverCorrection.ApplyCorrectionTable(FFTResult);
                    FilterCorrection.ApplyCorrectionTable(FFTResult);

                    FFTDisplay.ProcessFFTData(FFTResult, spectPart, baseAmp);
                    WaterfallDisplay.ProcessFFTData(FFTResult, spectPart, baseAmp);
                }
            }
        }