mirror of
https://github.com/DSheirer/sdrtrunk.git
synced 2026-11-12 08:37:25 -05:00
Resolves #364.
The C4FM and LSM decoders were issuing a PLL reset with each new channel that was allocated, causing any existing decoding channels to be disrupted. Decoding re-sync delays or inability to recapture the signal for decoding would likely result as the tuner's overall PPM caused misadjustment in the channel. Resolved a NPE that was occurring in the FrequencyController for sample rate changes.
This commit is contained in:
@@ -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);
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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());
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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.");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user