public void ProcessBuffer(Complex *iqBuffer, float *audioBuffer, int length)
        {
            if (_needConfigure)
            {
                Configure();
                _needConfigure = false;
            }

            if (_hookManager != null)
            {
                _hookManager.ProcessRawIQ(iqBuffer, length);
            }

            _downConverter.Process(iqBuffer, length);

            if (_hookManager != null)
            {
                _hookManager.ProcessFrequencyTranslatedIQ(iqBuffer, length);
            }

            if (_baseBandDecimator.StageCount > 0)
            {
                _baseBandDecimator.Process(iqBuffer, length);
                length /= (int)Math.Pow(2.0, _baseBandDecimator.StageCount);
            }

            _iqFilter.Process(iqBuffer, length);

            if (_hookManager != null)
            {
                _hookManager.ProcessDecimatedAndFilteredIQ(iqBuffer, length);
            }

            if (_actualDetectorType == DetectorType.RAW)
            {
                Utils.Memcpy(audioBuffer, iqBuffer, length * sizeof(Complex));
                return;
            }

            if (_rawAudioBuffer == null || _rawAudioBuffer.Length != length)
            {
                _rawAudioBuffer = UnsafeBuffer.Create(length, sizeof(float));
                _rawAudioPtr    = (float *)_rawAudioBuffer;
            }

            if (_actualDetectorType != DetectorType.WFM)
            {
                ScaleIQ(iqBuffer, length);
            }

            Demodulate(iqBuffer, _rawAudioPtr, length);

            if (_hookManager != null)
            {
                _hookManager.ProcessDemodulatorOutput(_rawAudioPtr, length);
            }

            if (_actualDetectorType != DetectorType.WFM)
            {
                if (_filterAudio)
                {
                    _audioFilter.Process(_rawAudioPtr, length);
                }

                if (_actualDetectorType != DetectorType.NFM && _useAgc)
                {
                    _agc.Process(_rawAudioPtr, length);
                }
            }

            if (_filterAudio)
            {
                _dcRemover.Process(_rawAudioPtr, length);
            }

            if (_actualDetectorType == DetectorType.WFM)
            {
                _rdsDecoder.Process(_rawAudioPtr, length);
                _stereoDecoder.Process(_rawAudioPtr, audioBuffer, length);
                length >>= _audioDecimationStageCount;
            }
            else
            {
                MonoToStereo(_rawAudioPtr, audioBuffer, length);
            }

            if (_hookManager != null)
            {
                length <<= 1;
                _hookManager.ProcessFilteredAudioOutput(audioBuffer, length);
            }
        }