mirror of
https://github.com/DSheirer/sdrtrunk.git
synced 2026-11-12 08:37:25 -05:00
#90 [WIP] merged metadata management for channel state, decoder states and audio metadata into a new metadata class. The new metadata class is maintained for each decoding audio channel, or in the future, a decoding TDMA channel. Audio playback, recording and streaming all use the same metadata object for the channel. The list of channel processing gui panels have been deleted and channel processing status will now reside in a table where each table row is a metadata instance from the processing channel. The channel processing manager is responsible for adding/removing the channel's metadata instance to/from the metadata table. This allows the channel processing table to be the controller for the messages, events and channel spectrum views, keyed to the selected table row metadata.
I still have to clean up the gui components and wire in the table selection listeners.
This commit is contained in:
@@ -1,22 +1,28 @@
|
||||
/*******************************************************************************
|
||||
* 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/>
|
||||
* sdrtrunk
|
||||
* Copyright (C) 2014-2017 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 instrument.gui;
|
||||
|
||||
import alias.AliasModel;
|
||||
import controller.channel.Channel;
|
||||
import controller.channel.ChannelModel;
|
||||
import controller.channel.ChannelProcessingManager;
|
||||
import controller.channel.map.ChannelMapModel;
|
||||
import instrument.Instrumentable;
|
||||
import instrument.InstrumentableProcessingChain;
|
||||
import instrument.tap.Tap;
|
||||
@@ -38,8 +44,21 @@ import instrument.tap.stream.QPSKTap;
|
||||
import instrument.tap.stream.QPSKTapPanel;
|
||||
import instrument.tap.stream.SymbolEventTap;
|
||||
import instrument.tap.stream.SymbolEventTapViewPanel;
|
||||
import message.Message;
|
||||
import module.Module;
|
||||
import module.decode.DecoderFactory;
|
||||
import module.decode.config.DecodeConfiguration;
|
||||
import module.log.EventLogManager;
|
||||
import net.miginfocom.swing.MigLayout;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import playlist.PlaylistManager;
|
||||
import sample.Listener;
|
||||
import source.IControllableFileSource;
|
||||
import source.Source;
|
||||
|
||||
import java.awt.Dimension;
|
||||
import javax.swing.*;
|
||||
import java.awt.*;
|
||||
import java.awt.event.ActionEvent;
|
||||
import java.awt.event.ActionListener;
|
||||
import java.awt.event.MouseEvent;
|
||||
@@ -47,312 +66,290 @@ import java.awt.event.MouseListener;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
|
||||
import javax.swing.JCheckBoxMenuItem;
|
||||
import javax.swing.JInternalFrame;
|
||||
import javax.swing.JMenu;
|
||||
import javax.swing.JMenuItem;
|
||||
import javax.swing.JPopupMenu;
|
||||
import javax.swing.JSeparator;
|
||||
|
||||
import message.Message;
|
||||
import module.Module;
|
||||
import module.decode.DecoderFactory;
|
||||
import module.decode.config.DecodeConfiguration;
|
||||
import module.log.EventLogManager;
|
||||
import net.miginfocom.swing.MigLayout;
|
||||
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import playlist.PlaylistManager;
|
||||
import sample.Listener;
|
||||
import source.IControllableFileSource;
|
||||
import source.Source;
|
||||
import alias.AliasModel;
|
||||
import controller.channel.Channel;
|
||||
import controller.channel.ChannelModel;
|
||||
import controller.channel.ChannelProcessingManager;
|
||||
import controller.channel.map.ChannelMapModel;
|
||||
|
||||
public class DecoderViewFrame extends JInternalFrame
|
||||
implements Listener<Message>
|
||||
public class DecoderViewFrame extends JInternalFrame implements Listener<Message>
|
||||
{
|
||||
private static final long serialVersionUID = 1L;
|
||||
private final static Logger mLog =
|
||||
LoggerFactory.getLogger( DecoderViewFrame.class );
|
||||
private final static Logger mLog = LoggerFactory.getLogger(DecoderViewFrame.class);
|
||||
|
||||
private DecodeConfiguration mDecodeConfig;
|
||||
private DecodeConfiguration mDecodeConfig;
|
||||
private InstrumentableProcessingChain mProcessingChain;
|
||||
private IControllableFileSource mSource;
|
||||
|
||||
private HashMap<Tap,TapViewPanel> mPanelMap =
|
||||
new HashMap<Tap,TapViewPanel>();
|
||||
|
||||
public DecoderViewFrame( PlaylistManager playlistManager,
|
||||
Channel channel,
|
||||
IControllableFileSource source )
|
||||
{
|
||||
mSource = source;
|
||||
private IControllableFileSource mSource;
|
||||
|
||||
mDecodeConfig = channel.getDecodeConfiguration();
|
||||
|
||||
mProcessingChain = new InstrumentableProcessingChain();
|
||||
private HashMap<Tap,TapViewPanel> mPanelMap = new HashMap<Tap,TapViewPanel>();
|
||||
|
||||
ChannelModel channelModel = new ChannelModel();
|
||||
ChannelMapModel channelMapModel = new ChannelMapModel();
|
||||
|
||||
ChannelProcessingManager channelProcessingManager =
|
||||
new ChannelProcessingManager( channelModel, channelMapModel,
|
||||
new AliasModel(), new EventLogManager(), null, null );
|
||||
|
||||
List<Module> modules = DecoderFactory.getModules( channelModel,
|
||||
channelMapModel, channelProcessingManager, new AliasModel(), channel );
|
||||
public DecoderViewFrame(PlaylistManager playlistManager, Channel channel, IControllableFileSource source)
|
||||
{
|
||||
mSource = source;
|
||||
|
||||
mProcessingChain.addModules( modules );
|
||||
mDecodeConfig = channel.getDecodeConfiguration();
|
||||
|
||||
mProcessingChain.addMessageListener( this );
|
||||
|
||||
mProcessingChain.setSource( (Source)mSource );
|
||||
|
||||
mProcessingChain.start();
|
||||
|
||||
initGui();
|
||||
}
|
||||
|
||||
private void initGui()
|
||||
{
|
||||
setLayout( new MigLayout( "insets 0 0 0 0 ", "[grow,fill]", "[grow,fill]" ) );
|
||||
mProcessingChain = new InstrumentableProcessingChain();
|
||||
|
||||
setTitle( "Decoder [" + mDecodeConfig.getDecoderType().getDisplayString() + "]" );
|
||||
setPreferredSize( new Dimension( 450, 250 ) );
|
||||
setSize( 450, 250 );
|
||||
ChannelModel channelModel = new ChannelModel();
|
||||
ChannelMapModel channelMapModel = new ChannelMapModel();
|
||||
|
||||
setResizable( true );
|
||||
setClosable( true );
|
||||
setIconifiable( true );
|
||||
setMaximizable( false );
|
||||
ChannelProcessingManager channelProcessingManager = new ChannelProcessingManager(channelModel, channelMapModel,
|
||||
new AliasModel(), new EventLogManager(), null, null);
|
||||
|
||||
addMouseListener( new MouseListener()
|
||||
{
|
||||
@Override
|
||||
public void mouseClicked( MouseEvent me )
|
||||
List<Module> modules = DecoderFactory.getModules(channelModel, channelMapModel, channelProcessingManager,
|
||||
new AliasModel(), channel, mProcessingChain.getChannelState().getMutableMetadata());
|
||||
|
||||
mProcessingChain.addModules(modules);
|
||||
|
||||
mProcessingChain.addMessageListener(this);
|
||||
|
||||
mProcessingChain.setSource((Source) mSource);
|
||||
|
||||
mProcessingChain.start();
|
||||
|
||||
initGui();
|
||||
}
|
||||
|
||||
private void initGui()
|
||||
{
|
||||
setLayout(new MigLayout("insets 0 0 0 0 ", "[grow,fill]", "[grow,fill]"));
|
||||
|
||||
setTitle("Decoder [" + mDecodeConfig.getDecoderType().getDisplayString() + "]");
|
||||
setPreferredSize(new Dimension(450, 250));
|
||||
setSize(450, 250);
|
||||
|
||||
setResizable(true);
|
||||
setClosable(true);
|
||||
setIconifiable(true);
|
||||
setMaximizable(false);
|
||||
|
||||
addMouseListener(new MouseListener()
|
||||
{
|
||||
@Override
|
||||
public void mouseClicked(MouseEvent me)
|
||||
{
|
||||
if( me.getButton() == MouseEvent.BUTTON3 )
|
||||
{
|
||||
JPopupMenu popup = new JPopupMenu();
|
||||
if(me.getButton() == MouseEvent.BUTTON3)
|
||||
{
|
||||
JPopupMenu popup = new JPopupMenu();
|
||||
|
||||
popup.add( getTapContextMenu() );
|
||||
popup.add(getTapContextMenu());
|
||||
|
||||
if( !mPanelMap.values().isEmpty() )
|
||||
{
|
||||
popup.add( new JSeparator() );
|
||||
|
||||
for( TapViewPanel panel: mPanelMap.values() )
|
||||
{
|
||||
popup.add( panel.getContextMenu() );
|
||||
}
|
||||
}
|
||||
|
||||
popup.show( DecoderViewFrame.this, me.getX(), me.getY() );
|
||||
}
|
||||
if(!mPanelMap.values().isEmpty())
|
||||
{
|
||||
popup.add(new JSeparator());
|
||||
|
||||
for(TapViewPanel panel : mPanelMap.values())
|
||||
{
|
||||
popup.add(panel.getContextMenu());
|
||||
}
|
||||
}
|
||||
|
||||
popup.show(DecoderViewFrame.this, me.getX(), me.getY());
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void mouseEntered( MouseEvent arg0 ) {}
|
||||
@Override
|
||||
public void mouseExited( MouseEvent arg0 ) {}
|
||||
@Override
|
||||
public void mousePressed( MouseEvent arg0 ) {}
|
||||
@Override
|
||||
public void mouseReleased( MouseEvent arg0 ) {}
|
||||
|
||||
} );
|
||||
}
|
||||
|
||||
private JMenu getTapContextMenu()
|
||||
{
|
||||
JMenu menu = new JMenu( "Modules" );
|
||||
@Override
|
||||
public void mouseEntered(MouseEvent arg0)
|
||||
{
|
||||
}
|
||||
|
||||
if( mProcessingChain != null )
|
||||
{
|
||||
for( Module module: mProcessingChain.getModules() )
|
||||
{
|
||||
if( module instanceof Instrumentable )
|
||||
{
|
||||
List<TapGroup> groups = ((Instrumentable)module).getTapGroups();
|
||||
|
||||
for( TapGroup group: groups )
|
||||
{
|
||||
menu.add( new TapGroupMenu( group ) );
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@Override
|
||||
public void mouseExited(MouseEvent arg0)
|
||||
{
|
||||
}
|
||||
|
||||
return menu;
|
||||
}
|
||||
|
||||
public void add( Tap tap )
|
||||
{
|
||||
TapViewPanel panel = null;
|
||||
|
||||
switch( tap.getType() )
|
||||
{
|
||||
case EVENT_SYNC_DETECT:
|
||||
break;
|
||||
case STREAM_BINARY:
|
||||
panel = new BinaryTapViewPanel( (BinaryTap)tap );
|
||||
break;
|
||||
case STREAM_COMPLEX:
|
||||
panel = new ComplexTapViewPanel( (ComplexTap)tap );
|
||||
break;
|
||||
case STREAM_COMPLEX_SAMPLE:
|
||||
panel = new ComplexSampleTapViewPanel( (ComplexSampleTap)tap );
|
||||
break;
|
||||
case STREAM_DIBIT:
|
||||
panel = new DibitTapViewPanel( (DibitTap)tap );
|
||||
break;
|
||||
case STREAM_EYE_DIAGRAM:
|
||||
panel = new EyeDiagramDataTapPanel( (EyeDiagramDataTap)tap ) ;
|
||||
break;
|
||||
case STREAM_FLOAT:
|
||||
panel = new FloatTapViewPanel( (FloatTap)tap );
|
||||
break;
|
||||
case STREAM_QPSK:
|
||||
panel = new QPSKTapPanel( (QPSKTap)tap );
|
||||
break;
|
||||
case STREAM_SYMBOL:
|
||||
panel = new SymbolEventTapViewPanel( (SymbolEventTap)tap );
|
||||
break;
|
||||
}
|
||||
|
||||
if( panel != null )
|
||||
{
|
||||
add( panel, "span" );
|
||||
|
||||
validate();
|
||||
|
||||
mPanelMap.put( tap, panel );
|
||||
@Override
|
||||
public void mousePressed(MouseEvent arg0)
|
||||
{
|
||||
}
|
||||
|
||||
for( Module module: mProcessingChain.getModules() )
|
||||
{
|
||||
if( module instanceof Instrumentable )
|
||||
{
|
||||
((Instrumentable)module).registerTap( tap );
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
mLog.info( "Tap panel is null, couldn't add for tap " +
|
||||
tap.getName() + "[" + tap.getType().toString() + "]" );
|
||||
}
|
||||
}
|
||||
|
||||
public void remove( Tap tap )
|
||||
{
|
||||
for( Module module: mProcessingChain.getModules() )
|
||||
{
|
||||
if( module instanceof Instrumentable )
|
||||
{
|
||||
((Instrumentable)module).unregisterTap( tap );
|
||||
}
|
||||
}
|
||||
|
||||
TapViewPanel panel = mPanelMap.get( tap );
|
||||
|
||||
remove( panel );
|
||||
|
||||
validate();
|
||||
|
||||
mPanelMap.remove( tap );
|
||||
}
|
||||
@Override
|
||||
public void mouseReleased(MouseEvent arg0)
|
||||
{
|
||||
}
|
||||
|
||||
public class AddAllTapsItem extends JMenuItem
|
||||
{
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
private final List<Tap> mTaps;
|
||||
|
||||
public AddAllTapsItem( final List<Tap> taps )
|
||||
{
|
||||
super( "All Taps" );
|
||||
|
||||
mTaps = taps;
|
||||
|
||||
addActionListener( new ActionListener()
|
||||
{
|
||||
@Override
|
||||
public void actionPerformed( ActionEvent e )
|
||||
{
|
||||
for( Tap tap: mTaps )
|
||||
{
|
||||
DecoderViewFrame.this.add( tap );
|
||||
}
|
||||
}
|
||||
} );
|
||||
}
|
||||
}
|
||||
|
||||
public class TapSelectionItem extends JCheckBoxMenuItem
|
||||
{
|
||||
private static final long serialVersionUID = 1L;
|
||||
private Tap mTap;
|
||||
|
||||
public TapSelectionItem( Tap tap )
|
||||
{
|
||||
super( tap.getName() );
|
||||
|
||||
mTap = tap;
|
||||
|
||||
if( mPanelMap.keySet().contains( tap ) )
|
||||
{
|
||||
setSelected( true );
|
||||
}
|
||||
|
||||
addActionListener( new ActionListener()
|
||||
{
|
||||
@Override
|
||||
public void actionPerformed( ActionEvent arg0 )
|
||||
{
|
||||
if( mPanelMap.keySet().contains( mTap ) )
|
||||
{
|
||||
DecoderViewFrame.this.remove( mTap );
|
||||
}
|
||||
else
|
||||
{
|
||||
DecoderViewFrame.this.add( mTap );
|
||||
}
|
||||
}
|
||||
} );
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void receive( Message message )
|
||||
{
|
||||
mLog.info( message.toString() );
|
||||
});
|
||||
}
|
||||
|
||||
private JMenu getTapContextMenu()
|
||||
{
|
||||
JMenu menu = new JMenu("Modules");
|
||||
|
||||
if(mProcessingChain != null)
|
||||
{
|
||||
for(Module module : mProcessingChain.getModules())
|
||||
{
|
||||
if(module instanceof Instrumentable)
|
||||
{
|
||||
List<TapGroup> groups = ((Instrumentable) module).getTapGroups();
|
||||
|
||||
for(TapGroup group : groups)
|
||||
{
|
||||
menu.add(new TapGroupMenu(group));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return menu;
|
||||
}
|
||||
|
||||
public void add(Tap tap)
|
||||
{
|
||||
TapViewPanel panel = null;
|
||||
|
||||
switch(tap.getType())
|
||||
{
|
||||
case EVENT_SYNC_DETECT:
|
||||
break;
|
||||
case STREAM_BINARY:
|
||||
panel = new BinaryTapViewPanel((BinaryTap) tap);
|
||||
break;
|
||||
case STREAM_COMPLEX:
|
||||
panel = new ComplexTapViewPanel((ComplexTap) tap);
|
||||
break;
|
||||
case STREAM_COMPLEX_SAMPLE:
|
||||
panel = new ComplexSampleTapViewPanel((ComplexSampleTap) tap);
|
||||
break;
|
||||
case STREAM_DIBIT:
|
||||
panel = new DibitTapViewPanel((DibitTap) tap);
|
||||
break;
|
||||
case STREAM_EYE_DIAGRAM:
|
||||
panel = new EyeDiagramDataTapPanel((EyeDiagramDataTap) tap);
|
||||
break;
|
||||
case STREAM_FLOAT:
|
||||
panel = new FloatTapViewPanel((FloatTap) tap);
|
||||
break;
|
||||
case STREAM_QPSK:
|
||||
panel = new QPSKTapPanel((QPSKTap) tap);
|
||||
break;
|
||||
case STREAM_SYMBOL:
|
||||
panel = new SymbolEventTapViewPanel((SymbolEventTap) tap);
|
||||
break;
|
||||
}
|
||||
|
||||
if(panel != null)
|
||||
{
|
||||
add(panel, "span");
|
||||
|
||||
validate();
|
||||
|
||||
mPanelMap.put(tap, panel);
|
||||
|
||||
for(Module module : mProcessingChain.getModules())
|
||||
{
|
||||
if(module instanceof Instrumentable)
|
||||
{
|
||||
((Instrumentable) module).registerTap(tap);
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
mLog.info("Tap panel is null, couldn't add for tap " +
|
||||
tap.getName() + "[" + tap.getType().toString() + "]");
|
||||
}
|
||||
}
|
||||
|
||||
public void remove(Tap tap)
|
||||
{
|
||||
for(Module module : mProcessingChain.getModules())
|
||||
{
|
||||
if(module instanceof Instrumentable)
|
||||
{
|
||||
((Instrumentable) module).unregisterTap(tap);
|
||||
}
|
||||
}
|
||||
|
||||
TapViewPanel panel = mPanelMap.get(tap);
|
||||
|
||||
remove(panel);
|
||||
|
||||
validate();
|
||||
|
||||
mPanelMap.remove(tap);
|
||||
}
|
||||
|
||||
public class AddAllTapsItem extends JMenuItem
|
||||
{
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
private final List<Tap> mTaps;
|
||||
|
||||
public AddAllTapsItem(final List<Tap> taps)
|
||||
{
|
||||
super("All Taps");
|
||||
|
||||
mTaps = taps;
|
||||
|
||||
addActionListener(new ActionListener()
|
||||
{
|
||||
@Override
|
||||
public void actionPerformed(ActionEvent e)
|
||||
{
|
||||
for(Tap tap : mTaps)
|
||||
{
|
||||
DecoderViewFrame.this.add(tap);
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
public class TapSelectionItem extends JCheckBoxMenuItem
|
||||
{
|
||||
private static final long serialVersionUID = 1L;
|
||||
private Tap mTap;
|
||||
|
||||
public TapSelectionItem(Tap tap)
|
||||
{
|
||||
super(tap.getName());
|
||||
|
||||
mTap = tap;
|
||||
|
||||
if(mPanelMap.keySet().contains(tap))
|
||||
{
|
||||
setSelected(true);
|
||||
}
|
||||
|
||||
addActionListener(new ActionListener()
|
||||
{
|
||||
@Override
|
||||
public void actionPerformed(ActionEvent arg0)
|
||||
{
|
||||
if(mPanelMap.keySet().contains(mTap))
|
||||
{
|
||||
DecoderViewFrame.this.remove(mTap);
|
||||
}
|
||||
else
|
||||
{
|
||||
DecoderViewFrame.this.add(mTap);
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void receive(Message message)
|
||||
{
|
||||
mLog.info(message.toString());
|
||||
}
|
||||
|
||||
public class TapGroupMenu extends JMenu
|
||||
{
|
||||
private static final long serialVersionUID = 1L;
|
||||
private TapGroup mTapGroup;
|
||||
|
||||
public TapGroupMenu(TapGroup tapGroup)
|
||||
{
|
||||
super(tapGroup.getName());
|
||||
|
||||
mTapGroup = tapGroup;
|
||||
|
||||
add(new AddAllTapsItem(mTapGroup.getTaps()));
|
||||
|
||||
add(new JSeparator());
|
||||
|
||||
for(Tap tap : mTapGroup.getTaps())
|
||||
{
|
||||
add(new TapSelectionItem(tap));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public class TapGroupMenu extends JMenu
|
||||
{
|
||||
private static final long serialVersionUID = 1L;
|
||||
private TapGroup mTapGroup;
|
||||
|
||||
public TapGroupMenu( TapGroup tapGroup )
|
||||
{
|
||||
super( tapGroup.getName() );
|
||||
|
||||
mTapGroup = tapGroup;
|
||||
|
||||
add( new AddAllTapsItem( mTapGroup.getTaps() ) );
|
||||
|
||||
add( new JSeparator() );
|
||||
|
||||
for( Tap tap: mTapGroup.getTaps() )
|
||||
{
|
||||
add( new TapSelectionItem( tap ) );
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user