mirror of
https://github.com/DSheirer/sdrtrunk.git
synced 2026-11-12 08:37:25 -05:00
39 - Adds P25/LSM support to the DemodulatorViewerFX application and
adds Feed forward gain support to the C4FM DQPSK demodulator which seems to improve output from the interpolating sample buffer at each symbol period. Updates the symbol timing gain for C4FM to decrease the gain a bit since the feed forward gain is providing a better interpolated symbol.
This commit is contained in:
@@ -20,6 +20,7 @@ import io.github.dsheirer.dsp.filter.FilterFactory;
|
||||
import io.github.dsheirer.dsp.filter.design.FilterDesignException;
|
||||
import io.github.dsheirer.dsp.filter.fir.FIRFilterSpecification;
|
||||
import io.github.dsheirer.dsp.filter.fir.complex.ComplexFIRFilter;
|
||||
import io.github.dsheirer.dsp.gain.ComplexFeedForwardGainControl;
|
||||
import io.github.dsheirer.dsp.psk.DQPSKDecisionDirectedDemodulator;
|
||||
import io.github.dsheirer.dsp.psk.InterpolatingSampleBuffer;
|
||||
import io.github.dsheirer.dsp.psk.pll.CostasLoop;
|
||||
@@ -34,11 +35,12 @@ import java.util.Map;
|
||||
public class P25DecoderC4FM extends P25Decoder
|
||||
{
|
||||
private final static Logger mLog = LoggerFactory.getLogger(P25DecoderC4FM.class);
|
||||
protected static final float SYMBOL_TIMING_GAIN = 0.1f;
|
||||
protected static final float SAMPLE_COUNTER_GAIN = 0.5f;
|
||||
protected InterpolatingSampleBuffer mInterpolatingSampleBuffer;
|
||||
protected DQPSKDecisionDirectedDemodulator mQPSKDemodulator;
|
||||
protected CostasLoop mCostasLoop;
|
||||
protected P25MessageFramer mMessageFramer;
|
||||
private ComplexFeedForwardGainControl mAGC = new ComplexFeedForwardGainControl(32);
|
||||
private Map<Double,float[]> mBasebandFilters = new HashMap<>();
|
||||
private ComplexFIRFilter mBasebandFilter;
|
||||
|
||||
@@ -61,7 +63,7 @@ public class P25DecoderC4FM extends P25Decoder
|
||||
mBasebandFilter = new ComplexFIRFilter(getBasebandFilter(), 1.0f);
|
||||
|
||||
mCostasLoop = new CostasLoop(getSampleRate(), getSymbolRate());
|
||||
mInterpolatingSampleBuffer = new InterpolatingSampleBuffer(getSamplesPerSymbol(), SYMBOL_TIMING_GAIN);
|
||||
mInterpolatingSampleBuffer = new InterpolatingSampleBuffer(getSamplesPerSymbol(), SAMPLE_COUNTER_GAIN);
|
||||
|
||||
mQPSKDemodulator = new DQPSKDecisionDirectedDemodulator(mCostasLoop, mInterpolatingSampleBuffer);
|
||||
|
||||
@@ -79,10 +81,13 @@ public class P25DecoderC4FM extends P25Decoder
|
||||
public void receive(ReusableComplexBuffer reusableComplexBuffer)
|
||||
{
|
||||
//User accounting of the incoming buffer is handled by the filter
|
||||
ReusableComplexBuffer filtered = filter(reusableComplexBuffer);
|
||||
ReusableComplexBuffer basebandFiltered = filter(reusableComplexBuffer);
|
||||
|
||||
//User accounting of the incoming buffer is handled by the gain filter
|
||||
ReusableComplexBuffer gainApplied = mAGC.filter(basebandFiltered);
|
||||
|
||||
//User accounting of the filtered buffer is handled by the demodulator
|
||||
mQPSKDemodulator.receive(filtered);
|
||||
mQPSKDemodulator.receive(gainApplied);
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -50,9 +50,6 @@ public class P25DecoderC4FMInstrumented extends P25DecoderC4FM
|
||||
{
|
||||
ReusableComplexBuffer filtered = super.filter(reusableComplexBuffer);
|
||||
|
||||
//Increment user count before we hand to another listener or return from this method
|
||||
filtered.incrementUserCount();
|
||||
|
||||
if(mFilteredSymbolListener != null)
|
||||
{
|
||||
filtered.incrementUserCount();
|
||||
@@ -70,7 +67,7 @@ public class P25DecoderC4FMInstrumented extends P25DecoderC4FM
|
||||
super.setSampleRate(sampleRate);
|
||||
|
||||
InterpolatingSampleBufferInstrumented instrumentedBuffer =
|
||||
new InterpolatingSampleBufferInstrumented(getSamplesPerSymbol(), SYMBOL_TIMING_GAIN);
|
||||
new InterpolatingSampleBufferInstrumented(getSamplesPerSymbol(), SAMPLE_COUNTER_GAIN);
|
||||
mInterpolatingSampleBuffer = instrumentedBuffer;
|
||||
|
||||
DQPSKDecisionDirectedDemodulatorInstrumented instrumented = new DQPSKDecisionDirectedDemodulatorInstrumented(mCostasLoop, instrumentedBuffer, getSampleRate());
|
||||
|
||||
@@ -34,7 +34,7 @@ import java.util.Map;
|
||||
public class P25DecoderLSM extends P25Decoder
|
||||
{
|
||||
private final static Logger mLog = LoggerFactory.getLogger(P25DecoderLSM.class);
|
||||
protected static final float SYMBOL_TIMING_GAIN = 0.1f;
|
||||
protected static final float SAMPLE_COUNTER_GAIN = 0.5f;
|
||||
|
||||
private Map<Double,float[]> mBasebandFilters = new HashMap<>();
|
||||
private ComplexFIRFilter mBasebandFilter;
|
||||
@@ -67,7 +67,7 @@ public class P25DecoderLSM extends P25Decoder
|
||||
mBasebandFilter = new ComplexFIRFilter(getBasebandFilter(), 1.0f);
|
||||
|
||||
mCostasLoop = new CostasLoop(getSampleRate(), getSymbolRate());
|
||||
mInterpolatingSampleBuffer = new InterpolatingSampleBuffer(getSamplesPerSymbol(), SYMBOL_TIMING_GAIN);
|
||||
mInterpolatingSampleBuffer = new InterpolatingSampleBuffer(getSamplesPerSymbol(), SAMPLE_COUNTER_GAIN);
|
||||
|
||||
mQPSKDemodulator = new DQPSKGardnerDemodulator(mCostasLoop, mInterpolatingSampleBuffer);
|
||||
|
||||
|
||||
@@ -52,9 +52,6 @@ public class P25DecoderLSMInstrumented extends P25DecoderLSM
|
||||
{
|
||||
ReusableComplexBuffer filtered = super.filter(reusableComplexBuffer);
|
||||
|
||||
//Increment user count before we hand to another listener or return from this method
|
||||
filtered.incrementUserCount();
|
||||
|
||||
if(mFilteredSymbolListener != null)
|
||||
{
|
||||
filtered.incrementUserCount();
|
||||
@@ -71,7 +68,7 @@ public class P25DecoderLSMInstrumented extends P25DecoderLSM
|
||||
{
|
||||
super.setSampleRate(sampleRate);
|
||||
|
||||
InterpolatingSampleBufferInstrumented instrumentedBuffer = new InterpolatingSampleBufferInstrumented(getSamplesPerSymbol(), SYMBOL_TIMING_GAIN);
|
||||
InterpolatingSampleBufferInstrumented instrumentedBuffer = new InterpolatingSampleBufferInstrumented(getSamplesPerSymbol(), SAMPLE_COUNTER_GAIN);
|
||||
mInterpolatingSampleBuffer = instrumentedBuffer;
|
||||
|
||||
DQPSKGardnerDemodulatorInstrumented instrumented = new DQPSKGardnerDemodulatorInstrumented(mCostasLoop, instrumentedBuffer, getSampleRate());
|
||||
|
||||
Reference in New Issue
Block a user