Merge pull request #365 from DSheirer/364-p25-pll-lock-gain

#364 Excessive P25 PLL Sync Lock Timelines
This commit is contained in:
Denny Sheirer
2018-07-14 11:29:18 -04:00
committed by GitHub
5 changed files with 35 additions and 21 deletions

View File

@@ -416,7 +416,9 @@ public class PolyphaseChannelManager implements ISourceEventProcessor
long centerFrequency = mChannelCalculator.getCenterFrequencyForIndexes(indexes);
//If the indexes size is the same then update the current processor, otherwise create a new one
if(channelSource.getPolyphaseChannelOutputProcessor().getInputChannelCount() == indexes.size())
IPolyphaseChannelOutputProcessor outputProcessor = channelSource.getPolyphaseChannelOutputProcessor();
if(outputProcessor != null && outputProcessor.getInputChannelCount() == indexes.size())
{
channelSource.getPolyphaseChannelOutputProcessor().setPolyphaseChannelIndices(indexes);
channelSource.setFrequency(centerFrequency);

View File

@@ -16,6 +16,8 @@
package io.github.dsheirer.dsp.psk.pll;
import io.github.dsheirer.sample.complex.Complex;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
/**
* Costas Loop - phase locked loop designed to automatically synchronize to the incoming carrier frequency in order to
@@ -28,6 +30,8 @@ import io.github.dsheirer.sample.complex.Complex;
*/
public class CostasLoop implements IPhaseLockedLoop
{
private final static Logger mLog = LoggerFactory.getLogger(CostasLoop.class);
public static final double TWO_PI = 2.0 * Math.PI;
private Complex mCurrentVector = new Complex(0, 0);
@@ -37,7 +41,10 @@ public class CostasLoop implements IPhaseLockedLoop
private double mDamping = Math.sqrt(2.0) / 2.0;
private double mAlphaGain;
private double mBetaGain;
private Tracking mTracking = Tracking.NORMAL;
private Tracking mTracking = Tracking.FASTEST;
private double mSymbolRate;
private double mSampleRate;
private int mCounter;
/**
* Costas Loop for tracking and correcting frequency error in a received carrier signal.
@@ -47,6 +54,8 @@ public class CostasLoop implements IPhaseLockedLoop
*/
public CostasLoop(double sampleRate, double symbolRate)
{
mSymbolRate = symbolRate;
mSampleRate = sampleRate;
mMaximumLoopFrequency = TWO_PI * (symbolRate / 2.0) / sampleRate;
updateLoopBandwidth();
}
@@ -171,6 +180,16 @@ public class CostasLoop implements IPhaseLockedLoop
{
mLoopFrequency = -mMaximumLoopFrequency;
}
//TODO: broadcast channel offset to the tuner to use in auto-adjusting tuner PPM
// mCounter++;
//
// if(mCounter > (5 * mSymbolRate))
// {
// mCounter = 0;
// mLog.info("Current Costas Loop Frequency: " + mLoopFrequency + " [" +
// (int)(mSampleRate / TWO_PI * mLoopFrequency) + " Hz Offset] sample rate [" + mSampleRate + "]");
// }
}
@Override

View File

@@ -64,7 +64,7 @@ public class P25DecoderC4FM extends P25Decoder
mBasebandFilter = new ComplexFIRFilter2(getBasebandFilter());
mCostasLoop = new CostasLoop(getSampleRate(), getSymbolRate());
mCostasLoop.setTracking(Tracking.FAST);
mCostasLoop.setTracking(Tracking.FASTEST);
mInterpolatingSampleBuffer = new InterpolatingSampleBuffer(getSamplesPerSymbol(), SAMPLE_COUNTER_GAIN);
mQPSKDemodulator = new DQPSKDecisionDirectedDemodulator(mCostasLoop, mInterpolatingSampleBuffer);
@@ -161,11 +161,6 @@ public class P25DecoderC4FM extends P25Decoder
{
switch(sourceEvent.getEvent())
{
case NOTIFICATION_FREQUENCY_CHANGE:
case NOTIFICATION_FREQUENCY_CORRECTION_CHANGE:
case NOTIFICATION_CHANNEL_FREQUENCY_CORRECTION_CHANGE:
mCostasLoop.reset();
break;
case NOTIFICATION_SAMPLE_RATE_CHANGE:
mCostasLoop.reset();
setSampleRate(sourceEvent.getValue().doubleValue());

View File

@@ -115,14 +115,9 @@ public class P25DecoderLSM extends P25Decoder
{
switch(sourceEvent.getEvent())
{
case NOTIFICATION_FREQUENCY_CHANGE:
case NOTIFICATION_FREQUENCY_CORRECTION_CHANGE:
case NOTIFICATION_CHANNEL_FREQUENCY_CORRECTION_CHANGE:
mCostasLoop.reset();
break;
case NOTIFICATION_SAMPLE_RATE_CHANGE:
mCostasLoop.reset();
setSampleRate(sourceEvent.getValue().doubleValue());
mCostasLoop.reset();
break;
}
}

View File

@@ -95,15 +95,18 @@ public class FrequencyController
*/
public void setSampleRate(int sampleRate) throws SourceException
{
if(!mLocked)
if(sampleRate != mSampleRate)
{
mSampleRate = sampleRate;
if(!mLocked)
{
mSampleRate = sampleRate;
broadcastSampleRateChange();
}
else
{
mLog.warn("Cannot change sample rate while tuner is is LOCKED state.");
broadcastSampleRateChange();
}
else
{
mLog.warn("Cannot change sample rate while tuner is is LOCKED state.");
}
}
}