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

@@ -1,6 +1,6 @@
/*******************************************************************************
* SDR Trunk
* Copyright (C) 2014 Dennis Sheirer
* Copyright (C) 2014-2016 Dennis Sheirer
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -26,7 +26,8 @@ import javax.swing.SwingUtilities;
import module.decode.config.AuxDecodeConfiguration;
import controller.channel.AbstractChannelEditor;
import controller.channel.ChannelNode;
import controller.channel.Channel;
import controller.channel.ConfigurationValidationException;
public class AuxDecodeComponentEditor extends AbstractChannelEditor
{
@@ -35,9 +36,9 @@ public class AuxDecodeComponentEditor extends AbstractChannelEditor
private HashMap<DecoderType,AuxDecoderCheckBox> mControls =
new HashMap<DecoderType,AuxDecoderCheckBox>();
public AuxDecodeComponentEditor( ChannelNode channelNode )
public AuxDecodeComponentEditor( Channel channel )
{
super( channelNode );
super( channel );
List<DecoderType> decoders = DecoderType.getAuxDecoders();
@@ -60,7 +61,7 @@ public class AuxDecodeComponentEditor extends AbstractChannelEditor
public AuxDecodeConfiguration getConfig()
{
return getChannelNode().getChannel().getAuxDecodeConfiguration();
return getChannel().getAuxDecodeConfiguration();
}
@Override
@@ -107,4 +108,18 @@ public class AuxDecodeComponentEditor extends AbstractChannelEditor
mDecoderType = decoder;
}
}
@Override
public void setConfiguration( Channel channel )
{
// TODO Auto-generated method stub
}
@Override
public void validateConfiguration() throws ConfigurationValidationException
{
// TODO Auto-generated method stub
}
}

View File

@@ -1,6 +1,7 @@
/*******************************************************************************
* SDR Trunk
* Copyright (C) 2014 Dennis Sheirer
* Copyright (C) 2014-2016 Dennis Sheirer
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -17,7 +18,6 @@
******************************************************************************/
package module.decode;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
@@ -30,11 +30,10 @@ import module.decode.config.DecodeConfigFactory;
import module.decode.config.DecodeConfiguration;
import net.miginfocom.swing.MigLayout;
import playlist.PlaylistManager;
import controller.Editor;
import controller.channel.AbstractChannelEditor;
import controller.channel.Channel;
import controller.channel.ChannelNode;
import controller.channel.ChannelValidationException;
import controller.channel.ChannelConfigurationEditor;
import controller.channel.ConfigurationValidationException;
public class DecodeComponentEditor extends AbstractChannelEditor
{
@@ -48,13 +47,12 @@ public class DecodeComponentEditor extends AbstractChannelEditor
public DecodeComponentEditor( PlaylistManager playlistManager )
{
this( new ChannelNode( new Channel() ), playlistManager );
this( playlistManager, new Channel() );
}
public DecodeComponentEditor( ChannelNode channelNode,
PlaylistManager playlistMangager )
public DecodeComponentEditor( PlaylistManager playlistMangager, Channel channel )
{
super( channelNode );
super( channel );
mPlaylistManager = playlistMangager;
@@ -87,17 +85,13 @@ public class DecodeComponentEditor extends AbstractChannelEditor
{
DecodeConfiguration config;
if( mChannelNode.getChannel()
.getDecodeConfiguration().getDecoderType() ==
selected )
if( mChannel.getDecodeConfiguration().getDecoderType() == selected )
{
config = mChannelNode.getChannel()
.getDecodeConfiguration();
config = mChannel.getDecodeConfiguration();
}
else
{
config = DecodeConfigFactory
.getDecodeConfiguration( selected );
config = DecodeConfigFactory.getDecodeConfiguration( selected );
}
//Remove the existing one
@@ -108,7 +102,7 @@ public class DecodeComponentEditor extends AbstractChannelEditor
//Change to the new one
mEditor = DecoderFactory.getEditorPanel( config,
mChannelNode, mPlaylistManager );
mChannel, mPlaylistManager );
add( mEditor, "span 2,center" );
@@ -125,8 +119,7 @@ public class DecodeComponentEditor extends AbstractChannelEditor
public void reset()
{
final DecoderType decoder = mChannelNode.getChannel()
.getDecodeConfiguration().getDecoderType();
final DecoderType decoder = mChannel.getDecodeConfiguration().getDecoderType();
SwingUtilities.invokeLater(new Runnable()
{
@@ -155,18 +148,31 @@ public class DecodeComponentEditor extends AbstractChannelEditor
}
//The component that calls save will invoke the change broadcast
mChannelNode.getChannel()
.setDecodeConfiguration( mEditor.getConfig() );
mChannel.setDecodeConfiguration( mEditor.getConfig() );
}
/**
* Validates the editor against the current decode editor
*/
// /**
// * Validates the editor against the current decode editor
// */
// @Override
// public void validate( ChannelConfigurationEditor editor ) throws ConfigurationValidationException
// {
// super.validate( editor );
//
// mEditor.validate( editor );
// }
@Override
public void validate( Editor editor ) throws ChannelValidationException
public void setConfiguration( Channel channel )
{
super.validate( editor );
// TODO Auto-generated method stub
}
@Override
public void validateConfiguration() throws ConfigurationValidationException
{
// TODO Auto-generated method stub
mEditor.validate( editor );
}
}

View File

@@ -31,9 +31,11 @@ import javax.swing.event.ChangeListener;
import module.decode.config.DecodeConfiguration;
import net.miginfocom.swing.MigLayout;
import controller.Editor;
import controller.channel.Channel;
import controller.channel.ChannelConfigurationEditor;
import controller.channel.ConfigurationValidationException;
public class DecodeEditor extends Editor
public class DecodeEditor extends ChannelConfigurationEditor
{
private static final long serialVersionUID = 1L;
@@ -110,7 +112,16 @@ public class DecodeEditor extends Editor
}
@Override
public void reset()
{
}
public void setConfiguration( Channel channel )
{
// TODO Auto-generated method stub
}
@Override
public void validateConfiguration() throws ConfigurationValidationException
{
// TODO Auto-generated method stub
}
}

View File

@@ -63,10 +63,10 @@ import module.decode.nbfm.NBFMDecoder;
import module.decode.nbfm.NBFMDecoderPanel;
import module.decode.nbfm.NBFMEditor;
import module.decode.p25.DecodeConfigP25Phase1;
import module.decode.p25.P25DecodeEditor;
import module.decode.p25.P25Decoder.Modulation;
import module.decode.p25.P25DecoderPanel;
import module.decode.p25.P25DecoderState;
import module.decode.p25.P25DecodeEditor;
import module.decode.p25.P25_C4FMDecoder;
import module.decode.p25.P25_LSMDecoder;
import module.decode.p25.audio.P25AudioModule;
@@ -84,6 +84,7 @@ import module.decode.tait.Tait1200Decoder;
import module.decode.tait.Tait1200DecoderPanel;
import module.decode.tait.Tait1200DecoderState;
import module.demodulate.am.AMDemodulatorModule;
import module.demodulate.audio.DemodulatedAudioFilterModule;
import module.demodulate.fm.FMDemodulatorModule;
import org.slf4j.Logger;
@@ -97,12 +98,11 @@ import settings.SettingsManager;
import util.TimeStamp;
import alias.AliasList;
import audio.AudioModule;
import controller.ResourceManager;
import controller.channel.Channel;
import controller.channel.Channel.ChannelType;
import controller.channel.ChannelNode;
import controller.channel.ChannelModel;
import controller.channel.ChannelProcessingManager;
import controller.channel.map.ChannelMap;
import controller.site.Site;
import controller.system.System;
import filter.AllPassFilter;
import filter.FilterSet;
import filter.IFilter;
@@ -120,72 +120,46 @@ public class DecoderFactory
* Returns a list of one primary decoder and any auxiliary decoders, as
* specified in the configurations.
*
* @param channelType - standard or traffic channel type
* @param resourceManager
* @param decodeConfig - primary decoder configuration
* @param recordConfig - recording configuration used by traffic channel manager
* @param auxConfig - auxiliary decoder(s) configuration
* @param optional alias list - (null is ok)
*
* @return list of configured decoders
*/
public static List<Module> getModules( ChannelType channelType,
ResourceManager resourceManager,
DecodeConfiguration decodeConfig,
RecordConfiguration recordConfig,
AuxDecodeConfiguration auxConfig,
AliasList aliasList,
String system,
String site,
String channelName )
public static List<Module> getModules( ChannelModel channelModel,
ChannelProcessingManager channelProcessingManager,
PlaylistManager playlistManager,
Channel channel )
{
List<Module> modules = getPrimaryModules( channelType, decodeConfig,
recordConfig, aliasList, system, site, channelName, resourceManager );
modules.addAll( getAuxiliaryDecoders( auxConfig, aliasList ) );
/* Get the optional alias list for the decode modules to use */
AliasList aliasList = playlistManager.getPlayist()
.getAliasDirectory().getAliasList( channel.getAliasListName() );
List<Module> modules = getPrimaryModules( channelModel, channelProcessingManager,
playlistManager, aliasList, channel );
modules.addAll( getAuxiliaryDecoders( channel.getAuxDecodeConfiguration(), aliasList ) );
return modules;
}
public static FMDemodulatorModule getFMDemodulator(
DecodeConfiguration config, int pass, int stop, boolean removeDC )
{
if( config.isAFCEnabled() )
{
return new FMDemodulatorModule( pass, stop,
config.getAFCMaximumCorrection(), removeDC );
}
else
{
return new FMDemodulatorModule( pass, stop,
NO_FREQUENCY_CORRECTION, removeDC );
}
}
/**
* Constructs a primary decoder as specified in the decode configuration
*
* @param channelType - traffic or standard decode channel
* @param decodeConfig - primary decoder configuration
* @param recordConfig - recording options
* @param aliasList - optional alias list
* @param resourceManager - shared resource manager
* @return configured decoder or null
*/
public static List<Module> getPrimaryModules( ChannelType channelType,
DecodeConfiguration decodeConfig,
RecordConfiguration recordConfig,
public static List<Module> getPrimaryModules( ChannelModel channelModel,
ChannelProcessingManager channelProcessingManager,
PlaylistManager playlistManager,
AliasList aliasList,
String system,
String site,
String channelName,
ResourceManager resourceManager )
Channel channel )
{
List<Module> modules = new ArrayList<Module>();
ChannelType channelType = channel.getChannelType();
/* Baseband low-pass filter pass and stop frequencies */
int pass = decodeConfig.getDecoderType().getChannelBandwidth() / 2;
int stop = pass + 1250;
DecodeConfiguration decodeConfig = channel.getDecodeConfiguration();
int iqPass = decodeConfig.getDecoderType().getChannelBandwidth() / 2;
int iqStop = iqPass + 1250;
RecordConfiguration recordConfig = channel.getRecordConfiguration();
boolean recordAudio = recordConfig == null ? false :
recordConfig.getRecorders().contains( RecorderType.AUDIO );
@@ -193,41 +167,44 @@ public class DecoderFactory
switch( decodeConfig.getDecoderType() )
{
case AM:
modules.add( new AMDemodulatorModule() );
modules.add( new AMDecoder( decodeConfig ) );
modules.add( new AlwaysUnsquelchedDecoderState( DecoderType.AM, channelName ) );
modules.add( new AudioModule( recordAudio, REMOVE_DC ) );
modules.add( new AlwaysUnsquelchedDecoderState( DecoderType.AM, channel.getName() ) );
modules.add( new AMDemodulatorModule() );
modules.add( new DemodulatedAudioFilterModule( 4000, 6000 ));
modules.add( new AudioModule( recordAudio ) );
break;
case NBFM:
modules.add( new AudioModule( recordAudio, NO_REMOVE_DC ) );
modules.add( new NBFMDecoder( decodeConfig ) );
modules.add( new AlwaysUnsquelchedDecoderState( DecoderType.NBFM, channelName ) );
modules.add( getFMDemodulator( decodeConfig, pass, stop, REMOVE_DC ) );
modules.add( new AlwaysUnsquelchedDecoderState( DecoderType.NBFM, channel.getName() ) );
modules.add( new FMDemodulatorModule( iqPass, iqStop ) );
modules.add( new DemodulatedAudioFilterModule( 4000, 6000 ));
modules.add( new AudioModule( recordAudio ) );
break;
case LTR_STANDARD:
modules.add( new AudioModule( recordAudio, REMOVE_DC ) );
MessageDirection direction = ((DecodeConfigLTRStandard)decodeConfig).getMessageDirection();
modules.add( new LTRStandardDecoder( aliasList, direction ) );
modules.add( new LTRStandardDecoderState( aliasList ) );
modules.add( getFMDemodulator( decodeConfig, pass, stop, NO_REMOVE_DC ) );
modules.add( new FMDemodulatorModule( iqPass, iqStop ) );
modules.add( new DemodulatedAudioFilterModule( 4000, 6000 ));
modules.add( new AudioModule( recordAudio ) );
break;
case LTR_NET:
modules.add( new AudioModule( recordAudio, REMOVE_DC ) );
modules.add( new LTRNetDecoder( (DecodeConfigLTRNet)decodeConfig, aliasList ) );
modules.add( new LTRNetDecoderState( aliasList ) );
modules.add( getFMDemodulator( decodeConfig, pass, stop, NO_REMOVE_DC ) );
modules.add( new FMDemodulatorModule( iqPass, iqStop ) );
modules.add( new DemodulatedAudioFilterModule( 4000, 6000 ));
modules.add( new AudioModule( recordAudio ) );
break;
case MPT1327:
DecodeConfigMPT1327 mptConfig = (DecodeConfigMPT1327)decodeConfig;
modules.add( new AudioModule( recordAudio, NO_REMOVE_DC ) );
ChannelMap channelMap = resourceManager.getPlaylistManager().getPlayist()
ChannelMap channelMap = playlistManager.getPlayist()
.getChannelMapList().getChannelMap( mptConfig.getChannelMapName() );
Sync sync = mptConfig.getSync();
modules.add( new MPT1327Decoder( aliasList, sync ) );
modules.add( new MPT1327DecoderState( aliasList, channelMap,
channelType, mptConfig.getCallTimeout() * 1000 ) );
@@ -235,30 +212,34 @@ public class DecoderFactory
{
long timeout = mptConfig.getCallTimeout() * 1000; //convert to milliseconds
modules.add( new TrafficChannelManager( resourceManager,
decodeConfig, recordConfig, system, site,
( aliasList != null ? aliasList.getName() : null ), timeout,
modules.add( new TrafficChannelManager( channelModel, channelProcessingManager,
decodeConfig, recordConfig, channel.getSystem(),
channel.getSite(), ( aliasList != null ? aliasList.getName() : null ), timeout,
mptConfig.getTrafficChannelPoolSize() ) );
}
modules.add( getFMDemodulator( decodeConfig, pass, stop, REMOVE_DC ) );
modules.add( new FMDemodulatorModule( iqPass, iqStop ) );
modules.add( new DemodulatedAudioFilterModule( 4000, 6000 ));
modules.add( new AudioModule( recordAudio ) );
break;
case PASSPORT:
modules.add( new AudioModule( recordAudio, REMOVE_DC ) );
modules.add( new PassportDecoder( decodeConfig, aliasList ) );
modules.add( new PassportDecoderState( aliasList ) );
modules.add( getFMDemodulator( decodeConfig, pass, stop, NO_REMOVE_DC ) );
modules.add( new FMDemodulatorModule( iqPass, iqStop ) );
modules.add( new DemodulatedAudioFilterModule( 4000, 6000 ));
modules.add( new AudioModule( recordAudio ) );
break;
case P25_PHASE1:
DecodeConfigP25Phase1 p25Config = (DecodeConfigP25Phase1)decodeConfig;
Modulation modulation = p25Config.getModulation();
switch( modulation )
{
case C4FM:
modules.add( getFMDemodulator( decodeConfig, 6750, 7500, NO_REMOVE_DC ) );
modules.add( new P25_C4FMDecoder( aliasList ) );
modules.add( new FMDemodulatorModule( 6750, 7500 ) );
modules.add( new P25_C4FMDecoder( aliasList, decodeConfig.getAFCMaximumCorrection() ) );
modules.add( new P25DecoderState( aliasList, channelType,
Modulation.C4FM, p25Config.getIgnoreDataCalls() ) );
break;
@@ -277,8 +258,9 @@ public class DecoderFactory
//Set call timeout to 3 seconds for P25 traffic channels
long timeout = 3000;
modules.add( new TrafficChannelManager( resourceManager,
decodeConfig, recordConfig, system, site,
modules.add( new TrafficChannelManager( channelModel,
channelProcessingManager, decodeConfig,
recordConfig, channel.getSystem(), channel.getSite(),
( aliasList != null ? aliasList.getName() : null ), timeout,
p25Config.getTrafficChannelPoolSize() ) );
}
@@ -449,7 +431,7 @@ public class DecoderFactory
}
public static DecodeEditor getEditorPanel( DecodeConfiguration config,
ChannelNode channelNode, PlaylistManager playlistManager )
Channel channel, PlaylistManager playlistManager )
{
DecodeEditor configuredPanel;
@@ -466,7 +448,7 @@ public class DecoderFactory
break;
case MPT1327:
configuredPanel = new MPT1327ConfigEditor( config,
channelNode, playlistManager );
channel, playlistManager );
break;
case PASSPORT:
configuredPanel = new PassportEditor( config );

View File

@@ -23,12 +23,14 @@ import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTable;
import module.ProcessingChain;
import net.miginfocom.swing.MigLayout;
import settings.SettingsManager;
import controller.channel.Channel;
import controller.channel.ChannelEvent;
import controller.channel.ChannelEvent.Event;
import controller.channel.ChannelEventListener;
import controller.channel.ChannelProcessingManager;
public class CallEventPanel extends JPanel implements ChannelEventListener
{
@@ -37,9 +39,13 @@ public class CallEventPanel extends JPanel implements ChannelEventListener
private JScrollPane mEmptyScroller;
private Channel mDisplayedChannel;
private CallEventAliasCellRenderer mRenderer;
private ChannelProcessingManager mChannelProcessingManager;
public CallEventPanel( SettingsManager settingsManager )
public CallEventPanel( SettingsManager settingsManager,
ChannelProcessingManager channelProcessingManager )
{
mChannelProcessingManager = channelProcessingManager;
setLayout( new MigLayout("insets 0 0 0 0 ", "[grow,fill]", "[grow,fill]") );
JTable table = new JTable( new CallEventModel() );
@@ -69,34 +75,43 @@ public class CallEventPanel extends JPanel implements ChannelEventListener
( mDisplayedChannel != null &&
mDisplayedChannel != event.getChannel() ) )
{
EventQueue.invokeLater( new Runnable()
{
@Override
public void run()
{
removeAll();
JTable table = new JTable(
event.getChannel().getCallEventModel() );
table.setAutoCreateRowSorter( true );
table.setAutoResizeMode( JTable.AUTO_RESIZE_LAST_COLUMN );
table.getColumnModel().getColumn( CallEventModel.FROM_ALIAS )
.setCellRenderer( mRenderer );
table.getColumnModel().getColumn( CallEventModel.TO_ALIAS )
.setCellRenderer( mRenderer );
add( new JScrollPane( table ) );
mDisplayedChannel = event.getChannel();
revalidate();
repaint();
}
} );
ProcessingChain chain = mChannelProcessingManager
.getProcessingChain( event.getChannel() );
if( chain != null )
{
final CallEventModel model = chain.getCallEventModel();
if( model != null )
{
EventQueue.invokeLater( new Runnable()
{
@Override
public void run()
{
removeAll();
JTable table = new JTable( model );
table.setAutoCreateRowSorter( true );
table.setAutoResizeMode( JTable.AUTO_RESIZE_LAST_COLUMN );
table.getColumnModel().getColumn( CallEventModel.FROM_ALIAS )
.setCellRenderer( mRenderer );
table.getColumnModel().getColumn( CallEventModel.TO_ALIAS )
.setCellRenderer( mRenderer );
add( new JScrollPane( table ) );
mDisplayedChannel = event.getChannel();
revalidate();
repaint();
}
} );
}
}
}
}
else if( event.getEvent() == Event.NOTIFICATION_PROCESSING_STOP ||

View File

@@ -36,6 +36,7 @@ import javax.swing.event.ChangeEvent;
import javax.swing.event.ChangeListener;
import message.Message;
import module.ProcessingChain;
import net.miginfocom.swing.MigLayout;
import org.slf4j.Logger;
@@ -48,6 +49,7 @@ import controller.channel.Channel;
import controller.channel.ChannelEvent;
import controller.channel.ChannelEvent.Event;
import controller.channel.ChannelEventListener;
import controller.channel.ChannelProcessingManager;
import filter.FilterEditorPanel;
import filter.FilterSet;
@@ -63,16 +65,21 @@ public class MessageActivityPanel extends JPanel implements ChannelEventListener
private JTable mMessageTable;
private Channel mDisplayedChannel;
private MessageActivityModel mDisplayedModel = EMPTY_MODEL;
private MessageManagementPanel mManagementPanel = new MessageManagementPanel();
private ChannelProcessingManager mChannelProcessingManager;
public MessageActivityPanel()
public MessageActivityPanel( ChannelProcessingManager channelProcessingManager )
{
mChannelProcessingManager = channelProcessingManager;
setLayout( new MigLayout("insets 0 0 0 0", "[][grow,fill]", "[]0[grow,fill]") );
add( mManagementPanel, "span,growx" );
mMessageTable = new JTable( EMPTY_MODEL );
mMessageTable = new JTable( mDisplayedModel );
add( new JScrollPane( mMessageTable ), "span,grow" );
}
@@ -91,7 +98,19 @@ public class MessageActivityPanel extends JPanel implements ChannelEventListener
{
mDisplayedChannel = event.getChannel();
mMessageTable.setModel( event.getChannel().getMessageActivityModel() );
ProcessingChain chain = mChannelProcessingManager
.getProcessingChain( mDisplayedChannel );
if( chain != null )
{
mDisplayedModel = chain.getMessageActivityModel();
}
else
{
mDisplayedModel = EMPTY_MODEL;
}
mMessageTable.setModel( mDisplayedModel );
if( mDisplayedChannel != null )
{
@@ -195,10 +214,9 @@ public class MessageActivityPanel extends JPanel implements ChannelEventListener
public void mouseReleased( MouseEvent arg0 ) {}
} );
if( mDisplayedChannel != null )
if( mDisplayedModel != null )
{
slider.setValue( mDisplayedChannel.getMessageActivityModel()
.getMaxMessageCount() );
slider.setValue( mDisplayedModel.getMaxMessageCount() );
}
else
{
@@ -210,10 +228,9 @@ public class MessageActivityPanel extends JPanel implements ChannelEventListener
@Override
public void stateChanged( ChangeEvent arg0 )
{
if( mDisplayedChannel != null )
if( mDisplayedModel != null )
{
mDisplayedChannel.getMessageActivityModel()
.setMaxMessageCount( slider.getValue() );
mDisplayedModel.setMaxMessageCount( slider.getValue() );
}
}
});
@@ -228,9 +245,9 @@ public class MessageActivityPanel extends JPanel implements ChannelEventListener
@Override
public void actionPerformed( ActionEvent e )
{
if( mDisplayedChannel != null )
if( mDisplayedModel != null )
{
mDisplayedChannel.getMessageActivityModel().clear();
mDisplayedModel.clear();
}
}
} );
@@ -258,50 +275,52 @@ public class MessageActivityPanel extends JPanel implements ChannelEventListener
}
else
{
final JFrame editor = new JFrame();
editor.setTitle( "Message Filter Editor" );
editor.setSize( 600, 400 );
editor.setLocationRelativeTo( MessageFilterButton.this );
editor.setDefaultCloseOperation( JFrame.DISPOSE_ON_CLOSE );
editor.setLayout( new MigLayout( "", "[grow,fill]",
"[grow,fill][][]" ) );
@SuppressWarnings( "unchecked" )
FilterSet<Message> filter = (FilterSet<Message>)
mDisplayedChannel.getMessageActivityModel()
.getMessageFilter();
FilterEditorPanel<Message> panel =
new FilterEditorPanel<Message>( filter );
JScrollPane scroller = new JScrollPane( panel );
scroller.setViewportView( panel );
editor.add( scroller, "wrap" );
editor.add( new JLabel( "Right-click to select/deselect "
+ "all nodes" ), "wrap" );
JButton close = new JButton( "Close" );
close.addActionListener( new ActionListener()
if( mDisplayedModel != null )
{
@Override
public void actionPerformed( ActionEvent e )
{
editor.dispose();
}
} );
editor.add( close );
final JFrame editor = new JFrame();
editor.setTitle( "Message Filter Editor" );
editor.setSize( 600, 400 );
editor.setLocationRelativeTo( MessageFilterButton.this );
editor.setDefaultCloseOperation( JFrame.DISPOSE_ON_CLOSE );
editor.setLayout( new MigLayout( "", "[grow,fill]",
"[grow,fill][][]" ) );
EventQueue.invokeLater( new Runnable()
{
public void run()
{
editor.setVisible( true );
}
} );
@SuppressWarnings( "unchecked" )
FilterSet<Message> filter = (FilterSet<Message>)
mDisplayedModel.getMessageFilter();
FilterEditorPanel<Message> panel =
new FilterEditorPanel<Message>( filter );
JScrollPane scroller = new JScrollPane( panel );
scroller.setViewportView( panel );
editor.add( scroller, "wrap" );
editor.add( new JLabel( "Right-click to select/deselect "
+ "all nodes" ), "wrap" );
JButton close = new JButton( "Close" );
close.addActionListener( new ActionListener()
{
@Override
public void actionPerformed( ActionEvent e )
{
editor.dispose();
}
} );
editor.add( close );
EventQueue.invokeLater( new Runnable()
{
public void run()
{
editor.setVisible( true );
}
} );
}
}
}
} );

