From dc3bcfd404c37aff941082063afe0431f84ab4e8 Mon Sep 17 00:00:00 2001 From: denny Date: Sun, 22 Nov 2015 11:29:05 -0500 Subject: [PATCH] Resolves issue with spectral and waterfall alignment with frequency overlay. Minor edits to MPT and P25 config editors Resolved issue with channels not accepting channel config changes between restarts (processing chain was not being deleted) Minor edits to P25 decoder state --- src/controller/channel/Channel.java | 12 ++- .../decode/mpt1327/MPT1327ConfigEditor.java | 4 +- src/module/decode/p25/P25DecoderPanel.java | 20 +++- src/module/decode/p25/P25DecoderState.java | 4 +- src/module/decode/p25/P25Editor.java | 4 +- .../decode/state/TrafficChannelManager.java | 94 ++++++++++--------- src/spectrum/OverlayPanel.java | 22 +++-- src/spectrum/SpectrumPanel.java | 14 +-- src/spectrum/WaterfallPanel.java | 25 +++-- 9 files changed, 120 insertions(+), 79 deletions(-) diff --git a/src/controller/channel/Channel.java b/src/controller/channel/Channel.java index 5a2e77f3..5c180f68 100644 --- a/src/controller/channel/Channel.java +++ b/src/controller/channel/Channel.java @@ -904,10 +904,16 @@ public class Channel extends Configuration { mProcessingChain.stop(); - mSelected = false; - } + if( mChannelType == ChannelType.STANDARD ) + { + mProcessingChain.dispose(); + mProcessingChain = null; + } - fireChannelEvent( Event.CHANNEL_PROCESSING_STOPPED ); + mSelected = false; + + fireChannelEvent( Event.CHANNEL_PROCESSING_STOPPED ); + } } /** diff --git a/src/module/decode/mpt1327/MPT1327ConfigEditor.java b/src/module/decode/mpt1327/MPT1327ConfigEditor.java index efe20467..01c2af35 100644 --- a/src/module/decode/mpt1327/MPT1327ConfigEditor.java +++ b/src/module/decode/mpt1327/MPT1327ConfigEditor.java @@ -126,14 +126,14 @@ public class MPT1327ConfigEditor extends DecodeEditor mTrafficChannelPoolSize.setLabelTable( mTrafficChannelPoolSize.createStandardLabels( 10, 10 ) ); mTrafficChannelPoolSize.setPaintLabels( true ); - mTrafficChannelPoolSizeLabel = new JLabel( "Traffic Channel Pool Size: " + mTrafficChannelPoolSize.getValue() + " " ); + mTrafficChannelPoolSizeLabel = new JLabel( "Traffic Channel Pool: " + mTrafficChannelPoolSize.getValue() + " " ); mTrafficChannelPoolSize.addChangeListener( new ChangeListener() { @Override public void stateChanged( ChangeEvent e ) { - mTrafficChannelPoolSizeLabel.setText( "Traffic Channel Pool Size: " + mTrafficChannelPoolSize.getValue() ); + mTrafficChannelPoolSizeLabel.setText( "Traffic Channel Pool: " + mTrafficChannelPoolSize.getValue() ); } } ); diff --git a/src/module/decode/p25/P25DecoderPanel.java b/src/module/decode/p25/P25DecoderPanel.java index 35aea8f5..15520e0b 100644 --- a/src/module/decode/p25/P25DecoderPanel.java +++ b/src/module/decode/p25/P25DecoderPanel.java @@ -148,8 +148,14 @@ public class P25DecoderPanel extends DecoderPanel if( from != null ) { mFromAlias.setText( from.getName() ); - mFromAlias.setIcon( mSettingsManager - .getImageIcon( from.getIconName(), SettingsManager.DEFAULT_ICON_SIZE ) ); + + String icon = from.getIconName(); + + if( icon != null ) + { + mFromAlias.setIcon( mSettingsManager.getImageIcon( + icon, SettingsManager.DEFAULT_ICON_SIZE ) ); + } } else { @@ -173,8 +179,14 @@ public class P25DecoderPanel extends DecoderPanel if( to != null ) { mToAlias.setText( to.getName() ); - mToAlias.setIcon( mSettingsManager - .getImageIcon( to.getIconName(), SettingsManager.DEFAULT_ICON_SIZE ) ); + + String icon = to.getIconName(); + + if( icon != null ) + { + mToAlias.setIcon( mSettingsManager.getImageIcon( + icon, SettingsManager.DEFAULT_ICON_SIZE ) ); + } } else { diff --git a/src/module/decode/p25/P25DecoderState.java b/src/module/decode/p25/P25DecoderState.java index 4400561a..82b7fd24 100644 --- a/src/module/decode/p25/P25DecoderState.java +++ b/src/module/decode/p25/P25DecoderState.java @@ -2922,7 +2922,7 @@ public class P25DecoderState extends DecoderState /** * Broadcasts an update for the TO group or unit address */ - private void updateTo( String to ) + private void updateTo( final String to ) { if( to != null && !to.contentEquals( "0000" ) && !to.contentEquals( "000000" ) ) { @@ -2959,7 +2959,7 @@ public class P25DecoderState extends DecoderState /** * Broadcasts an update for the FROM group or unit address */ - private void updateFrom( String from ) + private void updateFrom( final String from ) { if( from != null && !from.contentEquals( "0000" ) && !from.contentEquals( "000000" ) ) { diff --git a/src/module/decode/p25/P25Editor.java b/src/module/decode/p25/P25Editor.java index dc567fb4..6858109d 100644 --- a/src/module/decode/p25/P25Editor.java +++ b/src/module/decode/p25/P25Editor.java @@ -105,14 +105,14 @@ public class P25Editor extends DecodeEditor mTrafficChannelPoolSize.setLabelTable( mTrafficChannelPoolSize.createStandardLabels( 10, 10 ) ); mTrafficChannelPoolSize.setPaintLabels( true ); - mTrafficChannelPoolSizeLabel = new JLabel( "Traffic Channel Pool Size: " + mTrafficChannelPoolSize.getValue() + " " ); + mTrafficChannelPoolSizeLabel = new JLabel( "Traffic Channel Pool: " + mTrafficChannelPoolSize.getValue() + " " ); mTrafficChannelPoolSize.addChangeListener( new ChangeListener() { @Override public void stateChanged( ChangeEvent e ) { - mTrafficChannelPoolSizeLabel.setText( "Traffic Channel Pool Size: " + mTrafficChannelPoolSize.getValue() ); + mTrafficChannelPoolSizeLabel.setText( "Traffic Channel Pool: " + mTrafficChannelPoolSize.getValue() ); } } ); diff --git a/src/module/decode/state/TrafficChannelManager.java b/src/module/decode/state/TrafficChannelManager.java index f6eca7ee..33a2ab1d 100644 --- a/src/module/decode/state/TrafficChannelManager.java +++ b/src/module/decode/state/TrafficChannelManager.java @@ -48,6 +48,7 @@ public class TrafficChannelManager extends Module private String mAliasListName; private long mTrafficChannelTimeout; private CallEvent mPreviousDoNotMonitorCallEvent; + private boolean mShuttingDown = false; /** * Monitors call events and allocates traffic decoder channels in response @@ -157,55 +158,66 @@ public class TrafficChannelManager extends Module return channel; } + /** + * Processes the event and creates a traffic channel is resources are + * available + */ private void process( TrafficChannelAllocationEvent event ) { if( mCallEventListener != null ) { - CallEvent callEvent = event.getCallEvent(); - - /* Check for duplicate events and suppress */ - if( mTrafficChannelsInUse.containsKey( callEvent.getChannel() ) ) + synchronized( mCallEventListener ) { - return; - } + CallEvent callEvent = event.getCallEvent(); - long frequency = callEvent.getFrequency(); - - /* Check the from/to aliases for do not monitor priority */ - if( isDoNotMonitor( callEvent ) ) - { - callEvent.setCallEventType( CallEventType.CALL_DO_NOT_MONITOR ); - - if( isSameCallEvent( mPreviousDoNotMonitorCallEvent, callEvent ) ) + /* Check for duplicate events and suppress */ + if( mTrafficChannelsInUse.containsKey( callEvent.getChannel() ) ) { return; } - else - { - mPreviousDoNotMonitorCallEvent = callEvent; - } - } - else if( frequency > 0 ) - { - Channel channel = getChannel( callEvent.getChannel(), - new TunerChannel( Type.TRAFFIC, frequency, - mDecodeConfiguration.getDecoderType() - .getChannelBandwidth() ) ); - if( channel != null ) + long frequency = callEvent.getFrequency(); + + /* Check the from/to aliases for do not monitor priority */ + if( isDoNotMonitor( callEvent ) ) { - if( channel.isProcessing() ) + callEvent.setCallEventType( CallEventType.CALL_DO_NOT_MONITOR ); + + if( isSameCallEvent( mPreviousDoNotMonitorCallEvent, callEvent ) ) { - ChannelState state = channel.getChannelState(); - - /* Register as a listener to be notified when the call - * is completed */ - state.configureAsTrafficChannel( - new TrafficChannelStatusListener( this, - callEvent.getChannel() ), event ); - - /* Set state to call so that audio squelch state is correct */ - state.setState( State.CALL ); + return; + } + else + { + mPreviousDoNotMonitorCallEvent = callEvent; + } + } + else if( frequency > 0 ) + { + Channel channel = getChannel( callEvent.getChannel(), + new TunerChannel( Type.TRAFFIC, frequency, + mDecodeConfiguration.getDecoderType() + .getChannelBandwidth() ) ); + + if( channel != null ) + { + if( channel.isProcessing() ) + { + ChannelState state = channel.getChannelState(); + + /* Register as a listener to be notified when the call + * is completed */ + state.configureAsTrafficChannel( + new TrafficChannelStatusListener( this, + callEvent.getChannel() ), event ); + + /* Set state to call so that audio squelch state is correct */ + state.setState( State.CALL ); + } + else + { + callEvent.setCallEventType( CallEventType.CALL_DETECT ); + } } else { @@ -216,13 +228,9 @@ public class TrafficChannelManager extends Module { callEvent.setCallEventType( CallEventType.CALL_DETECT ); } + + mCallEventListener.receive( callEvent ); } - else - { - callEvent.setCallEventType( CallEventType.CALL_DETECT ); - } - - mCallEventListener.receive( callEvent ); } } diff --git a/src/spectrum/OverlayPanel.java b/src/spectrum/OverlayPanel.java index 965d72cb..a20a3968 100644 --- a/src/spectrum/OverlayPanel.java +++ b/src/spectrum/OverlayPanel.java @@ -446,16 +446,22 @@ public class OverlayPanel extends JPanel */ private double getAxisFromFrequency( long frequency ) { - //Determine frequency offset from middle - double frequencyOffset = frequency - getMinDisplayFrequency(); + double screenWidth = (double)getSize().getWidth(); - //Determine ratio of offset to bandwidth + double pixelsPerBin = screenWidth / (double)mDFTSize.getSize(); + + double pixelOffsetToMinDisplayFrequency = pixelsPerBin * 2.0d; + + //Calculate frequency offset from the min frequency + double frequencyOffset = (double)( frequency - getMinDisplayFrequency() ); + + //Determine ratio of frequency offset to overall bandwidth double ratio = frequencyOffset / (double)getDisplayBandwidth(); - //Calculate offset against the total width - double xOffset = (double)getSize().getWidth() * ratio; + //Apply the ratio to the screen width minus 1 bin width + double screenOffset = screenWidth * ratio; - return xOffset; + return pixelOffsetToMinDisplayFrequency + screenOffset; } /** @@ -749,9 +755,9 @@ public class OverlayPanel extends JPanel private long getMinDisplayFrequency() { - double bandwidthPerBin = (double)mBandwidth / (double)( mDFTSize.getSize() - 1 ); + double bandwidthPerBin = (double)mBandwidth / (double)( mDFTSize.getSize() ); - return getMinFrequency() + (int)( mDFTZoomWindowOffset * bandwidthPerBin ); + return getMinFrequency() + (int)( ( mDFTZoomWindowOffset ) * bandwidthPerBin ); } private long getMaxDisplayFrequency() diff --git a/src/spectrum/SpectrumPanel.java b/src/spectrum/SpectrumPanel.java index 53aeb69e..a272e3b1 100644 --- a/src/spectrum/SpectrumPanel.java +++ b/src/spectrum/SpectrumPanel.java @@ -214,14 +214,12 @@ public class SpectrumPanel extends JPanel float insideHeight = size.height - mSpectrumInset; float scalor = insideHeight / -mDBScale; - - float insideWidth = size.width; - int binCount = bins.length; + /* Calculate based on bin size - 1, since bin 0 is rendered at zero + * and the last bin is rendered at the width */ + float binSize = (float)size.width / ( (float)( bins.length ) ); - float binSize = insideWidth / ( binCount ); - - for( int x = 0; x < binCount; x++ ) + for( int x = 0; x < bins.length; x++ ) { float height; @@ -236,8 +234,10 @@ public class SpectrumPanel extends JPanel { height = 0; } + + float xAxis = (float)x * binSize; - spectrumShape.lineTo( ( x * binSize ), height ); + spectrumShape.lineTo( xAxis, height ); } } //Otherwise show an empty spectrum diff --git a/src/spectrum/WaterfallPanel.java b/src/spectrum/WaterfallPanel.java index 3b8be259..5d94b934 100644 --- a/src/spectrum/WaterfallPanel.java +++ b/src/spectrum/WaterfallPanel.java @@ -261,20 +261,24 @@ public class WaterfallPanel extends JPanel implements DFTResultsListener, * @param multiplier - current zoom multiplier * @return x-axis pixel offset */ - private int getPixelOffset( int multiplier ) + private double getPixelOffset( int multiplier ) { - int offset = 0; + double offset = 0; if( mZoom != 0 ) { - int zoomWidth = getWidth() * multiplier; + double binPixelWidth = getBinPixelWidth( multiplier ); - offset = -(int)( (double)zoomWidth / (double)mDFTSize * - (double)( mDFTZoomWindowOffset ) ); + offset = -binPixelWidth * (double)( mDFTZoomWindowOffset ); } return offset; } + + private double getBinPixelWidth( int multiplier ) + { + return ( (double)getWidth() * (double)multiplier ) / (double)mDFTSize; + } /** * Renders the screen at each refresh @@ -283,15 +287,20 @@ public class WaterfallPanel extends JPanel implements DFTResultsListener, { int multiplier = getZoomMultiplier(); - int offset = getPixelOffset( multiplier ); + double binPixelWidth = getBinPixelWidth( multiplier ); + + int offset = (int)( getPixelOffset( multiplier ) - binPixelWidth ); + +// mLog.debug( "Offset:" + offset + " Pixel Offset:" + getPixelOffset( multiplier ) + " bin pixel width:" + binPixelWidth ); g.drawImage( mWaterfallImage, offset, 0, - getWidth() * multiplier, + ( getWidth() * multiplier ) + (int)binPixelWidth, mImageHeight, this ); - + + Graphics2D graphics = (Graphics2D) g; graphics.setColor( mColorSpectrumCursor );