Work in progress.

-Started work on new channel editor channel viewer/controller
-Removed a number of unused buffer package classes
-Moved automatic frequency control to be a module and removed special
handling
-Added IUnfilteredRealBufferListener & Provider interfaces
-Completely removed the ResourceManager class
This commit is contained in:
denny
2016-01-10 18:02:04 -05:00
parent c405ddad96
commit 4be63d4b95
197 changed files with 4181 additions and 4439 deletions

View File

@@ -16,12 +16,13 @@ import sample.Listener;
import sample.real.RealBuffer;
import sample.real.RealSampleListener;
import sample.real.RealSampleProvider;
import source.tuner.frequency.FrequencyCorrectionControl;
import source.tuner.frequency.FrequencyCorrectionControl.FrequencyCorrectionResetListener;
import source.tuner.frequency.FrequencyChangeEvent;
import source.tuner.frequency.FrequencyChangeEvent.Event;
import source.tuner.frequency.IFrequencyChangeListener;
import dsp.gain.DirectGainControl;
public class C4FMSymbolFilter implements FrequencyCorrectionResetListener,
Listener<RealBuffer>,
public class C4FMSymbolFilter implements Listener<RealBuffer>,
IFrequencyChangeListener,
RealSampleProvider,
Instrumentable
{
@@ -201,15 +202,17 @@ public class C4FMSymbolFilter implements FrequencyCorrectionResetListener,
private float mHistory[] = new float[ NUMBER_FILTER_TAPS ];
private int mHistoryLast = 0;
private boolean mResetFrequencyTracker = false;
private RealSampleListener mListener;
private DirectGainControl mGainController =
new DirectGainControl( 15.0f, 0.1f, 35.0f, 0.3f );
private FrequencyCorrectionControl mFrequencyCorrectionControl;
private int mFrequencyAdjustmentRequested = 0;
private int mFrequencyCorrection = 0;
private int mFrequencyCorrectionMaximum = 3000;
private boolean mResetFrequencyTracker = false;
private FrequencyCorrectionProcessor mFrequencyCorrectionProcessor;
private Listener<FrequencyChangeEvent> mFrequencyChangeListener;
/**
* C4FM Symbol Filter
@@ -224,18 +227,15 @@ public class C4FMSymbolFilter implements FrequencyCorrectionResetListener,
* setting for this filter is 15.4 and that yields a symbol spread that
* is centered on 2.0, ranging 1.92 to 2.08.
*/
public C4FMSymbolFilter( FrequencyCorrectionControl frequencyControl )
public C4FMSymbolFilter( int frequencyCorrectionMaximum )
{
mFrequencyCorrectionControl = frequencyControl;
/* Register for reset events, so we can reset internal frequency tracking */
mFrequencyCorrectionControl.setListener( this );
mFrequencyCorrectionMaximum = frequencyCorrectionMaximum;
}
public void dispose()
{
mGainController = null;
mFrequencyCorrectionControl = null;
// mFrequencyCorrectionControl = null;
mListener = null;
}
@@ -253,13 +253,21 @@ public class C4FMSymbolFilter implements FrequencyCorrectionResetListener,
* the internal frequency correction tracker */
if( mFrequencyAdjustmentRequested != 0 )
{
mFrequencyCorrectionControl.adjust( mFrequencyAdjustmentRequested );
int correction = mFrequencyCorrection + mFrequencyAdjustmentRequested;
if( correction > mFrequencyCorrectionMaximum )
{
correction = mFrequencyCorrectionMaximum;
}
else if( correction < -mFrequencyCorrectionMaximum )
{
correction = -mFrequencyCorrectionMaximum;
}
broadcast( new FrequencyChangeEvent(
Event.REQUEST_CHANNEL_FREQUENCY_CORRECTION_CHANGE, correction ) );
mFrequencyAdjustmentRequested = 0;
//Reset internal frequency tracking
mCoarseFrequencyCorrection = 0.0f;
mFineFrequencyCorrection = 0.0f;
}
}
@@ -272,7 +280,8 @@ public class C4FMSymbolFilter implements FrequencyCorrectionResetListener,
mCoarseFrequencyCorrection = 0.0f;
mFineFrequencyCorrection = 0.0f;
mFrequencyCorrectionControl.setFrequencyCorrection( 0 );
broadcast( new FrequencyChangeEvent(
Event.REQUEST_CHANNEL_FREQUENCY_CORRECTION_CHANGE, 0 ));
mResetFrequencyTracker = false;
}
@@ -397,17 +406,6 @@ public class C4FMSymbolFilter implements FrequencyCorrectionResetListener,
}
}
/**
* Listener interface for frequency correction reset events. We reset the
* coarse and fine frequency control values when the tuner channel source
* has changed frequency (PPM) or sample rate
*/
@Override
public void resetFrequencyCorrection()
{
mResetFrequencyTracker = true;
}
@Override
public void setListener( RealSampleListener listener )
{
@@ -459,4 +457,56 @@ public class C4FMSymbolFilter implements FrequencyCorrectionResetListener,
mSymbolSpreadTap = null;
}
}
public void broadcast( FrequencyChangeEvent event )
{
if( mFrequencyChangeListener != null )
{
mFrequencyChangeListener.receive( event );
}
}
public void setFrequencyChangeListener( Listener<FrequencyChangeEvent> listener )
{
mFrequencyChangeListener = listener;
}
@Override
public Listener<FrequencyChangeEvent> getFrequencyChangeListener()
{
if( mFrequencyCorrectionProcessor == null )
{
mFrequencyCorrectionProcessor = new FrequencyCorrectionProcessor();
}
return mFrequencyCorrectionProcessor;
}
/**
* Receives notifications that the channel frequency correction has been
* applied and updates internal tracking value.
*/
public class FrequencyCorrectionProcessor implements Listener<FrequencyChangeEvent>
{
@Override
public void receive( FrequencyChangeEvent event )
{
switch( event.getEvent() )
{
case NOTIFICATION_CHANNEL_FREQUENCY_CORRECTION_CHANGE:
mFrequencyCorrection = event.getValue().intValue();
//Reset internal frequency tracking
mCoarseFrequencyCorrection = 0.0f;
mFineFrequencyCorrection = 0.0f;
break;
case NOTIFICATION_FREQUENCY_CORRECTION_CHANGE:
case NOTIFICATION_SAMPLE_RATE_CHANGE:
mResetFrequencyTracker = true;
break;
default:
break;
}
}
}
}