View File

@@ -29,7 +29,7 @@ import java.util.List;
import module.decode.Decoder;
import module.decode.DecoderType;
import sample.Listener;
import sample.real.IRealBufferListener;
import sample.real.IFilteredRealBufferListener;
import sample.real.RealBuffer;
import alias.AliasList;
import bits.MessageFramer;
@@ -44,7 +44,7 @@ import dsp.fsk.FSK2Decoder.Output;
* Fleetsync II Decoder - 1200 baud 2FSK decoder that can process 48k sample rate
* floating point samples and output fully framed Fleetsync II messages
*/
public class Fleetsync2Decoder extends Decoder implements IRealBufferListener,
public class Fleetsync2Decoder extends Decoder implements IFilteredRealBufferListener,
Instrumentable
{
/* Decimated sample rate ( 48,000 / 2 = 24,000 ) feeding the decoder */
@@ -169,7 +169,7 @@ public class Fleetsync2Decoder extends Decoder implements IRealBufferListener,
}
@Override
public Listener<RealBuffer> getRealBufferListener()
public Listener<RealBuffer> getFilteredRealBufferListener()
{
return mDecimationFilter;
}

View File

@@ -31,7 +31,7 @@ import module.decode.Decoder;
import module.decode.DecoderType;
import sample.Broadcaster;
import sample.Listener;
import sample.real.IRealBufferListener;
import sample.real.IFilteredRealBufferListener;
import sample.real.RealBuffer;
import sample.real.RealSampleListener;
import alias.AliasList;
@@ -46,7 +46,7 @@ import dsp.fsk.FSK2Decoder.Output;
/**
* LJ1200 - 1200 baud 2FSK decoder
*/
public class LJ1200Decoder extends Decoder implements IRealBufferListener,
public class LJ1200Decoder extends Decoder implements IFilteredRealBufferListener,
Instrumentable
{
/* Decimated sample rate ( 48,000 / 2 = 24,000 ) feeding the decoder */
@@ -187,7 +187,7 @@ public class LJ1200Decoder extends Decoder implements IRealBufferListener,
}
@Override
public Listener<RealBuffer> getRealBufferListener()
public Listener<RealBuffer> getFilteredRealBufferListener()
{
return mDecimationFilter;
}

