Resolves #186 - p25 C4FM decoder wasn't working (at all).

This commit is contained in:
Denny
2017-02-11 07:17:23 -05:00
parent 9cc0d367a8
commit fce3d5c4f3
4 changed files with 95 additions and 108 deletions

View File

@@ -103,35 +103,35 @@ public class DecoderFactory
//Low-pass filter with ~60 dB attenuation and 89 taps
private static final FIRFilterSpecification MPT1327_FILTER_SPECIFICATION = FIRFilterSpecification.lowPassBuilder()
.sampleRate( 48000 )
.gridDensity( 16 )
.passBandCutoff( 3200 )
.passBandAmplitude( 1.0 )
.passBandRipple( 0.02 )
.stopBandStart( 4000 )
.stopBandAmplitude( 0.0 )
.stopBandRipple( 0.03 )
.build();
.sampleRate( 48000 ).gridDensity( 16 ).passBandCutoff( 3200 ).passBandAmplitude( 1.0 ).passBandRipple( 0.02 )
.stopBandStart( 4000 ).stopBandAmplitude( 0.0 ).stopBandRipple( 0.03 ).build();
private static final FIRFilterSpecification P25_C4FM_IQ_SPECIFICATION = FIRFilterSpecification.lowPassBuilder()
.sampleRate(48000).gridDensity(16).passBandCutoff(6750).passBandAmplitude(1.0).passBandRipple(0.01)
.stopBandStart(7000).stopBandAmplitude(0.0).stopBandRipple(0.008).build();
private static final FIRFilterSpecification P25_C4FM_DEMOD_SPECIFICATION = FIRFilterSpecification.lowPassBuilder()
.sampleRate(48000).gridDensity(16).passBandCutoff(2500).passBandAmplitude(1.0).passBandRipple(0.01)
.stopBandStart(4000).stopBandAmplitude(0.0).stopBandRipple(0.008).build();
private static float[] MPT1327_LOWPASS_FILTER;
private static float[] P25_C4FM_IQ_FILTER;
private static float[] P25_C4FM_DEMOD_FILTER;
static
{
try
{
MPT1327_LOWPASS_FILTER = FilterFactory.getTaps(MPT1327_FILTER_SPECIFICATION);
P25_C4FM_IQ_FILTER = FilterFactory.getTaps(P25_C4FM_IQ_SPECIFICATION);
P25_C4FM_DEMOD_FILTER = FilterFactory.getTaps(P25_C4FM_DEMOD_SPECIFICATION);
}
catch(Exception e)
{
mLog.error("Couldn't design MPT1327 bandpass filter");
mLog.error("Couldn't design startup filter(s)");
}
}
public static final boolean NO_REMOVE_DC = false;
public static final boolean REMOVE_DC = true;
public static final int NO_FREQUENCY_CORRECTION = 0;
/**
* Returns a list of one primary decoder and any auxiliary decoders, as
* specified in the configurations.
@@ -228,7 +228,7 @@ public class DecoderFactory
}
modules.add(new FMDemodulatorModule(iqPass, iqStop));
modules.add(new DemodulatedAudioFilterModule(MPT1327_LOWPASS_FILTER, 1.0f));
modules.add(new DemodulatedAudioFilterModule(P25_C4FM_DEMOD_FILTER, 1.0f));
modules.add(new AudioModule(metadata));
break;
case PASSPORT:
@@ -247,7 +247,8 @@ public class DecoderFactory
switch(modulation)
{
case C4FM:
modules.add(new FMDemodulatorModule(6750, 7500));
modules.add(new FMDemodulatorModule(P25_C4FM_IQ_FILTER));
modules.add(new DemodulatedAudioFilterModule(P25_C4FM_DEMOD_FILTER, 1.0f));
modules.add(new P25_C4FMDecoder(aliasList, decodeConfig.getAFCMaximumCorrection()));
modules.add(new P25DecoderState(aliasList, channelType, Modulation.C4FM,
p25Config.getIgnoreDataCalls()));

View File

@@ -47,12 +47,10 @@ public class P25_C4FMDecoder extends P25Decoder
private final static Logger mLog = LoggerFactory.getLogger( P25_C4FMDecoder.class );
/* Instrumentation Taps */
private static final String INSTRUMENT_FILTER_OUTPUT = "Tap Point: Pre-Filter Output";
private static final String INSTRUMENT_C4FM_SYMBOL_FILTER_OUTPUT = "Tap Point: Symbol Filter Output";
private static final String INSTRUMENT_C4FM_SLICER_OUTPUT = "Tap Point: C4FM Slicer Output";
private List<TapGroup> mAvailableTaps;
private RealFIRFilter_RB_RB mC4FMPreFilter;
private C4FMSymbolFilter mSymbolFilter;
private C4FMSlicer mC4FMSlicer;
private P25MessageFramer mMessageFramer;
@@ -74,15 +72,9 @@ public class P25_C4FMDecoder extends P25Decoder
{
super( aliasList );
/* Filter demodulated sample buffers */
float[] filter = FilterFactory.getLowPass( 48000, 2500, 4000, 80, WindowType.HANNING, true );
mC4FMPreFilter = new RealFIRFilter_RB_RB( filter, 1.0f );
/* Shape gain and frequency offsets to optimize sample stream */
mSymbolFilter = new C4FMSymbolFilter( frequencyCorrectionMaximum );
mC4FMPreFilter.setListener( mSymbolFilter );
/* Convert samples to symbols */
mC4FMSlicer = new C4FMSlicer();
mSymbolFilter.setListener( mC4FMSlicer );
@@ -100,9 +92,6 @@ public class P25_C4FMDecoder extends P25Decoder
{
super.dispose();
mC4FMPreFilter.dispose();
mC4FMPreFilter = null;
mSymbolFilter.dispose();
mSymbolFilter = null;
@@ -121,7 +110,7 @@ public class P25_C4FMDecoder extends P25Decoder
@Override
public Listener<RealBuffer> getFilteredRealBufferListener()
{
return mC4FMPreFilter;
return mSymbolFilter;
}
/**
@@ -136,8 +125,6 @@ public class P25_C4FMDecoder extends P25Decoder
TapGroup group = new TapGroup( "P25 C4FM Decoder" );
group.add( new FloatBufferTap( INSTRUMENT_FILTER_OUTPUT, 0, 1.0f ) );
group.add( new FloatTap( INSTRUMENT_C4FM_SYMBOL_FILTER_OUTPUT, 0, 0.1f ) );
group.add( new DibitTap( INSTRUMENT_C4FM_SLICER_OUTPUT, 0, 0.1f ) );
@@ -165,11 +152,6 @@ public class P25_C4FMDecoder extends P25Decoder
switch( tap.getName() )
{
case INSTRUMENT_FILTER_OUTPUT:
FloatBufferTap filterOutput = (FloatBufferTap)tap;
mC4FMPreFilter.setListener( filterOutput );
filterOutput.setListener( mSymbolFilter );
break;
case INSTRUMENT_C4FM_SYMBOL_FILTER_OUTPUT:
FloatTap symbolTap = (FloatTap)tap;
mSymbolFilter.setListener( symbolTap );
@@ -201,9 +183,6 @@ public class P25_C4FMDecoder extends P25Decoder
switch( tap.getName() )
{
case INSTRUMENT_FILTER_OUTPUT:
mC4FMPreFilter.setListener( mSymbolFilter );
break;
case INSTRUMENT_C4FM_SYMBOL_FILTER_OUTPUT:
mSymbolFilter.setListener( mC4FMSlicer );
break;

View File

@@ -62,6 +62,13 @@ public class FMDemodulatorModule extends Module implements IComplexBufferListene
mIQFilter.setListener(mDemodulator);
}
public FMDemodulatorModule(float[] filter)
{
mIQFilter = new ComplexFIRFilter_CB_CB(filter, 1.0f);
mDemodulator = new FMDemodulator_CB(1.0f);
mIQFilter.setListener(mDemodulator);
}
@Override
public Listener<ComplexBuffer> getComplexBufferListener()
{