mirror of
https://github.com/DSheirer/sdrtrunk.git
synced 2026-11-12 16:47:31 -05:00
Automatic Frequency Control enhancement. Provides default AFC and ability to disable in the Decoder tab of each channel. Spectral display includes visual indicators of frequency center (grey) and current AFC offset (yellow).
This commit is contained in:
@@ -17,6 +17,11 @@
|
||||
******************************************************************************/
|
||||
package decode;
|
||||
|
||||
import java.awt.event.ActionEvent;
|
||||
import java.awt.event.ActionListener;
|
||||
|
||||
import javax.swing.JCheckBox;
|
||||
|
||||
import controller.Editor;
|
||||
import decode.config.DecodeConfiguration;
|
||||
|
||||
@@ -25,10 +30,25 @@ public class DecodeEditor extends Editor
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
protected DecodeConfiguration mConfig;
|
||||
|
||||
|
||||
protected JCheckBox mAFC;
|
||||
|
||||
public DecodeEditor( DecodeConfiguration config )
|
||||
{
|
||||
mConfig = config;
|
||||
|
||||
mAFC = new JCheckBox( "Automatic Frequency Control" );
|
||||
mAFC.setSelected( mConfig.isAFCEnabled() );
|
||||
mAFC.addActionListener( new ActionListener()
|
||||
{
|
||||
@Override
|
||||
public void actionPerformed( ActionEvent arg0 )
|
||||
{
|
||||
mConfig.setAFC( mAFC.isSelected() );
|
||||
}
|
||||
} );
|
||||
|
||||
add( mAFC, "wrap" );
|
||||
}
|
||||
|
||||
public DecodeConfiguration getConfig()
|
||||
|
||||
@@ -20,6 +20,7 @@ package decode;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import dsp.afc.AutomaticFrequencyControl;
|
||||
import message.Message;
|
||||
import sample.Broadcaster;
|
||||
import sample.Listener;
|
||||
@@ -130,6 +131,8 @@ public abstract class Decoder implements Listener<Message>
|
||||
{
|
||||
mFloatBroadcaster.addListener( listener );
|
||||
}
|
||||
|
||||
public abstract void addUnfilteredFloatListener( Listener<Float> listener );
|
||||
|
||||
public void removeFloatListener( Listener<Float> listener )
|
||||
{
|
||||
|
||||
@@ -17,6 +17,7 @@
|
||||
******************************************************************************/
|
||||
package decode.config;
|
||||
|
||||
import javax.xml.bind.annotation.XmlElement;
|
||||
import javax.xml.bind.annotation.XmlRootElement;
|
||||
import javax.xml.bind.annotation.XmlSeeAlso;
|
||||
|
||||
@@ -32,6 +33,7 @@ import decode.DecoderType;
|
||||
public abstract class DecodeConfiguration extends Configuration
|
||||
{
|
||||
private DecoderType mDecoderType = DecoderType.NBFM;
|
||||
private boolean mAFCEnabled = true;
|
||||
|
||||
public DecodeConfiguration()
|
||||
{
|
||||
@@ -47,4 +49,20 @@ public abstract class DecodeConfiguration extends Configuration
|
||||
{
|
||||
return mDecoderType;
|
||||
}
|
||||
|
||||
@XmlElement( name = "afc" )
|
||||
public boolean getAFC()
|
||||
{
|
||||
return mAFCEnabled;
|
||||
}
|
||||
|
||||
public boolean isAFCEnabled()
|
||||
{
|
||||
return mAFCEnabled;
|
||||
}
|
||||
|
||||
public void setAFC( boolean enabled )
|
||||
{
|
||||
mAFCEnabled = enabled;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -181,4 +181,10 @@ public class Fleetsync2Decoder extends Decoder implements Instrumentable
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void addUnfilteredFloatListener( Listener<Float> listener )
|
||||
{
|
||||
//Not implemented
|
||||
}
|
||||
}
|
||||
|
||||
@@ -24,6 +24,7 @@ import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import message.MessageDirection;
|
||||
import sample.Listener;
|
||||
import source.Source.SampleType;
|
||||
import alias.AliasList;
|
||||
import bits.MessageFramer;
|
||||
@@ -148,4 +149,14 @@ public class LTRNetDecoder extends Decoder implements Instrumentable
|
||||
{
|
||||
mLTRFSKDecoder.removeTap( tap );
|
||||
}
|
||||
|
||||
@Override
|
||||
public void addUnfilteredFloatListener( Listener<Float> listener )
|
||||
{
|
||||
if( mDemodulator != null )
|
||||
{
|
||||
mDemodulator.addListener( listener );
|
||||
}
|
||||
// TODO Auto-generated method stub
|
||||
}
|
||||
}
|
||||
|
||||
@@ -21,6 +21,7 @@ import java.awt.event.ActionEvent;
|
||||
import java.awt.event.ActionListener;
|
||||
|
||||
import javax.swing.DefaultComboBoxModel;
|
||||
import javax.swing.JCheckBox;
|
||||
import javax.swing.JComboBox;
|
||||
|
||||
import message.MessageDirection;
|
||||
|
||||
@@ -18,6 +18,7 @@
|
||||
package decode.ltrstandard;
|
||||
|
||||
import message.MessageDirection;
|
||||
import sample.Listener;
|
||||
import source.Source.SampleType;
|
||||
import alias.AliasList;
|
||||
import bits.MessageFramer;
|
||||
@@ -115,4 +116,13 @@ public class LTRStandardDecoder extends Decoder
|
||||
{
|
||||
return DecoderType.LTR_STANDARD;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void addUnfilteredFloatListener( Listener<Float> listener )
|
||||
{
|
||||
if( mDemodulator != null )
|
||||
{
|
||||
mDemodulator.addListener( listener );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -25,6 +25,7 @@ import instrument.tap.stream.FloatTap;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import sample.Listener;
|
||||
import source.Source.SampleType;
|
||||
import alias.AliasList;
|
||||
import bits.MessageFramer;
|
||||
@@ -199,4 +200,10 @@ public class MDCDecoder extends Decoder implements Instrumentable
|
||||
default:
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void addUnfilteredFloatListener( Listener<Float> listener )
|
||||
{
|
||||
//Not implemented
|
||||
}
|
||||
}
|
||||
|
||||
@@ -43,6 +43,7 @@ public class MPT1327ChannelState extends ChannelState
|
||||
private ChannelMap mChannelMap;
|
||||
private MPT1327ActivitySummary mActivitySummary;
|
||||
|
||||
|
||||
public MPT1327ChannelState( ProcessingChain processingChain,
|
||||
AliasList aliasList,
|
||||
ChannelMap channelMap )
|
||||
@@ -156,72 +157,72 @@ public class MPT1327ChannelState extends ChannelState
|
||||
setState( State.CONTROL );
|
||||
break;
|
||||
case GTC:
|
||||
int channelNumber = mpt.getChannel();
|
||||
|
||||
if( !getProcessingChain().getChannel()
|
||||
.hasTrafficChannel( channelNumber ) )
|
||||
if( mpt.isValidCall() )
|
||||
{
|
||||
String aliasListName = mProcessingChain
|
||||
.getChannel().getAliasListName();
|
||||
int channelNumber = mpt.getChannel();
|
||||
|
||||
Channel traffic = getTrafficChannel( channelNumber,
|
||||
aliasListName );
|
||||
|
||||
/* Set the system and site to same as control channel */
|
||||
traffic.setSystem( getProcessingChain().getChannel()
|
||||
.getSystem(), false );
|
||||
traffic.setSite( getProcessingChain().getChannel()
|
||||
.getSite(), false );
|
||||
if( !getProcessingChain().getChannel()
|
||||
.hasTrafficChannel( channelNumber ) )
|
||||
{
|
||||
String aliasListName = mProcessingChain
|
||||
.getChannel().getAliasListName();
|
||||
|
||||
Channel traffic = getTrafficChannel( channelNumber,
|
||||
aliasListName );
|
||||
|
||||
/* Set the system and site to same as control channel */
|
||||
traffic.setSystem( getProcessingChain().getChannel()
|
||||
.getSystem(), false );
|
||||
traffic.setSite( getProcessingChain().getChannel()
|
||||
.getSite(), false );
|
||||
|
||||
/* Add the traffic channel to the parent control channel */
|
||||
getProcessingChain().getChannel()
|
||||
.addTrafficChannel( channelNumber, traffic );
|
||||
/* Add the traffic channel to the parent control channel */
|
||||
getProcessingChain().getChannel()
|
||||
.addTrafficChannel( channelNumber, traffic );
|
||||
|
||||
/* Start the traffic channel */
|
||||
traffic.setEnabled( true );
|
||||
|
||||
/* Set traffic channel state info */
|
||||
MPT1327ChannelState trafficState =
|
||||
(MPT1327ChannelState)traffic
|
||||
.getProcessingChain().getChannelState();
|
||||
|
||||
MPT1327ChannelState controlState =
|
||||
(MPT1327ChannelState)getProcessingChain()
|
||||
.getChannelState();
|
||||
|
||||
trafficState.setChannelMap( controlState.getChannelMap() );
|
||||
trafficState.setChannelNumber( channelNumber );
|
||||
trafficState.setFromTalkgroup( mpt.getFromID() );
|
||||
trafficState.setToTalkgroup( mpt.getToID() );
|
||||
/* Start the traffic channel */
|
||||
traffic.setEnabled( true );
|
||||
|
||||
/* Set traffic channel state info */
|
||||
MPT1327ChannelState trafficState =
|
||||
(MPT1327ChannelState)traffic
|
||||
.getProcessingChain().getChannelState();
|
||||
|
||||
MPT1327ChannelState controlState =
|
||||
(MPT1327ChannelState)getProcessingChain()
|
||||
.getChannelState();
|
||||
|
||||
trafficState.setChannelMap( controlState.getChannelMap() );
|
||||
trafficState.setChannelNumber( channelNumber );
|
||||
trafficState.setFromTalkgroup( mpt.getFromID() );
|
||||
trafficState.setToTalkgroup( mpt.getToID() );
|
||||
|
||||
/* Add this control channel as message listener on the
|
||||
* traffic channel so we can receive call tear-down
|
||||
* messages */
|
||||
traffic.addListener( (Listener<Message>)this );
|
||||
|
||||
CallEventType type = traffic.isProcessing() ?
|
||||
CallEventType.CALL_START :
|
||||
CallEventType.CALL_START_NO_TUNER;
|
||||
|
||||
/*
|
||||
* Set the traffic channel's call event model to
|
||||
* share the control channel's call event model
|
||||
*/
|
||||
traffic.getProcessingChain().getChannelState()
|
||||
.setCallEventModel( mCallEventModel );
|
||||
|
||||
mCallEventModel.add(
|
||||
new MPT1327CallEvent.Builder( type )
|
||||
.aliasList( traffic.getProcessingChain().getAliasList() )
|
||||
.channel( channelNumber )
|
||||
.frequency( mChannelMap.getFrequency( channelNumber ) )
|
||||
.from( mpt.getFromID() )
|
||||
.to( mpt.getToID() )
|
||||
.build() );
|
||||
/* Add this control channel as message listener on the
|
||||
* traffic channel so we can receive call tear-down
|
||||
* messages */
|
||||
traffic.addListener( (Listener<Message>)this );
|
||||
|
||||
CallEventType type = traffic.isProcessing() ?
|
||||
CallEventType.CALL_START :
|
||||
CallEventType.CALL_START_NO_TUNER;
|
||||
|
||||
/*
|
||||
* Set the traffic channel's call event model to
|
||||
* share the control channel's call event model
|
||||
*/
|
||||
traffic.getProcessingChain().getChannelState()
|
||||
.setCallEventModel( mCallEventModel );
|
||||
|
||||
mCallEventModel.add(
|
||||
new MPT1327CallEvent.Builder( type )
|
||||
.aliasList( traffic.getProcessingChain().getAliasList() )
|
||||
.channel( channelNumber )
|
||||
.frequency( mChannelMap.getFrequency( channelNumber ) )
|
||||
.from( mpt.getFromID() )
|
||||
.to( mpt.getToID() )
|
||||
.build() );
|
||||
}
|
||||
}
|
||||
|
||||
long frequency = mChannelMap.getFrequency( channelNumber );
|
||||
|
||||
break;
|
||||
case CLEAR:
|
||||
case MAINT:
|
||||
@@ -237,7 +238,7 @@ public class MPT1327ChannelState extends ChannelState
|
||||
mCallEventModel.add(
|
||||
new MPT1327CallEvent.Builder( CallEventType.SDM )
|
||||
.aliasList( mAliasList )
|
||||
.details( mpt.getMessageType().getDescription() )
|
||||
.details( mpt.getMessage() )
|
||||
.from( mpt.getFromID() )
|
||||
.to( mpt.getToID() )
|
||||
.build() );
|
||||
@@ -378,6 +379,7 @@ public class MPT1327ChannelState extends ChannelState
|
||||
traffic.setSourceConfiguration( source );
|
||||
|
||||
DecodeConfigMPT1327 decode = new DecodeConfigMPT1327();
|
||||
|
||||
traffic.setDecodeConfiguration( decode );
|
||||
|
||||
traffic.setAliasListName( aliasListName );
|
||||
|
||||
@@ -25,13 +25,16 @@ import instrument.tap.stream.FloatTap;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import log.Log;
|
||||
import sample.Broadcaster;
|
||||
import sample.Listener;
|
||||
import source.Source.SampleType;
|
||||
import alias.AliasList;
|
||||
import bits.MessageFramer;
|
||||
import bits.SyncPattern;
|
||||
import decode.Decoder;
|
||||
import decode.DecoderType;
|
||||
import dsp.afc.AutomaticFrequencyControl;
|
||||
import dsp.filter.DCRemovalFilter;
|
||||
import dsp.filter.FilterFactory;
|
||||
import dsp.filter.Filters;
|
||||
@@ -95,7 +98,7 @@ public class MPT1327Decoder extends Decoder implements Instrumentable
|
||||
/* I/Q low pass filtering narrow band FM demodulator */
|
||||
mNBFMDemodulator = new NBFMDemodulator(
|
||||
FilterFactory.getLowPass( 48000, 4000, 73, WindowType.HAMMING ),
|
||||
1.0002 );
|
||||
1.0002, true );
|
||||
|
||||
this.addComplexListener( mNBFMDemodulator );
|
||||
|
||||
@@ -166,6 +169,15 @@ public class MPT1327Decoder extends Decoder implements Instrumentable
|
||||
mControlMessageFramer.addMessageListener( mMessageProcessor );
|
||||
mTrafficMessageFramer.addMessageListener( mMessageProcessor );
|
||||
}
|
||||
|
||||
@Override
|
||||
public void addUnfilteredFloatListener( Listener<Float> listener )
|
||||
{
|
||||
if( mNBFMDemodulator != null )
|
||||
{
|
||||
mNBFMDemodulator.addListener( listener );
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public DecoderType getType()
|
||||
|
||||
@@ -281,6 +281,13 @@ public class MPT1327Message extends Message
|
||||
return mCRC[ 0 ] == CRC.PASSED ||
|
||||
mCRC[ 0 ] == CRC.CORRECTED;
|
||||
}
|
||||
|
||||
public boolean isValidCall()
|
||||
{
|
||||
return getPrefix() != 0 &&
|
||||
getIdent1() != 0 &&
|
||||
getIdent2() != 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructs a decoded message string
|
||||
@@ -312,9 +319,9 @@ public class MPT1327Message extends Message
|
||||
*/
|
||||
public MPTMessageType getMessageType()
|
||||
{
|
||||
int type = mMessage.getInt( B1_MESSAGE_TYPE );
|
||||
int value = mMessage.getInt( B1_MESSAGE_TYPE );
|
||||
|
||||
return MPTMessageType.fromNumber( type );
|
||||
return MPTMessageType.fromNumber( value );
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -766,6 +773,7 @@ public class MPT1327Message extends Message
|
||||
case HEAD_PLUS2:
|
||||
case HEAD_PLUS3:
|
||||
case HEAD_PLUS4:
|
||||
sb.append( " " );
|
||||
sb.append( getSDM() );
|
||||
break;
|
||||
}
|
||||
@@ -947,9 +955,12 @@ public class MPT1327Message extends Message
|
||||
break;
|
||||
case USER:
|
||||
default:
|
||||
sb.append( format( prefix, 3 ) );
|
||||
sb.append( "-" );
|
||||
sb.append( format( ident, 4) );
|
||||
if( prefix != 0 || ident != 0 )
|
||||
{
|
||||
sb.append( format( prefix, 3 ) );
|
||||
sb.append( "-" );
|
||||
sb.append( format( ident, 4) );
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -1701,7 +1712,7 @@ public class MPT1327Message extends Message
|
||||
public enum Descriptor
|
||||
{
|
||||
DESC0( "EXTENDED ADDRESSING INFORMATION",
|
||||
"SERIAL NUMBER",
|
||||
"ESN",
|
||||
"SINGLE SEGMENT TRANSACTIONS (SST) ONLY" ),
|
||||
DESC1( "PSTN DIALED DIGITS", "RESERVED", "N/A" ),
|
||||
DESC2( "PABX EXTENSION", "RESERVED", "N/A" ),
|
||||
|
||||
@@ -17,9 +17,11 @@
|
||||
******************************************************************************/
|
||||
package decode.nbfm;
|
||||
|
||||
import sample.Listener;
|
||||
import source.Source.SampleType;
|
||||
import decode.Decoder;
|
||||
import decode.DecoderType;
|
||||
import dsp.afc.AutomaticFrequencyControl;
|
||||
import dsp.filter.DCRemovalFilter2;
|
||||
import dsp.nbfm.FilteringNBFMDemodulator;
|
||||
|
||||
@@ -32,7 +34,7 @@ public class NBFMConventionalDecoder extends Decoder
|
||||
private static final double sDC_REMOVAL_RATIO = 0.000003;
|
||||
|
||||
private FilteringNBFMDemodulator mDemodulator;
|
||||
private DCRemovalFilter2 mDCRemovalFilter;
|
||||
private DCRemovalFilter2 mDCRemovalFilter;
|
||||
|
||||
public NBFMConventionalDecoder( SampleType sampleType )
|
||||
{
|
||||
@@ -60,7 +62,7 @@ public class NBFMConventionalDecoder extends Decoder
|
||||
*/
|
||||
mDCRemovalFilter = new DCRemovalFilter2( sDC_REMOVAL_RATIO );
|
||||
mDemodulator.addListener( mDCRemovalFilter );
|
||||
|
||||
|
||||
/**
|
||||
* Route the demodulated, filtered samples back to this class to send
|
||||
* to all registered listeners
|
||||
@@ -74,4 +76,13 @@ public class NBFMConventionalDecoder extends Decoder
|
||||
{
|
||||
return DecoderType.NBFM;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void addUnfilteredFloatListener( Listener<Float> listener )
|
||||
{
|
||||
if( mDemodulator != null )
|
||||
{
|
||||
mDemodulator.addListener( listener );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -17,12 +17,16 @@
|
||||
******************************************************************************/
|
||||
package decode.nbfm;
|
||||
|
||||
import javax.swing.JCheckBox;
|
||||
|
||||
import decode.DecodeEditor;
|
||||
import decode.config.DecodeConfiguration;
|
||||
|
||||
public class NBFMEditor extends DecodeEditor
|
||||
{
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
private JCheckBox mAFC;
|
||||
|
||||
public NBFMEditor( DecodeConfiguration config )
|
||||
{
|
||||
|
||||
@@ -24,10 +24,12 @@ import instrument.tap.stream.FloatTap;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import sample.Listener;
|
||||
import source.Source.SampleType;
|
||||
import alias.AliasList;
|
||||
import decode.Decoder;
|
||||
import decode.DecoderType;
|
||||
import dsp.afc.AutomaticFrequencyControl;
|
||||
import dsp.filter.DCRemovalFilter2;
|
||||
import dsp.fsk.C4FMDecoder;
|
||||
import dsp.nbfm.FilteringNBFMDemodulator;
|
||||
@@ -141,4 +143,11 @@ public class P25Decoder extends Decoder implements Instrumentable
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void addUnfilteredFloatListener( Listener<Float> listener )
|
||||
{
|
||||
// TODO Auto-generated method stub
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@@ -23,12 +23,14 @@ import instrument.tap.Tap;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import sample.Listener;
|
||||
import source.Source.SampleType;
|
||||
import alias.AliasList;
|
||||
import bits.MessageFramer;
|
||||
import bits.SyncPattern;
|
||||
import decode.Decoder;
|
||||
import decode.DecoderType;
|
||||
import dsp.afc.AutomaticFrequencyControl;
|
||||
import dsp.filter.DCRemovalFilter2;
|
||||
import dsp.fsk.LTRFSKDecoder;
|
||||
import dsp.nbfm.FilteringNBFMDemodulator;
|
||||
@@ -138,4 +140,13 @@ public class PassportDecoder extends Decoder implements Instrumentable
|
||||
{
|
||||
mPassportFSKDecoder.removeTap( tap );
|
||||
}
|
||||
|
||||
@Override
|
||||
public void addUnfilteredFloatListener( Listener<Float> listener )
|
||||
{
|
||||
if( mNBFMDemodulator != null )
|
||||
{
|
||||
mNBFMDemodulator.addListener( listener );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user