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

@@ -25,5 +25,10 @@
<classpathentry kind="lib" path="imports/logback-core-1.1.2.jar"/> <classpathentry kind="lib" path="imports/logback-core-1.1.2.jar"/>
<classpathentry kind="lib" path="imports/commons-io-2.4.jar"/> <classpathentry kind="lib" path="imports/commons-io-2.4.jar"/>
<classpathentry kind="lib" path="imports/jmbe-interface-0.3.2.jar"/> <classpathentry kind="lib" path="imports/jmbe-interface-0.3.2.jar"/>
<classpathentry kind="lib" path="imports/tablefilter-swing-5.2.1.jar">
<attributes>
<attribute name="javadoc_location" value="jar:file:/home/denny/Downloads/tablefilter-swing-5.2.1-javadoc.jar!/"/>
</attributes>
</classpathentry>
<classpathentry kind="output" path="bin"/> <classpathentry kind="output" path="bin"/>
</classpath> </classpath>

BIN
images/control_play.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 592 B

BIN
images/control_stop.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 403 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 688 B

After

Width:  |  Height:  |  Size: 743 B

Binary file not shown.

View File

@@ -23,15 +23,27 @@ import java.awt.event.ActionListener;
import javax.swing.JMenuItem; import javax.swing.JMenuItem;
import javax.swing.JPopupMenu; import javax.swing.JPopupMenu;
import playlist.PlaylistManager;
import settings.SettingsManager;
import controller.ConfigurableNode; import controller.ConfigurableNode;
public class AliasDirectoryNode extends ConfigurableNode public class AliasDirectoryNode extends ConfigurableNode
{ {
private static final long serialVersionUID = 1L; private static final long serialVersionUID = 1L;
public AliasDirectoryNode( AliasDirectory directory ) private PlaylistManager mPlaylistManager;
private SettingsManager mSettingsManager;
public AliasDirectoryNode( PlaylistManager playlistManager,
SettingsManager settingsManager,
AliasDirectory directory )
{ {
super( directory ); super( playlistManager, directory );
mPlaylistManager = playlistManager;
mSettingsManager = settingsManager;
} }
public AliasDirectory getAliasDirectory() public AliasDirectory getAliasDirectory()
@@ -43,7 +55,7 @@ public class AliasDirectoryNode extends ConfigurableNode
{ {
for( AliasList list: getAliasDirectory().getAliasList() ) for( AliasList list: getAliasDirectory().getAliasList() )
{ {
AliasListNode node = new AliasListNode( list ); AliasListNode node = new AliasListNode( mPlaylistManager, mSettingsManager, list );
getModel().addNode( node, AliasDirectoryNode.this, getChildCount() ); getModel().addNode( node, AliasDirectoryNode.this, getChildCount() );
@@ -72,7 +84,7 @@ public class AliasDirectoryNode extends ConfigurableNode
getAliasDirectory().addAliasList( list ); getAliasDirectory().addAliasList( list );
AliasListNode node = new AliasListNode( list ); AliasListNode node = new AliasListNode( mPlaylistManager, mSettingsManager, list );
getModel().addNode( node, getModel().addNode( node,
AliasDirectoryNode.this, AliasDirectoryNode.this,

View File

@@ -19,6 +19,7 @@ package alias;
import java.awt.Color; import java.awt.Color;
import java.awt.Dimension; import java.awt.Dimension;
import java.awt.EventQueue;
import java.awt.event.ActionEvent; import java.awt.event.ActionEvent;
import java.awt.event.ActionListener; import java.awt.event.ActionListener;
@@ -32,19 +33,19 @@ import javax.swing.JPanel;
import javax.swing.JTextField; import javax.swing.JTextField;
import javax.swing.tree.TreePath; import javax.swing.tree.TreePath;
import map.IconManager;
import map.MapIcon; import map.MapIcon;
import map.MapIconListCellRenderer; import map.MapIconListCellRenderer;
import net.miginfocom.swing.MigLayout; import net.miginfocom.swing.MigLayout;
import settings.SettingsManager; import settings.SettingsManager;
import controller.ConfigurableNode; import controller.ConfigurableNode;
import controller.ResourceManager;
public class AliasEditor extends JPanel implements ActionListener public class AliasEditor extends JPanel implements ActionListener
{ {
private static final long serialVersionUID = 1L; private static final long serialVersionUID = 1L;
private AliasNode mAliasNode; private AliasNode mAliasNode;
private ResourceManager mResourceManager; private SettingsManager mSettingsManager;
private JLabel mLabelName; private JLabel mLabelName;
private JTextField mTextAlias; private JTextField mTextAlias;
@@ -54,10 +55,11 @@ public class AliasEditor extends JPanel implements ActionListener
private JComboBox<MapIcon> mComboMapIcon; private JComboBox<MapIcon> mComboMapIcon;
private JButton mBtnIconManager; private JButton mBtnIconManager;
public AliasEditor( AliasNode aliasNode, ResourceManager resourceManager ) public AliasEditor( AliasNode aliasNode,
SettingsManager settingsManager )
{ {
mAliasNode = aliasNode; mAliasNode = aliasNode;
mResourceManager = resourceManager; mSettingsManager = settingsManager;
initGUI(); initGUI();
} }
@@ -98,8 +100,7 @@ public class AliasEditor extends JPanel implements ActionListener
add( new JLabel( "Icon:" ) ); add( new JLabel( "Icon:" ) );
mComboMapIcon = new JComboBox<MapIcon>( mComboMapIcon = new JComboBox<MapIcon>( mSettingsManager.getMapIcons() );
mResourceManager.getSettingsManager().getMapIcons() );
MapIconListCellRenderer renderer = new MapIconListCellRenderer(); MapIconListCellRenderer renderer = new MapIconListCellRenderer();
renderer.setPreferredSize( new Dimension( 200, 30 ) ); renderer.setPreferredSize( new Dimension( 200, 30 ) );
@@ -112,8 +113,7 @@ public class AliasEditor extends JPanel implements ActionListener
iconName = SettingsManager.DEFAULT_ICON; iconName = SettingsManager.DEFAULT_ICON;
} }
MapIcon savedIcon = mResourceManager.getSettingsManager() MapIcon savedIcon = mSettingsManager.getMapIcon( iconName );
.getMapIcon( iconName );
if( savedIcon != null ) if( savedIcon != null )
{ {
@@ -131,7 +131,17 @@ public class AliasEditor extends JPanel implements ActionListener
@Override @Override
public void actionPerformed( ActionEvent arg0 ) public void actionPerformed( ActionEvent arg0 )
{ {
mResourceManager.getController().showIconManager(); final IconManager iconManager =
new IconManager( mSettingsManager, AliasEditor.this );
EventQueue.invokeLater( new Runnable()
{
@Override
public void run()
{
iconManager.setVisible( true );
}
} );
} }
} ); } );
add( mBtnIconManager, "span 2,wrap" ); add( mBtnIconManager, "span 2,wrap" );
@@ -194,7 +204,7 @@ public class AliasEditor extends JPanel implements ActionListener
mButtonColor.setBackground( mAliasNode.getAlias().getMapColor() ); mButtonColor.setBackground( mAliasNode.getAlias().getMapColor() );
mButtonColor.setForeground( mAliasNode.getAlias().getMapColor() ); mButtonColor.setForeground( mAliasNode.getAlias().getMapColor() );
MapIcon savedIcon = mResourceManager.getSettingsManager() MapIcon savedIcon = mSettingsManager
.getMapIcon( mAliasNode.getAlias().getIconName() ); .getMapIcon( mAliasNode.getAlias().getIconName() );
mComboMapIcon.setSelectedItem( savedIcon ); mComboMapIcon.setSelectedItem( savedIcon );

View File

@@ -17,19 +17,20 @@
******************************************************************************/ ******************************************************************************/
package alias; package alias;
import playlist.PlaylistManager;
import controller.ConfigurableNode; import controller.ConfigurableNode;
public class AliasIDNode extends ConfigurableNode public class AliasIDNode extends ConfigurableNode
{ {
private static final long serialVersionUID = 1L; private static final long serialVersionUID = 1L;
public AliasIDNode( AliasID id ) public AliasIDNode( PlaylistManager playlistManager, AliasID id )
{ {
super( id ); super( playlistManager, id );
} }
public void save() public void save()
{ {
getModel().getResourceManager().getPlaylistManager().save(); getPlaylistManager().save();
} }
} }

View File

@@ -26,15 +26,25 @@ import javax.swing.JPanel;
import javax.swing.JPopupMenu; import javax.swing.JPopupMenu;
import javax.swing.JSeparator; import javax.swing.JSeparator;
import playlist.PlaylistManager;
import settings.SettingsManager;
import controller.ConfigurableNode; import controller.ConfigurableNode;
public class AliasListNode extends ConfigurableNode public class AliasListNode extends ConfigurableNode
{ {
private static final long serialVersionUID = 1L; private static final long serialVersionUID = 1L;
public AliasListNode( AliasList list ) private PlaylistManager mPlaylistManager;
private SettingsManager mSettingsManager;
public AliasListNode( PlaylistManager playlistManager,
SettingsManager settingsManager,
AliasList list )
{ {
super( list ); super( playlistManager, list );
mPlaylistManager = playlistManager;
mSettingsManager = settingsManager;
} }
@Override @Override
@@ -52,7 +62,7 @@ public class AliasListNode extends ConfigurableNode
{ {
for( Group group: getList().getGroup() ) for( Group group: getList().getGroup() )
{ {
GroupNode node = new GroupNode( group ); GroupNode node = new GroupNode( mPlaylistManager, mSettingsManager, group );
getModel().addNode( node, AliasListNode.this, getChildCount() ); getModel().addNode( node, AliasListNode.this, getChildCount() );
@@ -81,7 +91,7 @@ public class AliasListNode extends ConfigurableNode
getList().addGroup( group ); getList().addGroup( group );
GroupNode node = new GroupNode( group ); GroupNode node = new GroupNode( mPlaylistManager, mSettingsManager, group );
getModel().addNode( node, getModel().addNode( node,
AliasListNode.this, AliasListNode.this,

View File

@@ -27,6 +27,8 @@ import javax.swing.JPanel;
import javax.swing.JPopupMenu; import javax.swing.JPopupMenu;
import map.MapIcon; import map.MapIcon;
import playlist.PlaylistManager;
import settings.SettingsManager;
import alias.action.AliasAction; import alias.action.AliasAction;
import alias.action.beep.BeepAction; import alias.action.beep.BeepAction;
import alias.action.beep.BeepActionNode; import alias.action.beep.BeepActionNode;
@@ -64,15 +66,22 @@ public class AliasNode extends ConfigurableNode
{ {
private static final long serialVersionUID = 1L; private static final long serialVersionUID = 1L;
public AliasNode( Alias alias ) private SettingsManager mSettingsManager;
private PlaylistManager mPlaylistManager;
public AliasNode( PlaylistManager playlistManager,
SettingsManager settingsManager,
Alias alias )
{ {
super( alias ); super( playlistManager, alias );
mSettingsManager = settingsManager;
} }
@Override @Override
public JPanel getEditor() public JPanel getEditor()
{ {
return new AliasEditor( this, getModel().getResourceManager() ); return new AliasEditor( this, mSettingsManager );
} }
public Alias getAlias() public Alias getAlias()
@@ -84,8 +93,7 @@ public class AliasNode extends ConfigurableNode
{ {
String icon = getAlias().getIconName(); String icon = getAlias().getIconName();
MapIcon mapIcon = getModel().getResourceManager() MapIcon mapIcon = mSettingsManager.getMapIcon( icon );
.getSettingsManager().getMapIcon( icon );
if( mapIcon != null ) if( mapIcon != null )
{ {
@@ -104,51 +112,51 @@ public class AliasNode extends ConfigurableNode
switch( aliasID.getType() ) switch( aliasID.getType() )
{ {
case ESN: case ESN:
getModel().addNode( new ESNNode( (Esn)aliasID ), getModel().addNode( new ESNNode( mPlaylistManager, (Esn)aliasID ),
AliasNode.this, getChildCount() ); AliasNode.this, getChildCount() );
break; break;
case Fleetsync: case Fleetsync:
getModel().addNode( new FleetsyncIDNode( (FleetsyncID)aliasID ), getModel().addNode( new FleetsyncIDNode( mPlaylistManager, (FleetsyncID)aliasID ),
AliasNode.this, getChildCount() ); AliasNode.this, getChildCount() );
break; break;
case LoJack: case LoJack:
getModel().addNode( new LoJackIDNode( (LoJackFunctionAndID)aliasID ), getModel().addNode( new LoJackIDNode( mPlaylistManager, (LoJackFunctionAndID)aliasID ),
AliasNode.this, getChildCount() ); AliasNode.this, getChildCount() );
break; break;
case LTRNetUID: case LTRNetUID:
getModel().addNode( new UniqueIDNode( (UniqueID)aliasID ), getModel().addNode( new UniqueIDNode( mPlaylistManager, (UniqueID)aliasID ),
AliasNode.this, getChildCount() ); AliasNode.this, getChildCount() );
break; break;
case MDC1200: case MDC1200:
getModel().addNode( new MDC1200IDNode( (MDC1200ID)aliasID ), getModel().addNode( new MDC1200IDNode( mPlaylistManager, (MDC1200ID)aliasID ),
AliasNode.this, getChildCount() ); AliasNode.this, getChildCount() );
break; break;
case MIN: case MIN:
getModel().addNode( new MINNode( (Min)aliasID ), getModel().addNode( new MINNode( mPlaylistManager, (Min)aliasID ),
AliasNode.this, getChildCount() ); AliasNode.this, getChildCount() );
break; break;
case MPT1327: case MPT1327:
getModel().addNode( new MPT1327IDNode( (MPT1327ID)aliasID ), getModel().addNode( new MPT1327IDNode( mPlaylistManager, (MPT1327ID)aliasID ),
AliasNode.this, getChildCount() ); AliasNode.this, getChildCount() );
break; break;
case NonRecordable: case NonRecordable:
getModel().addNode( new NonRecordableNode( (NonRecordable)aliasID ), getModel().addNode( new NonRecordableNode( mPlaylistManager, (NonRecordable)aliasID ),
AliasNode.this, getChildCount() ); AliasNode.this, getChildCount() );
break; break;
case Priority: case Priority:
getModel().addNode( new PriorityNode( (Priority)aliasID ), getModel().addNode( new PriorityNode( mPlaylistManager, (Priority)aliasID ),
AliasNode.this, getChildCount() ); AliasNode.this, getChildCount() );
break; break;
case Site: case Site:
getModel().addNode( new SiteIDNode( (SiteID)aliasID ), getModel().addNode( new SiteIDNode( mPlaylistManager, (SiteID)aliasID ),
AliasNode.this, getChildCount() ); AliasNode.this, getChildCount() );
break; break;
case Status: case Status:
getModel().addNode( new StatusIDNode( (StatusID)aliasID ), getModel().addNode( new StatusIDNode( mPlaylistManager, (StatusID)aliasID ),
AliasNode.this, getChildCount() ); AliasNode.this, getChildCount() );
break; break;
case Talkgroup: case Talkgroup:
getModel().addNode( new TalkgroupIDNode( (TalkgroupID)aliasID ), getModel().addNode( new TalkgroupIDNode( mPlaylistManager, (TalkgroupID)aliasID ),
AliasNode.this, getChildCount() ); AliasNode.this, getChildCount() );
break; break;
default: default:
@@ -161,17 +169,17 @@ public class AliasNode extends ConfigurableNode
{ {
if( action instanceof BeepAction ) if( action instanceof BeepAction )
{ {
getModel().addNode( new BeepActionNode( (BeepAction)action ), getModel().addNode( new BeepActionNode( mPlaylistManager, (BeepAction)action ),
AliasNode.this, getChildCount() ); AliasNode.this, getChildCount() );
} }
else if( action instanceof ClipAction ) else if( action instanceof ClipAction )
{ {
getModel().addNode( new ClipActionNode( (ClipAction)action ), getModel().addNode( new ClipActionNode( mPlaylistManager, (ClipAction)action ),
AliasNode.this, getChildCount() ); AliasNode.this, getChildCount() );
} }
else if( action instanceof ScriptAction ) else if( action instanceof ScriptAction )
{ {
getModel().addNode( new ScriptActionNode( (ScriptAction)action ), getModel().addNode( new ScriptActionNode( mPlaylistManager, (ScriptAction)action ),
AliasNode.this, getChildCount() ); AliasNode.this, getChildCount() );
} }
} }
@@ -200,7 +208,7 @@ public class AliasNode extends ConfigurableNode
getAlias().addAliasID( esn ); getAlias().addAliasID( esn );
ESNNode node = new ESNNode( esn ); ESNNode node = new ESNNode( mPlaylistManager, esn );
getModel().addNode( node, getModel().addNode( node,
AliasNode.this, AliasNode.this,
@@ -221,7 +229,7 @@ public class AliasNode extends ConfigurableNode
getAlias().addAliasID( fs ); getAlias().addAliasID( fs );
FleetsyncIDNode node = new FleetsyncIDNode( fs ); FleetsyncIDNode node = new FleetsyncIDNode( mPlaylistManager, fs );
getModel().addNode( node, getModel().addNode( node,
AliasNode.this, AliasNode.this,
@@ -242,7 +250,7 @@ public class AliasNode extends ConfigurableNode
getAlias().addAliasID( lj ); getAlias().addAliasID( lj );
LoJackIDNode node = new LoJackIDNode( lj ); LoJackIDNode node = new LoJackIDNode( mPlaylistManager, lj );
getModel().addNode( node, getModel().addNode( node,
AliasNode.this, AliasNode.this,
@@ -263,7 +271,7 @@ public class AliasNode extends ConfigurableNode
getAlias().addAliasID( mdc ); getAlias().addAliasID( mdc );
MDC1200IDNode node = new MDC1200IDNode( mdc ); MDC1200IDNode node = new MDC1200IDNode( mPlaylistManager, mdc );
getModel().addNode( node, getModel().addNode( node,
AliasNode.this, AliasNode.this,
@@ -284,7 +292,7 @@ public class AliasNode extends ConfigurableNode
getAlias().addAliasID( min ); getAlias().addAliasID( min );
MINNode node = new MINNode( min ); MINNode node = new MINNode( mPlaylistManager, min );
getModel().addNode( node, getModel().addNode( node,
AliasNode.this, AliasNode.this,
@@ -305,7 +313,7 @@ public class AliasNode extends ConfigurableNode
getAlias().addAliasID( mpt ); getAlias().addAliasID( mpt );
MPT1327IDNode node = new MPT1327IDNode( mpt ); MPT1327IDNode node = new MPT1327IDNode( mPlaylistManager, mpt );
getModel().addNode( node, getModel().addNode( node,
AliasNode.this, AliasNode.this,
@@ -326,7 +334,7 @@ public class AliasNode extends ConfigurableNode
getAlias().addAliasID( siteID ); getAlias().addAliasID( siteID );
SiteIDNode node = new SiteIDNode( siteID ); SiteIDNode node = new SiteIDNode( mPlaylistManager, siteID );
getModel().addNode( node, getModel().addNode( node,
AliasNode.this, AliasNode.this,
@@ -347,7 +355,7 @@ public class AliasNode extends ConfigurableNode
getAlias().addAliasID( statusID ); getAlias().addAliasID( statusID );
StatusIDNode node = new StatusIDNode( statusID ); StatusIDNode node = new StatusIDNode( mPlaylistManager, statusID );
getModel().addNode( node, getModel().addNode( node,
AliasNode.this, AliasNode.this,
@@ -369,7 +377,7 @@ public class AliasNode extends ConfigurableNode
getAlias().addAliasID( tg ); getAlias().addAliasID( tg );
TalkgroupIDNode node = new TalkgroupIDNode( tg ); TalkgroupIDNode node = new TalkgroupIDNode( mPlaylistManager, tg );
getModel().addNode( node, getModel().addNode( node,
AliasNode.this, AliasNode.this,
@@ -390,7 +398,7 @@ public class AliasNode extends ConfigurableNode
getAlias().addAliasID( uid ); getAlias().addAliasID( uid );
UniqueIDNode node = new UniqueIDNode( uid ); UniqueIDNode node = new UniqueIDNode( mPlaylistManager, uid );
getModel().addNode( node, getModel().addNode( node,
AliasNode.this, AliasNode.this,
@@ -416,7 +424,7 @@ public class AliasNode extends ConfigurableNode
getAlias().addAliasAction( clipAction ); getAlias().addAliasAction( clipAction );
ClipActionNode node = new ClipActionNode( clipAction ); ClipActionNode node = new ClipActionNode( mPlaylistManager, clipAction );
getModel().addNode( node, getModel().addNode( node,
AliasNode.this, AliasNode.this,
@@ -439,7 +447,7 @@ public class AliasNode extends ConfigurableNode
getAlias().addAliasAction( beepAction ); getAlias().addAliasAction( beepAction );
BeepActionNode node = new BeepActionNode( beepAction ); BeepActionNode node = new BeepActionNode( mPlaylistManager, beepAction );
getModel().addNode( node, getModel().addNode( node,
AliasNode.this, AliasNode.this,
@@ -462,7 +470,7 @@ public class AliasNode extends ConfigurableNode
getAlias().addAliasAction( scriptAction ); getAlias().addAliasAction( scriptAction );
ScriptActionNode node = new ScriptActionNode( scriptAction ); ScriptActionNode node = new ScriptActionNode( mPlaylistManager, scriptAction );
getModel().addNode( node, getModel().addNode( node,
AliasNode.this, AliasNode.this,
@@ -491,7 +499,7 @@ public class AliasNode extends ConfigurableNode
getAlias().addAliasID( non ); getAlias().addAliasID( non );
NonRecordableNode node = new NonRecordableNode( non ); NonRecordableNode node = new NonRecordableNode( mPlaylistManager, non );
getModel().addNode( node, getModel().addNode( node,
AliasNode.this, AliasNode.this,
@@ -518,7 +526,7 @@ public class AliasNode extends ConfigurableNode
getAlias().addAliasID( priority ); getAlias().addAliasID( priority );
PriorityNode node = new PriorityNode( priority ); PriorityNode node = new PriorityNode( mPlaylistManager, priority );
getModel().addNode( node, getModel().addNode( node,
AliasNode.this, AliasNode.this,

View File

@@ -26,15 +26,24 @@ import javax.swing.JPanel;
import javax.swing.JPopupMenu; import javax.swing.JPopupMenu;
import javax.swing.JSeparator; import javax.swing.JSeparator;
import playlist.PlaylistManager;
import settings.SettingsManager;
import controller.ConfigurableNode; import controller.ConfigurableNode;
public class GroupNode extends ConfigurableNode public class GroupNode extends ConfigurableNode
{ {
private static final long serialVersionUID = 1L; private static final long serialVersionUID = 1L;
public GroupNode( Group group ) private PlaylistManager mPlaylistManager;
private SettingsManager mSettingsManager;
public GroupNode( PlaylistManager playlistManager,
SettingsManager settingsManager,
Group group )
{ {
super( group ); super( playlistManager, group );
mSettingsManager = settingsManager;
} }
@Override @Override
@@ -52,7 +61,7 @@ public class GroupNode extends ConfigurableNode
{ {
for( Alias alias: getGroup().getAlias() ) for( Alias alias: getGroup().getAlias() )
{ {
AliasNode node = new AliasNode( alias ); AliasNode node = new AliasNode( mPlaylistManager, mSettingsManager, alias );
getModel().addNode( node, GroupNode.this, getChildCount() ); getModel().addNode( node, GroupNode.this, getChildCount() );
@@ -81,7 +90,7 @@ public class GroupNode extends ConfigurableNode
getGroup().addAlias( alias ); getGroup().addAlias( alias );
AliasNode node = new AliasNode( alias ); AliasNode node = new AliasNode( mPlaylistManager, mSettingsManager, alias );
getModel().addNode( node, getModel().addNode( node,
GroupNode.this, GroupNode.this,

View File

@@ -17,20 +17,25 @@
******************************************************************************/ ******************************************************************************/
package alias.action; package alias.action;
import playlist.PlaylistManager;
import controller.ConfigurableNode; import controller.ConfigurableNode;
public class AliasActionNode extends ConfigurableNode public class AliasActionNode extends ConfigurableNode
{ {
private static final long serialVersionUID = 1L; private static final long serialVersionUID = 1L;
public AliasActionNode( AliasAction action ) private PlaylistManager mPlaylistManager;
public AliasActionNode( PlaylistManager playlistManager, AliasAction action )
{ {
super( action ); super( playlistManager, action );
mPlaylistManager = playlistManager;
} }
public void save() public void save()
{ {
getModel().getResourceManager().getPlaylistManager().save(); mPlaylistManager.save();
} }
public String getIconPath() public String getIconPath()

View File

@@ -25,6 +25,7 @@ import javax.swing.JOptionPane;
import javax.swing.JPanel; import javax.swing.JPanel;
import javax.swing.JPopupMenu; import javax.swing.JPopupMenu;
import playlist.PlaylistManager;
import alias.AliasNode; import alias.AliasNode;
import alias.action.AliasActionNode; import alias.action.AliasActionNode;
@@ -32,9 +33,9 @@ public class BeepActionNode extends AliasActionNode
{ {
private static final long serialVersionUID = 1L; private static final long serialVersionUID = 1L;
public BeepActionNode( BeepAction beepAction ) public BeepActionNode( PlaylistManager playlistManager, BeepAction beepAction )
{ {
super( beepAction ); super( playlistManager, beepAction );
} }
@Override @Override

View File

@@ -25,6 +25,7 @@ import javax.swing.JOptionPane;
import javax.swing.JPanel; import javax.swing.JPanel;
import javax.swing.JPopupMenu; import javax.swing.JPopupMenu;
import playlist.PlaylistManager;
import alias.AliasNode; import alias.AliasNode;
import alias.action.AliasActionNode; import alias.action.AliasActionNode;
@@ -32,9 +33,9 @@ public class ClipActionNode extends AliasActionNode
{ {
private static final long serialVersionUID = 1L; private static final long serialVersionUID = 1L;
public ClipActionNode( ClipAction clipAction ) public ClipActionNode( PlaylistManager playlistManager, ClipAction clipAction )
{ {
super( clipAction ); super( playlistManager, clipAction );
} }
@Override @Override

View File

@@ -25,6 +25,7 @@ import javax.swing.JOptionPane;
import javax.swing.JPanel; import javax.swing.JPanel;
import javax.swing.JPopupMenu; import javax.swing.JPopupMenu;
import playlist.PlaylistManager;
import alias.AliasNode; import alias.AliasNode;
import alias.action.AliasActionNode; import alias.action.AliasActionNode;
@@ -32,9 +33,9 @@ public class ScriptActionNode extends AliasActionNode
{ {
private static final long serialVersionUID = 1L; private static final long serialVersionUID = 1L;
public ScriptActionNode( ScriptAction scriptAction ) public ScriptActionNode( PlaylistManager playlistManager, ScriptAction scriptAction )
{ {
super( scriptAction ); super( playlistManager, scriptAction );
} }
@Override @Override

View File

@@ -25,6 +25,7 @@ import javax.swing.JOptionPane;
import javax.swing.JPanel; import javax.swing.JPanel;
import javax.swing.JPopupMenu; import javax.swing.JPopupMenu;
import playlist.PlaylistManager;
import alias.AliasIDNode; import alias.AliasIDNode;
import alias.AliasNode; import alias.AliasNode;
@@ -32,9 +33,9 @@ public class ESNNode extends AliasIDNode
{ {
private static final long serialVersionUID = 1L; private static final long serialVersionUID = 1L;
public ESNNode( Esn esn ) public ESNNode( PlaylistManager playlistManager, Esn esn )
{ {
super( esn ); super( playlistManager, esn );
} }
@Override @Override

View File

@@ -25,6 +25,7 @@ import javax.swing.JOptionPane;
import javax.swing.JPanel; import javax.swing.JPanel;
import javax.swing.JPopupMenu; import javax.swing.JPopupMenu;
import playlist.PlaylistManager;
import alias.AliasIDNode; import alias.AliasIDNode;
import alias.AliasNode; import alias.AliasNode;
@@ -32,9 +33,9 @@ public class FleetsyncIDNode extends AliasIDNode
{ {
private static final long serialVersionUID = 1L; private static final long serialVersionUID = 1L;
public FleetsyncIDNode( FleetsyncID id ) public FleetsyncIDNode( PlaylistManager playlistManager, FleetsyncID id )
{ {
super( id ); super( playlistManager, id );
} }
@Override @Override

View File

@@ -25,6 +25,7 @@ import javax.swing.JOptionPane;
import javax.swing.JPanel; import javax.swing.JPanel;
import javax.swing.JPopupMenu; import javax.swing.JPopupMenu;
import playlist.PlaylistManager;
import alias.AliasIDNode; import alias.AliasIDNode;
import alias.AliasNode; import alias.AliasNode;
@@ -32,9 +33,9 @@ public class StatusIDNode extends AliasIDNode
{ {
private static final long serialVersionUID = 1L; private static final long serialVersionUID = 1L;
public StatusIDNode( StatusID id ) public StatusIDNode( PlaylistManager playlistManager, StatusID id )
{ {
super( id ); super( playlistManager, id );
} }
@Override @Override

View File

@@ -25,6 +25,7 @@ import javax.swing.JOptionPane;
import javax.swing.JPanel; import javax.swing.JPanel;
import javax.swing.JPopupMenu; import javax.swing.JPopupMenu;
import playlist.PlaylistManager;
import alias.AliasIDNode; import alias.AliasIDNode;
import alias.AliasNode; import alias.AliasNode;
@@ -32,9 +33,9 @@ public class LoJackIDNode extends AliasIDNode
{ {
private static final long serialVersionUID = 1L; private static final long serialVersionUID = 1L;
public LoJackIDNode( LoJackFunctionAndID id ) public LoJackIDNode( PlaylistManager playlistManager, LoJackFunctionAndID id )
{ {
super( id ); super( playlistManager,id );
} }
@Override @Override

View File

@@ -25,6 +25,7 @@ import javax.swing.JOptionPane;
import javax.swing.JPanel; import javax.swing.JPanel;
import javax.swing.JPopupMenu; import javax.swing.JPopupMenu;
import playlist.PlaylistManager;
import alias.AliasIDNode; import alias.AliasIDNode;
import alias.AliasNode; import alias.AliasNode;
@@ -32,9 +33,9 @@ public class MDC1200IDNode extends AliasIDNode
{ {
private static final long serialVersionUID = 1L; private static final long serialVersionUID = 1L;
public MDC1200IDNode( MDC1200ID id ) public MDC1200IDNode( PlaylistManager playlistManager, MDC1200ID id )
{ {
super( id ); super( playlistManager, id );
} }
@Override @Override

View File

@@ -25,6 +25,7 @@ import javax.swing.JOptionPane;
import javax.swing.JPanel; import javax.swing.JPanel;
import javax.swing.JPopupMenu; import javax.swing.JPopupMenu;
import playlist.PlaylistManager;
import alias.AliasIDNode; import alias.AliasIDNode;
import alias.AliasNode; import alias.AliasNode;
@@ -32,9 +33,9 @@ public class MINNode extends AliasIDNode
{ {
private static final long serialVersionUID = 1L; private static final long serialVersionUID = 1L;
public MINNode( Min min ) public MINNode( PlaylistManager playlistManager, Min min )
{ {
super( min ); super( playlistManager, min );
} }
@Override @Override

View File

@@ -25,6 +25,7 @@ import javax.swing.JOptionPane;
import javax.swing.JPanel; import javax.swing.JPanel;
import javax.swing.JPopupMenu; import javax.swing.JPopupMenu;
import playlist.PlaylistManager;
import alias.AliasIDNode; import alias.AliasIDNode;
import alias.AliasNode; import alias.AliasNode;
@@ -32,9 +33,9 @@ public class MPT1327IDNode extends AliasIDNode
{ {
private static final long serialVersionUID = 1L; private static final long serialVersionUID = 1L;
public MPT1327IDNode( MPT1327ID id ) public MPT1327IDNode( PlaylistManager playlistManager, MPT1327ID id )
{ {
super( id ); super( playlistManager, id );
} }
@Override @Override

View File

@@ -25,6 +25,7 @@ import javax.swing.JOptionPane;
import javax.swing.JPanel; import javax.swing.JPanel;
import javax.swing.JPopupMenu; import javax.swing.JPopupMenu;
import playlist.PlaylistManager;
import alias.AliasIDNode; import alias.AliasIDNode;
import alias.AliasNode; import alias.AliasNode;
@@ -32,9 +33,9 @@ public class SiteIDNode extends AliasIDNode
{ {
private static final long serialVersionUID = 1L; private static final long serialVersionUID = 1L;
public SiteIDNode( SiteID id ) public SiteIDNode( PlaylistManager playlistManager, SiteID id )
{ {
super( id ); super( playlistManager, id );
} }
@Override @Override

View File

@@ -25,6 +25,7 @@ import javax.swing.JOptionPane;
import javax.swing.JPanel; import javax.swing.JPanel;
import javax.swing.JPopupMenu; import javax.swing.JPopupMenu;
import playlist.PlaylistManager;
import alias.AliasIDNode; import alias.AliasIDNode;
import alias.AliasNode; import alias.AliasNode;
@@ -32,9 +33,9 @@ public class TalkgroupIDNode extends AliasIDNode
{ {
private static final long serialVersionUID = 1L; private static final long serialVersionUID = 1L;
public TalkgroupIDNode( TalkgroupID id ) public TalkgroupIDNode( PlaylistManager playlistManager, TalkgroupID id )
{ {
super( id ); super( playlistManager,id );
} }
@Override @Override

View File

@@ -25,6 +25,7 @@ import javax.swing.JOptionPane;
import javax.swing.JPanel; import javax.swing.JPanel;
import javax.swing.JPopupMenu; import javax.swing.JPopupMenu;
import playlist.PlaylistManager;
import alias.AliasIDNode; import alias.AliasIDNode;
import alias.AliasNode; import alias.AliasNode;
@@ -32,9 +33,9 @@ public class UniqueIDNode extends AliasIDNode
{ {
private static final long serialVersionUID = 1L; private static final long serialVersionUID = 1L;
public UniqueIDNode( UniqueID id ) public UniqueIDNode( PlaylistManager playlistManager, UniqueID id )
{ {
super( id ); super( playlistManager, id );
} }
@Override @Override

View File

@@ -25,6 +25,7 @@ import javax.swing.JOptionPane;
import javax.swing.JPanel; import javax.swing.JPanel;
import javax.swing.JPopupMenu; import javax.swing.JPopupMenu;
import playlist.PlaylistManager;
import alias.AliasIDNode; import alias.AliasIDNode;
import alias.AliasNode; import alias.AliasNode;
@@ -32,9 +33,9 @@ public class PriorityNode extends AliasIDNode
{ {
private static final long serialVersionUID = 1L; private static final long serialVersionUID = 1L;
public PriorityNode( Priority priority ) public PriorityNode( PlaylistManager playlistManager, Priority priority )
{ {
super( priority ); super( playlistManager, priority );
} }
@Override @Override

View File

@@ -25,6 +25,7 @@ import javax.swing.JOptionPane;
import javax.swing.JPanel; import javax.swing.JPanel;
import javax.swing.JPopupMenu; import javax.swing.JPopupMenu;
import playlist.PlaylistManager;
import alias.AliasID; import alias.AliasID;
import alias.AliasIDNode; import alias.AliasIDNode;
import alias.AliasNode; import alias.AliasNode;
@@ -33,9 +34,9 @@ public class NonRecordableNode extends AliasIDNode
{ {
private static final long serialVersionUID = 1L; private static final long serialVersionUID = 1L;
public NonRecordableNode( NonRecordable id ) public NonRecordableNode( PlaylistManager playlistManager, NonRecordable id )
{ {
super( id ); super( playlistManager, id );
} }
@Override @Override

View File

@@ -8,7 +8,7 @@ import org.slf4j.Logger;
import org.slf4j.LoggerFactory; import org.slf4j.LoggerFactory;
import sample.Listener; import sample.Listener;
import sample.real.IRealBufferListener; import sample.real.IFilteredRealBufferListener;
import sample.real.RealBuffer; import sample.real.RealBuffer;
import audio.metadata.AudioMetadata; import audio.metadata.AudioMetadata;
import audio.metadata.IMetadataListener; import audio.metadata.IMetadataListener;
@@ -18,7 +18,6 @@ import audio.squelch.SquelchState;
import controller.channel.ChannelEvent; import controller.channel.ChannelEvent;
import controller.channel.IChannelEventListener; import controller.channel.IChannelEventListener;
import dsp.filter.Filters; import dsp.filter.Filters;
import dsp.filter.dc.DCRemovalFilter_RB;
import dsp.filter.fir.real.RealFIRFilter_R_R; import dsp.filter.fir.real.RealFIRFilter_R_R;
/** /**
@@ -32,49 +31,31 @@ import dsp.filter.fir.real.RealFIRFilter_R_R;
public class AudioModule extends Module implements IAudioPacketProvider, public class AudioModule extends Module implements IAudioPacketProvider,
IChannelEventListener, IChannelEventListener,
IMetadataListener, IMetadataListener,
IRealBufferListener, IFilteredRealBufferListener,
ISquelchStateListener, ISquelchStateListener,
Listener<RealBuffer> Listener<RealBuffer>
{ {
protected static final Logger mLog = LoggerFactory.getLogger( AudioModule.class ); protected static final Logger mLog = LoggerFactory.getLogger( AudioModule.class );
/* Determines responsiveness of DC filter to frequency changes */
private static final float DC_REMOVAL_RATIO = 0.000003f;
/* Provides a unique identifier for this audio module instance to use as a /* Provides a unique identifier for this audio module instance to use as a
* source identifier for all audio packets */ * source identifier for all audio packets */
private static int UNIQUE_ID = 0; private static int UNIQUE_ID = 0;
private int mSourceID; private int mSourceID;
private AudioMetadata mAudioMetadata; private AudioMetadata mAudioMetadata;
private ChannelEventListener mChannelEventListener = new ChannelEventListener(); private ChannelEventListener mChannelEventListener = new ChannelEventListener();
private SquelchStateListener mSquelchStateListener = new SquelchStateListener(); private SquelchStateListener mSquelchStateListener = new SquelchStateListener();
private SquelchState mSquelchState = SquelchState.SQUELCH; private SquelchState mSquelchState = SquelchState.SQUELCH;
private RealFIRFilter_R_R mAudioFilter = new RealFIRFilter_R_R(
Filters.FIR_BANDPASS_AUDIO_48KHZ.getCoefficients(), 2.0f );
private DCRemovalFilter_RB mDCRemovalFilter;
private Listener<AudioPacket> mAudioPacketListener; private Listener<AudioPacket> mAudioPacketListener;
private boolean mRemoveDC = false; //TODO: remove this -- is being replaced by the DemodulatedAudioFilterModule
private RealFIRFilter_R_R mAudioFilter = new RealFIRFilter_R_R(
Filters.FIR_BANDPASS_AUDIO_48KHZ.getCoefficients(), 2.0f );
public AudioModule( boolean record, boolean removeDC ) public AudioModule( boolean record )
{ {
mSourceID = ++UNIQUE_ID; mSourceID = ++UNIQUE_ID;
mAudioMetadata = new AudioMetadata( mSourceID, record ); mAudioMetadata = new AudioMetadata( mSourceID, record );
mRemoveDC = removeDC;
if( mRemoveDC )
{
mDCRemovalFilter = new DCRemovalFilter_RB( DC_REMOVAL_RATIO );
mDCRemovalFilter.setListener( this );
}
} }
@Override @Override
@@ -132,13 +113,8 @@ public class AudioModule extends Module implements IAudioPacketProvider,
} }
@Override @Override
public Listener<RealBuffer> getRealBufferListener() public Listener<RealBuffer> getFilteredRealBufferListener()
{ {
if( mRemoveDC )
{
return mDCRemovalFilter;
}
return this; return this;
} }

View File

@@ -27,6 +27,7 @@ import org.slf4j.LoggerFactory;
import sample.Listener; import sample.Listener;
import settings.SettingsManager; import settings.SettingsManager;
import source.SourceManager;
import source.mixer.MixerChannelConfiguration; import source.mixer.MixerChannelConfiguration;
import source.mixer.MixerManager; import source.mixer.MixerManager;
import audio.output.AudioOutput; import audio.output.AudioOutput;
@@ -43,14 +44,18 @@ public class AudioPanel extends JPanel implements Listener<AudioEvent>
new ImageIcon( "images/audio_unmuted.png" ), 38 ); new ImageIcon( "images/audio_unmuted.png" ), 38 );
private SettingsManager mSettingsManager; private SettingsManager mSettingsManager;
private SourceManager mSourceManager;
private IAudioController mController; private IAudioController mController;
private JButton mMuteButton; private JButton mMuteButton;
private AudioChannelsPanel mAudioChannelsPanel; private AudioChannelsPanel mAudioChannelsPanel;
public AudioPanel( SettingsManager settingsManager, IAudioController controller ) public AudioPanel( SettingsManager settingsManager,
SourceManager sourceManager,
IAudioController controller )
{ {
mSettingsManager = settingsManager; mSettingsManager = settingsManager;
mSourceManager = sourceManager;
mController = controller; mController = controller;
mController.addControllerListener( this ); mController.addControllerListener( this );
@@ -148,7 +153,7 @@ public class AudioPanel extends JPanel implements Listener<AudioEvent>
JMenu outputMenu = new JMenu( "Audio Output" ); JMenu outputMenu = new JMenu( "Audio Output" );
MixerChannelConfiguration[] mixerConfigurations = MixerChannelConfiguration[] mixerConfigurations =
MixerManager.getInstance().getOutputMixers(); mSourceManager.getMixerManager().getOutputMixers();
for( MixerChannelConfiguration mixerConfig: mixerConfigurations ) for( MixerChannelConfiguration mixerConfig: mixerConfigurations )
{ {

View File

@@ -1,33 +0,0 @@
/*******************************************************************************
* SDR Trunk
* Copyright (C) 2014 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
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>
******************************************************************************/
package buffer;
public class BufferOverflowException extends Exception
{
private static final long serialVersionUID = 1L;
public BufferOverflowException( String text )
{
super( text );
}
public BufferOverflowException( String text, Throwable exc )
{
super( text, exc );
}
}

View File

@@ -1,23 +0,0 @@
/*******************************************************************************
* SDR Trunk
* Copyright (C) 2014 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
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>
******************************************************************************/
package buffer;
public interface BufferOverflowListener
{
public void overflow( Object source, String message );
}

View File

@@ -1,60 +0,0 @@
/*******************************************************************************
* SDR Trunk
* Copyright (C) 2014 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
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>
******************************************************************************/
package buffer;
public class ByteArrayDelayBuffer
{
private int mBufferSize;
private byte[][] mBuffer = null;
private int mBufferPointer = 0;
/**
* Implements a delay buffer for byte arrays. As a new byte[] is placed
* into the buffer, the oldest byte[] is returned
* @param bufferSize - number of byte arrays to buffer
*/
public ByteArrayDelayBuffer( int bufferSize )
{
mBufferSize = bufferSize;
}
/**
* Inserts new bytes into the buffer
*
* @return - oldest byte[] from the buffer, or null if the buffer is not
* yet full
*/
public byte[] get( byte[] bytes )
{
if( mBuffer == null )
{
mBuffer = new byte[ mBufferSize ][ bytes.length ];
}
byte[] returnBytes = mBuffer[ mBufferPointer ];
mBuffer[ mBufferPointer++ ] = bytes;
if( mBufferPointer >= mBufferSize )
{
mBufferPointer = 0;
}
return returnBytes;
}
}

View File

@@ -1,23 +0,0 @@
/*******************************************************************************
* SDR Trunk
* Copyright (C) 2014 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
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>
******************************************************************************/
package buffer;
public interface ByteArrayListener
{
public void receive( byte[] data );
}

View File

@@ -1,25 +0,0 @@
/*******************************************************************************
* SDR Trunk
* Copyright (C) 2014 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
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>
******************************************************************************/
package buffer;
import java.nio.ByteBuffer;
public interface ByteBufferListener
{
public void receive( ByteBuffer buffer );
}

View File

@@ -1,33 +0,0 @@
/*******************************************************************************
* SDR Trunk
* Copyright (C) 2014 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
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>
******************************************************************************/
package buffer;
public interface ByteBufferProvider
{
/**
* Adds a sample listener to receive samples
*/
public void addByteBufferListener( ByteBufferListener listener );
/**
* Removes the sample listener, if it is currently registered as a listener
*/
public void removeByteBufferListener( ByteBufferListener listener );
}

View File

@@ -1,91 +0,0 @@
/*******************************************************************************
* SDR Trunk
* Copyright (C) 2014 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
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>
******************************************************************************/
package buffer;
import java.nio.ByteBuffer;
import java.util.Enumeration;
import sample.complex.Complex;
/**
* Provides a complex sample enumeration wrapper around a byte array containing
* interleaved byte-length I & Q sample values in the range of 0 - 255, converting
* those samples into complex samples with value range of -128 to 0 to 127.
*/
public class ComplexByteBuffer implements Enumeration<Complex>
{
private static float[] mValues;
/**
* Creates a lookup table that converts the 8-bit valued range from 0 - 255
* into scaled float values of -128 to 0 to 127
*/
static
{
mValues = new float[ 256 ];
float scale = (float)( 1.0f / 127.0f );
for( int x = 0; x < 256; x++ )
{
mValues[ x ] = (float)( x - 128 ) * scale;
}
}
private ByteBuffer mBytes;
// private byte[] mBytes;
// private int mPointer;
public ComplexByteBuffer( byte[] bytes )
{
mBytes = ByteBuffer.wrap( bytes );
// mBytes = bytes;
// mPointer = 0;
}
public byte[] toArray()
{
// return mBytes;
return mBytes.array();
}
/**
* Indicates if there are more complex samples remaining.
*/
@Override
public boolean hasMoreElements()
{
// return mPointer < mBytes.length;
return mBytes.hasRemaining();
}
/**
* Returns the next complex sample.
*
* Note: does not check for buffer overrun. Use the hasMoreElements()
* method to ensure you do not read past the end of the buffer.
*/
@Override
public Complex nextElement()
{
// return new ComplexSample( mValues[ ( mBytes[ mPointer++ ] & 0xFF ) ],
// mValues[ ( mBytes[ mPointer++ ] & 0xFF ) ] );
return new Complex( mValues[ ( mBytes.get() & 0xFF ) ],
mValues[ ( mBytes.get() & 0xFF ) ] );
}
}

View File

@@ -1,73 +0,0 @@
/*******************************************************************************
* SDR Trunk
* Copyright (C) 2014 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
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>
******************************************************************************/
package buffer;
import java.nio.ByteBuffer;
import java.nio.ByteOrder;
import java.util.Arrays;
import sample.complex.Complex;
public class ComplexSampleBufferAssembler
{
private ByteBuffer mByteBuffer;
private int mSizeInBytes;
public ComplexSampleBufferAssembler( int size )
{
mSizeInBytes = size * 4;
//Allocate a byte buffer with 4 bytes per sample (ie 2 x 16-bit samples)
mByteBuffer = ByteBuffer.allocate( mSizeInBytes );
mByteBuffer.order( ByteOrder.LITTLE_ENDIAN );
}
/**
* Load the sample's bytes, left then right, little endian, into the
* backing byte array
*/
public void put( Complex sample )
{
mByteBuffer.putShort( (short)( sample.left() * Short.MAX_VALUE ) );
mByteBuffer.putShort( (short)( sample.right() * Short.MAX_VALUE ) );
}
/**
* Indicates if there is room for more samples in the buffer, or if it is full
*/
public boolean hasRemaining()
{
return mByteBuffer.hasRemaining();
}
/**
* Returns a copy of the byte array backing this buffer
*/
public ByteBuffer get()
{
return ByteBuffer.wrap( Arrays.copyOf( mByteBuffer.array(), mSizeInBytes ) );
}
/**
* Clear the bytes from the underlying buffer and reset the pointer to 0.
*/
public void clear()
{
mByteBuffer.clear();
}
}

View File

@@ -1,67 +0,0 @@
/*******************************************************************************
* SDR Trunk
* Copyright (C) 2014 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
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>
******************************************************************************/
package buffer;
import sample.Listener;
/**
* Delay Buffer - implements a circular delay buffer backed by an object array
*/
public class DelayBuffer<T> implements Listener<T>
{
private Object[] mBuffer;
private int mBufferPointer = 0;
private Listener<T> mListener;
public DelayBuffer( int length )
{
mBuffer = new Object[ length ];
}
@Override
@SuppressWarnings( "unchecked" )
public void receive( T value )
{
Object delayed = mBuffer[ mBufferPointer ];
mBuffer[ mBufferPointer ] = value;
mBufferPointer++;
/* Wrap the buffer pointer around to 0 when necessary */
if( mBufferPointer >= mBuffer.length )
{
mBufferPointer = 0;
}
if( mListener != null && delayed != null )
{
mListener.receive( (T)delayed );
}
}
public void setListener( Listener<T> listener )
{
mListener = listener;
}
public void removeListener( Listener<T> listener )
{
mListener = null;
}
}

View File

@@ -1,97 +0,0 @@
/*******************************************************************************
* SDR Trunk
* Copyright (C) 2014 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
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>
******************************************************************************/
package buffer;
import java.util.ArrayList;
import java.util.Arrays;
public class FloatArrayCircularAveragingBuffer
{
private ArrayList<float[]> mBuffer;
private int mBufferPointer;
private int mBufferSize;
private float[] mAverage;
public FloatArrayCircularAveragingBuffer( int bufferSize )
{
mBufferSize = bufferSize;
mBuffer = new ArrayList<float[]>();
}
/**
* Replaces the oldest float array element in the buffer with this new
* float array element, and then returns the average of the buffer contents
* with the newElement values included in the average array
*/
public float[] get( float[] newElement )
{
/**
* If we've never setup the average array, or the newElements length is
* different than what we've been processing, reset the buffer & averages
*/
if( mAverage == null || mAverage.length != newElement.length )
{
reset( newElement.length );
}
float[] oldElement = mBuffer.get( mBufferPointer );
for( int x = 0; x < newElement.length; x++ )
{
/**
* Change the current average value in each array element by the
* difference of the new element minus the old element, divided
* by the buffer size ... average it
*/
mAverage[ x ] +=
( ( newElement[ x ] - oldElement[ x ] ) / mBufferSize );
}
mBuffer.set( mBufferPointer, newElement );
mBufferPointer++;
if( mBufferPointer >= mBufferSize )
{
mBufferPointer = 0;
}
return mAverage;
}
/**
* Clears buffer and average and fills buffer with zero-valued float arrays
*/
private void reset( int arrayLength )
{
mAverage = new float[ arrayLength ];
Arrays.fill( mAverage, 0.0f );
mBuffer.clear();
mBufferPointer = 0;
float[] emptyArray = new float[ arrayLength ];
Arrays.fill( emptyArray, 0.0f );
for( int x = 0; x < mBufferSize; x++ )
{
mBuffer.add( emptyArray );
}
}
}

View File

@@ -1,70 +0,0 @@
/*******************************************************************************
* SDR Trunk
* Copyright (C) 2014 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
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>
******************************************************************************/
package buffer;
import java.util.Arrays;
import sample.Listener;
/**
* Assembles single samples into sample blocks (ie arrays) for broadcast to
* registered SampleBlockListeners
*/
public class FloatBufferAssembler implements Listener<Float>
{
private Float[] mFloatBuffer;
private int mBufferSize;
private int mBufferPointer = 0;
private Listener<Float[]> mListener;
public FloatBufferAssembler( int bufferSize )
{
mBufferSize = bufferSize;
mFloatBuffer = new Float[ mBufferSize ];
}
/**
* Stores received samples in the sample block and manages the storage
* pointer. Sends sample blocks when full.
*/
@Override
public void receive( Float sample )
{
mFloatBuffer[ mBufferPointer++ ] = sample;
if( mBufferPointer == mBufferSize )
{
if( mListener != null )
{
mListener.receive( Arrays.copyOf( mFloatBuffer, mBufferSize ) );
}
mBufferPointer = 0;
}
}
/**
* Adds a new sampleblock listener to receive sample blocks as they are
* assembled from the sample stream
*/
public void setListener( Listener<Float[]> listener )
{
mListener = listener;
}
}

View File

@@ -1,110 +0,0 @@
/*******************************************************************************
* SDR Trunk
* Copyright (C) 2014 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
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>
******************************************************************************/
package buffer;
import java.util.Arrays;
/**
* Circular sample buffer - allocates a buffer and stores samples in a circular
* fashion, overwriting older samples with newly arrived samples. Initially
* fills buffer with 0-valued samples
*
* Produces no output. Obtain the average buffer value on-demand via the
* getAverage() method
*/
public class FloatCircularAveragingBuffer
{
private float[] mBuffer;
private int mBufferPointer = 0;
private int mSampleCountForAveraging;
private int mCurrentSampleCount = 0;
private float mAverage = 0.0f;
public FloatCircularAveragingBuffer( int size, int sampleCountForAveraging )
{
mBuffer = new float[ size ];
mSampleCountForAveraging = sampleCountForAveraging;
Arrays.fill( mBuffer, 0.0f );
}
/**
* Convenience wrapper to throw away to put the new sample and throwaway
* the oldest sample
*/
public void put( float newestSample )
{
get( newestSample );
}
/**
* Loads the newest sample into the buffer and returns the oldest sample
*/
public float get( float newestSample )
{
float oldestSample = mBuffer[ mBufferPointer ];
mBuffer[ mBufferPointer ] = newestSample;
mBufferPointer++;
if( mBufferPointer >= mBuffer.length )
{
mBufferPointer = 0;
}
mCurrentSampleCount++;
if( mCurrentSampleCount >= mSampleCountForAveraging )
{
calculateAverage();
mCurrentSampleCount = 0;
}
return oldestSample;
}
/**
* Calculates the average of the maximum and minimum values present in
* the buffer
*/
private void calculateAverage()
{
float min = mBuffer[ 0 ];
float max = mBuffer[ 0 ];
for( int x = 0; x < mBuffer.length; x++ )
{
if( mBuffer[ x ] < min )
{
min = mBuffer[ x ];
}
if( mBuffer[ x ] > max )
{
max = mBuffer[ x ];
}
}
mAverage = (float)( ( min + max ) / 2.0f );
}
public float getAverage()
{
return mAverage;
}
}

View File

@@ -1,68 +0,0 @@
/*******************************************************************************
* SDR Trunk
* Copyright (C) 2014 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
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>
******************************************************************************/
package buffer;
import java.util.Arrays;
/**
* Circular sample buffer - stores samples in a circular buffer
* overwriting older samples with newly arrived samples. Initially
* fills buffer with 0-valued samples
*
* Continuously calculates the average of the samples in the buffer, with the
* average available from the average() method.
*/
public class FloatCircularAveragingBuffer2
{
private float[] mBuffer;
private int mBufferPointer = 0;
private float mAverage = 0.0f;
public FloatCircularAveragingBuffer2( int size )
{
mBuffer = new float[ size ];
Arrays.fill( mBuffer, 0.0f );
}
/**
* Loads the newest sample into the buffer and returns the oldest sample
*/
public float get( float newestSample )
{
float oldestSample = mBuffer[ mBufferPointer ];
mBuffer[ mBufferPointer ] = newestSample;
mBufferPointer++;
if( mBufferPointer >= mBuffer.length )
{
mBufferPointer = 0;
}
mAverage = mAverage - ( oldestSample / mBuffer.length ) +
( newestSample / mBuffer.length );
return oldestSample;
}
public float average()
{
return mAverage;
}
}

View File

@@ -1,66 +0,0 @@
/*******************************************************************************
* SDR Trunk
* Copyright (C) 2014 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
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>
******************************************************************************/
package buffer;
import java.nio.ByteBuffer;
public class FloatSampleBuffer
{
private static final long serialVersionUID = 1L;
private int mSize;
private float[] mBuffer;
private int mBufferPointer = 0;
public FloatSampleBuffer( int size )
{
super();
mBuffer = new float[ size ];
}
public void put( float sample )
{
if( !isFull() )
{
mBuffer[ mBufferPointer++ ] = sample;
}
}
public void reset()
{
mBufferPointer = 0;
}
public boolean isFull()
{
return mBufferPointer >= mBuffer.length;
}
public byte[] getBytes()
{
ByteBuffer bb = ByteBuffer.allocate( mBuffer.length * 2 );
for( int x = 0; x < mBuffer.length; x++ )
{
bb.putShort( ((Float)mBuffer[ x ]).shortValue() );
}
return bb.array();
}
}

View File

@@ -1,72 +0,0 @@
/*******************************************************************************
* SDR Trunk
* Copyright (C) 2014 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
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>
******************************************************************************/
package buffer;
import java.nio.ByteBuffer;
import java.nio.ByteOrder;
public class FloatSampleBufferAssembler
{
private ByteBuffer mByteBuffer;
private int mSizeInBytes;
public FloatSampleBufferAssembler( int size )
{
mSizeInBytes = size * 2;
//Allocate a byte buffer with 2 bytes per sample (ie 1 x 16-bit sample)
mByteBuffer = ByteBuffer.allocate( mSizeInBytes );
mByteBuffer.order( ByteOrder.LITTLE_ENDIAN );
}
/**
* Load the sample's bytes, left then right, little endian, into the
* backing byte array
*/
public void put( float sample )
{
mByteBuffer.putShort( (short)( sample * 32768 ) );
}
/**
* Indicates if there is room for more samples in the buffer, or if it is full
*/
public boolean hasRemaining()
{
return mByteBuffer.hasRemaining();
}
/**
* Returns a copy of the byte array backing this buffer
*/
public ByteBuffer get()
{
return mByteBuffer;
// return ByteBuffer.wrap( Arrays.copyOf( mByteBuffer.array(), mSizeInBytes ) );
}
/**
* Clear the bytes from the underlying buffer and reset the pointer to 0.
*/
public void reset()
{
// mByteBuffer.clear();
mByteBuffer = ByteBuffer.allocate( mSizeInBytes );
mByteBuffer.order( ByteOrder.LITTLE_ENDIAN );
}
}

View File

@@ -1,86 +0,0 @@
/*******************************************************************************
* SDR Trunk
* Copyright (C) 2014 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
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>
******************************************************************************/
package buffer;
/**
* Implements a FIFO circular buffer for floats that provides access
* to each sample by index number, where index 0 is the newest/latest
* complex sample and index (length - 1) is the oldest sample in the buffer.
*/
public class FloatTappedCircularBuffer
{
private Float[] mBuffer;
private int mBufferPointer = 0;
public FloatTappedCircularBuffer( int length )
{
mBuffer = new Float[ length ];
//Pre-load the buffer with 0-valued samples
for( int x = 0; x < length; x++ )
{
mBuffer[ x ] = Float.valueOf( 0.0f );
}
}
/**
* Adds the sample to the buffer and removes the oldest sample
* @param sample
*/
public void add( Float sample )
{
mBuffer[ mBufferPointer++ ] = sample;
//Reset the buffer pointer once it points past the end of the buffer
if( mBufferPointer >= mBuffer.length )
{
mBufferPointer = 0;
}
}
/**
* Retrieves a sample currently in the buffer by index position.
*
* Index 0 is the newest/latest sample in the buffer and index (length - 1)
* is the oldest.
*
* Note: the buffer is preloaded with complex samples of 0,0 value.
*
* @param index where 0 is the newest/latest sample and length-1 is the oldest
* @return complex sample from the buffer.
* @throws ArrayIndexOutOfBoundsException if you attempt to access a sample
* outside of the buffer size
*/
public Float get( int index )
{
/* Since the samples are stored in a forward fashion, we have to access
* the samples in reverse to comply with the access contract, where
* index 0 is the newest and index (length -1) is the oldest, all
* relative to the current buffer pointer */
int pointer = mBuffer.length - 1 + mBufferPointer - index;
if( pointer >= mBuffer.length )
{
pointer -= mBuffer.length;
}
return mBuffer[ pointer ];
}
}

View File

@@ -1,69 +0,0 @@
/*******************************************************************************
* SDR Trunk
* Copyright (C) 2014 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
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>
******************************************************************************/
package buffer;
import java.nio.ByteBuffer;
import java.nio.ByteOrder;
import sample.Broadcaster;
import sample.Listener;
public class FloatToByteBufferAssembler implements Listener<Float>
{
private Broadcaster<ByteBuffer> mBroadcaster = new Broadcaster<ByteBuffer>();
private int mBufferSize = 0;
private ByteBuffer mBuffer;
public FloatToByteBufferAssembler( int bufferSize )
{
mBufferSize = bufferSize;
resetBuffer();
}
public void addByteBufferListener( Listener<ByteBuffer> listener )
{
mBroadcaster.addListener( listener );
}
public void removeByteBufferListener( Listener<ByteBuffer> listener )
{
mBroadcaster.removeListener( listener );
}
private void resetBuffer()
{
mBuffer = ByteBuffer.allocate( mBufferSize );
mBuffer.order( ByteOrder.BIG_ENDIAN );
}
@Override
public void receive( Float sample )
{
mBuffer.putShort( Float.valueOf( sample ).shortValue() );
if( mBuffer.position() >= mBufferSize )
{
//Buffer is full ... send it
mBroadcaster.receive( mBuffer );
//Reset the buffer
resetBuffer();
}
}
}

View File

@@ -1,59 +0,0 @@
/*******************************************************************************
* SDR Trunk
* Copyright (C) 2014 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
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>
******************************************************************************/
package buffer;
import java.nio.ByteBuffer;
import java.nio.ByteOrder;
import java.util.Enumeration;
import sample.complex.Complex;
import source.mixer.MixerChannel;
public class StereoByteBuffer implements Enumeration<Complex>
{
private ByteBuffer mByteBuffer;
public StereoByteBuffer( byte[] bytes, int frames )
{
mByteBuffer = ByteBuffer.wrap( bytes );
mByteBuffer.order( ByteOrder.LITTLE_ENDIAN );
}
public byte[] array()
{
return mByteBuffer.array();
}
public ByteBuffer getChannel( MixerChannel channel )
{
return StereoToMonoByteBufferConverter.getChannel( mByteBuffer, channel );
}
@Override
public boolean hasMoreElements()
{
return mByteBuffer.hasRemaining();
}
@Override
public Complex nextElement()
{
return new Complex( (float)mByteBuffer.getShort(),
(float)mByteBuffer.getShort() );
}
}

View File

@@ -1,24 +0,0 @@
/*******************************************************************************
* SDR Trunk
* Copyright (C) 2014 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
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>
******************************************************************************/
package buffer;
public interface StereoByteBufferListener
{
public void receive( StereoByteBuffer buffer );
}

View File

@@ -1,32 +0,0 @@
/*******************************************************************************
* SDR Trunk
* Copyright (C) 2014 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
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>
******************************************************************************/
package buffer;
public interface StereoByteBufferProvider
{
/**
* Adds a sample listener to receive samples
*/
public void addStereoByteBufferListener( StereoByteBufferListener listener );
/**
* Removes the sample listener, if it is currently registered as a listener
*/
public void removeStereoByteBufferListener( StereoByteBufferListener listener );
}

View File

@@ -1,58 +0,0 @@
/*******************************************************************************
* SDR Trunk
* Copyright (C) 2014 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
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>
******************************************************************************/
package buffer;
import java.nio.ByteBuffer;
import java.nio.ByteOrder;
import source.mixer.MixerChannel;
public class StereoToMonoByteBufferConverter
{
public static ByteBuffer getChannel( ByteBuffer buffer, MixerChannel channel )
{
byte[] channelBuffer = new byte[ buffer.capacity() / 2 ];
int channelBufferPointer = 0;
if( channel == MixerChannel.RIGHT )
{
//throw away the first two bytes
buffer.get();
buffer.get();
}
while( channelBufferPointer < channelBuffer.length )
{
if( buffer.hasRemaining() )
{
channelBuffer[ channelBufferPointer++ ] = buffer.get();
channelBuffer[ channelBufferPointer++ ] = buffer.get();
}
if( buffer.hasRemaining() )
{
buffer.get();
buffer.get();
}
}
return ByteBuffer.wrap( channelBuffer ).order( ByteOrder.LITTLE_ENDIAN );
}
}

View File

@@ -17,14 +17,24 @@
******************************************************************************/ ******************************************************************************/
package controller; package controller;
import playlist.PlaylistManager;
public abstract class ConfigurableNode extends BaseNode public abstract class ConfigurableNode extends BaseNode
{ {
private static final long serialVersionUID = 1L; private static final long serialVersionUID = 1L;
public ConfigurableNode( Object object ) private PlaylistManager mPlaylistManager;
public ConfigurableNode( PlaylistManager playlistManager, Object object )
{ {
super( object ); super( object );
mPlaylistManager = playlistManager;
}
protected PlaylistManager getPlaylistManager()
{
return mPlaylistManager;
} }
/** /**
@@ -32,7 +42,7 @@ public abstract class ConfigurableNode extends BaseNode
*/ */
public void save() public void save()
{ {
getModel().getResourceManager().getPlaylistManager().save(); mPlaylistManager.save();
BaseNode parent = (BaseNode)getParent(); BaseNode parent = (BaseNode)getParent();

View File

@@ -28,9 +28,14 @@ import javax.swing.tree.DefaultTreeModel;
import javax.swing.tree.MutableTreeNode; import javax.swing.tree.MutableTreeNode;
import javax.swing.tree.TreePath; import javax.swing.tree.TreePath;
import map.IconManager;
import module.decode.DecoderType; import module.decode.DecoderType;
import playlist.PlaylistManager;
import playlist.PlaylistNode; import playlist.PlaylistNode;
import settings.SettingsManager;
import source.SourceManager;
import source.recording.RecordingGroupNode;
import source.tuner.Tuner; import source.tuner.Tuner;
import source.tuner.TunerGroupNode; import source.tuner.TunerGroupNode;
import source.tuner.TunerNode; import source.tuner.TunerNode;
@@ -39,14 +44,14 @@ import controller.channel.Channel;
import controller.channel.ChannelModel; import controller.channel.ChannelModel;
import controller.channel.ChannelNode; import controller.channel.ChannelNode;
import controller.channel.ChannelProcessingManager;
public class ConfigurationControllerModel extends DefaultTreeModel public class ConfigurationControllerModel extends DefaultTreeModel
{ {
private static final long serialVersionUID = 1L; private static final long serialVersionUID = 1L;
private JTree mTree; private JTree mTree;
private ResourceManager mResourceManager;
private ArrayList<TunerSelectionListener> mTunerSelectionListeners = private ArrayList<TunerSelectionListener> mTunerSelectionListeners =
new ArrayList<TunerSelectionListener>(); new ArrayList<TunerSelectionListener>();
@@ -54,7 +59,11 @@ public class ConfigurationControllerModel extends DefaultTreeModel
private TunerGroupNode mTunerGroupNode; private TunerGroupNode mTunerGroupNode;
// private RecordingGroupNode mRecordingGroupNode; // private RecordingGroupNode mRecordingGroupNode;
private IconManager mIconManagerFrame; private ChannelModel mChannelModel;
private ChannelProcessingManager mChannelProcessingManager;
private PlaylistManager mPlaylistManager;
private SettingsManager mSettingsManager;
private SourceManager mSourceManager;
private ChannelModel mChannelModel; private ChannelModel mChannelModel;
/** /**
@@ -64,13 +73,20 @@ public class ConfigurationControllerModel extends DefaultTreeModel
* work well with the JTree as the system view. * work well with the JTree as the system view.
*/ */
public ConfigurationControllerModel( ChannelModel channelModel, public ConfigurationControllerModel( ChannelModel channelModel,
ResourceManager resourceManager ) ChannelProcessingManager channelProcessingManager,
PlaylistManager playlistManager,
SettingsManager settingsManager,
SourceManager sourceManager )
{ {
super( new BaseNode( null ) ); super( new BaseNode( null ) );
mChannelModel = channelModel; mChannelModel = channelModel;
mResourceManager = resourceManager; mChannelModel = channelModel;
mChannelProcessingManager = channelProcessingManager;
mPlaylistManager = playlistManager;
mSettingsManager = settingsManager;
mSourceManager = sourceManager;
/** /**
* Give the root node a reference to this model, so that all nodes can * Give the root node a reference to this model, so that all nodes can
@@ -84,23 +100,6 @@ public class ConfigurationControllerModel extends DefaultTreeModel
return mTree; return mTree;
} }
public void showIconManager()
{
if( mIconManagerFrame == null )
{
mIconManagerFrame = new IconManager( mResourceManager, mTree );
mResourceManager.getSettingsManager().addListener( mIconManagerFrame );
}
if( !mIconManagerFrame.isVisible() )
{
mIconManagerFrame.setVisible( true );
}
mIconManagerFrame.toFront();
}
/** /**
* init() gets invoked manually/externally, after all of the references * init() gets invoked manually/externally, after all of the references
* are established in the constructor * are established in the constructor
@@ -124,7 +123,8 @@ public class ConfigurationControllerModel extends DefaultTreeModel
/** /**
* Add the playlist node * Add the playlist node
*/ */
mPlaylistNode = new PlaylistNode(); mPlaylistNode = new PlaylistNode( mChannelModel, mChannelProcessingManager,
mPlaylistManager, mSettingsManager, mSourceManager );
insertNodeInto( mPlaylistNode, (MutableTreeNode)root, 1 ); insertNodeInto( mPlaylistNode, (MutableTreeNode)root, 1 );
mPlaylistNode.loadPlaylist(); mPlaylistNode.loadPlaylist();
} }
@@ -137,11 +137,6 @@ public class ConfigurationControllerModel extends DefaultTreeModel
} }
} }
public ResourceManager getResourceManager()
{
return mResourceManager;
}
public void setTree( JTree tree ) public void setTree( JTree tree )
{ {
mTree = tree; mTree = tree;
@@ -149,11 +144,13 @@ public class ConfigurationControllerModel extends DefaultTreeModel
private void addTuners( TunerGroupNode parent ) private void addTuners( TunerGroupNode parent )
{ {
List<Tuner> tuners = mResourceManager.getTunerManager().getTuners(); List<Tuner> tuners = mSourceManager.getTunerManager().getTuners();
for( Tuner tuner: tuners ) for( Tuner tuner: tuners )
{ {
TunerNode child = new TunerNode( mChannelModel, tuner ); TunerNode child = new TunerNode( mChannelModel,
mChannelProcessingManager, mPlaylistManager, mSettingsManager,
tuner );
insertNodeInto( child, parent, parent.getChildCount() ); insertNodeInto( child, parent, parent.getChildCount() );

View File

@@ -33,8 +33,10 @@ import module.decode.event.CallEventPanel;
import module.decode.event.MessageActivityPanel; import module.decode.event.MessageActivityPanel;
import module.decode.state.ChannelList; import module.decode.state.ChannelList;
import net.miginfocom.swing.MigLayout; import net.miginfocom.swing.MigLayout;
import playlist.PlaylistEditor;
import playlist.PlaylistManager; import playlist.PlaylistManager;
import settings.SettingsManager; import settings.SettingsManager;
import source.SourceManager;
import spectrum.ChannelSpectrumPanel; import spectrum.ChannelSpectrumPanel;
import audio.AudioManager; import audio.AudioManager;
import audio.AudioPanel; import audio.AudioPanel;
@@ -53,15 +55,16 @@ public class ControllerPanel extends JPanel
private CallEventPanel mCallEventPanel; private CallEventPanel mCallEventPanel;
private MessageActivityPanel mMessageActivityPanel = private MessageActivityPanel mMessageActivityPanel;
new MessageActivityPanel();
private ChannelSpectrumPanel mChannelSpectrumPanel; private ChannelSpectrumPanel mChannelSpectrumPanel;
private JideTabbedPane mTabbedPane; private PlaylistEditor mPlaylistEditor;
private JideTabbedPane mTabbedPane;
protected ConfigurationTreePanel mSystemControlViewPanel; protected ConfigurationTreePanel mSystemControlViewPanel;
protected ConfigurationEditor mConfigurationEditor; protected OldConfigurationEditor mConfigurationEditor;
protected JideSplitPane mSystemControlSplitPane; protected JideSplitPane mSystemControlSplitPane;
protected JTable mChannelActivityTable = new JTable(); protected JTable mChannelActivityTable = new JTable();
@@ -78,19 +81,29 @@ public class ControllerPanel extends JPanel
ChannelProcessingManager channelProcessingManager, ChannelProcessingManager channelProcessingManager,
MapService mapService, MapService mapService,
PlaylistManager playlistManager, PlaylistManager playlistManager,
SettingsManager settingsManager ) SettingsManager settingsManager,
SourceManager sourceManager )
{ {
mChannelModel = channelModel; mChannelModel = channelModel;
mController = controller; mController = controller;
mSettingsManager = settingsManager; mSettingsManager = settingsManager;
mAudioPanel = new AudioPanel( mSettingsManager, audioManager ); mAudioPanel = new AudioPanel( mSettingsManager, sourceManager, audioManager );
mMapPanel = new MapPanel( mapService, mSettingsManager, channelProcessingManager ); mMapPanel = new MapPanel( mapService, mSettingsManager );
mCallEventPanel = new CallEventPanel( mSettingsManager ); mMessageActivityPanel = new MessageActivityPanel( channelProcessingManager );
mChannelStateList = new ChannelList( playlistManager, mSettingsManager ); mCallEventPanel = new CallEventPanel( mSettingsManager,
channelProcessingManager );
mChannelSpectrumPanel = new ChannelSpectrumPanel( mSettingsManager,
channelProcessingManager );
mChannelStateList = new ChannelList( channelModel, channelProcessingManager,
playlistManager, mSettingsManager );
mPlaylistEditor = new PlaylistEditor( channelModel, playlistManager, sourceManager );
init(); init();
} }
@@ -102,7 +115,7 @@ public class ControllerPanel extends JPanel
"[grow,fill]") ); "[grow,fill]") );
//System Configuration View and Editor //System Configuration View and Editor
mConfigurationEditor = new ConfigurationEditor(); mConfigurationEditor = new OldConfigurationEditor();
mSystemControlViewPanel = new ConfigurationTreePanel( mController ); mSystemControlViewPanel = new ConfigurationTreePanel( mController );
mSystemControlViewPanel.addTreeSelectionListener( mConfigurationEditor ); mSystemControlViewPanel.addTreeSelectionListener( mConfigurationEditor );
@@ -112,8 +125,6 @@ public class ControllerPanel extends JPanel
mSystemControlSplitPane.add( mSystemControlViewPanel ); mSystemControlSplitPane.add( mSystemControlViewPanel );
mSystemControlSplitPane.add( mConfigurationEditor ); mSystemControlSplitPane.add( mConfigurationEditor );
mChannelSpectrumPanel = new ChannelSpectrumPanel( mSettingsManager );
//Tabbed View - configuration, calls, messages, map //Tabbed View - configuration, calls, messages, map
mTabbedPane = new JideTabbedPane(); mTabbedPane = new JideTabbedPane();
mTabbedPane.setFont( this.getFont() ); mTabbedPane.setFont( this.getFont() );
@@ -123,9 +134,7 @@ public class ControllerPanel extends JPanel
mTabbedPane.addTab( "Events", mCallEventPanel ); mTabbedPane.addTab( "Events", mCallEventPanel );
mTabbedPane.addTab( "Messages", mMessageActivityPanel ); mTabbedPane.addTab( "Messages", mMessageActivityPanel );
JTable channelsTable = new JTable( mChannelModel ); mTabbedPane.addTab( "Playlist", mPlaylistEditor );
JScrollPane channelsScroller = new JScrollPane( channelsTable );
mTabbedPane.addTab( "Channels", channelsScroller );
/** /**
* Change listener to enable/disable the channel spectrum display * Change listener to enable/disable the channel spectrum display

View File

@@ -26,7 +26,7 @@ import javax.swing.JTree;
import javax.swing.event.TreeSelectionEvent; import javax.swing.event.TreeSelectionEvent;
import javax.swing.event.TreeSelectionListener; import javax.swing.event.TreeSelectionListener;
public class ConfigurationEditor extends JPanel public class OldConfigurationEditor extends JPanel
implements TreeSelectionListener implements TreeSelectionListener
{ {
private static final long serialVersionUID = 1L; private static final long serialVersionUID = 1L;
@@ -34,7 +34,7 @@ public class ConfigurationEditor extends JPanel
/** /**
* Host for configuration editor display panels * Host for configuration editor display panels
*/ */
public ConfigurationEditor() public OldConfigurationEditor()
{ {
init(); init();
} }

View File

@@ -1,177 +0,0 @@
/*******************************************************************************
* SDR Trunk
* Copyright (C) 2014 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
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>
******************************************************************************/
package controller;
import map.MapService;
import module.log.EventLogManager;
import playlist.PlaylistManager;
import record.RecorderManager;
import settings.SettingsManager;
import source.SourceManager;
import source.recording.RecordingSourceManager;
import source.tuner.TunerManager;
import audio.AudioManager;
import controller.channel.ChannelModel;
/**
* Manager for system wide resources
*/
public class ResourceManager
{
private AudioManager mAudioManager;
private EventLogManager mEventLogManager;
private PlaylistManager mPlaylistManager;
private RecorderManager mRecorderManager;
private RecordingSourceManager mRecordingSourceManager;
private SettingsManager mSettingsManager;
private SourceManager mSourceManager;
private TunerManager mTunerManager;
private ConfigurationControllerModel mController;
private MapService mMapService;
private ThreadPoolManager mThreadPoolManager;
public ResourceManager( PlaylistManager playlistManager,
ThreadPoolManager threadPoolManager,
ChannelModel channelModel )
{
this( threadPoolManager,
new SettingsManager(),
playlistManager,
new EventLogManager(),
channelModel );
}
public ResourceManager( ThreadPoolManager threadPoolManager,
SettingsManager settingsManager,
PlaylistManager playlistManager,
EventLogManager eventLogManager,
ChannelModel channelModel )
{
mThreadPoolManager = threadPoolManager;
mSettingsManager = settingsManager;
mPlaylistManager = playlistManager;
mEventLogManager = eventLogManager;
/**
* ChannelManager requires a reference to the ResourceManager so that
* channel processing chains can access system wide resources
*/
mAudioManager = new AudioManager( mThreadPoolManager );
mRecorderManager = new RecorderManager( mThreadPoolManager );
mSourceManager = new SourceManager( this );
mRecordingSourceManager = new RecordingSourceManager( this );
mTunerManager = new TunerManager( this );
mController = new ConfigurationControllerModel( channelModel, this );
mMapService = new MapService( this );
}
public AudioManager getAudioManager()
{
return mAudioManager;
}
public void setAudioManager( AudioManager audioManager )
{
mAudioManager = audioManager;
}
public ConfigurationControllerModel getController()
{
return mController;
}
public ThreadPoolManager getThreadPoolManager()
{
return mThreadPoolManager;
}
public void setController( ConfigurationControllerModel controller )
{
mController = controller;
}
public TunerManager getTunerManager()
{
return mTunerManager;
}
public MapService getMapService()
{
return mMapService;
}
public SettingsManager getSettingsManager()
{
return mSettingsManager;
}
public void setSettingsManager( SettingsManager manager )
{
mSettingsManager = manager;
}
public PlaylistManager getPlaylistManager()
{
return mPlaylistManager;
}
public void setPlaylistManager( PlaylistManager aliasManager )
{
mPlaylistManager = aliasManager;
}
public EventLogManager getEventLogManager()
{
return mEventLogManager;
}
public void setEventLogManager( EventLogManager eventLogManager )
{
mEventLogManager = eventLogManager;
}
public RecorderManager getRecorderManager()
{
return mRecorderManager;
}
public void setRecorderManager( RecorderManager recorderManager )
{
mRecorderManager = recorderManager;
}
public SourceManager getSourceManager()
{
return mSourceManager;
}
public void setSourceManager( SourceManager sourceManager )
{
mSourceManager = sourceManager;
}
public RecordingSourceManager getRecordingSourceManager()
{
return mRecordingSourceManager;
}
public void setRecordingSourceManager( RecordingSourceManager manager )
{
mRecordingSourceManager = manager;
}
}

View File

@@ -17,23 +17,22 @@
******************************************************************************/ ******************************************************************************/
package controller.channel; package controller.channel;
import controller.Editor;
public abstract class AbstractChannelEditor extends Editor public abstract class AbstractChannelEditor extends ChannelConfigurationEditor
{ {
private static final long serialVersionUID = 1L; private static final long serialVersionUID = 1L;
protected ChannelNode mChannelNode; protected Channel mChannel;
public AbstractChannelEditor( ChannelNode channel ) public AbstractChannelEditor( Channel channel )
{ {
super(); super();
mChannelNode = channel; mChannel = channel;
} }
public ChannelNode getChannelNode() public Channel getChannel()
{ {
return mChannelNode; return mChannel;
} }
public abstract void save(); public abstract void save();

View File

@@ -1,6 +1,6 @@
/******************************************************************************* /*******************************************************************************
* SDR Trunk * 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 * 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 * it under the terms of the GNU General Public License as published by
@@ -17,35 +17,21 @@
******************************************************************************/ ******************************************************************************/
package controller.channel; package controller.channel;
import java.util.List;
import javax.xml.bind.annotation.XmlAttribute; import javax.xml.bind.annotation.XmlAttribute;
import javax.xml.bind.annotation.XmlElement; import javax.xml.bind.annotation.XmlElement;
import javax.xml.bind.annotation.XmlRootElement; import javax.xml.bind.annotation.XmlRootElement;
import javax.xml.bind.annotation.XmlSeeAlso; import javax.xml.bind.annotation.XmlSeeAlso;
import javax.xml.bind.annotation.XmlTransient; import javax.xml.bind.annotation.XmlTransient;
import message.Message;
import module.Module;
import module.ProcessingChain;
import module.decode.DecoderFactory;
import module.decode.config.AuxDecodeConfiguration; import module.decode.config.AuxDecodeConfiguration;
import module.decode.config.DecodeConfigFactory; import module.decode.config.DecodeConfigFactory;
import module.decode.config.DecodeConfiguration; import module.decode.config.DecodeConfiguration;
import module.decode.event.CallEventModel;
import module.decode.event.MessageActivityModel;
import module.decode.state.ChannelState;
import module.log.MessageEventLogger;
import module.log.config.EventLogConfiguration; import module.log.config.EventLogConfiguration;
import org.slf4j.Logger; import org.slf4j.Logger;
import org.slf4j.LoggerFactory; import org.slf4j.LoggerFactory;
import record.RecorderManager;
import record.RecorderType;
import record.config.RecordConfiguration; import record.config.RecordConfiguration;
import source.Source;
import source.SourceException;
import source.SourceType; import source.SourceType;
import source.config.SourceConfigFactory; import source.config.SourceConfigFactory;
import source.config.SourceConfigRecording; import source.config.SourceConfigRecording;
@@ -53,26 +39,24 @@ import source.config.SourceConfigTuner;
import source.config.SourceConfiguration; import source.config.SourceConfiguration;
import source.tuner.TunerChannel; import source.tuner.TunerChannel;
import source.tuner.TunerChannel.Type; import source.tuner.TunerChannel.Type;
import alias.AliasList;
import audio.metadata.Metadata; import source.tuner.frequency.FrequencyChangeEvent;
import audio.metadata.MetadataType; import source.tuner.frequency.FrequencyChangeEvent.Event;
import controller.ResourceManager; import source.tuner.frequency.IFrequencyChangeProcessor;
import controller.config.Configuration; import controller.config.Configuration;
import filter.FilterSet;
@XmlSeeAlso( { Configuration.class } ) @XmlSeeAlso( { Configuration.class } )
@XmlRootElement( name = "channel" ) @XmlRootElement( name = "channel" )
public class Channel extends Configuration public class Channel extends Configuration implements IFrequencyChangeProcessor
{ {
private final static Logger mLog = LoggerFactory.getLogger( Channel.class ); private final static Logger mLog = LoggerFactory.getLogger( Channel.class );
private static final boolean DISABLED = false; // Standard channels are persisted and traffic channels are temporary
public enum ChannelType { STANDARD, TRAFFIC };
public enum ChannelType
{ // Static unique channel identifier tracking
STANDARD, private static int UNIQUE_ID = 0;
TRAFFIC
};
private DecodeConfiguration mDecodeConfiguration = private DecodeConfiguration mDecodeConfiguration =
DecodeConfigFactory.getDefaultDecodeConfiguration(); DecodeConfigFactory.getDefaultDecodeConfiguration();
@@ -84,30 +68,33 @@ public class Channel extends Configuration
new EventLogConfiguration(); new EventLogConfiguration();
private RecordConfiguration mRecordConfiguration = new RecordConfiguration(); private RecordConfiguration mRecordConfiguration = new RecordConfiguration();
private ResourceManager mResourceManager;
private String mAliasListName; private String mAliasListName;
private String mSystem; private String mSystem = "System";
private String mSite; private String mSite = "Site";
private String mName; private String mName = "Channel";
private boolean mEnabled; private boolean mEnabled;
private boolean mSelected; private boolean mSelected;
private ChannelType mChannelType;
private ChannelState mChannelState; private TunerChannel mTunerChannel = null;
private CallEventModel mCallEventModel;
private MessageActivityModel mMessageActivityModel;
private MessageEventLogger mEventLogger;
private ProcessingChain mProcessingChain;
private long mTrafficChannelTimeout = private ChannelType mChannelType = ChannelType.STANDARD;
DecodeConfiguration.DEFAULT_CALL_TIMEOUT_SECONDS;
private int mChannelID;
private int mChannelFrequencyCorrection = 0;
/** /**
* Constructs a new standard channel with a default name of "New Channel" * Channel represents a complete set of configurations needed to setup and
* manage a processing chain and/or manage as a set of business objects that
* can be displayed in graphical components.
*
* @param channelName
* @param channelType
*/ */
public Channel() public Channel( String channelName, ChannelType channelType )
{ {
this( "New Channel", ChannelType.STANDARD ); this( channelName );
mChannelType = channelType;
} }
/** /**
@@ -115,103 +102,33 @@ public class Channel extends Configuration
*/ */
public Channel( String channelName ) public Channel( String channelName )
{ {
this( channelName, ChannelType.STANDARD ); this();
}
/**
* Constructs a new channel with the specified channel name and type.
*
* @param channelName
* @param channelType
*/
public Channel( String channelName, ChannelType channelType )
{
mName = channelName; mName = channelName;
mChannelType = channelType;
} }
/** /**
* Indicates if the channel has Automatic or Direct Frequency Control * Constructs a new standard channel with a default name of "Channel"
*/
public boolean hasFrequencyControl()
{
return mProcessingChain != null &&
mProcessingChain.hasFrequencyCorrectionControl();
}
public long getFrequencyCorrection()
{
if( hasFrequencyControl() )
{
return mProcessingChain.getFrequencyCorrectionControl().getErrorCorrection();
}
return 0;
}
/**
* Sets the channel state traffic channel call end timer to the specified
* value.
*/
public void setTrafficChannelTimeout( long milliseconds )
{
mTrafficChannelTimeout = milliseconds;
if( mChannelState != null )
{
mChannelState.setTrafficChannelTimeout( milliseconds );
}
}
/**
* Sets the resource manager responsible for this channel and registers
* the channel manager as a listener to this channel. Fires channel add
* channel event to the newly added channel manager channel listener.
*
* Note: resource manager instance is applied after object construction
* since we construct the channel objects from the xml playlist
*/ */
//TODO: remove this //TODO: remove this
public void setResourceManager( ResourceManager resourceManager ) public Channel()
{ {
mResourceManager = resourceManager; mChannelID = UNIQUE_ID++;
/* If we're enabled, fire enable changed event to get processing started */
if( mEnabled )
{
enableChanged();
}
} }
//TODO: remove this //TODO: remove this
@XmlTransient
public ResourceManager getResourceManager()
{
return mResourceManager;
}
/** /**
* Returns the processing chain for this channel. If the processing chain * Unique identifier for this channel. Value is transient (not persisted).
* is not currently constructed and running, this method will return null.
*/ */
@XmlTransient @XmlTransient
public ProcessingChain getProcessingChain() public int getChannelID()
{ {
return mProcessingChain; return mChannelID;
} }
/** /**
* Indicates if this channel has a processing chain constructed and it * Indicates if this channel has been selected for prioritized audio output
* is processing. * and display of processing chain products
*/
public boolean isProcessing()
{
return mProcessingChain != null && mProcessingChain.processing();
}
/**
* Indicates if this channel has been selected for audio output
*/ */
@XmlTransient @XmlTransient
public boolean isSelected() public boolean isSelected()
@@ -224,100 +141,12 @@ public class Channel extends Configuration
mSelected = selected; mSelected = selected;
} }
@XmlTransient
public CallEventModel getCallEventModel()
{
return mCallEventModel;
}
/**
* Returns the MessageEventLogger for this processing chain
*/
@XmlTransient
public MessageEventLogger getEventLogger()
{
return mEventLogger;
}
/**
* Sets the MessageEventLogger for this processing chain
*/
public void setEventLogger( MessageEventLogger eventLogger )
{
mEventLogger = eventLogger;
}
@XmlTransient
public MessageActivityModel getMessageActivityModel()
{
return mMessageActivityModel;
}
@XmlTransient
public ChannelState getChannelState()
{
return mChannelState;
}
@XmlTransient @XmlTransient
public ChannelType getChannelType() public ChannelType getChannelType()
{ {
return mChannelType; return mChannelType;
} }
/**
* Orderly shutdown method when this channel is going to be deleted.
*/
public void dispose()
{
setEnabled( DISABLED );
}
/**
* Returns a full channel name containing the system, site and channel name.
*/
public String getChannelDisplayName()
{
StringBuilder sb = new StringBuilder();
sb.append( ( mSystem == null ? "-" : mSystem ) );
sb.append( ( mSite == null ? "-" : mSite ) );
sb.append( mName );
return sb.toString();
}
/**
* Returns the tuner channel requirement for this channel when the source
* configuration specifies a tuner and frequency as the source for this
* channel.
*
* If the source configuration is anything else, this method returns null.
*/
public TunerChannel getTunerChannel()
{
TunerChannel retVal = null;
if( mSourceConfiguration.getSourceType() == SourceType.TUNER )
{
SourceConfigTuner config = (SourceConfigTuner)mSourceConfiguration;
retVal = new TunerChannel( Type.LOCKED, config.getFrequency(),
mDecodeConfiguration.getDecoderType().getChannelBandwidth() );
}
else if( mSourceConfiguration.getSourceType() == SourceType.RECORDING )
{
SourceConfigRecording config =
(SourceConfigRecording)mSourceConfiguration;
retVal = new TunerChannel( Type.LOCKED, config.getFrequency(),
mDecodeConfiguration.getDecoderType().getChannelBandwidth() );
}
return retVal;
}
/** /**
* Returns the owning system for this channel. * Returns the owning system for this channel.
*/ */
@@ -343,7 +172,7 @@ public class Channel extends Configuration
@XmlAttribute( name = "site" ) @XmlAttribute( name = "site" )
public String getSite() public String getSite()
{ {
return mSite; return mSite;
} }
public void setSite( String site ) public void setSite( String site )
@@ -356,37 +185,65 @@ public class Channel extends Configuration
return mSite != null; return mSite != null;
} }
/** /**
* Default display string for this channel -- the channel name. * Returns the name of this channel.
*/ */
public String toString() @XmlAttribute( name = "name" )
public String getName()
{ {
return mName; return mName;
} }
/**
* Sets the name of this channel.
*/
public void setName( String name )
{
mName = name;
}
/**
* Default display string for this channel: SYSTEM_SITE_NAME
*/
public String toString()
{
StringBuilder sb = new StringBuilder();
sb.append( hasSystem() ? getSystem() : "SYSTEM" );
sb.append( "_" );
sb.append( hasSite() ? getSite() : "SITE" );
sb.append( "_" );
sb.append( getName() );
return sb.toString();
}
/** /**
* Indicates if this channel is enabled for processing. * Indicates if this channel is enabled for processing.
*/ */
@XmlAttribute @XmlAttribute( name = "enabled" )
public boolean getEnabled() public boolean getEnabled()
{ {
return mEnabled; return mEnabled;
} }
/** /**
* Enables/disables this channel for processing. Automatically starts or * Indicates if this channel will automatically start processing on
* stops channel processing in response to this change. * application startup or if this channel is currently processing after
* application startup.
*
* Note: this method is package private and is intended to be managed
* by a co-package central processing manager
*
* @see controller.ChannelProcessingManager
*/ */
public void setEnabled( boolean enabled ) void setEnabled( boolean enabled )
{ {
mEnabled = enabled; mEnabled = enabled;
enableChanged();
} }
/** /**
* Returns the alias list that is used by this channel for looking up alias * Returns the alias list that is used by this channel for looking up alias
* values for the various identifiers produced by the decoder. * values for the various identifiers produced by the decoder(s).
*/ */
@XmlElement( name = "alias_list_name" ) @XmlElement( name = "alias_list_name" )
public String getAliasListName() public String getAliasListName()
@@ -404,7 +261,7 @@ public class Channel extends Configuration
} }
/** /**
* Gets the decoder configuration used by this channel * Gets the primary decoder configuration used by this channel
*/ */
@XmlElement( name = "decode_configuration" ) @XmlElement( name = "decode_configuration" )
public DecodeConfiguration getDecodeConfiguration() public DecodeConfiguration getDecodeConfiguration()
@@ -413,7 +270,7 @@ public class Channel extends Configuration
} }
/** /**
* Sets the decoder configuration used by this channel * Sets the primary decoder configuration used by this channel
*/ */
public void setDecodeConfiguration( DecodeConfiguration config ) public void setDecodeConfiguration( DecodeConfiguration config )
{ {
@@ -421,7 +278,8 @@ public class Channel extends Configuration
} }
/** /**
* Gets the aux decoder configuration used by this channel * Gets the aux decoder configuration used by this channel. Aux decoders
* operate on demodulated audio
*/ */
@XmlElement( name = "aux_decode_configuration" ) @XmlElement( name = "aux_decode_configuration" )
public AuxDecodeConfiguration getAuxDecodeConfiguration() public AuxDecodeConfiguration getAuxDecodeConfiguration()
@@ -438,7 +296,8 @@ public class Channel extends Configuration
} }
/** /**
* Returns the source configuration for this channel. * Returns the source configuration for this channel. A channel source
* identifies where the processing chain will get source sample data from.
*/ */
@XmlElement( name = "source_configuration" ) @XmlElement( name = "source_configuration" )
public SourceConfiguration getSourceConfiguration() public SourceConfiguration getSourceConfiguration()
@@ -452,6 +311,10 @@ public class Channel extends Configuration
public void setSourceConfiguration( SourceConfiguration config ) public void setSourceConfiguration( SourceConfiguration config )
{ {
mSourceConfiguration = config; mSourceConfiguration = config;
//Clear the tune channel object so that it can be recreated if the
//source configuration changes
mTunerChannel = null;
} }
/** /**
@@ -489,252 +352,41 @@ public class Channel extends Configuration
} }
/** /**
* Returns the name of this channel. * Convenience method to construct a tuner channel object representing a
*/ * tuner or recording source frequency and bandwidth that can be used by
@XmlAttribute * application components for graphically representing this channel.
public String getName()
{
return mName;
}
/**
* Sets the name of this channel.
*/
public void setName( String name )
{
mName = name;
}
/**
* Responds to changes in the enabled setting by starting the processing
* change if the channel is now enabled, or stopping the procesing chain
* if it was already started.
*/
private void enableChanged()
{
if( mEnabled )
{
start();
}
else
{
stop();
}
}
/**
* Starts the channel processing chain.
*/
private void start()
{
if( mEnabled && mResourceManager != null )
{
setupChannelState();
try
{
setup();
mProcessingChain.start();
}
catch( SourceException se )
{
//Do nothing, we couldn't get a source for the channel
}
}
}
private void setupChannelState()
{
if( mChannelState == null )
{
mChannelState = new ChannelState( mResourceManager
.getThreadPoolManager(), mChannelType );
mChannelState.setTrafficChannelTimeout( mTrafficChannelTimeout );
}
}
/**
* Sets up the channel and prepares to start processing. Sets up the
* processing chain and requests a source.
* *
* @throws SourceException - if no source is available or if there is an * If the source configuration is not a tuner or recording, this method
* error obtaining a source * returns null.
*/ */
public void setup() throws SourceException @XmlTransient
{ public TunerChannel getTunerChannel()
setupProcessingChain(); {
setupSource(); if( mTunerChannel == null )
} {
if( mSourceConfiguration.getSourceType() == SourceType.TUNER )
{
SourceConfigTuner config = (SourceConfigTuner)mSourceConfiguration;
mTunerChannel = new TunerChannel( Type.LOCKED, config.getFrequency(),
mDecodeConfiguration.getDecoderType().getChannelBandwidth() );
}
else if( mSourceConfiguration.getSourceType() == SourceType.RECORDING )
{
SourceConfigRecording config =
(SourceConfigRecording)mSourceConfiguration;
mTunerChannel = new TunerChannel( Type.LOCKED, config.getFrequency(),
mDecodeConfiguration.getDecoderType().getChannelBandwidth() );
}
}
return mTunerChannel;
}
/** /**
* Setup recording options. Adds RecorderManager as a audio packet listener * Convenience method to indicate if any part of this channel is contained
* to receive and record decoded audio. * within the minimum and maximum frequency values.
*/
private void setupRecording()
{
List<RecorderType> recorders = mRecordConfiguration.getRecorders();
if( !recorders.isEmpty() )
{
if( recorders.contains( RecorderType.AUDIO ) )
{
mProcessingChain.addAudioPacketListener(
mResourceManager.getRecorderManager() );
}
/* Add baseband recorder */
if( ( recorders.contains( RecorderType.BASEBAND ) &&
mChannelType == ChannelType.STANDARD ) )
{
mProcessingChain.addModule( RecorderManager.getBasebandRecorder(
mResourceManager.getThreadPoolManager(), getChannelName() ) );
}
/* Add traffic channel baseband recorder */
if( recorders.contains( RecorderType.TRAFFIC_BASEBAND ) &&
mChannelType == ChannelType.TRAFFIC )
{
mProcessingChain.addModule( RecorderManager.getBasebandRecorder(
mResourceManager.getThreadPoolManager(), getChannelName() ) );
}
}
}
private String getChannelName()
{
StringBuilder sb = new StringBuilder();
sb.append( mSystem );
sb.append( "_" );
sb.append( mSite );
sb.append( "_" );
sb.append( mName );
return sb.toString();
}
private void setupLogging()
{
if( mProcessingChain != null )
{
String channelName = getChannelName();
List<Module> loggers = mResourceManager.getEventLogManager()
.getLoggers( mEventLogConfiguration, channelName );
if( !loggers.isEmpty() )
{
mProcessingChain.addModules( loggers );
}
}
}
private void setupProcessingChain()
{
if( mProcessingChain == null )
{
mProcessingChain = new ProcessingChain();
/* Get the optional alias list for the decode modules to use */
AliasList aliasList = mResourceManager.getPlaylistManager()
.getPlayist().getAliasDirectory().getAliasList( mAliasListName );
/* Add the channel state as a module */
mProcessingChain.addModule( mChannelState );
/* Processing Modules */
List<Module> modules = DecoderFactory.getModules( mChannelType,
mResourceManager, mDecodeConfiguration, mRecordConfiguration,
mAuxDecodeConfiguration, aliasList, mSystem,
mSite, mName );
mProcessingChain.addModules( modules );
/* Get message filters for the set of processing modules */
FilterSet<Message> messageFilter = DecoderFactory.getMessageFilters( modules );
/* Setup the message activity model and add message listeners */
mMessageActivityModel = new MessageActivityModel( messageFilter );
mProcessingChain.addMessageListener( mMessageActivityModel );
/* Add audio manager as listener for audio packets */
mProcessingChain.addAudioPacketListener(
mResourceManager.getAudioManager() );
/* Create the call event model to receive call events */
mCallEventModel = new CallEventModel();
mProcessingChain.addCallEventListener( mCallEventModel );
setupLogging();
setupRecording();
/* Inject channel metadata that will be inserted into audio packets
* for the recorder manager and streaming */
mProcessingChain.broadcast(
new Metadata( MetadataType.SYSTEM, mSystem ) );
mProcessingChain.broadcast(
new Metadata( MetadataType.SITE_ID, mSite ) );
mProcessingChain.broadcast(
new Metadata( MetadataType.CHANNEL_NAME, mName ) );
}
}
/**
* Attempts to obtain a source and apply it to the processing chain.
*
* @throws SourceException - if the processing chain is not setup or if
* there is an error produced while obtaining the source
*/
private void setupSource() throws SourceException
{
if( mProcessingChain != null )
{
Source source = mResourceManager.getSourceManager()
.getSource( getSourceConfiguration(), getDecodeConfiguration()
.getDecoderType().getChannelBandwidth() );
if( source != null )
{
mProcessingChain.setSource( source );
}
else
{
throw new SourceException( "Couldn't obtain tuner channel source" );
}
}
else
{
throw new SourceException( "Cannot obtain source for a null "
+ "processing chain - setup the processing chain first" );
}
}
/**
* Stops the channel processing chain
*/
private void stop()
{
if( !mEnabled && mProcessingChain != null )
{
fireChannelEvent( Event.CHANNEL_PROCESSING_STOPPED );
mProcessingChain.stop();
if( mChannelType == ChannelType.STANDARD )
{
mProcessingChain.dispose();
mProcessingChain = null;
}
mSelected = false;
}
}
/**
* Indicates if any part of this channel is contained within the
* minimum and maximum frequency values.
*/ */
public boolean isWithin( long minimum, long maximum ) public boolean isWithin( long minimum, long maximum )
{ {

View File

@@ -1,6 +1,7 @@
/******************************************************************************* /*******************************************************************************
* SDR Trunk * 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 * 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 * it under the terms of the GNU General Public License as published by
@@ -15,37 +16,29 @@
* You should have received a copy of the GNU General Public License * You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/> * along with this program. If not, see <http://www.gnu.org/licenses/>
******************************************************************************/ ******************************************************************************/
package controller; package controller.channel;
import javax.swing.JPanel; import javax.swing.JPanel;
import net.miginfocom.swing.MigLayout; public abstract class ChannelConfigurationEditor extends JPanel
import controller.channel.ChannelValidationException;
public abstract class Editor extends JPanel
{ {
private static final long serialVersionUID = 1L; private static final long serialVersionUID = 1L;
public Editor() /**
{ * Sets or resets the configuration editor components
setLayout( new MigLayout() ); */
} public abstract void setConfiguration( Channel channel );
public abstract void save();
public abstract void reset();
/** /**
* Override this method to allow the editor to inspect the argument for * Saves the contents of the editor components to the configuration
* valid configuration
*
* @param editor - any editor
*
* @throws ChannelValidationException if the configuration is not compatible
* with this editor's configuration. Supplies a validation text value for
* display to the user
*/ */
public void validate( Editor editor ) throws ChannelValidationException public abstract void save();
{
} /**
* Validates the contents of the editor components prior to saving the
* content to the configuration.
*
* @throws ConfigurationValidationException if the content is invalid
*/
public abstract void validateConfiguration() throws ConfigurationValidationException;
} }

View File

@@ -19,21 +19,17 @@ package controller.channel;
import java.awt.Color; import java.awt.Color;
import java.awt.ComponentOrientation; import java.awt.Component;
import java.awt.event.ActionEvent; import java.awt.event.ActionEvent;
import java.awt.event.ActionListener; import java.awt.event.ActionListener;
import java.util.Collections;
import java.util.List;
import javax.swing.DefaultComboBoxModel;
import javax.swing.JButton; import javax.swing.JButton;
import javax.swing.JCheckBox; import javax.swing.JCheckBox;
import javax.swing.JComboBox; import javax.swing.JComboBox;
import javax.swing.JLabel; import javax.swing.JLabel;
import javax.swing.JOptionPane; import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.JTextField; import javax.swing.JTextField;
import javax.swing.tree.DefaultTreeModel;
import javax.swing.tree.TreePath;
import module.decode.AuxDecodeComponentEditor; import module.decode.AuxDecodeComponentEditor;
import module.decode.DecodeComponentEditor; import module.decode.DecodeComponentEditor;
@@ -46,20 +42,21 @@ import org.slf4j.LoggerFactory;
import playlist.PlaylistManager; import playlist.PlaylistManager;
import record.RecordComponentEditor; import record.RecordComponentEditor;
import source.SourceComponentEditor; import source.SourceComponentEditor;
import source.SourceManager;
import alias.AliasList; import alias.AliasList;
import com.jidesoft.swing.JideTabbedPane; import com.jidesoft.swing.JideTabbedPane;
import controller.Editor; import controller.channel.ChannelEvent.Event;
public class ChannelEditor extends Editor implements ActionListener public class ChannelEditor extends JPanel
implements ActionListener, ChannelEventListener
{ {
private static final long serialVersionUID = 1L;
private final static Logger mLog = LoggerFactory.getLogger( ChannelEditor.class ); private final static Logger mLog = LoggerFactory.getLogger( ChannelEditor.class );
private static final long serialVersionUID = 1L; private ChannelConfigurationEditor mNameConfigurationEditor;
private DefaultTreeModel mTreeModel;
private ChannelNode mChannelNode;
private DecodeComponentEditor mDecodeEditor; private DecodeComponentEditor mDecodeEditor;
private AuxDecodeComponentEditor mAuxDecodeEditor; private AuxDecodeComponentEditor mAuxDecodeEditor;
private EventLogComponentEditor mEventLogEditor; private EventLogComponentEditor mEventLogEditor;
@@ -70,84 +67,63 @@ public class ChannelEditor extends Editor implements ActionListener
private JCheckBox mChannelEnabled = new JCheckBox(); private JCheckBox mChannelEnabled = new JCheckBox();
private JComboBox<AliasList> mComboAliasLists; private JComboBox<AliasList> mComboAliasLists;
private Channel mChannel;
private ChannelModel mChannelModel;
private PlaylistManager mPlaylistManager; private PlaylistManager mPlaylistManager;
private SourceManager mSourceManager;
public ChannelEditor( ChannelNode channel, PlaylistManager playlistManager ) public ChannelEditor( ChannelModel channelModel,
PlaylistManager playlistManager,
SourceManager sourceManager )
{ {
super(); super();
mChannelNode = channel; mChannelModel = channelModel;
mPlaylistManager = playlistManager; mPlaylistManager = playlistManager;
mSourceManager = sourceManager;
mNameConfigurationEditor = new NameConfigurationEditor(
mChannelModel, mPlaylistManager );
initGUI(); initGUI();
} }
public void setChannel( Channel channel )
{
mNameConfigurationEditor.setConfiguration( channel );
mChannel = channel;
}
private void initGUI() private void initGUI()
{ {
setLayout( new MigLayout( "fill,wrap 2", "[right,grow][grow]", "[][][][][grow][]" ) ); setLayout( new MigLayout( "fill,wrap 2", "[right,grow][grow]", "[][][][][grow][]" ) );
add( new JLabel( "Channel Configuration" ), "span, align center" ); add( new JLabel( "Channel Configuration" ), "span, align center" );
add( new JLabel( "Enabled:" ) ); add( new JLabel( "Enabled:" ), "wrap" );
mChannelEnabled.setSelected( add( mNameConfigurationEditor );
mChannelNode.getChannel().getEnabled() );
mChannelEnabled.setComponentOrientation( ComponentOrientation.RIGHT_TO_LEFT );
add( mChannelEnabled );
add( new JLabel( "Name:" ) );
mChannelName = new JTextField( mChannelNode.getChannel().getName() );
add( mChannelName, "growx,push" );
/**
* ComboBox: Alias Lists
*/
add( new JLabel( "Alias List:" ) );
mComboAliasLists = new JComboBox<AliasList>();
List<AliasList> lists = mChannelNode.getModel().getResourceManager()
.getPlaylistManager().getPlayist().getAliasDirectory().getAliasList();
Collections.sort( lists );
mComboAliasLists.setModel( new DefaultComboBoxModel<AliasList>(
lists.toArray( new AliasList[ lists.size() ] ) ) );
String aliasListName =
mChannelNode.getChannel().getAliasListName();
if( aliasListName != null )
{
AliasList selected = mChannelNode.getModel().getResourceManager()
.getPlaylistManager().getPlayist().getAliasDirectory()
.getAliasList( aliasListName );
mComboAliasLists.setSelectedItem( selected );
}
add( mComboAliasLists, "growx,push" );
JideTabbedPane tabs = new JideTabbedPane(); JideTabbedPane tabs = new JideTabbedPane();
tabs.setFont( this.getFont() ); tabs.setFont( this.getFont() );
tabs.setForeground( Color.BLACK ); tabs.setForeground( Color.BLACK );
mSourceEditor = new SourceComponentEditor( mChannelNode ); tabs.addTab( "Name/Alias", mNameConfigurationEditor );
tabs.addTab( "Source", mSourceEditor ); // mSourceEditor = new SourceComponentEditor( mSourceManager, mChannel );
// tabs.addTab( "Source", mSourceEditor );
mDecodeEditor = new DecodeComponentEditor( mChannelNode, mPlaylistManager ); //
tabs.addTab( "Decoder", mDecodeEditor ); // mDecodeEditor = new DecodeComponentEditor( mPlaylistManager, mChannel );
// tabs.addTab( "Decoder", mDecodeEditor );
mAuxDecodeEditor = new AuxDecodeComponentEditor( mChannelNode ); //
tabs.addTab( "Aux", mAuxDecodeEditor ); // mAuxDecodeEditor = new AuxDecodeComponentEditor( mChannel );
// tabs.addTab( "Aux", mAuxDecodeEditor );
mEventLogEditor = new EventLogComponentEditor( mChannelNode ); //
tabs.addTab( "Event Log", mEventLogEditor ); // mEventLogEditor = new EventLogComponentEditor( mChannel );
// tabs.addTab( "Event Log", mEventLogEditor );
mRecordEditor = new RecordComponentEditor( mChannelNode ); //
tabs.addTab( "Record", mRecordEditor ); // mRecordEditor = new RecordComponentEditor( mChannel );
// tabs.addTab( "Record", mRecordEditor );
add( tabs, "span,grow,push" ); add( tabs, "span,grow,push" );
@@ -160,6 +136,12 @@ public class ChannelEditor extends Editor implements ActionListener
add( btnReset, "growx,push" ); add( btnReset, "growx,push" );
} }
@Override
public void channelChanged( ChannelEvent event )
{
}
@Override @Override
public void actionPerformed( ActionEvent e ) public void actionPerformed( ActionEvent e )
{ {
@@ -171,109 +153,105 @@ public class ChannelEditor extends Editor implements ActionListener
} }
else if( command.contentEquals( "Reset" ) ) else if( command.contentEquals( "Reset" ) )
{ {
reset(); setChannel( mChannel );
}
if( mTreeModel != null )
{
mTreeModel.nodeChanged( mChannelNode );
} }
} }
@Override
public void save() public void save()
{ {
try try
{ {
/** //Validate each of the configuration editors to check for errors
* Validate the source configuration against the other component mNameConfigurationEditor.validateConfiguration();
* configuration editors // /**
*/ // * Validate the source configuration against the other component
validate( mSourceEditor.getSourceEditor() ); // * configuration editors
// */
boolean expanded = mChannelNode.getModel().getTree() // validate( mSourceEditor.getSourceEditor() );
.isExpanded( new TreePath( mChannelNode ) ); //
// mSourceEditor.save();
mSourceEditor.save(); // mDecodeEditor.save();
mDecodeEditor.save(); // mAuxDecodeEditor.save();
mAuxDecodeEditor.save(); // mEventLogEditor.save();
mEventLogEditor.save(); // mRecordEditor.save();
mRecordEditor.save(); //
// mChannel.setName( mChannelName.getText() );
mChannelNode.getChannel().setName( mChannelName.getText() ); // mChannel.setEnabled( mChannelEnabled.isSelected() );
mChannelNode.getChannel().setEnabled( mChannelEnabled.isSelected() ); //
// AliasList selected = mComboAliasLists.getItemAt(
AliasList selected = mComboAliasLists.getItemAt( // mComboAliasLists.getSelectedIndex() );
mComboAliasLists.getSelectedIndex() ); // if( selected != null )
if( selected != null ) // {
{ // mChannel.setAliasListName( selected.getName() );
mChannelNode.getChannel().setAliasListName( selected.getName() ); // }
}
mChannelNode.save();
mChannelNode.show();
if( expanded )
{
mChannelNode.getModel().getTree().expandPath( new TreePath( mChannelNode ) );
}
} }
catch ( ChannelValidationException validationException ) catch ( ConfigurationValidationException validationException )
{ {
/* ChannelValidationException can be thrown by any of the component /* ChannelValidationException can be thrown by any of the component
* editors. Show the validation error text in a popup menu to the * editors. Show the validation error text in a popup menu to the
* user */ * user and set the focus on the error component */
JOptionPane.showMessageDialog( ChannelEditor.this, JOptionPane.showMessageDialog( ChannelEditor.this,
validationException.getMessage(), validationException.getMessage(),
"Channel Configuration Error", "Channel Configuration Error",
JOptionPane.ERROR_MESSAGE ); JOptionPane.ERROR_MESSAGE );
Component component = validationException.getComponent();
if( component != null )
{
component.requestFocus();
}
return;
} }
//Save the contents of each editor to the channel configuration
mNameConfigurationEditor.save();
//Broadcast a channel configuration change event
mChannelModel.broadcast( new ChannelEvent( mChannel,
Event.NOTIFICATION_CONFIGURATION_CHANGE ) );
} }
@Override // @Override
public void reset() // public void reset()
{ // {
mChannelName.setText( // mChannelName.setText( mChannel.getName() );
mChannelNode.getChannel().getName() ); // mChannelName.requestFocus();
mChannelName.requestFocus(); // mChannelName.requestFocusInWindow();
mChannelName.requestFocusInWindow(); //
// mChannelEnabled.setSelected( mChannel.getEnabled() );
// mChannelEnabled.requestFocus();
// mChannelEnabled.requestFocusInWindow();
//
// String aliasListName = mChannel.getAliasListName();
//
// if( aliasListName != null )
// {
// AliasList selected = mPlaylistManager.getPlayist().getAliasDirectory()
// .getAliasList( aliasListName );
//
// mComboAliasLists.setSelectedItem( selected );
// }
//
//
// mSourceEditor.reset();
// mDecodeEditor.reset();
// mAuxDecodeEditor.reset();
// mEventLogEditor.reset();
// mRecordEditor.reset();
// }
mChannelEnabled.setSelected( // /**
mChannelNode.getChannel().getEnabled() ); // * Validate the specified editor against each of the component editors
mChannelEnabled.requestFocus(); // */
mChannelEnabled.requestFocusInWindow(); // @Override
// public void validate( ChannelConfigurationEditor editor ) throws ConfigurationValidationException
String aliasListName = // {
mChannelNode.getChannel().getAliasListName(); // mSourceEditor.validate( editor );
// mDecodeEditor.validate( editor );
if( aliasListName != null ) // mAuxDecodeEditor.validate( editor );
{ // mEventLogEditor.validate( editor );
AliasList selected = mChannelNode.getModel().getResourceManager() // mRecordEditor.validate( editor );
.getPlaylistManager().getPlayist().getAliasDirectory() // }
.getAliasList( aliasListName );
mComboAliasLists.setSelectedItem( selected );
}
mSourceEditor.reset();
mDecodeEditor.reset();
mAuxDecodeEditor.reset();
mEventLogEditor.reset();
mRecordEditor.reset();
}
/**
* Validate the specified editor against each of the component editors
*/
@Override
public void validate( Editor editor ) throws ChannelValidationException
{
mSourceEditor.validate( editor );
mDecodeEditor.validate( editor );
mAuxDecodeEditor.validate( editor );
mEventLogEditor.validate( editor );
mRecordEditor.validate( editor );
}
} }

View File

@@ -64,6 +64,8 @@ public class ChannelEvent
NOTIFICATION_SELECTION_CHANGE, NOTIFICATION_SELECTION_CHANGE,
//Channel's channel-state has been reset //Channel's channel-state has been reset
NOTIFICATION_STATE_RESET, NOTIFICATION_STATE_RESET,
//Request to delete the channel
REQUEST_DELETE,
//Request to deselect the channel //Request to deselect the channel
REQUEST_DESELECT, REQUEST_DESELECT,
//Request to disable a channel - response will be a PROCESSING_STOP_NOTIFICATION //Request to disable a channel - response will be a PROCESSING_STOP_NOTIFICATION

View File

@@ -0,0 +1,346 @@
/*******************************************************************************
* SDR Trunk
* Copyright (C) 2015 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
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>
******************************************************************************/
package controller.channel;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.concurrent.CopyOnWriteArrayList;
import javax.swing.event.TableModelEvent;
import javax.swing.event.TableModelListener;
import javax.swing.table.TableModel;
import module.decode.DecoderType;
import controller.channel.Channel.ChannelType;
import controller.channel.ChannelEvent.Event;
/**
* Channel Model
*/
public class ChannelModel implements IChannelEventBroadcaster, TableModel
{
private ChannelSelectionManager mChannelSelectionManager;
private List<Channel> mChannels = new ArrayList<>();
private List<Channel> mTrafficChannels = new ArrayList<>();
private List<ChannelEventListener> mListeners = new CopyOnWriteArrayList<>();
private List<TableModelListener> mTableModelListeners = new CopyOnWriteArrayList<>();
public ChannelModel()
{
mChannelSelectionManager = new ChannelSelectionManager( this );
addListener( mChannelSelectionManager );
}
/**
* Unmodifiable list of non-traffic channels currently in the model
*/
public List<Channel> getChannels()
{
return Collections.unmodifiableList( mChannels );
}
/**
* Returns a list of unique system values from across the channel set
*/
public List<String> getSystems()
{
List<String> systems = new ArrayList<>();
for( Channel channel: mChannels )
{
if( channel.hasSystem() && !systems.contains( channel.getSystem() ) )
{
systems.add( channel.getSystem() );
}
}
Collections.sort( systems );
return systems;
}
/**
* Returns a list of unique site values for all channels that have a matching
* system value
*/
public List<String> getSites( String system )
{
List<String> sites = new ArrayList<>();
if( system != null )
{
for( Channel channel: mChannels )
{
if( channel.hasSystem() &&
system.equals( channel.getSystem() ) &&
channel.hasSite() &&
!sites.contains( channel.getSite() ) )
{
sites.add( channel.getSite() );
}
}
}
Collections.sort( sites );
return sites;
}
/**
* Broadcasts the channel event to all registered listeners
*/
@Override
public void broadcast( ChannelEvent event )
{
for( ChannelEventListener listener: mListeners )
{
listener.channelChanged( event );
}
if( event.getChannel().getChannelType() == ChannelType.STANDARD )
{
switch( event.getEvent() )
{
case NOTIFICATION_CONFIGURATION_CHANGE:
case NOTIFICATION_PROCESSING_START:
case NOTIFICATION_PROCESSING_STOP:
case NOTIFICATION_SELECTION_CHANGE:
int index = mChannels.indexOf( event.getChannel() );
broadcast( new TableModelEvent( this, index ) );
break;
default:
break;
}
}
if( event.getEvent() == Event.REQUEST_DELETE )
{
removeChannel( event.getChannel() );
}
}
/**
* Bulk loading of channel list. Each channel is added and a channel add
* event is broadcast.
*/
public void addChannels( List<Channel> channels )
{
for( Channel channel: channels )
{
addChannel( channel );
}
}
/**
* Adds the channel to the model and broadcasts a channel add event
*/
public void addChannel( Channel channel )
{
switch( channel.getChannelType() )
{
case STANDARD:
mChannels.add( channel );
int index = mChannels.size() - 1;
broadcast( new TableModelEvent( this, index, index,
TableModelEvent.ALL_COLUMNS, TableModelEvent.INSERT ) );
break;
case TRAFFIC:
mTrafficChannels.add( channel );
break;
default:
break;
}
broadcast( new ChannelEvent( channel, Event.NOTIFICATION_ADD ) );
}
/**
* Removes the channel from the model and broadcasts a channel remove event
*/
public void removeChannel( Channel channel )
{
switch( channel.getChannelType() )
{
case STANDARD:
int index = mChannels.indexOf( channel );
mChannels.remove( channel );
if( index >= 0 )
{
broadcast( new TableModelEvent( this, index, index,
TableModelEvent.ALL_COLUMNS, TableModelEvent.DELETE ) );
}
break;
case TRAFFIC:
mTrafficChannels.remove( channel );
break;
default:
break;
}
broadcast( new ChannelEvent( channel, Event.NOTIFICATION_DELETE ) );
}
/**
* Returns a list of channels that fall within the frequency range
*
* @param start frequency of the range
* @param stop frequency of the range
*
* @return list of channels or an empty list if none fall within the range
*/
public List<Channel> getChannelsInFrequencyRange( long start, long stop )
{
List<Channel> channels = new ArrayList<>();
for( Channel channel: mChannels )
{
if( channel.isWithin( start, stop ) )
{
channels.add( channel );
}
}
for( Channel channel: mTrafficChannels )
{
if( channel.isWithin( start, stop ) )
{
channels.add( channel );
}
}
return channels;
}
public void addListener( ChannelEventListener listener )
{
mListeners.add( listener );
}
public void removeListener( ChannelEventListener listener )
{
mListeners.remove( listener );
}
//Table Model Interface Methods - standard channels only
@Override
public int getRowCount()
{
return mChannels.size();
}
@Override
public int getColumnCount()
{
return 6;
}
@Override
public String getColumnName( int columnIndex )
{
switch( columnIndex )
{
case 0:
return "System";
case 1:
return "Site";
case 2:
return "Name";
case 3:
return "Alias List";
case 4:
return "Source";
case 5:
return "Decoder";
}
return null;
}
@Override
public Class<?> getColumnClass( int columnIndex )
{
return String.class;
}
@Override
public boolean isCellEditable( int rowIndex, int columnIndex )
{
return false;
}
@Override
public Object getValueAt( int rowIndex, int columnIndex )
{
Channel channel = mChannels.get( rowIndex );
switch( columnIndex )
{
case 0:
return channel.getSystem();
case 1:
return channel.getSite();
case 2:
return channel.getName();
case 3:
return channel.getAliasListName();
case 4:
return channel.getSourceConfiguration().getDescription();
case 5:
return channel.getDecodeConfiguration()
.getDecoderType().getShortDisplayString();
}
return null;
}
@Override
public void setValueAt( Object aValue, int rowIndex, int columnIndex )
{
throw new IllegalArgumentException( "Not yet implemented" );
}
private void broadcast( TableModelEvent event )
{
for( TableModelListener listener: mTableModelListeners )
{
listener.tableChanged( event );
}
}
@Override
public void addTableModelListener( TableModelListener listener )
{
mTableModelListeners.add( listener );
}
@Override
public void removeTableModelListener( TableModelListener listener )
{
mTableModelListeners.remove( listener );
}
public void createChannel( DecoderType decoderType, long frequency )
{
throw new UnsupportedOperationException( "Not yet implemented" );
}
}

View File

@@ -27,6 +27,8 @@ import javax.swing.JPopupMenu;
import org.slf4j.Logger; import org.slf4j.Logger;
import org.slf4j.LoggerFactory; import org.slf4j.LoggerFactory;
import playlist.PlaylistManager;
import source.SourceManager;
import source.tuner.TunerChannel; import source.tuner.TunerChannel;
import controller.ConfigurableNode; import controller.ConfigurableNode;
import controller.site.SiteNode; import controller.site.SiteNode;
@@ -44,9 +46,21 @@ public class ChannelNode extends ConfigurableNode implements ChannelEventListene
private static DecimalFormat sFORMAT = new DecimalFormat( "0.0000" ); private static DecimalFormat sFORMAT = new DecimalFormat( "0.0000" );
public ChannelNode( Channel channel ) private ChannelModel mChannelModel;
private ChannelProcessingManager mChannelProcessingManager;
private SourceManager mSourceManager;
public ChannelNode( Channel channel,
ChannelModel channelModel,
ChannelProcessingManager channelProcessingManager,
PlaylistManager playlistManager,
SourceManager sourceManager )
{ {
super( channel ); super( playlistManager, channel );
mChannelModel = channelModel;
mChannelProcessingManager = channelProcessingManager;
mSourceManager = sourceManager;
} }
public void init() public void init()
@@ -69,9 +83,6 @@ public class ChannelNode extends ConfigurableNode implements ChannelEventListene
/* Add this node as listener to receive changes from underlying channel */ /* Add this node as listener to receive changes from underlying channel */
// getChannel().addListener( this ); // getChannel().addListener( this );
/* Add the resource manager to the channel so that the channel
* can provide channel change events to all system resources */
getChannel().setResourceManager( getModel().getResourceManager() );
} }
/** /**
@@ -109,7 +120,7 @@ public class ChannelNode extends ConfigurableNode implements ChannelEventListene
{ {
if( getChannel().getEnabled() ) if( getChannel().getEnabled() )
{ {
if( getChannel().isProcessing() ) if( getChannel().getEnabled() )
{ {
return Color.GREEN; return Color.GREEN;
} }
@@ -125,9 +136,7 @@ public class ChannelNode extends ConfigurableNode implements ChannelEventListene
@Override @Override
public JPanel getEditor() public JPanel getEditor()
{ {
return new ChannelEditor( this, return new OldChannelEditor( getChannel(), mChannelModel, getPlaylistManager(), mSourceManager );
getChannel().getResourceManager() == null ? null :
getChannel().getResourceManager().getPlaylistManager() );
} }
public Channel getChannel() public Channel getChannel()
@@ -158,9 +167,9 @@ public class ChannelNode extends ConfigurableNode implements ChannelEventListene
{ {
JPopupMenu popupMenu = new JPopupMenu(); JPopupMenu popupMenu = new JPopupMenu();
JMenu channelMenu = ChannelUtils.getContextMenu( JMenu channelMenu = ChannelUtils.getContextMenu( mChannelModel,
getModel().getResourceManager().getPlaylistManager(), mChannelProcessingManager, getPlaylistManager(), getChannel(),
getChannel(), getModel().getTree() ); getModel().getTree() );
if( channelMenu != null ) if( channelMenu != null )
{ {

View File

@@ -0,0 +1,301 @@
/*******************************************************************************
* SDR Trunk
* 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
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>
******************************************************************************/
package controller.channel;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.concurrent.CopyOnWriteArrayList;
import message.Message;
import module.Module;
import module.ProcessingChain;
import module.decode.DecoderFactory;
import module.decode.event.MessageActivityModel;
import module.log.EventLogManager;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import playlist.PlaylistManager;
import record.RecorderManager;
import record.RecorderType;
import sample.Listener;
import source.Source;
import source.SourceException;
import source.SourceManager;
import audio.AudioPacket;
import audio.metadata.Metadata;
import audio.metadata.MetadataType;
import controller.ThreadPoolManager;
import controller.channel.Channel.ChannelType;
import controller.channel.ChannelEvent.Event;
import filter.FilterSet;
public class ChannelProcessingManager implements ChannelEventListener
{
private final static Logger mLog = LoggerFactory.getLogger( ChannelProcessingManager.class );
private Map<Integer,ProcessingChain> mProcessingChains = new HashMap<>();
private List<Listener<AudioPacket>> mAudioPacketListeners = new CopyOnWriteArrayList<>();
private List<Listener<Message>> mMessageListeners = new CopyOnWriteArrayList<>();
private ChannelModel mChannelModel;
private EventLogManager mEventLogManager;
private PlaylistManager mPlaylistManager;
private RecorderManager mRecorderManager;
private SourceManager mSourceManager;
private ThreadPoolManager mThreadPoolManager;
public ChannelProcessingManager( ChannelModel channelModel,
EventLogManager eventLogManager,
PlaylistManager playlistManager,
RecorderManager recorderManager,
SourceManager sourceManager,
ThreadPoolManager threadPoolManager )
{
mChannelModel = channelModel;
mEventLogManager = eventLogManager;
mPlaylistManager = playlistManager;
mRecorderManager = recorderManager;
mSourceManager = sourceManager;
mThreadPoolManager = threadPoolManager;
mChannelModel.addListener( this );
}
/**
* Indicates if a processing chain is constructed for the channel and that
* the processing chain is currently processing.
*/
public boolean isProcessing( Channel channel )
{
if( mProcessingChains.containsKey( channel.getChannelID() ) )
{
return mProcessingChains.get( channel.getChannelID() ).isProcessing();
}
return false;
}
/**
* Returns the current processing chain associated with the channel, or
* null if a processing chain is not currently setup for the channel
*/
public ProcessingChain getProcessingChain( Channel channel )
{
return mProcessingChains.get( channel.getChannelID() );
}
@Override
public void channelChanged( ChannelEvent event )
{
Channel channel = event.getChannel();
switch( event.getEvent() )
{
case REQUEST_ENABLE:
if( !mProcessingChains.containsKey( channel.getChannelID() ) ||
!mProcessingChains.get( channel.getChannelID() ).isProcessing() )
{
startProcessing( channel );
}
break;
case REQUEST_DISABLE:
if( channel.getEnabled() )
{
switch( channel.getChannelType() )
{
case STANDARD:
stopProcessing( channel, true );
break;
case TRAFFIC:
//Don't remove traffic channel processing chains
//until explicitly deleted, so that we can reuse them
stopProcessing( channel, false );
default:
break;
}
}
case NOTIFICATION_DELETE:
if( channel.getEnabled() )
{
stopProcessing( channel, true );
}
break;
default:
break;
}
}
private void startProcessing( Channel channel )
{
ProcessingChain processingChain = mProcessingChains.get( channel.getChannelID() );
//If we're already processing, ignore the request
if( processingChain != null && processingChain.isProcessing() )
{
return;
}
//Ensure that we can get a source before we construct a new processing chain
Source source = null;
try
{
source = mSourceManager.getSource( channel.getSourceConfiguration(),
channel.getDecodeConfiguration().getDecoderType().getChannelBandwidth() );
}
catch( SourceException se )
{
mLog.debug( "Error obtaining source for channel [" + channel.getName() + "]", se );
}
if( source == null )
{
channel.setEnabled( false );
mChannelModel.broadcast(
new ChannelEvent( channel, Event.NOTIFICATION_ENABLE_REJECTED ) );
return;
}
if( processingChain == null )
{
processingChain = new ProcessingChain( mThreadPoolManager,
channel.getChannelType() );
/* Register global listeners */
for( Listener<AudioPacket> listener: mAudioPacketListeners )
{
processingChain.addAudioPacketListener( listener );
}
for( Listener<Message> listener: mMessageListeners )
{
processingChain.addMessageListener( listener );
}
/* Processing Modules */
List<Module> modules = DecoderFactory.getModules( mChannelModel,
this, mPlaylistManager, channel );
processingChain.addModules( modules );
/* Setup message activity model with filtering */
FilterSet<Message> messageFilter = DecoderFactory.getMessageFilters( modules );
MessageActivityModel messageModel = new MessageActivityModel( messageFilter );
processingChain.setMessageActivityModel( messageModel );
/* Setup event logging */
List<Module> loggers = mEventLogManager.getLoggers(
channel.getEventLogConfiguration(), channel.getName() );
if( !loggers.isEmpty() )
{
processingChain.addModules( loggers );
}
/* Setup recorders */
List<RecorderType> recorders = channel.getRecordConfiguration().getRecorders();
if( !recorders.isEmpty() )
{
if( recorders.contains( RecorderType.AUDIO ) )
{
processingChain.addAudioPacketListener( mRecorderManager );
}
/* Add baseband recorder */
if( ( recorders.contains( RecorderType.BASEBAND ) &&
channel.getChannelType() == ChannelType.STANDARD ) )
{
processingChain.addModule( mRecorderManager.getBasebandRecorder(
channel.toString() ) );
}
/* Add traffic channel baseband recorder */
if( recorders.contains( RecorderType.TRAFFIC_BASEBAND ) &&
channel.getChannelType() == ChannelType.TRAFFIC )
{
processingChain.addModule( mRecorderManager
.getBasebandRecorder( channel.toString() ) );
}
}
/* Inject channel metadata that will be inserted into audio packets
* for the recorder manager and streaming */
processingChain.broadcast(
new Metadata( MetadataType.SYSTEM, channel.getSystem() ) );
processingChain.broadcast(
new Metadata( MetadataType.SITE_ID, channel.getSite() ) );
processingChain.broadcast(
new Metadata( MetadataType.CHANNEL_NAME, channel.getName() ) );
}
processingChain.setSource( source );
processingChain.start();
channel.setEnabled( true );
mChannelModel.broadcast(
new ChannelEvent( channel, Event.NOTIFICATION_PROCESSING_START ) );
}
private void stopProcessing( Channel channel, boolean remove )
{
mChannelModel.broadcast(
new ChannelEvent( channel, Event.NOTIFICATION_PROCESSING_STOP ) );
}
/**
* Adds a message listener that will be added to all channels to receive
* any messages.
*/
public void addAudioPacketListener( Listener<AudioPacket> listener )
{
mAudioPacketListeners.add( listener );
}
/**
* Removes a message listener.
*/
public void removeAudioPacketListener( Listener<AudioPacket> listener )
{
mAudioPacketListeners.remove( listener );
}
/**
* Adds a message listener that will be added to all channels to receive
* any messages.
*/
public void addMessageListener( Listener<Message> listener )
{
mMessageListeners.add( listener );
}
/**
* Removes a message listener.
*/
public void removeMessageListener( Listener<Message> listener )
{
mMessageListeners.remove( listener );
}
}

View File

@@ -0,0 +1,71 @@
/*******************************************************************************
* SDR Trunk
* Copyright (C) 2015 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
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>
******************************************************************************/
package controller.channel;
import controller.channel.ChannelEvent.Event;
public class ChannelSelectionManager implements ChannelEventListener
{
private IChannelEventBroadcaster mChannelEventBroadcaster;
private Channel mSelectedChannel = null;
/**
* Manages channel selection state to ensure that only one channel is ever
* in a selected state.
*/
public ChannelSelectionManager( IChannelEventBroadcaster broadcaster )
{
mChannelEventBroadcaster = broadcaster;
}
@Override
public void channelChanged( ChannelEvent event )
{
switch( event.getEvent() )
{
case REQUEST_SELECT:
if( mSelectedChannel != null )
{
mSelectedChannel.setSelected( false );
mChannelEventBroadcaster.broadcast( new ChannelEvent( mSelectedChannel,
Event.NOTIFICATION_SELECTION_CHANGE ) );
mSelectedChannel = null;
}
mSelectedChannel = event.getChannel();
mSelectedChannel.setSelected( true );
mChannelEventBroadcaster.broadcast( new ChannelEvent( event.getChannel(),
Event.NOTIFICATION_SELECTION_CHANGE ) );
break;
case NOTIFICATION_PROCESSING_STOP:
case REQUEST_DESELECT:
if( mSelectedChannel != null &&
mSelectedChannel == event.getChannel() )
{
mSelectedChannel.setSelected( false );
mSelectedChannel = null;
mChannelEventBroadcaster.broadcast( new ChannelEvent( event.getChannel(),
Event.NOTIFICATION_SELECTION_CHANGE ) );
}
break;
default:
break;
}
}
}

View File

@@ -9,10 +9,11 @@ import javax.swing.JMenuItem;
import javax.swing.JOptionPane; import javax.swing.JOptionPane;
import javax.swing.JSeparator; import javax.swing.JSeparator;
import controller.channel.ChannelEvent.Event;
import module.ProcessingChain;
import module.decode.event.ActivitySummaryFrame; import module.decode.event.ActivitySummaryFrame;
import module.decode.state.DecoderState; import module.decode.state.DecoderState;
import playlist.PlaylistManager; import playlist.PlaylistManager;
import controller.channel.ChannelEvent.Event;
public class ChannelUtils public class ChannelUtils
{ {
@@ -23,7 +24,9 @@ public class ChannelUtils
/** /**
* Creates a context menu for the channel argument * Creates a context menu for the channel argument
*/ */
public static JMenu getContextMenu( final PlaylistManager playlistManager, public static JMenu getContextMenu( final ChannelModel channelModel,
final ChannelProcessingManager channelProcessingManager,
final PlaylistManager playlistManager,
final Channel channel, final Channel channel,
final Component anchor ) final Component anchor )
{ {
@@ -39,12 +42,8 @@ public class ChannelUtils
@Override @Override
public void actionPerformed( ActionEvent e ) public void actionPerformed( ActionEvent e )
{ {
channel.setEnabled( DISABLED ); channelModel.broadcast(
new ChannelEvent( channel, Event.REQUEST_DISABLE ) );
if( playlistManager != null )
{
playlistManager.save();
}
} }
} ); } );
@@ -62,10 +61,14 @@ public class ChannelUtils
{ {
StringBuilder sb = new StringBuilder(); StringBuilder sb = new StringBuilder();
for( DecoderState decoderState: channel ProcessingChain chain = channelProcessingManager.getProcessingChain( channel );
.getProcessingChain().getDecoderStates() )
if( chain != null )
{ {
sb.append( decoderState.getActivitySummary() ); for( DecoderState decoderState: chain.getDecoderStates() )
{
sb.append( decoderState.getActivitySummary() );
}
} }
new ActivitySummaryFrame( sb.toString(), anchor ); new ActivitySummaryFrame( sb.toString(), anchor );
@@ -82,12 +85,8 @@ public class ChannelUtils
@Override @Override
public void actionPerformed( ActionEvent e ) public void actionPerformed( ActionEvent e )
{ {
channel.setEnabled( ENABLED ); channelModel.broadcast(
new ChannelEvent( channel, Event.REQUEST_ENABLE ) );
if( playlistManager != null )
{
playlistManager.save();
}
} }
} ); } );
@@ -108,16 +107,8 @@ public class ChannelUtils
if( response == JOptionPane.YES_OPTION ) if( response == JOptionPane.YES_OPTION )
{ {
/* Disable the channel */ channelModel.broadcast(
channel.setEnabled( DISABLED ); new ChannelEvent( channel, Event.REQUEST_DELETE ) );
/* Broadcast channel deleted event */
// channel.fireChannelEvent( Event.NOTIFICATION_DELETE );
if( playlistManager != null )
{
playlistManager.save();
}
} }
} }
} ); } );

View File

@@ -1,11 +0,0 @@
package controller.channel;
public class ChannelValidationException extends Exception
{
private static final long serialVersionUID = 1L;
public ChannelValidationException( String validationMessage )
{
super( validationMessage );
}
}

View File

@@ -0,0 +1,23 @@
package controller.channel;
import java.awt.Component;
public class ConfigurationValidationException extends Exception
{
private static final long serialVersionUID = 1L;
private Component mComponent;
public ConfigurationValidationException( Component component,
String validationMessage )
{
super( validationMessage );
mComponent = component;
}
public Component getComponent()
{
return mComponent;
}
}

View File

@@ -1,6 +1,6 @@
/******************************************************************************* /*******************************************************************************
* SDR Trunk * SDR Trunk
* Copyright (C) 2014 Dennis Sheirer * Copyright (C) 2016 Dennis Sheirer
* *
* This program is free software: you can redistribute it and/or modify * 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 * it under the terms of the GNU General Public License as published by
@@ -15,9 +15,15 @@
* You should have received a copy of the GNU General Public License * You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/> * along with this program. If not, see <http://www.gnu.org/licenses/>
******************************************************************************/ ******************************************************************************/
package buffer; package controller.channel;
public interface ComplexByteBufferListener /**
* Provides channel event broadcasting capability.
*/
public interface IChannelEventBroadcaster
{ {
public void receive( ComplexByteBuffer buffer ); /**
* Broadcasts the channel event
*/
public void broadcast( ChannelEvent event );
} }

View File

@@ -0,0 +1,221 @@
package controller.channel;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.util.Collections;
import java.util.List;
import javax.swing.ComboBoxModel;
import javax.swing.DefaultComboBoxModel;
import javax.swing.JButton;
import javax.swing.JComboBox;
import javax.swing.JLabel;
import javax.swing.JOptionPane;
import javax.swing.JTextField;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import net.miginfocom.swing.MigLayout;
import playlist.PlaylistManager;
import alias.AliasList;
public class NameConfigurationEditor extends ChannelConfigurationEditor
{
private static final long serialVersionUID = 1L;
private final static Logger mLog = LoggerFactory.getLogger( NameConfigurationEditor.class );
private static ComboBoxModel<String> EMPTY_MODEL = new DefaultComboBoxModel<>();
private ChannelModel mChannelModel;
private PlaylistManager mPlaylistManager;
private JTextField mChannelName = new JTextField( "Please select a channel to edit" );
private JComboBox<String> mSystemNameCombo = new JComboBox<>( EMPTY_MODEL );
private JComboBox<String> mSiteNameCombo = new JComboBox<>( EMPTY_MODEL );
private JComboBox<AliasList> mAliasListCombo;
private Channel mChannel;
public NameConfigurationEditor( ChannelModel model,
PlaylistManager playlistManager )
{
mChannelModel = model;
mPlaylistManager = playlistManager;
setLayout( new MigLayout( "fill,wrap 2", "[right][]", "[][][][grow]" ) );
add( new JLabel( "Name:" ) );
add( mChannelName, "growx" );
mSystemNameCombo.setEditable( true );
mSystemNameCombo.addActionListener( new ActionListener()
{
@Override
public void actionPerformed( ActionEvent e )
{
Object selected = mSystemNameCombo.getSelectedItem();
if( selected != null )
{
String system = (String)selected;
List<String> sites = mChannelModel.getSites( system );
if( !sites.contains( mChannel.getSite() ) )
{
sites.add( mChannel.getSite() );
}
if( sites.isEmpty() )
{
mSiteNameCombo.setModel( EMPTY_MODEL );
}
else
{
mSiteNameCombo.setModel( new DefaultComboBoxModel<String>(
sites.toArray( new String[ sites.size() ] ) ) );;
}
mSiteNameCombo.setSelectedItem( mChannel.getSite() );
}
}
} );
add( new JLabel( "System:" ) );
add( mSystemNameCombo, "growx" );
mSiteNameCombo.setEditable( true );
add( new JLabel( "Site:" ) );
add( mSiteNameCombo, "growx" );
/**
* ComboBox: Alias Lists
*/
add( new JLabel( "Alias List:" ) );
mAliasListCombo = new JComboBox<AliasList>();
List<AliasList> lists = mPlaylistManager.getPlayist()
.getAliasDirectory().getAliasList();
Collections.sort( lists );
mAliasListCombo.setModel( new DefaultComboBoxModel<AliasList>(
lists.toArray( new AliasList[ lists.size() ] ) ) );
add( mAliasListCombo, "growx" );
add( new JLabel() );
final JButton aliasListButton = new JButton( "New Alias List ..." );
aliasListButton.addActionListener( new ActionListener()
{
@Override
public void actionPerformed( ActionEvent e )
{
String name = JOptionPane.showInputDialog( aliasListButton,
"Please enter an Alias List name:" );
if( name != null && !name.isEmpty() )
{
AliasList aliasList = new AliasList( name );
mPlaylistManager.getPlayist().getAliasDirectory()
.addAliasList( aliasList );
mPlaylistManager.save();
List<AliasList> lists = mPlaylistManager.getPlayist()
.getAliasDirectory().getAliasList();
Collections.sort( lists );
mAliasListCombo.setModel( new DefaultComboBoxModel<AliasList>(
lists.toArray( new AliasList[ lists.size() ] ) ) );
mAliasListCombo.setSelectedItem( aliasList );
}
}
} );
add( aliasListButton, "growx" );
}
@Override
public void save()
{
if( mChannel != null )
{
mChannel.setName( mChannelName.getText() );
Object system = mSystemNameCombo.getSelectedItem();
mChannel.setSystem( ( system == null ? null : (String)system ) );
Object site = mSiteNameCombo.getSelectedItem();
mChannel.setSystem( ( site == null ? null : (String)site ) );
}
}
@Override
public void validateConfiguration() throws ConfigurationValidationException
{
//System and site can be null, but we must (should?) have a channel name
String name = mChannelName.getText();
if( name == null || name.isEmpty() )
{
throw new ConfigurationValidationException(
mChannelName, "Channel name cannot be empty" );
}
}
@Override
public void setConfiguration( Channel channel )
{
mChannel = channel;
mChannelName.setText( channel.getName() );
List<String> systems = mChannelModel.getSystems();
if( systems.isEmpty() )
{
mSystemNameCombo.setModel( EMPTY_MODEL );
}
else
{
mSystemNameCombo.setModel( new DefaultComboBoxModel<String>(
systems.toArray( new String[ systems.size() ] ) ) );;
}
mSystemNameCombo.setSelectedItem( channel.getSystem() );
List<String> sites = mChannelModel.getSites( channel.getSystem() );
if( sites.isEmpty() )
{
mSiteNameCombo.setModel( EMPTY_MODEL );
}
else
{
mSiteNameCombo.setModel( new DefaultComboBoxModel<String>(
sites.toArray( new String[ sites.size() ] ) ) );;
}
mSiteNameCombo.setSelectedItem( channel.getSite() );
String aliasListName = mChannel.getAliasListName();
if( aliasListName != null )
{
AliasList selected = mPlaylistManager.getPlayist().getAliasDirectory()
.getAliasList( aliasListName );
mAliasListCombo.setSelectedItem( selected );
}
}
}

View File

@@ -0,0 +1,260 @@
/*******************************************************************************
* SDR Trunk
* Copyright (C) 2014 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
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>
******************************************************************************/
package controller.channel;
import java.awt.Color;
import java.awt.ComponentOrientation;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.util.Collections;
import java.util.List;
import javax.swing.DefaultComboBoxModel;
import javax.swing.JButton;
import javax.swing.JCheckBox;
import javax.swing.JComboBox;
import javax.swing.JLabel;
import javax.swing.JTextField;
import module.decode.AuxDecodeComponentEditor;
import module.decode.DecodeComponentEditor;
import module.log.EventLogComponentEditor;
import net.miginfocom.swing.MigLayout;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import playlist.PlaylistManager;
import record.RecordComponentEditor;
import source.SourceComponentEditor;
import source.SourceManager;
import alias.AliasList;
import com.jidesoft.swing.JideTabbedPane;
public class OldChannelEditor extends ChannelConfigurationEditor implements ActionListener
{
private final static Logger mLog = LoggerFactory.getLogger( OldChannelEditor.class );
private static final long serialVersionUID = 1L;
private DecodeComponentEditor mDecodeEditor;
private AuxDecodeComponentEditor mAuxDecodeEditor;
private EventLogComponentEditor mEventLogEditor;
private RecordComponentEditor mRecordEditor;
private SourceComponentEditor mSourceEditor;
private JTextField mChannelName;
private JCheckBox mChannelEnabled = new JCheckBox();
private JComboBox<AliasList> mComboAliasLists;
private Channel mChannel;
private ChannelModel mChannelModel;
private PlaylistManager mPlaylistManager;
private SourceManager mSourceManager;
public OldChannelEditor( Channel channel,
ChannelModel channelModel,
PlaylistManager playlistManager,
SourceManager sourceManager )
{
super();
mChannel = channel;
mChannelModel = channelModel;
mPlaylistManager = playlistManager;
mSourceManager = sourceManager;
initGUI();
}
private void initGUI()
{
setLayout( new MigLayout( "fill,wrap 2", "[right,grow][grow]", "[][][][][grow][]" ) );
add( new JLabel( "Channel Configuration" ), "span, align center" );
add( new JLabel( "Enabled:" ) );
mChannelEnabled.setSelected( mChannel.getEnabled() );
mChannelEnabled.setComponentOrientation( ComponentOrientation.RIGHT_TO_LEFT );
add( mChannelEnabled );
add( new JLabel( "Name:" ) );
mChannelName = new JTextField( mChannel.getName() );
add( mChannelName, "growx,push" );
/**
* ComboBox: Alias Lists
*/
add( new JLabel( "Alias List:" ) );
mComboAliasLists = new JComboBox<AliasList>();
List<AliasList> lists = mPlaylistManager.getPlayist()
.getAliasDirectory().getAliasList();
Collections.sort( lists );
mComboAliasLists.setModel( new DefaultComboBoxModel<AliasList>(
lists.toArray( new AliasList[ lists.size() ] ) ) );
String aliasListName = mChannel.getAliasListName();
if( aliasListName != null )
{
AliasList selected = mPlaylistManager.getPlayist().getAliasDirectory()
.getAliasList( aliasListName );
mComboAliasLists.setSelectedItem( selected );
}
add( mComboAliasLists, "growx,push" );
JideTabbedPane tabs = new JideTabbedPane();
tabs.setFont( this.getFont() );
tabs.setForeground( Color.BLACK );
mSourceEditor = new SourceComponentEditor( mSourceManager, mChannel );
tabs.addTab( "Source", mSourceEditor );
mDecodeEditor = new DecodeComponentEditor( mPlaylistManager, mChannel );
tabs.addTab( "Decoder", mDecodeEditor );
mAuxDecodeEditor = new AuxDecodeComponentEditor( mChannel );
tabs.addTab( "Aux", mAuxDecodeEditor );
mEventLogEditor = new EventLogComponentEditor( mChannel );
tabs.addTab( "Event Log", mEventLogEditor );
mRecordEditor = new RecordComponentEditor( mChannel );
tabs.addTab( "Record", mRecordEditor );
add( tabs, "span,grow,push" );
JButton btnSave = new JButton( "Save" );
btnSave.addActionListener( OldChannelEditor.this );
add( btnSave, "growx,push" );
JButton btnReset = new JButton( "Reset" );
btnReset.addActionListener( OldChannelEditor.this );
add( btnReset, "growx,push" );
}
@Override
public void actionPerformed( ActionEvent e )
{
String command = e.getActionCommand();
if( command.contentEquals( "Save" ) )
{
save();
}
else if( command.contentEquals( "Reset" ) )
{
// reset();
}
}
@Override
public void save()
{
// try
// {
// /**
// * Validate the source configuration against the other component
// * configuration editors
// */
// validate( mSourceEditor.getSourceEditor() );
//
// mSourceEditor.save();
// mDecodeEditor.save();
// mAuxDecodeEditor.save();
// mEventLogEditor.save();
// mRecordEditor.save();
//
// mChannel.setName( mChannelName.getText() );
// mChannel.setEnabled( mChannelEnabled.isSelected() );
//
// AliasList selected = mComboAliasLists.getItemAt(
// mComboAliasLists.getSelectedIndex() );
// if( selected != null )
// {
// mChannel.setAliasListName( selected.getName() );
// }
// }
// catch ( ConfigurationValidationException validationException )
// {
// /* ChannelValidationException can be thrown by any of the component
// * editors. Show the validation error text in a popup menu to the
// * user */
// JOptionPane.showMessageDialog( OldChannelEditor.this,
// validationException.getMessage(),
// "Channel Configuration Error",
// JOptionPane.ERROR_MESSAGE );
// }
}
// @Override
// public void reset()
// {
// mChannelName.setText( mChannel.getName() );
// mChannelName.requestFocus();
// mChannelName.requestFocusInWindow();
//
// mChannelEnabled.setSelected( mChannel.getEnabled() );
// mChannelEnabled.requestFocus();
// mChannelEnabled.requestFocusInWindow();
//
// String aliasListName = mChannel.getAliasListName();
//
// if( aliasListName != null )
// {
// AliasList selected = mPlaylistManager.getPlayist().getAliasDirectory()
// .getAliasList( aliasListName );
//
// mComboAliasLists.setSelectedItem( selected );
// }
//
//
// mSourceEditor.reset();
// mDecodeEditor.reset();
// mAuxDecodeEditor.reset();
// mEventLogEditor.reset();
// mRecordEditor.reset();
// }
@Override
public void setConfiguration( Channel channel )
{
}
@Override
public void validateConfiguration() throws ConfigurationValidationException
{
mSourceEditor.validate();
mDecodeEditor.validate();
mAuxDecodeEditor.validate();
mEventLogEditor.validate();
mRecordEditor.validate();
}
}

View File

@@ -23,15 +23,16 @@ import java.awt.event.ActionListener;
import javax.swing.JMenuItem; import javax.swing.JMenuItem;
import javax.swing.JPopupMenu; import javax.swing.JPopupMenu;
import playlist.PlaylistManager;
import controller.ConfigurableNode; import controller.ConfigurableNode;
public class ChannelMapListNode extends ConfigurableNode public class ChannelMapListNode extends ConfigurableNode
{ {
private static final long serialVersionUID = 1L; private static final long serialVersionUID = 1L;
public ChannelMapListNode( ChannelMapList list ) public ChannelMapListNode( PlaylistManager playlistManager, ChannelMapList list )
{ {
super( list ); super( playlistManager, list );
} }
public ChannelMapList getChannelMapList() public ChannelMapList getChannelMapList()
@@ -43,7 +44,7 @@ public class ChannelMapListNode extends ConfigurableNode
{ {
for( ChannelMap channelMap: getChannelMapList().getChannelMap() ) for( ChannelMap channelMap: getChannelMapList().getChannelMap() )
{ {
ChannelMapNode node = new ChannelMapNode( channelMap ); ChannelMapNode node = new ChannelMapNode( getPlaylistManager(), channelMap );
getModel().addNode( node, ChannelMapListNode.this, getChildCount() ); getModel().addNode( node, ChannelMapListNode.this, getChildCount() );
@@ -72,7 +73,7 @@ public class ChannelMapListNode extends ConfigurableNode
getChannelMapList().addChannelMap( channelMap ); getChannelMapList().addChannelMap( channelMap );
getModel().addNode( new ChannelMapNode( channelMap ), getModel().addNode( new ChannelMapNode( getPlaylistManager(), channelMap ),
ChannelMapListNode.this, ChannelMapListNode.this,
ChannelMapListNode.this.getChildCount() ); ChannelMapListNode.this.getChildCount() );

View File

@@ -25,15 +25,16 @@ import javax.swing.JMenuItem;
import javax.swing.JPanel; import javax.swing.JPanel;
import javax.swing.JPopupMenu; import javax.swing.JPopupMenu;
import playlist.PlaylistManager;
import controller.ConfigurableNode; import controller.ConfigurableNode;
public class ChannelMapNode extends ConfigurableNode public class ChannelMapNode extends ConfigurableNode
{ {
private static final long serialVersionUID = 1L; private static final long serialVersionUID = 1L;
public ChannelMapNode( ChannelMap ChannelMap ) public ChannelMapNode( PlaylistManager playlistManager, ChannelMap ChannelMap )
{ {
super( ChannelMap ); super( playlistManager, ChannelMap );
} }
public void init() public void init()

View File

@@ -29,9 +29,13 @@ import javax.swing.JPopupMenu;
import javax.swing.JSeparator; import javax.swing.JSeparator;
import javax.swing.tree.DefaultMutableTreeNode; import javax.swing.tree.DefaultMutableTreeNode;
import playlist.PlaylistManager;
import source.SourceManager;
import controller.ConfigurableNode; import controller.ConfigurableNode;
import controller.channel.Channel; import controller.channel.Channel;
import controller.channel.ChannelModel;
import controller.channel.ChannelNode; import controller.channel.ChannelNode;
import controller.channel.ChannelProcessingManager;
import controller.system.System; import controller.system.System;
import controller.system.SystemNode; import controller.system.SystemNode;
@@ -39,16 +43,29 @@ public class SiteNode extends ConfigurableNode
{ {
private static final long serialVersionUID = 1L; private static final long serialVersionUID = 1L;
public SiteNode( Site site ) private ChannelModel mChannelModel;
private ChannelProcessingManager mChannelProcessingManager;
private SourceManager mSourceManager;
public SiteNode( Site site,
ChannelModel channelModel,
ChannelProcessingManager channelProcessingManager,
PlaylistManager playlistManager,
SourceManager sourceManager )
{ {
super( site ); super( playlistManager, site );
mChannelModel = channelModel;
mChannelProcessingManager = channelProcessingManager;
mSourceManager = sourceManager;
} }
public void init() public void init()
{ {
for( Channel channel: getSite().getChannel() ) for( Channel channel: getSite().getChannel() )
{ {
ChannelNode node = new ChannelNode( channel ); ChannelNode node = new ChannelNode( channel, mChannelModel,
mChannelProcessingManager, getPlaylistManager(), mSourceManager );
getModel().insertNodeInto( node, SiteNode.this, getChildCount() ); getModel().insertNodeInto( node, SiteNode.this, getChildCount() );
@@ -130,7 +147,8 @@ public class SiteNode extends ConfigurableNode
getSite().addChannel( channel ); getSite().addChannel( channel );
ChannelNode node = new ChannelNode( channel ); ChannelNode node = new ChannelNode( channel, mChannelModel,
mChannelProcessingManager, getPlaylistManager(), mSourceManager );
getModel().addNode( node, getModel().addNode( node,
SiteNode.this, SiteNode.this,
@@ -139,11 +157,6 @@ public class SiteNode extends ConfigurableNode
sort(); sort();
save(); save();
node.show(); node.show();
/* Give channel reference to the resource manager and the
* channel will register the listeners and send a channel
* add event */
channel.setResourceManager( getModel().getResourceManager() );
} }
} ); } );

View File

@@ -23,15 +23,31 @@ import java.awt.event.ActionListener;
import javax.swing.JMenuItem; import javax.swing.JMenuItem;
import javax.swing.JPopupMenu; import javax.swing.JPopupMenu;
import playlist.PlaylistManager;
import source.SourceManager;
import controller.ConfigurableNode; import controller.ConfigurableNode;
import controller.channel.ChannelModel;
import controller.channel.ChannelProcessingManager;
public class SystemListNode extends ConfigurableNode public class SystemListNode extends ConfigurableNode
{ {
private static final long serialVersionUID = 1L; private static final long serialVersionUID = 1L;
public SystemListNode( SystemList list ) private ChannelModel mChannelModel;
private ChannelProcessingManager mChannelProcessingManager;
private SourceManager mSourceManager;
public SystemListNode( SystemList list,
ChannelModel channelModel,
ChannelProcessingManager channelProcessingManager,
PlaylistManager playlistManager,
SourceManager sourceManager )
{ {
super( list ); super( playlistManager, list );
mChannelModel = channelModel;
mChannelProcessingManager = channelProcessingManager;
mSourceManager = sourceManager;
} }
public SystemList getSystemList() public SystemList getSystemList()
@@ -43,7 +59,8 @@ public class SystemListNode extends ConfigurableNode
{ {
for( System system: getSystemList().getSystem() ) for( System system: getSystemList().getSystem() )
{ {
SystemNode node = new SystemNode( system ); SystemNode node = new SystemNode( system, mChannelModel,
mChannelProcessingManager, getPlaylistManager(), mSourceManager );
getModel().addNode( node, SystemListNode.this, getChildCount() ); getModel().addNode( node, SystemListNode.this, getChildCount() );
@@ -72,9 +89,9 @@ public class SystemListNode extends ConfigurableNode
getSystemList().addSystem( system ); getSystemList().addSystem( system );
getModel().addNode( new SystemNode( system ), getModel().addNode( new SystemNode( system, mChannelModel,
SystemListNode.this, mChannelProcessingManager, getPlaylistManager(), mSourceManager ),
SystemListNode.this.getChildCount() ); SystemListNode.this, SystemListNode.this.getChildCount() );
} }
} ); } );

View File

@@ -29,7 +29,11 @@ import javax.swing.JPopupMenu;
import javax.swing.JSeparator; import javax.swing.JSeparator;
import javax.swing.tree.DefaultMutableTreeNode; import javax.swing.tree.DefaultMutableTreeNode;
import playlist.PlaylistManager;
import source.SourceManager;
import controller.ConfigurableNode; import controller.ConfigurableNode;
import controller.channel.ChannelModel;
import controller.channel.ChannelProcessingManager;
import controller.site.Site; import controller.site.Site;
import controller.site.SiteNode; import controller.site.SiteNode;
@@ -37,16 +41,29 @@ public class SystemNode extends ConfigurableNode
{ {
private static final long serialVersionUID = 1L; private static final long serialVersionUID = 1L;
public SystemNode( System system ) private ChannelModel mChannelModel;
private ChannelProcessingManager mChannelProcessingManager;
private SourceManager mSourceManager;
public SystemNode( System system,
ChannelModel channelModel,
ChannelProcessingManager channelProcessingManager,
PlaylistManager playlistManager,
SourceManager sourceManager )
{ {
super( system ); super( playlistManager, system );
mChannelModel = channelModel;
mChannelProcessingManager = channelProcessingManager;
mSourceManager = sourceManager;
} }
public void init() public void init()
{ {
for( Site site: getSystem().getSite() ) for( Site site: getSystem().getSite() )
{ {
SiteNode node = new SiteNode( site ); SiteNode node = new SiteNode( site, mChannelModel,
mChannelProcessingManager, getPlaylistManager(), mSourceManager );
getModel().insertNodeInto( node, SystemNode.this, getChildCount() ); getModel().insertNodeInto( node, SystemNode.this, getChildCount() );
@@ -133,7 +150,8 @@ public class SystemNode extends ConfigurableNode
Site site = new Site(); Site site = new Site();
getSystem().addSite( site ); getSystem().addSite( site );
SiteNode node = new SiteNode( site ); SiteNode node = new SiteNode( site, mChannelModel,
mChannelProcessingManager, getPlaylistManager(), mSourceManager );
getModel().addNode( node, getModel().addNode( node,
SystemNode.this, SystemNode.this,

View File

@@ -0,0 +1,60 @@
package dsp.filter.dc;
import sample.Listener;
import sample.real.RealBuffer;
public class DCRemovalFilter_RealBuffer implements Listener<RealBuffer>
{
private Listener<RealBuffer> mListener;
/**
* Removes DC bias present across the samples in the buffer by calculating
* the mean DC component and subtracting that component from each of the
* samples.
*/
public DCRemovalFilter_RealBuffer()
{
}
public void dispose()
{
mListener = null;
}
public RealBuffer filter( RealBuffer buffer )
{
double accumulator = 0.0d;
for( float sample: buffer.getSamples() )
{
accumulator += sample;
}
float mean = (float)( accumulator / (double)buffer.getSamples().length );
for( float sample: buffer.getSamples() )
{
sample -= mean;
}
return buffer;
}
@Override
public void receive( RealBuffer buffer )
{
if( mListener != null )
{
mListener.receive( filter( buffer ) );
}
}
public void setListener( Listener<RealBuffer> listener )
{
mListener = listener;
}
public void removeListener()
{
mListener = null;
}
}

View File

@@ -46,7 +46,7 @@ import org.slf4j.LoggerFactory;
import sample.Listener; import sample.Listener;
import sample.complex.Complex; import sample.complex.Complex;
import sample.complex.ComplexSampleListener; import sample.complex.ComplexSampleListener;
import source.tuner.frequency.FrequencyChangeListener; import source.tuner.frequency.IFrequencyChangeListener;
import buffer.FloatAveragingBuffer; import buffer.FloatAveragingBuffer;
import dsp.filter.interpolator.RealInterpolator; import dsp.filter.interpolator.RealInterpolator;
import dsp.symbol.Dibit; import dsp.symbol.Dibit;
@@ -79,7 +79,7 @@ public class LSMDemodulator implements Instrumentable, ComplexSampleListener
private CostasLoop mCostasLoop = new CostasLoop(); private CostasLoop mCostasLoop = new CostasLoop();
private FrequencyChangeListener mFrequencyChangeListener; private IFrequencyChangeListener mFrequencyChangeListener;
private EyeDiagramDataTap mEyeDiagramDataTap; private EyeDiagramDataTap mEyeDiagramDataTap;
@@ -153,12 +153,12 @@ public class LSMDemodulator implements Instrumentable, ComplexSampleListener
} }
} }
public void addListener( FrequencyChangeListener listener ) public void addListener( IFrequencyChangeListener listener )
{ {
mFrequencyChangeListener = listener; mFrequencyChangeListener = listener;
} }
public void removeListener( FrequencyChangeListener listener ) public void removeListener( IFrequencyChangeListener listener )
{ {
mFrequencyChangeListener = null; mFrequencyChangeListener = null;
} }

View File

@@ -48,7 +48,7 @@ import sample.Listener;
import sample.Provider; import sample.Provider;
import sample.complex.Complex; import sample.complex.Complex;
import sample.complex.ComplexSampleListener; import sample.complex.ComplexSampleListener;
import source.tuner.frequency.FrequencyChangeListener; import source.tuner.frequency.IFrequencyChangeListener;
import buffer.FloatAveragingBuffer; import buffer.FloatAveragingBuffer;
import dsp.filter.interpolator.RealInterpolator; import dsp.filter.interpolator.RealInterpolator;
import dsp.symbol.Dibit; import dsp.symbol.Dibit;
@@ -84,7 +84,7 @@ public class LSMDemodulator2 implements Instrumentable, ComplexSampleListener,
private CostasLoop mCostasLoop = new CostasLoop(); private CostasLoop mCostasLoop = new CostasLoop();
private FrequencyChangeListener mFrequencyChangeListener; private IFrequencyChangeListener mFrequencyChangeListener;
private EyeDiagramDataTap mEyeDiagramDataTap; private EyeDiagramDataTap mEyeDiagramDataTap;
@@ -143,12 +143,12 @@ public class LSMDemodulator2 implements Instrumentable, ComplexSampleListener,
} }
} }
public void addListener( FrequencyChangeListener listener ) public void addListener( IFrequencyChangeListener listener )
{ {
mFrequencyChangeListener = listener; mFrequencyChangeListener = listener;
} }
public void removeListener( FrequencyChangeListener listener ) public void removeListener( IFrequencyChangeListener listener )
{ {
mFrequencyChangeListener = null; mFrequencyChangeListener = null;
} }

View File

@@ -43,7 +43,9 @@ import javax.swing.JOptionPane;
import javax.swing.JSeparator; import javax.swing.JSeparator;
import javax.swing.KeyStroke; import javax.swing.KeyStroke;
import map.IconManager;
import map.MapService; import map.MapService;
import module.log.EventLogManager;
import net.miginfocom.swing.MigLayout; import net.miginfocom.swing.MigLayout;
import org.slf4j.Logger; import org.slf4j.Logger;
@@ -51,7 +53,9 @@ import org.slf4j.LoggerFactory;
import playlist.PlaylistManager; import playlist.PlaylistManager;
import properties.SystemProperties; import properties.SystemProperties;
import record.RecorderManager;
import settings.SettingsManager; import settings.SettingsManager;
import source.SourceManager;
import source.tuner.Tuner; import source.tuner.Tuner;
import source.tuner.TunerSelectionListener; import source.tuner.TunerSelectionListener;
import spectrum.SpectralDisplayPanel; import spectrum.SpectralDisplayPanel;
@@ -63,7 +67,6 @@ import com.jidesoft.swing.JideSplitPane;
import controller.ConfigurationControllerModel; import controller.ConfigurationControllerModel;
import controller.ControllerPanel; import controller.ControllerPanel;
import controller.ResourceManager;
import controller.ThreadPoolManager; import controller.ThreadPoolManager;
import controller.ThreadPoolManager.ThreadType; import controller.ThreadPoolManager.ThreadType;
import controller.channel.ChannelEventListener; import controller.channel.ChannelEventListener;
@@ -76,6 +79,7 @@ public class SDRTrunk
private final static Logger mLog = LoggerFactory.getLogger( SDRTrunk.class ); private final static Logger mLog = LoggerFactory.getLogger( SDRTrunk.class );
private ControllerPanel mControllerPanel; private ControllerPanel mControllerPanel;
private SettingsManager mSettingsManager;
private SpectralDisplayPanel mSpectralPanel; private SpectralDisplayPanel mSpectralPanel;
private JFrame mMainGui = new JFrame(); private JFrame mMainGui = new JFrame();
@@ -108,48 +112,53 @@ public class SDRTrunk
//Log current properties setting //Log current properties setting
SystemProperties.getInstance().logCurrentSettings(); SystemProperties.getInstance().logCurrentSettings();
ChannelModel channelModel = new ChannelModel(); mSettingsManager = new SettingsManager();
ChannelProcessingManager channelProcessingManager =
new ChannelProcessingManager( channelModel );
channelModel.addListener( channelProcessingManager );
ThreadPoolManager threadPoolManager = new ThreadPoolManager(); ThreadPoolManager threadPoolManager = new ThreadPoolManager();
SourceManager sourceManager = new SourceManager( mSettingsManager, threadPoolManager );
ChannelModel channelModel = new ChannelModel();
PlaylistManager playlistManager = new PlaylistManager( channelModel );
RecorderManager recorderManager = new RecorderManager( threadPoolManager );
EventLogManager eventLogManager = new EventLogManager();
ChannelProcessingManager channelProcessingManager =
new ChannelProcessingManager( channelModel, eventLogManager,
playlistManager, recorderManager, sourceManager, threadPoolManager );
channelModel.addListener( channelProcessingManager );
channelProcessingManager.addAudioPacketListener( recorderManager );
AliasActionManager aliasActionManager = new AliasActionManager( threadPoolManager ); AliasActionManager aliasActionManager = new AliasActionManager( threadPoolManager );
channelProcessingManager.addListener( aliasActionManager ); channelProcessingManager.addMessageListener( aliasActionManager );
AudioManager audioManager = new AudioManager( threadPoolManager );
channelProcessingManager.addAudioPacketListener( audioManager );
MapService mapService = new MapService( mSettingsManager );
channelProcessingManager.addMessageListener( mapService );
ChannelSelectionManager channelSelectionManager = ChannelSelectionManager channelSelectionManager =
new ChannelSelectionManager( channelModel ); new ChannelSelectionManager( channelModel );
channelModel.addListener( channelSelectionManager ); channelModel.addListener( channelSelectionManager );
//Initialize the playlist manager to load the saved playlist
playlistManager.init();
/** ConfigurationControllerModel configurationControllerModel =
* Construct the resource manager now, so that it can use the system new ConfigurationControllerModel( channelModel, channelProcessingManager,
* properties that were just loaded playlistManager, mSettingsManager, sourceManager );
*/
//TODO: get rid of resource manager ... below is start of breaking out
//the encapsulated pieces from the resource manager
PlaylistManager playlistManager = new PlaylistManager( channelModel );
ResourceManager resource =
new ResourceManager( playlistManager, threadPoolManager, channelModel );
AudioManager audio = resource.getAudioManager(); mControllerPanel = new ControllerPanel( audioManager, configurationControllerModel,
ConfigurationControllerModel configurationControllerModel = resource.getController(); channelModel, channelProcessingManager, mapService, playlistManager,
MapService map = resource.getMapService(); mSettingsManager, sourceManager );
SettingsManager settings = resource.getSettingsManager();
mControllerPanel = mSpectralPanel = new SpectralDisplayPanel( configurationControllerModel,
new ControllerPanel( audio, channelModel, channelProcessingManager, playlistManager, mSettingsManager );
configurationControllerModel,
channelModel,
channelProcessingManager,
map,
playlistManager,
settings );
mSpectralPanel = new SpectralDisplayPanel( channelModel,
configurationControllerModel, playlistManager, settings );
mTitle = getTitle(); mTitle = getTitle();
@@ -162,7 +171,7 @@ public class SDRTrunk
{ {
Runnable cml = new ChannelMemoryLogger(); Runnable cml = new ChannelMemoryLogger();
channelModel.addListener( (ChannelEventListener)cml ); channelModel.addListener( (ChannelEventListener)cml );
resource.getThreadPoolManager().scheduleFixedRate( threadPoolManager.scheduleFixedRate(
ThreadType.DECODER, cml, 5, TimeUnit.SECONDS ); ThreadType.DECODER, cml, 5, TimeUnit.SECONDS );
} }
@@ -277,7 +286,16 @@ public class SDRTrunk
@Override @Override
public void actionPerformed( ActionEvent arg0 ) public void actionPerformed( ActionEvent arg0 )
{ {
mControllerPanel.getController().showIconManager(); final IconManager iconManager = new IconManager( mSettingsManager, mMainGui );
EventQueue.invokeLater( new Runnable()
{
@Override
public void run()
{
iconManager.setVisible( true );
}
} );
} }
} ); } );
fileMenu.add( settingsMenu ); fileMenu.add( settingsMenu );

View File

@@ -33,6 +33,7 @@ import java.text.ParseException;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.HashMap; import java.util.HashMap;
import java.util.Iterator; import java.util.Iterator;
import java.util.List;
import javax.swing.JLabel; import javax.swing.JLabel;
import javax.swing.JPanel; import javax.swing.JPanel;
@@ -44,17 +45,17 @@ import org.slf4j.Logger;
import org.slf4j.LoggerFactory; import org.slf4j.LoggerFactory;
import source.tuner.frequency.FrequencyChangeEvent; import source.tuner.frequency.FrequencyChangeEvent;
import source.tuner.frequency.FrequencyChangeListener;
import source.tuner.frequency.FrequencyChangeEvent.Event; import source.tuner.frequency.FrequencyChangeEvent.Event;
import source.tuner.frequency.IFrequencyChangeListener;
import source.tuner.frequency.IFrequencyChangeProcessor;
public class JFrequencyControl extends JPanel implements FrequencyChangeListener public class JFrequencyControl extends JPanel implements IFrequencyChangeProcessor
{ {
private static final long serialVersionUID = 1L; private static final long serialVersionUID = 1L;
private final static Logger mLog = private final static Logger mLog =
LoggerFactory.getLogger( JFrequencyControl.class ); LoggerFactory.getLogger( JFrequencyControl.class );
private ArrayList<FrequencyChangeListener> mListeners = private List<IFrequencyChangeProcessor> mProcessors = new ArrayList<>();
new ArrayList<FrequencyChangeListener>();
private Color mHighlightColor = Color.YELLOW; private Color mHighlightColor = Color.YELLOW;
@@ -136,7 +137,7 @@ public class JFrequencyControl extends JPanel implements FrequencyChangeListener
@Override @Override
public void frequencyChanged( FrequencyChangeEvent event ) public void frequencyChanged( FrequencyChangeEvent event )
{ {
if( event.getEvent() == Event.FREQUENCY_CHANGE_NOTIFICATION ) if( event.getEvent() == Event.NOTIFICATION_FREQUENCY_CHANGE )
{ {
setFrequency( event.getValue().longValue(), false ); setFrequency( event.getValue().longValue(), false );
} }
@@ -177,10 +178,10 @@ public class JFrequencyControl extends JPanel implements FrequencyChangeListener
{ {
updateFrequency(); updateFrequency();
Iterator<FrequencyChangeListener> it = mListeners.iterator(); Iterator<IFrequencyChangeProcessor> it = mProcessors.iterator();
FrequencyChangeEvent event = FrequencyChangeEvent event =
new FrequencyChangeEvent( Event.FREQUENCY_CHANGE_NOTIFICATION, mFrequency ); new FrequencyChangeEvent( Event.NOTIFICATION_FREQUENCY_CHANGE, mFrequency );
while( it.hasNext() ) while( it.hasNext() )
{ {
@@ -188,14 +189,14 @@ public class JFrequencyControl extends JPanel implements FrequencyChangeListener
} }
} }
public void addListener( FrequencyChangeListener listener ) public void addListener( IFrequencyChangeProcessor processor )
{ {
mListeners.add( listener ); mProcessors.add( processor );
} }
public void removeListener( FrequencyChangeListener listener ) public void removeListener( IFrequencyChangeProcessor processor )
{ {
mListeners.remove( listener ); mProcessors.remove( processor );
} }
public class Digit extends JTextField public class Digit extends JTextField

View File

@@ -9,11 +9,13 @@ import java.util.List;
import module.Module; import module.Module;
import module.ProcessingChain; import module.ProcessingChain;
import source.Source; import source.Source;
import controller.channel.Channel.ChannelType;
public class InstrumentableProcessingChain extends ProcessingChain implements Instrumentable public class InstrumentableProcessingChain extends ProcessingChain implements Instrumentable
{ {
public InstrumentableProcessingChain() public InstrumentableProcessingChain()
{ {
super( ChannelType.STANDARD );
} }
public void setSource( Source source ) throws IllegalStateException public void setSource( Source source ) throws IllegalStateException

View File

@@ -13,8 +13,6 @@ import module.decode.config.DecodeConfiguration;
import net.miginfocom.swing.MigLayout; import net.miginfocom.swing.MigLayout;
import playlist.PlaylistManager; import playlist.PlaylistManager;
import source.IControllableFileSource; import source.IControllableFileSource;
import controller.ResourceManager;
import controller.ThreadPoolManager;
import controller.channel.ChannelModel; import controller.channel.ChannelModel;
public class DecoderSelectionFrame extends JInternalFrame public class DecoderSelectionFrame extends JInternalFrame
@@ -22,7 +20,7 @@ public class DecoderSelectionFrame extends JInternalFrame
private static final long serialVersionUID = 1L; private static final long serialVersionUID = 1L;
private DecodeComponentEditor mDecodeEditor = new DecodeComponentEditor( null ); private DecodeComponentEditor mDecodeEditor = new DecodeComponentEditor( null );
private ResourceManager mResourceManager; private PlaylistManager mPlaylistManager;
private IControllableFileSource mSource; private IControllableFileSource mSource;
private JDesktopPane mDesktop; private JDesktopPane mDesktop;
@@ -31,9 +29,7 @@ public class DecoderSelectionFrame extends JInternalFrame
IControllableFileSource source ) IControllableFileSource source )
{ {
ChannelModel channelModel = new ChannelModel(); ChannelModel channelModel = new ChannelModel();
mPlaylistManager = new PlaylistManager( channelModel );
mResourceManager = new ResourceManager( new PlaylistManager( channelModel ),
new ThreadPoolManager(), channelModel );
mDesktop = desktop; mDesktop = desktop;
mSource = source; mSource = source;
@@ -78,12 +74,7 @@ public class DecoderSelectionFrame extends JInternalFrame
if( config != null ) if( config != null )
{ {
DecoderViewFrame decoderFrame = new DecoderViewFrame( DecoderViewFrame decoderFrame = new DecoderViewFrame(
mResourceManager, mPlaylistManager, null, mSource );
config,
null,
null,
null,
mSource );
decoderFrame.setVisible( true ); decoderFrame.setVisible( true );

View File

@@ -57,22 +57,20 @@ import javax.swing.JSeparator;
import message.Message; import message.Message;
import module.Module; import module.Module;
import module.decode.DecoderFactory; import module.decode.DecoderFactory;
import module.decode.config.AuxDecodeConfiguration;
import module.decode.config.DecodeConfiguration; import module.decode.config.DecodeConfiguration;
import net.miginfocom.swing.MigLayout; import net.miginfocom.swing.MigLayout;
import org.slf4j.Logger; import org.slf4j.Logger;
import org.slf4j.LoggerFactory; import org.slf4j.LoggerFactory;
import record.config.RecordConfiguration; import playlist.PlaylistManager;
import sample.Listener; import sample.Listener;
import source.IControllableFileSource; import source.IControllableFileSource;
import source.Source; import source.Source;
import alias.AliasList; import controller.ThreadPoolManager;
import controller.ResourceManager; import controller.channel.Channel;
import controller.channel.Channel.ChannelType; import controller.channel.ChannelModel;
import controller.site.Site; import controller.channel.ChannelProcessingManager;
import controller.system.System;
public class DecoderViewFrame extends JInternalFrame public class DecoderViewFrame extends JInternalFrame
implements Listener<Message> implements Listener<Message>
@@ -88,29 +86,23 @@ public class DecoderViewFrame extends JInternalFrame
private HashMap<Tap,TapViewPanel> mPanelMap = private HashMap<Tap,TapViewPanel> mPanelMap =
new HashMap<Tap,TapViewPanel>(); new HashMap<Tap,TapViewPanel>();
public DecoderViewFrame( ResourceManager resourceManager, public DecoderViewFrame( PlaylistManager playlistManager,
DecodeConfiguration decodeConfig, Channel channel,
RecordConfiguration recordConfig,
AuxDecodeConfiguration auxConfig,
AliasList aliasList,
IControllableFileSource source ) IControllableFileSource source )
{ {
mSource = source; mSource = source;
mDecodeConfig = decodeConfig; mDecodeConfig = channel.getDecodeConfiguration();
mProcessingChain = new InstrumentableProcessingChain(); mProcessingChain = new InstrumentableProcessingChain();
List<Module> modules = DecoderFactory ChannelModel channelModel = new ChannelModel();
.getModules( ChannelType.STANDARD, ChannelProcessingManager channelProcessingManager =
resourceManager, new ChannelProcessingManager( channelModel, null,
decodeConfig, playlistManager, null, null, new ThreadPoolManager() );
recordConfig,
auxConfig, List<Module> modules = DecoderFactory.getModules( channelModel,
aliasList, channelProcessingManager, playlistManager, channel );
"Instrumented",
"Instrumented",
"Channel Name" );
mProcessingChain.addModules( modules ); mProcessingChain.addModules( modules );

View File

@@ -50,7 +50,7 @@ import org.slf4j.LoggerFactory;
import settings.Setting; import settings.Setting;
import settings.SettingChangeListener; import settings.SettingChangeListener;
import controller.ResourceManager; import settings.SettingsManager;
public class IconManager extends JFrame public class IconManager extends JFrame
implements ActionListener, SettingChangeListener implements ActionListener, SettingChangeListener
@@ -62,8 +62,6 @@ public class IconManager extends JFrame
private final static Logger mLog = private final static Logger mLog =
LoggerFactory.getLogger( IconManager.class ); LoggerFactory.getLogger( IconManager.class );
private ResourceManager mResourceManager;
private static final String sMSG_NEW = "Type a name for the new icon, " private static final String sMSG_NEW = "Type a name for the new icon, "
+ "select the file, and click Save,\nor Cancel to reset"; + "select the file, and click Save,\nor Cancel to reset";
private static final String sMSG_EDIT = "Change the name for the selected \n" private static final String sMSG_EDIT = "Change the name for the selected \n"
@@ -81,9 +79,11 @@ public class IconManager extends JFrame
private JFileChooser mFileChooser; private JFileChooser mFileChooser;
private Mode mMode = Mode.NORMAL; private Mode mMode = Mode.NORMAL;
public IconManager( ResourceManager resourceManager, Component displayOver ) private SettingsManager mSettingsManager;
public IconManager( SettingsManager settingsManager, Component displayOver )
{ {
mResourceManager = resourceManager; mSettingsManager = settingsManager;
init( displayOver ); init( displayOver );
} }
@@ -128,7 +128,7 @@ public class IconManager extends JFrame
/** /**
* MapIcon list * MapIcon list
*/ */
MapIcon[] icons = mResourceManager.getSettingsManager().getMapIcons(); MapIcon[] icons = mSettingsManager.getMapIcons();
Arrays.sort( icons ); Arrays.sort( icons );
mIconList = new JList<MapIcon>( icons ); mIconList = new JList<MapIcon>( icons );
@@ -176,8 +176,7 @@ public class IconManager extends JFrame
@Override @Override
public void actionPerformed( ActionEvent e ) public void actionPerformed( ActionEvent e )
{ {
mResourceManager.getSettingsManager() mSettingsManager.setDefaultIcon( icon );
.setDefaultIcon( icon );
refreshList(); refreshList();
} }
@@ -193,8 +192,7 @@ public class IconManager extends JFrame
@Override @Override
public void actionPerformed( ActionEvent arg0 ) public void actionPerformed( ActionEvent arg0 )
{ {
mResourceManager.getSettingsManager() mSettingsManager.deleteMapIcon( icon );
.deleteMapIcon( icon );
} }
} ); } );
@@ -350,7 +348,7 @@ public class IconManager extends JFrame
private void refreshList() private void refreshList()
{ {
MapIcon[] icons = mResourceManager.getSettingsManager().getMapIcons(); MapIcon[] icons = mSettingsManager.getMapIcons();
Arrays.sort( icons ); Arrays.sort( icons );
@@ -371,8 +369,7 @@ public class IconManager extends JFrame
{ {
if( path != null && !path.isEmpty() ) if( path != null && !path.isEmpty() )
{ {
mResourceManager.getSettingsManager() mSettingsManager.addMapIcon( new MapIcon( name, path, true ) );
.addMapIcon( new MapIcon( name, path, true ) );
} }
else else
{ {
@@ -400,8 +397,7 @@ public class IconManager extends JFrame
{ {
selected.setName( name ); selected.setName( name );
selected.setPath( path ); selected.setPath( path );
mResourceManager.getSettingsManager() mSettingsManager.updatMapIcon( selected, name, path );
.updatMapIcon( selected, name, path );
} }
else else
{ {

View File

@@ -46,17 +46,12 @@ public class MapPanel extends JPanel implements PlottableUpdateListener
private JXMapViewer mMapViewer = new JXMapViewer(); private JXMapViewer mMapViewer = new JXMapViewer();
private PlottableEntityPainter mMapPainter; private PlottableEntityPainter mMapPainter;
public MapPanel( MapService mapService, public MapPanel( MapService mapService, SettingsManager settingsManager )
SettingsManager settingsManager,
ChannelProcessingManager channelProcessingManager )
{ {
mSettingsManager = settingsManager; mSettingsManager = settingsManager;
mMapService = mapService; mMapService = mapService;
mMapPainter = new PlottableEntityPainter( mSettingsManager ); mMapPainter = new PlottableEntityPainter( mSettingsManager );
/* Add Map Service as message listener to receive all messages */
channelProcessingManager.addListener( (Listener<Message>)mMapService );
init(); init();
} }

View File

@@ -30,7 +30,6 @@ import sample.Listener;
import settings.SettingsManager; import settings.SettingsManager;
import alias.Alias; import alias.Alias;
import controller.NamingThreadFactory; import controller.NamingThreadFactory;
import controller.ResourceManager;
public class MapService implements Listener<Message> public class MapService implements Listener<Message>
{ {
@@ -49,11 +48,11 @@ public class MapService implements Listener<Message>
private HashMap<String,PlottableEntity> mEntities = private HashMap<String,PlottableEntity> mEntities =
new HashMap<String,PlottableEntity>(); new HashMap<String,PlottableEntity>();
private ResourceManager mResourceManager; private SettingsManager mSettingsManager;
public MapService( ResourceManager resourceManager ) public MapService( SettingsManager resourceManager )
{ {
mResourceManager = resourceManager; mSettingsManager = resourceManager;
// scheduler.scheduleAtFixedRate( new CullThread(), 5, 5, TimeUnit.MINUTES ); // scheduler.scheduleAtFixedRate( new CullThread(), 5, 5, TimeUnit.MINUTES );
} }
@@ -111,8 +110,7 @@ public class MapService implements Listener<Message>
iconName = SettingsManager.DEFAULT_ICON; iconName = SettingsManager.DEFAULT_ICON;
} }
icon = mResourceManager.getSettingsManager() icon = mSettingsManager.getMapIcon( iconName );
.getMapIcon( iconName );
} }
if( color == null ) if( color == null )

View File

@@ -1,6 +1,6 @@
/******************************************************************************* /*******************************************************************************
* SDR Trunk * SDR Trunk
* Copyright (C) 2015 Dennis Sheirer * Copyright (C) 2015-2016 Dennis Sheirer
* *
* This program is free software: you can redistribute it and/or modify * 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 * it under the terms of the GNU General Public License as published by
@@ -26,8 +26,11 @@ import message.IMessageListener;
import message.IMessageProvider; import message.IMessageProvider;
import message.Message; import message.Message;
import module.decode.event.CallEvent; import module.decode.event.CallEvent;
import module.decode.event.CallEventModel;
import module.decode.event.ICallEventListener; import module.decode.event.ICallEventListener;
import module.decode.event.ICallEventProvider; import module.decode.event.ICallEventProvider;
import module.decode.event.MessageActivityModel;
import module.decode.state.ChannelState;
import module.decode.state.DecoderState; import module.decode.state.DecoderState;
import module.decode.state.DecoderStateEvent; import module.decode.state.DecoderStateEvent;
import module.decode.state.DecoderStateEvent.Event; import module.decode.state.DecoderStateEvent.Event;
@@ -42,16 +45,19 @@ import sample.Broadcaster;
import sample.Listener; import sample.Listener;
import sample.complex.ComplexBuffer; import sample.complex.ComplexBuffer;
import sample.complex.IComplexBufferListener; import sample.complex.IComplexBufferListener;
import sample.real.IRealBufferListener; import sample.real.IFilteredRealBufferListener;
import sample.real.IRealBufferProvider; import sample.real.IFilteredRealBufferProvider;
import sample.real.IUnFilteredRealBufferListener;
import sample.real.IUnFilteredRealBufferProvider;
import sample.real.RealBuffer; import sample.real.RealBuffer;
import source.ComplexSource; import source.ComplexSource;
import source.RealSource; import source.RealSource;
import source.Source; import source.Source;
import source.SourceException; import source.SourceException;
import source.tuner.TunerChannelSource; import source.tuner.TunerChannelSource;
import source.tuner.frequency.FrequencyCorrectionControl; import source.tuner.frequency.FrequencyChangeEvent;
import source.tuner.frequency.IFrequencyCorrectionController; import source.tuner.frequency.IFrequencyChangeListener;
import source.tuner.frequency.IFrequencyChangeProvider;
import audio.AudioPacket; import audio.AudioPacket;
import audio.IAudioPacketListener; import audio.IAudioPacketListener;
import audio.IAudioPacketProvider; import audio.IAudioPacketProvider;
@@ -62,6 +68,7 @@ import audio.squelch.ISquelchStateListener;
import audio.squelch.ISquelchStateProvider; import audio.squelch.ISquelchStateProvider;
import audio.squelch.SquelchState; import audio.squelch.SquelchState;
import controller.ThreadPoolManager; import controller.ThreadPoolManager;
import controller.channel.Channel.ChannelType;
import controller.channel.ChannelEvent; import controller.channel.ChannelEvent;
import controller.channel.IChannelEventListener; import controller.channel.IChannelEventListener;
import controller.channel.IChannelEventProvider; import controller.channel.IChannelEventProvider;
@@ -95,8 +102,10 @@ public class ProcessingChain implements IChannelEventListener
private Broadcaster<ChannelEvent> mChannelEventBroadcaster = new Broadcaster<>(); private Broadcaster<ChannelEvent> mChannelEventBroadcaster = new Broadcaster<>();
private Broadcaster<ComplexBuffer> mComplexBufferBroadcaster = new Broadcaster<>(); private Broadcaster<ComplexBuffer> mComplexBufferBroadcaster = new Broadcaster<>();
private Broadcaster<DecoderStateEvent> mDecoderStateEventBroadcaster = new Broadcaster<>(); private Broadcaster<DecoderStateEvent> mDecoderStateEventBroadcaster = new Broadcaster<>();
private Broadcaster<FrequencyChangeEvent> mFrequencyChangeEventBroadcaster = new Broadcaster<>();
private Broadcaster<Message> mMessageBroadcaster = new Broadcaster<>(); private Broadcaster<Message> mMessageBroadcaster = new Broadcaster<>();
private Broadcaster<RealBuffer> mRealBufferBroadcaster = new Broadcaster<>(); private Broadcaster<RealBuffer> mFilteredRealBufferBroadcaster = new Broadcaster<>();
private Broadcaster<RealBuffer> mUnFilteredRealBufferBroadcaster = new Broadcaster<>();
private Broadcaster<SquelchState> mSquelchStateBroadcaster = new Broadcaster<>(); private Broadcaster<SquelchState> mSquelchStateBroadcaster = new Broadcaster<>();
// private ThreadPoolManager mThreadPoolManager; // private ThreadPoolManager mThreadPoolManager;
@@ -104,10 +113,48 @@ public class ProcessingChain implements IChannelEventListener
protected Source mSource; protected Source mSource;
private List<Module> mModules = new ArrayList<>(); private List<Module> mModules = new ArrayList<>();
private IFrequencyCorrectionController mFrequencyCorrectionController; private CallEventModel mCallEventModel;
private ChannelState mChannelState;
private MessageActivityModel mMessageActivityModel;
public ProcessingChain() public ProcessingChain( ChannelType channelType )
{ {
this( new ThreadPoolManager(), channelType );
}
public ProcessingChain( ThreadPoolManager threadManager,
ChannelType channelType )
{
mThreadPoolManager = threadManager;
mChannelState = new ChannelState( mThreadPoolManager, channelType );
addModule( mChannelState );
mCallEventModel = new CallEventModel();
addCallEventListener( mCallEventModel );
}
public MessageActivityModel getMessageActivityModel()
{
return mMessageActivityModel;
}
public CallEventModel getCallEventModel()
{
return mCallEventModel;
}
public ChannelState getChannelState()
{
return mChannelState;
}
public void setMessageActivityModel( MessageActivityModel model )
{
mMessageActivityModel = model;
addMessageListener( mMessageActivityModel );
} }
public void dispose() public void dispose()
@@ -121,14 +168,16 @@ public class ProcessingChain implements IChannelEventListener
mModules.clear(); mModules.clear();
mFrequencyCorrectionController = null;
mThreadPoolManager = null;
mBufferProcessingTask = null;
mAudioPacketBroadcaster.dispose(); mAudioPacketBroadcaster.dispose();
mCallEventBroadcaster.dispose(); mCallEventBroadcaster.dispose();
mChannelEventBroadcaster.dispose(); mChannelEventBroadcaster.dispose();
mComplexBufferBroadcaster.dispose(); mComplexBufferBroadcaster.dispose();
mMessageBroadcaster.dispose(); mMessageBroadcaster.dispose();
mRealBufferBroadcaster.dispose(); mFilteredRealBufferBroadcaster.dispose();
mSquelchStateBroadcaster.dispose(); mSquelchStateBroadcaster.dispose();
} }
@@ -147,7 +196,7 @@ public class ProcessingChain implements IChannelEventListener
* Indicates if this processing chain is currently receiving samples from * Indicates if this processing chain is currently receiving samples from
* a source and sending those samples to the decoders. * a source and sending those samples to the decoders.
*/ */
public boolean processing() public boolean isProcessing()
{ {
return mRunning.get(); return mRunning.get();
} }
@@ -160,28 +209,6 @@ public class ProcessingChain implements IChannelEventListener
return mSource != null; return mSource != null;
} }
/**
* Indicates if one of the modules provides frequency error control.
*/
public boolean hasFrequencyCorrectionControl()
{
return mFrequencyCorrectionController != null &&
mFrequencyCorrectionController.hasFrequencyCorrectionControl();
}
/**
* Frequency correction controller. Can be null.
*/
public FrequencyCorrectionControl getFrequencyCorrectionControl()
{
if( mFrequencyCorrectionController != null )
{
return mFrequencyCorrectionController.getFrequencyCorrectionControl();
}
return null;
}
/** /**
* Applies a sample source to this processing chain. Processing won't * Applies a sample source to this processing chain. Processing won't
* start until the start() method is invoked. * start until the start() method is invoked.
@@ -194,7 +221,7 @@ public class ProcessingChain implements IChannelEventListener
*/ */
public void setSource( Source source ) throws IllegalStateException public void setSource( Source source ) throws IllegalStateException
{ {
if( processing() ) if( isProcessing() )
{ {
throw new IllegalStateException( "Processing chain is currently " throw new IllegalStateException( "Processing chain is currently "
+ "processing. Invoke stop() on the processing chain before " + "processing. Invoke stop() on the processing chain before "
@@ -202,23 +229,6 @@ public class ProcessingChain implements IChannelEventListener
} }
mSource = source; mSource = source;
/* Establish two-way communication between the tuner channel source and
* the decoder for fine tuning frequency error correction feedback from
* the decoder. The tuner channel source will also notify the frequency
* controller during frequency changes to allow the controller to reset
* frequency error tracking */
if( mSource != null &&
mSource instanceof TunerChannelSource &&
hasFrequencyCorrectionControl() )
{
TunerChannelSource channel = (TunerChannelSource)mSource;
FrequencyCorrectionControl control = getFrequencyCorrectionControl();
channel.setFrequencyChangeListener( control );
control.setFrequencyChangeListener( channel );
}
} }
/** /**
@@ -247,24 +257,45 @@ public class ProcessingChain implements IChannelEventListener
return decoderStates; return decoderStates;
} }
/**
* Adds the list of modules to this processing chain
*/
public void addModules( List<Module> modules )
{
for( Module module: modules )
{
addModule( module );
}
}
/** /**
* Adds a module to the processing chain. Each module is tested for the * Adds a module to the processing chain. Each module is tested for the
* interfaces that it supports and is registered or receives a listener * interfaces that it supports and is registered or receives a listener
* to consume or produce the supported interface data type. All elements * to consume or produce the supported interface data type. All elements
* that are produced by any component are automatically routed to all other * and events that are produced by any module are automatically routed to
* components that support the corresponding listener interface. * all other components that support the corresponding listener interface.
* *
* At least one module should consume complex samples and either produce * At least one module should consume complex samples and either produce
* decoded messages and/or audio, or produce decoded real sample buffers * decoded messages and/or audio, or produce decoded real sample buffers
* for all other modules to consume. * for all other modules to consume.
* *
* @param module - processing module, demodulator or decoder * @param module - processing module, demodulator, decoder, source, state
* machine, etc.
*/ */
public void addModule( Module module ) public void addModule( Module module )
{ {
mModules.add( module ); mModules.add( module );
/* >>>>>>>>>>>>>>>>>>>>>>>>>>>>>> Listeners <<<<<<<<<<<<<<<<<<<<<<<<<<< */ registerListeners( module );
registerProviders( module );
}
/**
* Registers the module as a listener to each of the broadcasters that
* provide the data interface(s) supported by the module.
*/
private void registerListeners( Module module )
{
if( module instanceof IAudioPacketListener ) if( module instanceof IAudioPacketListener )
{ {
mAudioPacketBroadcaster.addListener( mAudioPacketBroadcaster.addListener(
@@ -295,6 +326,12 @@ public class ProcessingChain implements IChannelEventListener
((IDecoderStateEventListener)module).getDecoderStateListener() ); ((IDecoderStateEventListener)module).getDecoderStateListener() );
} }
if( module instanceof IFrequencyChangeListener )
{
mFrequencyChangeEventBroadcaster.addListener(
((IFrequencyChangeListener)module).getFrequencyChangeListener());
}
if( module instanceof IMessageListener ) if( module instanceof IMessageListener )
{ {
mMessageBroadcaster.addListener( mMessageBroadcaster.addListener(
@@ -307,10 +344,10 @@ public class ProcessingChain implements IChannelEventListener
((IMetadataListener)module).getMetadataListener() ); ((IMetadataListener)module).getMetadataListener() );
} }
if( module instanceof IRealBufferListener ) if( module instanceof IFilteredRealBufferListener )
{ {
mRealBufferBroadcaster.addListener( mFilteredRealBufferBroadcaster.addListener(
((IRealBufferListener)module).getRealBufferListener() ); ((IFilteredRealBufferListener)module).getFilteredRealBufferListener() );
} }
if( module instanceof ISquelchStateListener ) if( module instanceof ISquelchStateListener )
@@ -319,7 +356,19 @@ public class ProcessingChain implements IChannelEventListener
((ISquelchStateListener)module).getSquelchStateListener() ); ((ISquelchStateListener)module).getSquelchStateListener() );
} }
/* >>>>>>>>>>>>>>>>>>> Providers <<<<<<<<<<<<<<<<<<<<<<<<< */ if( module instanceof IUnFilteredRealBufferListener )
{
mFilteredRealBufferBroadcaster.addListener(
((IUnFilteredRealBufferListener)module).getUnFilteredRealBufferListener() );
}
}
/**
* Registers the broadcaster(s) as listeners to the module for each
* provider interface that is supported by the module.
*/
private void registerProviders( Module module )
{
if( module instanceof IAudioPacketProvider ) if( module instanceof IAudioPacketProvider )
{ {
((IAudioPacketProvider)module).setAudioPacketListener( ((IAudioPacketProvider)module).setAudioPacketListener(
@@ -343,9 +392,10 @@ public class ProcessingChain implements IChannelEventListener
mDecoderStateEventBroadcaster ); mDecoderStateEventBroadcaster );
} }
if( module instanceof IFrequencyCorrectionController ) if( module instanceof IFrequencyChangeProvider )
{ {
mFrequencyCorrectionController = (IFrequencyCorrectionController)module; ((IFrequencyChangeProvider)module).setFrequencyChangeListener(
mFrequencyChangeEventBroadcaster );
} }
if( module instanceof IMessageProvider ) if( module instanceof IMessageProvider )
@@ -359,9 +409,10 @@ public class ProcessingChain implements IChannelEventListener
mMetadataBroadcaster ); mMetadataBroadcaster );
} }
if( module instanceof IRealBufferProvider ) if( module instanceof IFilteredRealBufferProvider )
{ {
((IRealBufferProvider)module).setRealBufferListener( mRealBufferBroadcaster ); ((IFilteredRealBufferProvider)module)
.setFilteredRealBufferListener( mFilteredRealBufferBroadcaster );
} }
if( module instanceof ISquelchStateProvider ) if( module instanceof ISquelchStateProvider )
@@ -369,20 +420,14 @@ public class ProcessingChain implements IChannelEventListener
((ISquelchStateProvider)module).setSquelchStateListener( ((ISquelchStateProvider)module).setSquelchStateListener(
mSquelchStateBroadcaster ); mSquelchStateBroadcaster );
} }
}
/** if( module instanceof IUnFilteredRealBufferProvider )
* Adds the list of modules to this processing chain
*/
public void addModules( List<Module> modules )
{
for( Module module: modules )
{ {
addModule( module ); ((IUnFilteredRealBufferProvider)module)
.setUnFilteredRealBufferListener( mUnFilteredRealBufferBroadcaster );
} }
} }
/** /**
* Starts processing if the chain has a valid source. Invocations on an * Starts processing if the chain has a valid source. Invocations on an
* already started chain have no effect. * already started chain have no effect.
@@ -421,7 +466,7 @@ public class ProcessingChain implements IChannelEventListener
((ComplexSource)mSource).setListener( mComplexBufferBroadcaster ); ((ComplexSource)mSource).setListener( mComplexBufferBroadcaster );
break; break;
case REAL: case REAL:
((RealSource)mSource).setListener( mRealBufferBroadcaster ); ((RealSource)mSource).setListener( mFilteredRealBufferBroadcaster );
break; break;
default: default:
throw new IllegalArgumentException( "Unrecognized source " throw new IllegalArgumentException( "Unrecognized source "
@@ -448,7 +493,7 @@ public class ProcessingChain implements IChannelEventListener
} }
else else
{ {
mLog.debug( "Source is null on start()" ); mLog.error( "Source is null on start()" );
} }
} }
} }
@@ -469,7 +514,7 @@ public class ProcessingChain implements IChannelEventListener
((ComplexSource)mSource).removeListener( mComplexBufferBroadcaster ); ((ComplexSource)mSource).removeListener( mComplexBufferBroadcaster );
break; break;
case REAL: case REAL:
((RealSource)mSource).removeListener( mRealBufferBroadcaster ); ((RealSource)mSource).removeListener( mFilteredRealBufferBroadcaster );
break; break;
default: default:
throw new IllegalArgumentException( "Unrecognized source " throw new IllegalArgumentException( "Unrecognized source "
@@ -585,12 +630,12 @@ public class ProcessingChain implements IChannelEventListener
public void addRealBufferListener( Listener<RealBuffer> listener ) public void addRealBufferListener( Listener<RealBuffer> listener )
{ {
mRealBufferBroadcaster.addListener( listener ); mFilteredRealBufferBroadcaster.addListener( listener );
} }
public void removeRealBufferListener( Listener<RealBuffer> listener ) public void removeRealBufferListener( Listener<RealBuffer> listener )
{ {
mRealBufferBroadcaster.removeListener( listener ); mFilteredRealBufferBroadcaster.removeListener( listener );
} }
@Override @Override

View File

@@ -1,6 +1,6 @@
/******************************************************************************* /*******************************************************************************
* SDR Trunk * 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 * 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 * 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 module.decode.config.AuxDecodeConfiguration;
import controller.channel.AbstractChannelEditor; import controller.channel.AbstractChannelEditor;
import controller.channel.ChannelNode; import controller.channel.Channel;
import controller.channel.ConfigurationValidationException;
public class AuxDecodeComponentEditor extends AbstractChannelEditor public class AuxDecodeComponentEditor extends AbstractChannelEditor
{ {
@@ -35,9 +36,9 @@ public class AuxDecodeComponentEditor extends AbstractChannelEditor
private HashMap<DecoderType,AuxDecoderCheckBox> mControls = private HashMap<DecoderType,AuxDecoderCheckBox> mControls =
new HashMap<DecoderType,AuxDecoderCheckBox>(); new HashMap<DecoderType,AuxDecoderCheckBox>();
public AuxDecodeComponentEditor( ChannelNode channelNode ) public AuxDecodeComponentEditor( Channel channel )
{ {
super( channelNode ); super( channel );
List<DecoderType> decoders = DecoderType.getAuxDecoders(); List<DecoderType> decoders = DecoderType.getAuxDecoders();
@@ -60,7 +61,7 @@ public class AuxDecodeComponentEditor extends AbstractChannelEditor
public AuxDecodeConfiguration getConfig() public AuxDecodeConfiguration getConfig()
{ {
return getChannelNode().getChannel().getAuxDecodeConfiguration(); return getChannel().getAuxDecodeConfiguration();
} }
@Override @Override
@@ -107,4 +108,18 @@ public class AuxDecodeComponentEditor extends AbstractChannelEditor
mDecoderType = decoder; 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 * 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 * 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 * it under the terms of the GNU General Public License as published by
@@ -17,7 +18,6 @@
******************************************************************************/ ******************************************************************************/
package module.decode; package module.decode;
import java.awt.event.ActionEvent; import java.awt.event.ActionEvent;
import java.awt.event.ActionListener; import java.awt.event.ActionListener;
@@ -30,11 +30,10 @@ import module.decode.config.DecodeConfigFactory;
import module.decode.config.DecodeConfiguration; import module.decode.config.DecodeConfiguration;
import net.miginfocom.swing.MigLayout; import net.miginfocom.swing.MigLayout;
import playlist.PlaylistManager; import playlist.PlaylistManager;
import controller.Editor;
import controller.channel.AbstractChannelEditor; import controller.channel.AbstractChannelEditor;
import controller.channel.Channel; import controller.channel.Channel;
import controller.channel.ChannelNode; import controller.channel.ChannelConfigurationEditor;
import controller.channel.ChannelValidationException; import controller.channel.ConfigurationValidationException;
public class DecodeComponentEditor extends AbstractChannelEditor public class DecodeComponentEditor extends AbstractChannelEditor
{ {
@@ -48,13 +47,12 @@ public class DecodeComponentEditor extends AbstractChannelEditor
public DecodeComponentEditor( PlaylistManager playlistManager ) public DecodeComponentEditor( PlaylistManager playlistManager )
{ {
this( new ChannelNode( new Channel() ), playlistManager ); this( playlistManager, new Channel() );
} }
public DecodeComponentEditor( ChannelNode channelNode, public DecodeComponentEditor( PlaylistManager playlistMangager, Channel channel )
PlaylistManager playlistMangager )
{ {
super( channelNode ); super( channel );
mPlaylistManager = playlistMangager; mPlaylistManager = playlistMangager;
@@ -87,17 +85,13 @@ public class DecodeComponentEditor extends AbstractChannelEditor
{ {
DecodeConfiguration config; DecodeConfiguration config;
if( mChannelNode.getChannel() if( mChannel.getDecodeConfiguration().getDecoderType() == selected )
.getDecodeConfiguration().getDecoderType() ==
selected )
{ {
config = mChannelNode.getChannel() config = mChannel.getDecodeConfiguration();
.getDecodeConfiguration();
} }
else else
{ {
config = DecodeConfigFactory config = DecodeConfigFactory.getDecodeConfiguration( selected );
.getDecodeConfiguration( selected );
} }
//Remove the existing one //Remove the existing one
@@ -108,7 +102,7 @@ public class DecodeComponentEditor extends AbstractChannelEditor
//Change to the new one //Change to the new one
mEditor = DecoderFactory.getEditorPanel( config, mEditor = DecoderFactory.getEditorPanel( config,
mChannelNode, mPlaylistManager ); mChannel, mPlaylistManager );
add( mEditor, "span 2,center" ); add( mEditor, "span 2,center" );
@@ -125,8 +119,7 @@ public class DecodeComponentEditor extends AbstractChannelEditor
public void reset() public void reset()
{ {
final DecoderType decoder = mChannelNode.getChannel() final DecoderType decoder = mChannel.getDecodeConfiguration().getDecoderType();
.getDecodeConfiguration().getDecoderType();
SwingUtilities.invokeLater(new Runnable() SwingUtilities.invokeLater(new Runnable()
{ {
@@ -155,18 +148,31 @@ public class DecodeComponentEditor extends AbstractChannelEditor
} }
//The component that calls save will invoke the change broadcast //The component that calls save will invoke the change broadcast
mChannelNode.getChannel() mChannel.setDecodeConfiguration( mEditor.getConfig() );
.setDecodeConfiguration( mEditor.getConfig() );
} }
/** // /**
* Validates the editor against the current decode editor // * Validates the editor against the current decode editor
*/ // */
@Override // @Override
public void validate( Editor editor ) throws ChannelValidationException // public void validate( ChannelConfigurationEditor editor ) throws ConfigurationValidationException
{ // {
super.validate( editor ); // super.validate( editor );
//
// mEditor.validate( editor );
// }
@Override
public void setConfiguration( Channel channel )
{
// 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 module.decode.config.DecodeConfiguration;
import net.miginfocom.swing.MigLayout; 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; private static final long serialVersionUID = 1L;
@@ -110,7 +112,16 @@ public class DecodeEditor extends Editor
} }
@Override @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.NBFMDecoderPanel;
import module.decode.nbfm.NBFMEditor; import module.decode.nbfm.NBFMEditor;
import module.decode.p25.DecodeConfigP25Phase1; import module.decode.p25.DecodeConfigP25Phase1;
import module.decode.p25.P25DecodeEditor;
import module.decode.p25.P25Decoder.Modulation; import module.decode.p25.P25Decoder.Modulation;
import module.decode.p25.P25DecoderPanel; import module.decode.p25.P25DecoderPanel;
import module.decode.p25.P25DecoderState; import module.decode.p25.P25DecoderState;
import module.decode.p25.P25DecodeEditor;
import module.decode.p25.P25_C4FMDecoder; import module.decode.p25.P25_C4FMDecoder;
import module.decode.p25.P25_LSMDecoder; import module.decode.p25.P25_LSMDecoder;
import module.decode.p25.audio.P25AudioModule; import module.decode.p25.audio.P25AudioModule;
@@ -84,6 +84,7 @@ import module.decode.tait.Tait1200Decoder;
import module.decode.tait.Tait1200DecoderPanel; import module.decode.tait.Tait1200DecoderPanel;
import module.decode.tait.Tait1200DecoderState; import module.decode.tait.Tait1200DecoderState;
import module.demodulate.am.AMDemodulatorModule; import module.demodulate.am.AMDemodulatorModule;
import module.demodulate.audio.DemodulatedAudioFilterModule;
import module.demodulate.fm.FMDemodulatorModule; import module.demodulate.fm.FMDemodulatorModule;
import org.slf4j.Logger; import org.slf4j.Logger;
@@ -97,12 +98,11 @@ import settings.SettingsManager;
import util.TimeStamp; import util.TimeStamp;
import alias.AliasList; import alias.AliasList;
import audio.AudioModule; import audio.AudioModule;
import controller.ResourceManager; import controller.channel.Channel;
import controller.channel.Channel.ChannelType; import controller.channel.Channel.ChannelType;
import controller.channel.ChannelNode; import controller.channel.ChannelModel;
import controller.channel.ChannelProcessingManager;
import controller.channel.map.ChannelMap; import controller.channel.map.ChannelMap;
import controller.site.Site;
import controller.system.System;
import filter.AllPassFilter; import filter.AllPassFilter;
import filter.FilterSet; import filter.FilterSet;
import filter.IFilter; import filter.IFilter;
@@ -120,72 +120,46 @@ public class DecoderFactory
* Returns a list of one primary decoder and any auxiliary decoders, as * Returns a list of one primary decoder and any auxiliary decoders, as
* specified in the configurations. * 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 * @return list of configured decoders
*/ */
public static List<Module> getModules( ChannelType channelType, public static List<Module> getModules( ChannelModel channelModel,
ResourceManager resourceManager, ChannelProcessingManager channelProcessingManager,
DecodeConfiguration decodeConfig, PlaylistManager playlistManager,
RecordConfiguration recordConfig, Channel channel )
AuxDecodeConfiguration auxConfig,
AliasList aliasList,
String system,
String site,
String channelName )
{ {
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; 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 * 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, public static List<Module> getPrimaryModules( ChannelModel channelModel,
DecodeConfiguration decodeConfig, ChannelProcessingManager channelProcessingManager,
RecordConfiguration recordConfig, PlaylistManager playlistManager,
AliasList aliasList, AliasList aliasList,
String system, Channel channel )
String site,
String channelName,
ResourceManager resourceManager )
{ {
List<Module> modules = new ArrayList<Module>(); List<Module> modules = new ArrayList<Module>();
ChannelType channelType = channel.getChannelType();
/* Baseband low-pass filter pass and stop frequencies */ /* Baseband low-pass filter pass and stop frequencies */
int pass = decodeConfig.getDecoderType().getChannelBandwidth() / 2; DecodeConfiguration decodeConfig = channel.getDecodeConfiguration();
int stop = pass + 1250;
int iqPass = decodeConfig.getDecoderType().getChannelBandwidth() / 2;
int iqStop = iqPass + 1250;
RecordConfiguration recordConfig = channel.getRecordConfiguration();
boolean recordAudio = recordConfig == null ? false : boolean recordAudio = recordConfig == null ? false :
recordConfig.getRecorders().contains( RecorderType.AUDIO ); recordConfig.getRecorders().contains( RecorderType.AUDIO );
@@ -193,41 +167,44 @@ public class DecoderFactory
switch( decodeConfig.getDecoderType() ) switch( decodeConfig.getDecoderType() )
{ {
case AM: case AM:
modules.add( new AMDemodulatorModule() );
modules.add( new AMDecoder( decodeConfig ) ); modules.add( new AMDecoder( decodeConfig ) );
modules.add( new AlwaysUnsquelchedDecoderState( DecoderType.AM, channelName ) ); modules.add( new AlwaysUnsquelchedDecoderState( DecoderType.AM, channel.getName() ) );
modules.add( new AudioModule( recordAudio, REMOVE_DC ) ); modules.add( new AMDemodulatorModule() );
modules.add( new DemodulatedAudioFilterModule( 4000, 6000 ));
modules.add( new AudioModule( recordAudio ) );
break; break;
case NBFM: case NBFM:
modules.add( new AudioModule( recordAudio, NO_REMOVE_DC ) );
modules.add( new NBFMDecoder( decodeConfig ) ); modules.add( new NBFMDecoder( decodeConfig ) );
modules.add( new AlwaysUnsquelchedDecoderState( DecoderType.NBFM, channelName ) ); modules.add( new AlwaysUnsquelchedDecoderState( DecoderType.NBFM, channel.getName() ) );
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; break;
case LTR_STANDARD: case LTR_STANDARD:
modules.add( new AudioModule( recordAudio, REMOVE_DC ) );
MessageDirection direction = ((DecodeConfigLTRStandard)decodeConfig).getMessageDirection(); MessageDirection direction = ((DecodeConfigLTRStandard)decodeConfig).getMessageDirection();
modules.add( new LTRStandardDecoder( aliasList, direction ) ); modules.add( new LTRStandardDecoder( aliasList, direction ) );
modules.add( new LTRStandardDecoderState( aliasList ) ); 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; break;
case LTR_NET: case LTR_NET:
modules.add( new AudioModule( recordAudio, REMOVE_DC ) );
modules.add( new LTRNetDecoder( (DecodeConfigLTRNet)decodeConfig, aliasList ) ); modules.add( new LTRNetDecoder( (DecodeConfigLTRNet)decodeConfig, aliasList ) );
modules.add( new LTRNetDecoderState( 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; break;
case MPT1327: case MPT1327:
DecodeConfigMPT1327 mptConfig = (DecodeConfigMPT1327)decodeConfig; DecodeConfigMPT1327 mptConfig = (DecodeConfigMPT1327)decodeConfig;
modules.add( new AudioModule( recordAudio, NO_REMOVE_DC ) ); ChannelMap channelMap = playlistManager.getPlayist()
ChannelMap channelMap = resourceManager.getPlaylistManager().getPlayist()
.getChannelMapList().getChannelMap( mptConfig.getChannelMapName() ); .getChannelMapList().getChannelMap( mptConfig.getChannelMapName() );
Sync sync = mptConfig.getSync(); Sync sync = mptConfig.getSync();
modules.add( new MPT1327Decoder( aliasList, sync ) ); modules.add( new MPT1327Decoder( aliasList, sync ) );
modules.add( new MPT1327DecoderState( aliasList, channelMap, modules.add( new MPT1327DecoderState( aliasList, channelMap,
channelType, mptConfig.getCallTimeout() * 1000 ) ); channelType, mptConfig.getCallTimeout() * 1000 ) );
@@ -235,30 +212,34 @@ public class DecoderFactory
{ {
long timeout = mptConfig.getCallTimeout() * 1000; //convert to milliseconds long timeout = mptConfig.getCallTimeout() * 1000; //convert to milliseconds
modules.add( new TrafficChannelManager( resourceManager, modules.add( new TrafficChannelManager( channelModel, channelProcessingManager,
decodeConfig, recordConfig, system, site, decodeConfig, recordConfig, channel.getSystem(),
( aliasList != null ? aliasList.getName() : null ), timeout, channel.getSite(), ( aliasList != null ? aliasList.getName() : null ), timeout,
mptConfig.getTrafficChannelPoolSize() ) ); 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; break;
case PASSPORT: case PASSPORT:
modules.add( new AudioModule( recordAudio, REMOVE_DC ) );
modules.add( new PassportDecoder( decodeConfig, aliasList ) ); modules.add( new PassportDecoder( decodeConfig, aliasList ) );
modules.add( new PassportDecoderState( 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; break;
case P25_PHASE1: case P25_PHASE1:
DecodeConfigP25Phase1 p25Config = (DecodeConfigP25Phase1)decodeConfig; DecodeConfigP25Phase1 p25Config = (DecodeConfigP25Phase1)decodeConfig;
Modulation modulation = p25Config.getModulation(); Modulation modulation = p25Config.getModulation();
switch( modulation ) switch( modulation )
{ {
case C4FM: case C4FM:
modules.add( getFMDemodulator( decodeConfig, 6750, 7500, NO_REMOVE_DC ) ); modules.add( new FMDemodulatorModule( 6750, 7500 ) );
modules.add( new P25_C4FMDecoder( aliasList ) ); modules.add( new P25_C4FMDecoder( aliasList, decodeConfig.getAFCMaximumCorrection() ) );
modules.add( new P25DecoderState( aliasList, channelType, modules.add( new P25DecoderState( aliasList, channelType,
Modulation.C4FM, p25Config.getIgnoreDataCalls() ) ); Modulation.C4FM, p25Config.getIgnoreDataCalls() ) );
break; break;
@@ -277,8 +258,9 @@ public class DecoderFactory
//Set call timeout to 3 seconds for P25 traffic channels //Set call timeout to 3 seconds for P25 traffic channels
long timeout = 3000; long timeout = 3000;
modules.add( new TrafficChannelManager( resourceManager, modules.add( new TrafficChannelManager( channelModel,
decodeConfig, recordConfig, system, site, channelProcessingManager, decodeConfig,
recordConfig, channel.getSystem(), channel.getSite(),
( aliasList != null ? aliasList.getName() : null ), timeout, ( aliasList != null ? aliasList.getName() : null ), timeout,
p25Config.getTrafficChannelPoolSize() ) ); p25Config.getTrafficChannelPoolSize() ) );
} }
@@ -449,7 +431,7 @@ public class DecoderFactory
} }
public static DecodeEditor getEditorPanel( DecodeConfiguration config, public static DecodeEditor getEditorPanel( DecodeConfiguration config,
ChannelNode channelNode, PlaylistManager playlistManager ) Channel channel, PlaylistManager playlistManager )
{ {
DecodeEditor configuredPanel; DecodeEditor configuredPanel;
@@ -466,7 +448,7 @@ public class DecoderFactory
break; break;
case MPT1327: case MPT1327:
configuredPanel = new MPT1327ConfigEditor( config, configuredPanel = new MPT1327ConfigEditor( config,
channelNode, playlistManager ); channel, playlistManager );
break; break;
case PASSPORT: case PASSPORT:
configuredPanel = new PassportEditor( config ); configuredPanel = new PassportEditor( config );

View File

@@ -23,12 +23,14 @@ import javax.swing.JPanel;
import javax.swing.JScrollPane; import javax.swing.JScrollPane;
import javax.swing.JTable; import javax.swing.JTable;
import module.ProcessingChain;
import net.miginfocom.swing.MigLayout; import net.miginfocom.swing.MigLayout;
import settings.SettingsManager; import settings.SettingsManager;
import controller.channel.Channel; import controller.channel.Channel;
import controller.channel.ChannelEvent; import controller.channel.ChannelEvent;
import controller.channel.ChannelEvent.Event; import controller.channel.ChannelEvent.Event;
import controller.channel.ChannelEventListener; import controller.channel.ChannelEventListener;
import controller.channel.ChannelProcessingManager;
public class CallEventPanel extends JPanel implements ChannelEventListener public class CallEventPanel extends JPanel implements ChannelEventListener
{ {
@@ -37,9 +39,13 @@ public class CallEventPanel extends JPanel implements ChannelEventListener
private JScrollPane mEmptyScroller; private JScrollPane mEmptyScroller;
private Channel mDisplayedChannel; private Channel mDisplayedChannel;
private CallEventAliasCellRenderer mRenderer; 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]") ); setLayout( new MigLayout("insets 0 0 0 0 ", "[grow,fill]", "[grow,fill]") );
JTable table = new JTable( new CallEventModel() ); JTable table = new JTable( new CallEventModel() );
@@ -69,34 +75,43 @@ public class CallEventPanel extends JPanel implements ChannelEventListener
( mDisplayedChannel != null && ( mDisplayedChannel != null &&
mDisplayedChannel != event.getChannel() ) ) mDisplayedChannel != event.getChannel() ) )
{ {
EventQueue.invokeLater( new Runnable() ProcessingChain chain = mChannelProcessingManager
.getProcessingChain( event.getChannel() );
if( chain != null )
{ {
@Override final CallEventModel model = chain.getCallEventModel();
public void run()
if( model != null )
{ {
removeAll(); EventQueue.invokeLater( new Runnable()
{
@Override
public void run()
{
removeAll();
JTable table = new JTable( JTable table = new JTable( model );
event.getChannel().getCallEventModel() );
table.setAutoCreateRowSorter( true ); table.setAutoCreateRowSorter( true );
table.setAutoResizeMode( JTable.AUTO_RESIZE_LAST_COLUMN ); table.setAutoResizeMode( JTable.AUTO_RESIZE_LAST_COLUMN );
table.getColumnModel().getColumn( CallEventModel.FROM_ALIAS ) table.getColumnModel().getColumn( CallEventModel.FROM_ALIAS )
.setCellRenderer( mRenderer ); .setCellRenderer( mRenderer );
table.getColumnModel().getColumn( CallEventModel.TO_ALIAS ) table.getColumnModel().getColumn( CallEventModel.TO_ALIAS )
.setCellRenderer( mRenderer ); .setCellRenderer( mRenderer );
add( new JScrollPane( table ) ); add( new JScrollPane( table ) );
mDisplayedChannel = event.getChannel(); mDisplayedChannel = event.getChannel();
revalidate(); revalidate();
repaint(); repaint();
}
} );
} }
} ); }
} }
} }
else if( event.getEvent() == Event.NOTIFICATION_PROCESSING_STOP || 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 javax.swing.event.ChangeListener;
import message.Message; import message.Message;
import module.ProcessingChain;
import net.miginfocom.swing.MigLayout; import net.miginfocom.swing.MigLayout;
import org.slf4j.Logger; import org.slf4j.Logger;
@@ -48,6 +49,7 @@ import controller.channel.Channel;
import controller.channel.ChannelEvent; import controller.channel.ChannelEvent;
import controller.channel.ChannelEvent.Event; import controller.channel.ChannelEvent.Event;
import controller.channel.ChannelEventListener; import controller.channel.ChannelEventListener;
import controller.channel.ChannelProcessingManager;
import filter.FilterEditorPanel; import filter.FilterEditorPanel;
import filter.FilterSet; import filter.FilterSet;
@@ -63,16 +65,21 @@ public class MessageActivityPanel extends JPanel implements ChannelEventListener
private JTable mMessageTable; private JTable mMessageTable;
private Channel mDisplayedChannel; private Channel mDisplayedChannel;
private MessageActivityModel mDisplayedModel = EMPTY_MODEL;
private MessageManagementPanel mManagementPanel = new MessageManagementPanel(); private MessageManagementPanel mManagementPanel = new MessageManagementPanel();
public MessageActivityPanel() private ChannelProcessingManager mChannelProcessingManager;
public MessageActivityPanel( ChannelProcessingManager channelProcessingManager )
{ {
mChannelProcessingManager = channelProcessingManager;
setLayout( new MigLayout("insets 0 0 0 0", "[][grow,fill]", "[]0[grow,fill]") ); setLayout( new MigLayout("insets 0 0 0 0", "[][grow,fill]", "[]0[grow,fill]") );
add( mManagementPanel, "span,growx" ); add( mManagementPanel, "span,growx" );
mMessageTable = new JTable( EMPTY_MODEL ); mMessageTable = new JTable( mDisplayedModel );
add( new JScrollPane( mMessageTable ), "span,grow" ); add( new JScrollPane( mMessageTable ), "span,grow" );
} }
@@ -91,7 +98,19 @@ public class MessageActivityPanel extends JPanel implements ChannelEventListener
{ {
mDisplayedChannel = event.getChannel(); 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 ) if( mDisplayedChannel != null )
{ {
@@ -195,10 +214,9 @@ public class MessageActivityPanel extends JPanel implements ChannelEventListener
public void mouseReleased( MouseEvent arg0 ) {} public void mouseReleased( MouseEvent arg0 ) {}
} ); } );
if( mDisplayedChannel != null ) if( mDisplayedModel != null )
{ {
slider.setValue( mDisplayedChannel.getMessageActivityModel() slider.setValue( mDisplayedModel.getMaxMessageCount() );
.getMaxMessageCount() );
} }
else else
{ {
@@ -210,10 +228,9 @@ public class MessageActivityPanel extends JPanel implements ChannelEventListener
@Override @Override
public void stateChanged( ChangeEvent arg0 ) public void stateChanged( ChangeEvent arg0 )
{ {
if( mDisplayedChannel != null ) if( mDisplayedModel != null )
{ {
mDisplayedChannel.getMessageActivityModel() mDisplayedModel.setMaxMessageCount( slider.getValue() );
.setMaxMessageCount( slider.getValue() );
} }
} }
}); });
@@ -228,9 +245,9 @@ public class MessageActivityPanel extends JPanel implements ChannelEventListener
@Override @Override
public void actionPerformed( ActionEvent e ) 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 else
{ {
final JFrame editor = new JFrame(); if( mDisplayedModel != null )
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()
{ {
@Override final JFrame editor = new JFrame();
public void actionPerformed( ActionEvent e )
{
editor.dispose();
}
} );
editor.add( close ); 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() @SuppressWarnings( "unchecked" )
{ FilterSet<Message> filter = (FilterSet<Message>)
public void run() mDisplayedModel.getMessageFilter();
{
editor.setVisible( true ); 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.Decoder;
import module.decode.DecoderType; import module.decode.DecoderType;
import sample.Listener; import sample.Listener;
import sample.real.IRealBufferListener; import sample.real.IFilteredRealBufferListener;
import sample.real.RealBuffer; import sample.real.RealBuffer;
import alias.AliasList; import alias.AliasList;
import bits.MessageFramer; 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 * Fleetsync II Decoder - 1200 baud 2FSK decoder that can process 48k sample rate
* floating point samples and output fully framed Fleetsync II messages * 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 Instrumentable
{ {
/* Decimated sample rate ( 48,000 / 2 = 24,000 ) feeding the decoder */ /* Decimated sample rate ( 48,000 / 2 = 24,000 ) feeding the decoder */
@@ -169,7 +169,7 @@ public class Fleetsync2Decoder extends Decoder implements IRealBufferListener,
} }
@Override @Override
public Listener<RealBuffer> getRealBufferListener() public Listener<RealBuffer> getFilteredRealBufferListener()
{ {
return mDecimationFilter; return mDecimationFilter;
} }

View File

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

View File

@@ -28,14 +28,15 @@ import message.MessageDirection;
import module.decode.Decoder; import module.decode.Decoder;
import module.decode.DecoderType; import module.decode.DecoderType;
import sample.Listener; import sample.Listener;
import sample.real.IRealBufferListener; import sample.real.IUnFilteredRealBufferListener;
import sample.real.RealBuffer; import sample.real.RealBuffer;
import alias.AliasList; import alias.AliasList;
import bits.MessageFramer; import bits.MessageFramer;
import bits.SyncPattern; import bits.SyncPattern;
import dsp.fsk.LTRFSKDecoder; 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; public static final int LTR_STANDARD_MESSAGE_LENGTH = 40;
private LTRFSKDecoder mLTRFSKDecoder; private LTRFSKDecoder mLTRFSKDecoder;
@@ -44,6 +45,10 @@ public class LTRNetDecoder extends Decoder implements IRealBufferListener, Instr
private List<TapGroup> mAvailableTaps; 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 ) public LTRNetDecoder( DecodeConfigLTRNet config, AliasList aliasList )
{ {
mLTRFSKDecoder = new LTRFSKDecoder(); mLTRFSKDecoder = new LTRFSKDecoder();
@@ -79,7 +84,7 @@ public class LTRNetDecoder extends Decoder implements IRealBufferListener, Instr
} }
@Override @Override
public Listener<RealBuffer> getRealBufferListener() public Listener<RealBuffer> getUnFilteredRealBufferListener()
{ {
return mLTRFSKDecoder; return mLTRFSKDecoder;
} }

View File

@@ -21,14 +21,14 @@ import message.MessageDirection;
import module.decode.Decoder; import module.decode.Decoder;
import module.decode.DecoderType; import module.decode.DecoderType;
import sample.Listener; import sample.Listener;
import sample.real.IRealBufferListener; import sample.real.IUnFilteredRealBufferListener;
import sample.real.RealBuffer; import sample.real.RealBuffer;
import alias.AliasList; import alias.AliasList;
import bits.MessageFramer; import bits.MessageFramer;
import bits.SyncPattern; import bits.SyncPattern;
import dsp.fsk.LTRFSKDecoder; 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; public static final int LTR_STANDARD_MESSAGE_LENGTH = 40;
@@ -36,6 +36,10 @@ public class LTRStandardDecoder extends Decoder implements IRealBufferListener
private MessageFramer mLTRMessageFramer; private MessageFramer mLTRMessageFramer;
private LTRStandardMessageProcessor mLTRMessageProcessor; 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, public LTRStandardDecoder( AliasList aliasList,
MessageDirection direction ) MessageDirection direction )
{ {
@@ -68,7 +72,7 @@ public class LTRStandardDecoder extends Decoder implements IRealBufferListener
} }
@Override @Override
public Listener<RealBuffer> getRealBufferListener() public Listener<RealBuffer> getUnFilteredRealBufferListener()
{ {
return mLTRFSKDecoder; return mLTRFSKDecoder;
} }

View File

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

View File

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

View File

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

Some files were not shown because too many files have changed in this diff Show More