diff --git a/src/main/java/io/github/dsheirer/dsp/filter/channelizer/PolyphaseChannelManager.java b/src/main/java/io/github/dsheirer/dsp/filter/channelizer/PolyphaseChannelManager.java index 1320cb51..8be164e1 100644 --- a/src/main/java/io/github/dsheirer/dsp/filter/channelizer/PolyphaseChannelManager.java +++ b/src/main/java/io/github/dsheirer/dsp/filter/channelizer/PolyphaseChannelManager.java @@ -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); diff --git a/src/main/java/io/github/dsheirer/dsp/psk/pll/CostasLoop.java b/src/main/java/io/github/dsheirer/dsp/psk/pll/CostasLoop.java index 38b8d101..9c7968ee 100644 --- a/src/main/java/io/github/dsheirer/dsp/psk/pll/CostasLoop.java +++ b/src/main/java/io/github/dsheirer/dsp/psk/pll/CostasLoop.java @@ -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 diff --git a/src/main/java/io/github/dsheirer/module/decode/p25/P25DecoderC4FM.java b/src/main/java/io/github/dsheirer/module/decode/p25/P25DecoderC4FM.java index 62e3d42b..f29512f8 100644 --- a/src/main/java/io/github/dsheirer/module/decode/p25/P25DecoderC4FM.java +++ b/src/main/java/io/github/dsheirer/module/decode/p25/P25DecoderC4FM.java @@ -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()); diff --git a/src/main/java/io/github/dsheirer/module/decode/p25/P25DecoderLSM.java b/src/main/java/io/github/dsheirer/module/decode/p25/P25DecoderLSM.java index 5e3648de..835c9769 100644 --- a/src/main/java/io/github/dsheirer/module/decode/p25/P25DecoderLSM.java +++ b/src/main/java/io/github/dsheirer/module/decode/p25/P25DecoderLSM.java @@ -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; } } diff --git a/src/main/java/io/github/dsheirer/source/tuner/frequency/FrequencyController.java b/src/main/java/io/github/dsheirer/source/tuner/frequency/FrequencyController.java index e0af77b8..9631c710 100644 --- a/src/main/java/io/github/dsheirer/source/tuner/frequency/FrequencyController.java +++ b/src/main/java/io/github/dsheirer/source/tuner/frequency/FrequencyController.java @@ -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."); + } } }