public void Process(float sample) { // Increment VCO _vco.Next(); // Multiply with oscillator float signal = (float)_vco.Cos() * sample; signal *= _errScale; _errSample = signal; // Notch out 2x carrier signal = (float)_notchFilter.filter(signal); // Low-pass to get phase error float phaseError = (float)_armFilter.filter(signal); //phaseError *= _errScale; //_errSample = phaseError; // Low-pass the non-integrated error signal to determine if the loop is locked _lockSample = (float)_lockFilter.filter(phaseError); if (_useIntegrator) { phaseError = _piPhase.Process(phaseError); } // Tune the VCO to correct the phase and frequency errors if (_isTrackingEnabled) { _vco.Tune(phaseError); } }
public void Process(float sample) { // Increment VCO _vco.Next(); // Multiply with oscillator float signalI = (float)_vco.Cos() * sample; float signalQ = -(float)_vco.Sin() * sample; // TODO: Do we need to clip? Should be handled by EQ someday if (!_doFilterOutput) { // Take our demodulated data out before the arm filters _iSample = signalI; _qSample = signalQ; } // Notch out 2x carrier signalI = (float)_iNotchFilter.filter(signalI); signalQ = (float)_qNotchFilter.filter(signalQ); // Low-pass to get phase error float phaseI = (float)_iArmFilter.filter(signalI); float phaseQ = (float)_qArmFilter.filter(signalQ); if (_doFilterOutput) { _iSample = phaseI; _qSample = phaseQ; } // Calculate phase error float phaseError = _phaseErrorCalculator(phaseI, phaseQ); phaseError *= _errScale; _errSample = phaseError; // Low-pass the non-integrated error signal to determine if the loop is locked _lockSample = (float)_lockFilter.filter(phaseError); phaseError = _piPhase.Process(phaseError); // Tune the VCO to correct the phase and frequency errors if (_isTrackingEnabled) { _vco.Tune(phaseError); } }