View File

@@ -28,14 +28,15 @@ import message.MessageDirection;
import module.decode.Decoder;
import module.decode.DecoderType;
import sample.Listener;
import sample.real.IRealBufferListener;
import sample.real.IUnFilteredRealBufferListener;
import sample.real.RealBuffer;
import alias.AliasList;
import bits.MessageFramer;
import bits.SyncPattern;
import dsp.fsk.LTRFSKDecoder;
public class LTRNetDecoder extends Decoder implements IRealBufferListener, Instrumentable
public class LTRNetDecoder extends Decoder
implements IUnFilteredRealBufferListener, Instrumentable
{
public static final int LTR_STANDARD_MESSAGE_LENGTH = 40;
private LTRFSKDecoder mLTRFSKDecoder;
@@ -44,6 +45,10 @@ public class LTRNetDecoder extends Decoder implements IRealBufferListener, Instr
private List<TapGroup> mAvailableTaps;
/**
* LTR-Net Decoder. Decodes unfiltered (e.g. demodulated but with no DC or
* audio filtering) samples and produces LTR-Net messages.
*/
public LTRNetDecoder( DecodeConfigLTRNet config, AliasList aliasList )
{
mLTRFSKDecoder = new LTRFSKDecoder();
@@ -79,7 +84,7 @@ public class LTRNetDecoder extends Decoder implements IRealBufferListener, Instr
}
@Override
public Listener<RealBuffer> getRealBufferListener()
public Listener<RealBuffer> getUnFilteredRealBufferListener()
{
return mLTRFSKDecoder;
}

View File

@@ -21,14 +21,14 @@ import message.MessageDirection;
import module.decode.Decoder;
import module.decode.DecoderType;
import sample.Listener;
import sample.real.IRealBufferListener;
import sample.real.IUnFilteredRealBufferListener;
import sample.real.RealBuffer;
import alias.AliasList;
import bits.MessageFramer;
import bits.SyncPattern;
import dsp.fsk.LTRFSKDecoder;
public class LTRStandardDecoder extends Decoder implements IRealBufferListener
public class LTRStandardDecoder extends Decoder implements IUnFilteredRealBufferListener
{
public static final int LTR_STANDARD_MESSAGE_LENGTH = 40;
@@ -36,6 +36,10 @@ public class LTRStandardDecoder extends Decoder implements IRealBufferListener
private MessageFramer mLTRMessageFramer;
private LTRStandardMessageProcessor mLTRMessageProcessor;
/**
* LTR Decoder. Decodes unfiltered (e.g. demodulated but with no DC or
* audio filtering) samples and produces LTR Standard messages.
*/
public LTRStandardDecoder( AliasList aliasList,
MessageDirection direction )
{
@@ -68,7 +72,7 @@ public class LTRStandardDecoder extends Decoder implements IRealBufferListener
}
@Override
public Listener<RealBuffer> getRealBufferListener()
public Listener<RealBuffer> getUnFilteredRealBufferListener()
{
return mLTRFSKDecoder;
}

View File

@@ -30,7 +30,7 @@ import java.util.List;
import module.decode.Decoder;
import module.decode.DecoderType;
import sample.Listener;
import sample.real.IRealBufferListener;
import sample.real.IFilteredRealBufferListener;
import sample.real.RealBuffer;
import alias.AliasList;
import bits.MessageFramer;
@@ -46,7 +46,7 @@ import dsp.fsk.FSK2Decoder.Output;
* MDC1200 Decoder - 1200 baud 2FSK decoder that can process 48k sample rate
* complex or floating point samples and output fully framed MDC1200 messages
*/
public class MDCDecoder extends Decoder implements IRealBufferListener,
public class MDCDecoder extends Decoder implements IFilteredRealBufferListener,
Instrumentable
{
/* Decimated sample rate ( 48,000 / 2 = 24,000 ) feeding the decoder */
@@ -197,7 +197,7 @@ public class MDCDecoder extends Decoder implements IRealBufferListener,
}
@Override
public Listener<RealBuffer> getRealBufferListener()
public Listener<RealBuffer> getFilteredRealBufferListener()
{
return mDecimationFilter;
}

View File

@@ -31,7 +31,7 @@ import module.decode.DecodeEditor;
import module.decode.config.DecodeConfiguration;
import module.decode.mpt1327.MPT1327Decoder.Sync;
import playlist.PlaylistManager;
import controller.channel.ChannelNode;
import controller.channel.Channel;
import controller.channel.map.ChannelMap;
public class MPT1327ConfigEditor extends DecodeEditor
@@ -44,16 +44,16 @@ public class MPT1327ConfigEditor extends DecodeEditor
private JSlider mCallTimeout;
private JLabel mTrafficChannelPoolSizeLabel;
private JSlider mTrafficChannelPoolSize;
private ChannelNode mChannelNode;
private Channel mChannel;
private PlaylistManager mPlaylistManager;
public MPT1327ConfigEditor( DecodeConfiguration config,
ChannelNode channelNode,
Channel channel,
PlaylistManager playlistManager )
{
super( config );
mChannelNode = channelNode;
mChannel = channel;
mPlaylistManager = playlistManager;
initGUI();
@@ -140,7 +140,7 @@ public class MPT1327ConfigEditor extends DecodeEditor
add( mTrafficChannelPoolSizeLabel );
add( mTrafficChannelPoolSize, "wrap,grow" );
reset();
// reset();
}
@Override
@@ -167,36 +167,35 @@ public class MPT1327ConfigEditor extends DecodeEditor
config.setTrafficChannelPoolSize( mTrafficChannelPoolSize.getValue() );
}
@Override
public void reset()
{
DecodeConfigMPT1327 config = (DecodeConfigMPT1327)mConfig;
String name = config.getChannelMapName();
ChannelMap selected = null;
if( name != null )
{
for( ChannelMap map: mChannelNode.getModel().getResourceManager()
.getPlaylistManager().getPlayist().getChannelMapList()
.getChannelMap() )
{
if( map.getName().equalsIgnoreCase( name ) )
{
selected = map;
}
}
}
mComboChannelMaps.setSelectedItem( selected );
mComboChannelMaps.requestFocus();
mComboChannelMaps.requestFocusInWindow();
mComboSync.setSelectedItem( config.getSync() );
mCallTimeout.setValue( config.getCallTimeout() );
mTrafficChannelPoolSize.setValue( config.getTrafficChannelPoolSize() );
}
// @Override
// public void reset()
// {
// DecodeConfigMPT1327 config = (DecodeConfigMPT1327)mConfig;
//
// String name = config.getChannelMapName();
//
// ChannelMap selected = null;
//
// if( name != null )
// {
// for( ChannelMap map: mPlaylistManager.getPlayist().getChannelMapList()
// .getChannelMap() )
// {
// if( map.getName().equalsIgnoreCase( name ) )
// {
// selected = map;
// }
// }
// }
//
// mComboChannelMaps.setSelectedItem( selected );
// mComboChannelMaps.requestFocus();
// mComboChannelMaps.requestFocusInWindow();
//
// mComboSync.setSelectedItem( config.getSync() );
//
// mCallTimeout.setValue( config.getCallTimeout() );
//
// mTrafficChannelPoolSize.setValue( config.getTrafficChannelPoolSize() );
// }
}

