public void Process(float *baseBand, int length) { #region Initialize buffers if (_rawBuffer == null || _rawBuffer.Length != length) { _rawBuffer = UnsafeBuffer.Create(length, sizeof(Complex)); _rawPtr = (Complex *)_rawBuffer; } if (_magBuffer == null || _magBuffer.Length != length) { _magBuffer = UnsafeBuffer.Create(length, sizeof(float)); _magPtr = (float *)_magBuffer; } if (_dataBuffer == null || _dataBuffer.Length != length) { _dataBuffer = UnsafeBuffer.Create(length, sizeof(float)); _dataPtr = (float *)_dataBuffer; } #endregion // Downconvert for (var i = 0; i < length; i++) { _osc->Tick(); _rawPtr[i] = _osc->Phase * baseBand[i]; } // Decimate _decimator.Process(_rawPtr, length); length /= _decimationFactor; // Filter _baseBandFilter.Process(_rawPtr, length); // PLL for (var i = 0; i < length; i++) { _dataPtr[i] = _pll->Process(_rawPtr[i]).Imag; } //if (!_pll->IsLocked) //{ // _bitDecoder.Reset(); // return; //} // Matched filter _matchedFilter.Process(_dataPtr, length); // Recover signal energy to sustain the oscillation in the IIR for (var i = 0; i < length; i++) { _magPtr[i] = Math.Abs(_dataPtr[i]); } // Synchronize to RDS bitrate _syncFilter->Process(_magPtr, length); // Detect RDS bits for (int i = 0; i < length; i++) { var data = _dataPtr[i]; var syncVal = _magPtr[i]; var slope = syncVal - _lastSync; _lastSync = syncVal; if (slope < 0.0f && _lastSyncSlope * slope < 0.0f) { bool bit = _lastData > 0; _bitDecoder.Process(bit ^ _lastBit); _lastBit = bit; } _lastData = data; _lastSyncSlope = slope; } }
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); } }