View File

@@ -34,8 +34,8 @@ import org.slf4j.LoggerFactory;
import source.SourceEditor;
import source.tuner.TunerEditor;
import controller.Editor;
import controller.channel.ChannelValidationException;
import controller.channel.ChannelConfigurationEditor;
import controller.channel.ConfigurationValidationException;
public class P25DecodeEditor extends DecodeEditor
{
@@ -101,29 +101,29 @@ public class P25DecodeEditor extends DecodeEditor
add( new JLabel( "Ignore Data Calls" ) );
add( mIgnoreDataCalls, "wrap,grow" );
reset();
// reset();
}
/**
* Enforce source=tuner for CQPSK modulation
*/
@Override
public void validate( Editor editor ) throws ChannelValidationException
{
if( editor instanceof SourceEditor &&
((DecodeConfigP25Phase1)mConfig).getModulation() == Modulation.CQPSK )
{
if( !( editor instanceof TunerEditor ) )
{
throw new ChannelValidationException(
"<html><body width='175'><h1>LSM Simulcast</h1>"
+ "<p>P25 LSM Simulcast decoder can only be used with "
+ "a tuner source. Please change the Source to use a tuner"
+ " or change the P25 Decoder to C4FM modulation" );
}
}
}
// /**
// * Enforce source=tuner for CQPSK modulation
// */
// @Override
// public void validate( ChannelConfigurationEditor editor ) throws ConfigurationValidationException
// {
// if( editor instanceof SourceEditor &&
// ((DecodeConfigP25Phase1)mConfig).getModulation() == Modulation.CQPSK )
// {
// if( !( editor instanceof TunerEditor ) )
// {
// throw new ConfigurationValidationException(
// "<html><body width='175'><h1>LSM Simulcast</h1>"
// + "<p>P25 LSM Simulcast decoder can only be used with "
// + "a tuner source. Please change the Source to use a tuner"
// + " or change the P25 Decoder to C4FM modulation" );
//
// }
// }
// }
@Override
public void save()
@@ -135,13 +135,13 @@ public class P25DecodeEditor extends DecodeEditor
config.setTrafficChannelPoolSize( mTrafficChannelPoolSize.getValue() );
}
@Override
public void reset()
{
DecodeConfigP25Phase1 config = (DecodeConfigP25Phase1)mConfig;
mComboModulation.setSelectedItem( config.getModulation() );
mIgnoreDataCalls.setSelected( config.getIgnoreDataCalls() );
mTrafficChannelPoolSize.setValue( config.getTrafficChannelPoolSize() );
}
// @Override
// public void reset()
// {
// DecodeConfigP25Phase1 config = (DecodeConfigP25Phase1)mConfig;
//
// mComboModulation.setSelectedItem( config.getModulation() );
// mIgnoreDataCalls.setSelected( config.getIgnoreDataCalls() );
// mTrafficChannelPoolSize.setValue( config.getTrafficChannelPoolSize() );
// }
}

View File