View File

@@ -35,7 +35,7 @@ import org.slf4j.LoggerFactory;
import sample.Broadcaster;
import sample.Listener;
import sample.real.IRealBufferListener;
import sample.real.IFilteredRealBufferListener;
import sample.real.RealBuffer;
import alias.AliasList;
import bits.MessageFramer;
@@ -55,7 +55,7 @@ import dsp.fsk.FSK2Decoder.Output;
* traffic messages.
*/
public class MPT1327Decoder extends Decoder
implements IRealBufferListener, Instrumentable
implements IFilteredRealBufferListener, Instrumentable
{
private final static Logger mLog = LoggerFactory.getLogger( MPT1327Decoder.class );
@@ -146,7 +146,7 @@ public class MPT1327Decoder extends Decoder
}
@Override
public Listener<RealBuffer> getRealBufferListener()
public Listener<RealBuffer> getFilteredRealBufferListener()
{
return mDecimationFilter;
}

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
*/

View File

@@ -28,7 +28,7 @@ import module.decode.Decoder;
import module.decode.DecoderType;
import module.decode.config.DecodeConfiguration;
import sample.Listener;
import sample.real.IRealBufferListener;
import sample.real.IUnFilteredRealBufferListener;
import sample.real.RealBuffer;
import alias.AliasList;
import bits.MessageFramer;
@@ -36,7 +36,7 @@ import bits.SyncPattern;
import dsp.fsk.LTRFSKDecoder;
public class PassportDecoder extends Decoder
implements IRealBufferListener, Instrumentable
implements IUnFilteredRealBufferListener, Instrumentable
{
public static final int PASSPORT_MESSAGE_LENGTH = 68;
public static final int PASSPORT_SYNC_LENGTH = 9;
@@ -47,8 +47,11 @@ public class PassportDecoder extends Decoder
private List<TapGroup> mAvailableTaps;
public PassportDecoder( DecodeConfiguration config,
AliasList aliasList )
/**
* Passport Decoder. Decodes unfiltered (e.g. demodulated but with no DC or
* audio filtering) samples and produces Passport messages.
*/
public PassportDecoder( DecodeConfiguration config, AliasList aliasList )
{
mPassportFSKDecoder = new LTRFSKDecoder();
@@ -64,7 +67,7 @@ public class PassportDecoder extends Decoder
}
@Override
public Listener<RealBuffer> getRealBufferListener()
public Listener<RealBuffer> getUnFilteredRealBufferListener()
{
return mPassportFSKDecoder;
}

View File

@@ -16,6 +16,8 @@ import org.slf4j.LoggerFactory;
import playlist.PlaylistManager;
import settings.SettingsManager;
import controller.channel.Channel;
import controller.channel.ChannelModel;
import controller.channel.ChannelProcessingManager;
/**
* Channel Collection assembles a primary channel panel and any related decoder
@@ -28,15 +30,21 @@ public class ChannelCollectionPanel extends JPanel
private final static Logger mLog = LoggerFactory.getLogger( ChannelCollectionPanel.class );
private ChannelModel mChannelModel;
private ChannelProcessingManager mChannelProcessingManager;
private PlaylistManager mPlaylistManager;
private SettingsManager mSettingsManager;
private List<ChannelStatePanel> mChannelPanels = new ArrayList<ChannelStatePanel>();
public ChannelCollectionPanel( PlaylistManager playlistManager,
public ChannelCollectionPanel( ChannelModel channelModel,
ChannelProcessingManager channelProcessingManager,
PlaylistManager playlistManager,
SettingsManager settingsManager,
Channel channel )
{
mChannelModel = channelModel;
mChannelProcessingManager = channelProcessingManager;
mPlaylistManager = playlistManager;
mSettingsManager = settingsManager;
@@ -49,8 +57,8 @@ public class ChannelCollectionPanel extends JPanel
setOpaque( false );
ChannelStatePanel csp = new ChannelStatePanel( mPlaylistManager,
mSettingsManager, channel );
ChannelStatePanel csp = new ChannelStatePanel( mChannelModel,
mChannelProcessingManager, mPlaylistManager, mSettingsManager, channel );
mChannelPanels.add( csp );

View File

@@ -43,6 +43,8 @@ import settings.SettingsManager;
import controller.channel.Channel;
import controller.channel.ChannelEvent;
import controller.channel.ChannelEventListener;
import controller.channel.ChannelModel;
import controller.channel.ChannelProcessingManager;
/**
* Gui wrapper for the list of currently processing primary channels
@@ -56,12 +58,18 @@ public class ChannelList extends JPanel implements ChannelEventListener
private HashMap<Channel,ChannelCollectionPanel> mDisplayedPanels =
new HashMap<Channel,ChannelCollectionPanel>();
private ChannelModel mChannelModel;
private ChannelProcessingManager mChannelProcessingManager;
private PlaylistManager mPlaylistManager;
private SettingsManager mSettingsManager;
public ChannelList( PlaylistManager playlistManager,
public ChannelList( ChannelModel channelModel,
ChannelProcessingManager channelProcessingManager,
PlaylistManager playlistManager,
SettingsManager settingsManager )
{
mChannelModel = channelModel;
mChannelProcessingManager = channelProcessingManager;
mPlaylistManager = playlistManager;
mSettingsManager = settingsManager;
@@ -96,8 +104,8 @@ public class ChannelList extends JPanel implements ChannelEventListener
{
if( !mDisplayedPanels.containsKey( channel ) )
{
ChannelCollectionPanel panel = new ChannelCollectionPanel(
mPlaylistManager, mSettingsManager, channel );
ChannelCollectionPanel panel = new ChannelCollectionPanel( mChannelModel,
mChannelProcessingManager, mPlaylistManager, mSettingsManager, channel );
add( panel, "wrap" );

View File

@@ -14,6 +14,7 @@ import javax.swing.JLabel;
import javax.swing.JMenu;
import javax.swing.JPanel;
import module.ProcessingChain;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@@ -31,6 +32,11 @@ import settings.Setting;
import settings.SettingChangeListener;
import settings.SettingsManager;
import controller.channel.Channel;
import controller.channel.ChannelModel;
import controller.channel.ChannelProcessingManager;
import controller.channel.ChannelUtils;
public class ChannelStatePanel extends JPanel
implements Listener<ChangedAttribute>, SettingChangeListener
{
@@ -38,10 +44,6 @@ public class ChannelStatePanel extends JPanel
private final static Logger mLog = LoggerFactory.getLogger( ChannelStatePanel.class );
private static final boolean ENABLED = true;
private static final boolean DISABLED = false;
private static final boolean BROADCAST_CHANGE = true;
private Font mFontDetails = new Font( Font.MONOSPACED, Font.PLAIN, 12 );
private Font mFontDecoder = new Font( Font.MONOSPACED, Font.PLAIN, 12 );
@@ -75,7 +77,10 @@ public class ChannelStatePanel extends JPanel
protected SettingsManager mSettingsManager;
private Channel mChannel;
private ChannelState mChannelState;
private List<DecoderPanel> mDecoderPanels = new ArrayList<>();
private ChannelModel mChannelModel;
private ChannelProcessingManager mChannelProcessingManager;
/**
* Gui component to a channel state. Provides System, Site and channel
@@ -83,21 +88,31 @@ public class ChannelStatePanel extends JPanel
*
* Updates color background according to current channel state.
*/
public ChannelStatePanel( PlaylistManager playlistManager,
public ChannelStatePanel( ChannelModel channelModel,
ChannelProcessingManager channelProcessingManager,
PlaylistManager playlistManager,
SettingsManager settingsManager,
Channel channel )
{
mChannelModel = channelModel;
mChannelProcessingManager = channelProcessingManager;
mPlaylistManager = playlistManager;
mSettingsManager = settingsManager;
mSettingsManager.addListener( this );
mChannel = channel;
mChannel.getChannelState().setChangedAttributeListener( this );
ProcessingChain processingChain =
channelProcessingManager.getProcessingChain( mChannel );
mChannelState = processingChain.getChannelState();
mChannelState.setChangedAttributeListener( this );
init();
for( DecoderState decoderState: getChannel().getProcessingChain().getDecoderStates() )
for( DecoderState decoderState: processingChain.getDecoderStates() )
{
DecoderPanel panel = DecoderFactory.getDecoderPanel( mSettingsManager, decoderState );
mDecoderPanels.add( panel );
@@ -126,8 +141,7 @@ public class ChannelStatePanel extends JPanel
mChannelLabel.setForeground( mColorLabelDetails );
add( mChannelLabel, "wrap" );
mStateLabel = new JLabel( mChannel.getChannelState().getState()
.getDisplayValue() );
mStateLabel = new JLabel( mChannelState.getState().getDisplayValue() );
mStateLabel.setFont( mFontDecoder );
mStateLabel.setForeground( mColorLabelDecoder );
add( mStateLabel );
@@ -161,8 +175,6 @@ public class ChannelStatePanel extends JPanel
mOptionsLabel.setFont( mFontDetails );
mOptionsLabel.setForeground( mColorLabelAuxDecoder );
add( mOptionsLabel, "wrap" );
// add( new JSeparator( JSeparator.HORIZONTAL ), "span,growx" );
}
public Channel getChannel()
@@ -177,7 +189,8 @@ public class ChannelStatePanel extends JPanel
mSettingsManager.removeListener( this );
mSettingsManager = null;
mChannel.getChannelState().removeChangedAttributeListener();
mChannelState.removeChangedAttributeListener();
mChannelState = null;
mChannel = null;
for( DecoderPanel panel: mDecoderPanels )
@@ -192,8 +205,6 @@ public class ChannelStatePanel extends JPanel
@Override
public void receive( final ChangedAttribute changedAttribute )
{
final ChannelState state = mChannel.getChannelState();
EventQueue.invokeLater( new Runnable()
{
@Override
@@ -202,9 +213,9 @@ public class ChannelStatePanel extends JPanel
switch( changedAttribute )
{
case CHANNEL_STATE:
if( state.getState() != null )
if( mChannelState.getState() != null )
{
mStateLabel.setText( state.getState().getDisplayValue() );
mStateLabel.setText( mChannelState.getState().getDisplayValue() );
}
break;
case SOURCE:
@@ -214,7 +225,7 @@ public class ChannelStatePanel extends JPanel
case CHANNEL_NAME:
case SITE_NAME:
case SYSTEM_NAME:
mChannelLabel.setText( mChannel.getChannelDisplayName() );
mChannelLabel.setText( mChannel.toString() );
break;
default:
break;
@@ -419,7 +430,7 @@ public class ChannelStatePanel extends JPanel
public JMenu getContextMenu()
{
return ChannelUtils.getContextMenu( mPlaylistManager, mChannel,
ChannelStatePanel.this );
return ChannelUtils.getContextMenu( mChannelModel, mChannelProcessingManager,
mPlaylistManager, mChannel, ChannelStatePanel.this );
}
}

View File

@@ -6,6 +6,7 @@ import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
import module.Module;
import module.ProcessingChain;
import module.decode.config.DecodeConfiguration;
import module.decode.event.CallEvent;
import module.decode.event.CallEvent.CallEventType;
@@ -21,11 +22,12 @@ import source.tuner.TunerChannel;
import source.tuner.TunerChannel.Type;
import alias.Alias;
import alias.priority.Priority;
import controller.ResourceManager;
import controller.channel.Channel;
import controller.channel.Channel.ChannelType;
import controller.site.Site;
import controller.system.System;
import controller.channel.ChannelEvent;
import controller.channel.ChannelEvent.Event;
import controller.channel.ChannelModel;
import controller.channel.ChannelProcessingManager;
public class TrafficChannelManager extends Module
implements ICallEventProvider, IDecoderStateEventListener
@@ -40,15 +42,14 @@ public class TrafficChannelManager extends Module
private DecoderStateEventListener mEventListener = new DecoderStateEventListener();
private Listener<CallEvent> mCallEventListener;
private ChannelModel mChannelModel;
private ChannelProcessingManager mChannelProcessingManager;
private DecodeConfiguration mDecodeConfiguration;
private RecordConfiguration mRecordConfiguration;
private ResourceManager mResourceManager;
private String mSystem;
private String mSite;
private String mAliasListName;
private long mTrafficChannelTimeout;
private CallEvent mPreviousDoNotMonitorCallEvent;
private boolean mShuttingDown = false;
/**
* Monitors call events and allocates traffic decoder channels in response
@@ -68,7 +69,8 @@ public class TrafficChannelManager extends Module
* @param trafficChannelPoolSize - maximum number of allocated traffic channels
* in the pool
*/
public TrafficChannelManager( ResourceManager resourceManager,
public TrafficChannelManager( ChannelModel channelModel,
ChannelProcessingManager channelProcessingManager,
DecodeConfiguration decodeConfiguration,
RecordConfiguration recordConfiguration,
String system,
@@ -77,13 +79,14 @@ public class TrafficChannelManager extends Module
long trafficChannelTimeout,
int trafficChannelPoolSize )
{
mResourceManager = resourceManager;
mChannelModel = channelModel;
mChannelProcessingManager = channelProcessingManager;
mDecodeConfiguration = decodeConfiguration;
mRecordConfiguration = recordConfiguration;
mSystem = system;
mSite = site;
mAliasListName = aliasListName;
mTrafficChannelTimeout = trafficChannelTimeout;
// mTrafficChannelTimeout = trafficChannelTimeout;
mTrafficChannelPoolMaximumSize = trafficChannelPoolSize;
}
@@ -91,7 +94,6 @@ public class TrafficChannelManager extends Module
public void dispose()
{
mCallEventListener = null;
mResourceManager = null;
mDecodeConfiguration = null;
mPreviousDoNotMonitorCallEvent = null;
}
@@ -115,7 +117,7 @@ public class TrafficChannelManager extends Module
{
for( Channel configuredChannel: mTrafficChannelPool )
{
if( !configuredChannel.isProcessing() )
if( !configuredChannel.getEnabled() )
{
channel = configuredChannel;
break;
@@ -130,12 +132,10 @@ public class TrafficChannelManager extends Module
channel.setRecordConfiguration( mRecordConfiguration );
channel.setResourceManager( mResourceManager );
channel.setTrafficChannelTimeout( mTrafficChannelTimeout );
channel.setAliasListName( mAliasListName );
mChannelModel.addChannel( channel );
mTrafficChannelPool.add( channel );
}
@@ -143,26 +143,15 @@ public class TrafficChannelManager extends Module
if( channel != null )
{
channel.setSourceConfiguration( new SourceConfigTuner( tunerChannel ) );
channel.setSystem( mSystem );
channel.setSite( mSite );
channel.setName( channelNumber );
channel.setEnabled( true );
mChannelModel.broadcast( new ChannelEvent( channel,
Event.NOTIFICATION_CONFIGURATION_CHANGE ) );
/* Check the channel obtained a source and is currently processing */
if( channel.isProcessing() )
{
mTrafficChannelsInUse.put( channelNumber, channel );
}
else
{
channel.setEnabled( false );
channel.setSystem( mSystem );
channel.setSite( mSite );
channel.setName( "Traffic" );
}
mChannelModel.broadcast( new ChannelEvent( channel,
Event.REQUEST_ENABLE ) );
}
}
@@ -210,26 +199,29 @@ public class TrafficChannelManager extends Module
if( channel != null )
{
if( channel.isProcessing() )
if( channel.getEnabled() )
{
callEvent.setDetails( "TRAFFIC CHANNEL ALLOCATED" );
ChannelState state = channel.getChannelState();
/* Register as a listener to be notified when the call
* is completed */
state.configureAsTrafficChannel(
new TrafficChannelStatusListener( this,
callEvent.getChannel() ), event );
/* Set state to call so that audio squelch state is correct */
state.setState( State.CALL );
ProcessingChain chain = mChannelProcessingManager
.getProcessingChain( channel );
if( chain != null )
{
ChannelState state = chain.getChannelState();
/* Register as a listener to be notified when the call
* is completed */
state.configureAsTrafficChannel(
new TrafficChannelStatusListener( this,
callEvent.getChannel() ), event );
/* Set state to call so that audio squelch state is correct */
state.setState( State.CALL );
}
}
else
{
callEvent.setCallEventType( CallEventType.CALL_DETECT );
callEvent.setDetails( "CHANNEL PROCESSING ERROR" );
}
}
}
else
{
@@ -390,15 +382,13 @@ public class TrafficChannelManager extends Module
{
synchronized( mTrafficChannelsInUse )
{
if( channelNumber != null &&
mTrafficChannelsInUse.containsKey( channelNumber ) )
if( channelNumber != null && mTrafficChannelsInUse.containsKey( channelNumber ) )
{
Channel channel = mTrafficChannelsInUse.get( channelNumber );
mChannelModel.broadcast( new ChannelEvent( channel, Event.REQUEST_DISABLE ) );
mTrafficChannelsInUse.remove( channelNumber );
/* Disable the channel and broadcast a notification */
channel.setEnabled( false );
}
}
}

View File

@@ -31,7 +31,7 @@ import module.decode.Decoder;
import module.decode.DecoderType;
import sample.Broadcaster;
import sample.Listener;
import sample.real.IRealBufferListener;
import sample.real.IFilteredRealBufferListener;
import sample.real.RealBuffer;
import alias.AliasList;
import bits.MessageFramer;
@@ -45,7 +45,7 @@ import dsp.fsk.FSK2Decoder.Output;
/**
* TAIT 1200 - 1200 baud 2FSK decoder
*/
public class Tait1200Decoder extends Decoder implements IRealBufferListener,
public class Tait1200Decoder extends Decoder implements IFilteredRealBufferListener,
Instrumentable
{
/* Decimated sample rate ( 48,000 / 2 = 24,000 ) feeding the decoder */
@@ -179,7 +179,7 @@ public class Tait1200Decoder extends Decoder implements IRealBufferListener,
}
@Override
public Listener<RealBuffer> getRealBufferListener()
public Listener<RealBuffer> getFilteredRealBufferListener()
{
return mDecimationFilter;
}