@@ -3,11 +3,9 @@ package module.decode.p25;
import instrument.Instrumentable;
import module.decode.Decoder;
import module.decode.DecoderType;
import source.tuner.frequency.IFrequencyCorrectionController;
import alias.AliasList;
public abstract class P25Decoder extends Decoder
implements IFrequencyCorrectionController, Instrumentable
public abstract class P25Decoder extends Decoder implements Instrumentable
{
private P25MessageProcessor mMessageProcessor;

View File

@@ -24,22 +24,24 @@ import instrument.tap.stream.FloatBufferTap;
import instrument.tap.stream.FloatTap;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import sample.Listener;
import sample.real.IRealBufferListener;
import sample.real.IFilteredRealBufferListener;
import sample.real.RealBuffer;
import source.tuner.frequency.FrequencyCorrectionControl;
import source.tuner.frequency.FrequencyChangeEvent;
import source.tuner.frequency.IFrequencyChangeListener;
import source.tuner.frequency.IFrequencyChangeProvider;
import alias.AliasList;
import dsp.filter.FilterFactory;
import dsp.filter.Window.WindowType;
import dsp.filter.fir.real.RealFIRFilter_RB_RB;
public class P25_C4FMDecoder extends P25Decoder implements IRealBufferListener
public class P25_C4FMDecoder extends P25Decoder
implements IFrequencyChangeListener, IFrequencyChangeProvider,IFilteredRealBufferListener
{
private final static Logger mLog = LoggerFactory.getLogger( P25_C4FMDecoder.class );
@@ -48,11 +50,8 @@ public class P25_C4FMDecoder extends P25Decoder implements IRealBufferListener
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 final static int MAXIMUM_FREQUENCY_CORRECTION = 3000; //Hertz, +/-
private List<TapGroup> mAvailableTaps;
private RealFIRFilter_RB_RB mC4FMPreFilter;
private FrequencyCorrectionControl mFrequencyCorrectionControl;
private C4FMSymbolFilter mSymbolFilter;
private C4FMSlicer mC4FMSlicer;
private P25MessageFramer mMessageFramer;
@@ -70,23 +69,18 @@ public class P25_C4FMDecoder extends P25Decoder implements IRealBufferListener
* infrastructure and subscriber identities that will be included in each
* decoded message
*/
public P25_C4FMDecoder( AliasList aliasList )
public P25_C4FMDecoder( AliasList aliasList, int frequencyCorrectionMaximum )
{
super( aliasList );
/* Filter demodulated sample buffers */
float[] filter = FilterFactory.getLowPass( 48000, 2500, 4000, 80, WindowType.HANNING, true );
mLog.debug( "Demod Filter tap count:" + filter.length + " coefficients:" + Arrays.toString( filter ) );
// mLog.debug( "Demod Filter tap count:" + filter.length + " coefficients:" + Arrays.toString( filter ) );
mC4FMPreFilter = new RealFIRFilter_RB_RB( filter, 1.0f );
/* Issue tuned frequency correction commands, remotely controlled by the
* downstream symbol filter */
mFrequencyCorrectionControl = new FrequencyCorrectionControl(
MAXIMUM_FREQUENCY_CORRECTION );
/* Shape gain and frequency offsets to optimize sample stream */
mSymbolFilter = new C4FMSymbolFilter( mFrequencyCorrectionControl );
mSymbolFilter = new C4FMSymbolFilter( frequencyCorrectionMaximum );
mC4FMPreFilter.setListener( mSymbolFilter );
/* Convert samples to symbols */
@@ -109,9 +103,6 @@ public class P25_C4FMDecoder extends P25Decoder implements IRealBufferListener
mC4FMPreFilter.dispose();
mC4FMPreFilter = null;
mFrequencyCorrectionControl.dispose();
mFrequencyCorrectionControl = null;
mSymbolFilter.dispose();
mSymbolFilter = null;
@@ -128,19 +119,7 @@ public class P25_C4FMDecoder extends P25Decoder implements IRealBufferListener
}
@Override
public boolean hasFrequencyCorrectionControl()
{
return mFrequencyCorrectionControl != null;
}
@Override
public FrequencyCorrectionControl getFrequencyCorrectionControl()
{
return mFrequencyCorrectionControl;
}
@Override
public Listener<RealBuffer> getRealBufferListener()
public Listener<RealBuffer> getFilteredRealBufferListener()
{
return mC4FMPreFilter;
}
@@ -262,4 +241,33 @@ public class P25_C4FMDecoder extends P25Decoder implements IRealBufferListener
// TODO Auto-generated method stub
}
@Override
public void setFrequencyChangeListener( Listener<FrequencyChangeEvent> listener )
{
if( mSymbolFilter != null )
{
mSymbolFilter.setFrequencyChangeListener( listener );
}
}
@Override
public void removeFrequencyChangeListener()
{
if( mSymbolFilter != null )
{
mSymbolFilter.setFrequencyChangeListener( null );
}
}
@Override
public Listener<FrequencyChangeEvent> getFrequencyChangeListener()
{
if( mSymbolFilter != null )
{
return mSymbolFilter.getFrequencyChangeListener();
}
return null;
}
}

View File

@@ -34,7 +34,6 @@ import sample.Listener;
import sample.complex.ComplexBuffer;
import sample.complex.ComplexBufferToStreamConverter;
import sample.complex.IComplexBufferListener;
import source.tuner.frequency.FrequencyCorrectionControl;
import alias.AliasList;
import dsp.filter.FilterFactory;
import dsp.filter.Window.WindowType;
@@ -119,18 +118,6 @@ public class P25_LSMDecoder extends P25Decoder implements IComplexBufferListener
return Modulation.CQPSK;
}
@Override
public boolean hasFrequencyCorrectionControl()
{
return false;
}
@Override
public FrequencyCorrectionControl getFrequencyCorrectionControl()
{
return null;
}
/**
* Provides a list of instrumentation taps for monitoring internal processing
*/