diff --git a/.idea/copyright/sdrtrunk.xml b/.idea/copyright/sdrtrunk.xml
index 888c0641..d2ce33df 100644
--- a/.idea/copyright/sdrtrunk.xml
+++ b/.idea/copyright/sdrtrunk.xml
@@ -1,6 +1,6 @@
-
+
\ No newline at end of file
diff --git a/src/gui/control/JFrequencyControl.java b/src/gui/control/JFrequencyControl.java
index 3f4a5102..ca2053aa 100644
--- a/src/gui/control/JFrequencyControl.java
+++ b/src/gui/control/JFrequencyControl.java
@@ -1,19 +1,19 @@
/*******************************************************************************
- * 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
+ * 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
******************************************************************************/
package gui.control;
@@ -35,15 +35,15 @@ import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
-import javax.swing.JLabel;
-import javax.swing.JPanel;
-import javax.swing.JTextField;
+import javax.swing.*;
import net.miginfocom.swing.MigLayout;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
+import source.InvalidFrequencyException;
+import source.SourceException;
import source.tuner.frequency.FrequencyChangeEvent;
import source.tuner.frequency.FrequencyChangeEvent.Event;
import source.tuner.frequency.IFrequencyChangeProcessor;
@@ -51,413 +51,465 @@ import source.tuner.frequency.IFrequencyChangeProcessor;
public class JFrequencyControl extends JPanel implements IFrequencyChangeProcessor
{
private static final long serialVersionUID = 1L;
- private final static Logger mLog =
- LoggerFactory.getLogger( JFrequencyControl.class );
+ private final static Logger mLog =
+ LoggerFactory.getLogger(JFrequencyControl.class);
+
+ private List mProcessors = new ArrayList<>();
- private List mProcessors = new ArrayList<>();
-
private Color mHighlightColor = Color.YELLOW;
-
- private long mFrequency;
-
- private Cursor mBlankCursor;
-
- private HashMap mDigits = new HashMap();
-
- public JFrequencyControl()
- {
- init();
- }
-
- public JFrequencyControl( long value )
- {
- this();
- mFrequency = value;
- }
-
- private void init()
- {
- setLayout( new MigLayout( "insets 0 0 0 0", "[]0[]", "" ) );
-
- Font font = new Font( Font.MONOSPACED, Font.BOLD, 30 );
-
- for( int x = 9; x >= 0; x-- )
- {
- Digit digit = null;
- try
- {
- digit = new Digit( x );
- }
- catch ( ParseException e )
- {
- mLog.error( "JFrequencyControl - parse exception "
- + "constructing a digit - " + e );
- }
+ private long mFrequency;
- if( digit != null )
- {
- mDigits.put( x, digit );
-
- add( digit );
-
- digit.setFont( font );
+ private Cursor mBlankCursor;
- if( x == 6 )
- {
- JLabel period = new JLabel( "." );
-
- add( period );
- }
- }
- }
-
- add( new JLabel( " MHz" ) );
+ private HashMap mDigits = new HashMap();
- /**
- * Create a blank cursor to use when the mouse is over the digits
- */
- //Create an empty byte array
- byte[] imageByte = new byte[ 0 ];
-
- //Create image for cursor using empty array
- Image cursorImage = Toolkit.getDefaultToolkit().createImage( imageByte );
-
- mBlankCursor = Toolkit.getDefaultToolkit()
- .createCustomCursor( cursorImage, new Point( 0, 0 ), "cursor" );
-
- revalidate();
- }
-
- @Override
- public void setEnabled( boolean enabled )
- {
- super.setEnabled( enabled );
-
- for( Digit digit: mDigits.values() )
- {
- digit.setEnabled( enabled );
- }
- }
-
- /**
- * Receives a frequency change event invoked by another control. We don't
- * rebroadcast this event, just set the control to indicate the new frequency.
- */
- @Override
- public void frequencyChanged( FrequencyChangeEvent event )
+ public JFrequencyControl()
{
- if( event.getEvent() == Event.NOTIFICATION_FREQUENCY_CHANGE )
- {
- setFrequency( event.getValue().longValue(), false );
- }
+ init();
}
-
- /**
- * Loads the frequency into the display and optionally fires a change event
- * to all registered listeners
- */
- public void setFrequency( long frequency, boolean fireChangeEvent )
- {
- mFrequency = frequency;
-
- for( Digit digit: mDigits.values() )
- {
- digit.setFrequency( frequency, fireChangeEvent );
- }
- }
-
- public long getFrequency()
- {
- return mFrequency;
- }
-
- private void updateFrequency()
- {
- long frequency = 0;
-
- for( Digit digit: mDigits.values() )
- {
- frequency += digit.getFrequency();
- }
-
- mFrequency = frequency;
- }
-
- private void fireFrequencyChanged()
- {
- updateFrequency();
-
- Iterator it = mProcessors.iterator();
-
- FrequencyChangeEvent event = new FrequencyChangeEvent(
- Event.REQUEST_FREQUENCY_CHANGE, mFrequency );
-
- while( it.hasNext() )
- {
- it.next().frequencyChanged( event );
- }
- }
-
- public void addListener( IFrequencyChangeProcessor processor )
- {
- mProcessors.add( processor );
- }
-
- public void removeListener( IFrequencyChangeProcessor processor )
- {
- mProcessors.remove( processor );
- }
-
+
+ public JFrequencyControl(long value)
+ {
+ this();
+ mFrequency = value;
+ }
+
+ private void init()
+ {
+ setLayout(new MigLayout("insets 0 0 0 0", "[]0[]", ""));
+
+ Font font = new Font(Font.MONOSPACED, Font.BOLD, 30);
+
+ for (int x = 9; x >= 0; x--)
+ {
+ Digit digit = null;
+
+ try
+ {
+ digit = new Digit(x);
+ }
+ catch (ParseException e)
+ {
+ mLog.error("JFrequencyControl - parse exception "
+ + "constructing a digit - " + e);
+ }
+
+ if (digit != null)
+ {
+ mDigits.put(x, digit);
+
+ add(digit);
+
+ digit.setFont(font);
+
+ if (x == 6)
+ {
+ JLabel period = new JLabel(".");
+
+ add(period);
+ }
+ }
+ }
+
+ add(new JLabel(" MHz"));
+
+ /**
+ * Create a blank cursor to use when the mouse is over the digits
+ */
+ //Create an empty byte array
+ byte[] imageByte = new byte[0];
+
+ //Create image for cursor using empty array
+ Image cursorImage = Toolkit.getDefaultToolkit().createImage(imageByte);
+
+ mBlankCursor = Toolkit.getDefaultToolkit()
+ .createCustomCursor(cursorImage, new Point(0, 0), "cursor");
+
+ revalidate();
+ }
+
+ @Override
+ public void setEnabled(boolean enabled)
+ {
+ super.setEnabled(enabled);
+
+ for (Digit digit : mDigits.values())
+ {
+ digit.setEnabled(enabled);
+ }
+ }
+
+ /**
+ * Receives a frequency change event invoked by another control. We don't
+ * rebroadcast this event, just set the control to indicate the new frequency.
+ */
+ @Override
+ public void frequencyChanged(FrequencyChangeEvent event)
+ {
+ if (event.getEvent() == Event.NOTIFICATION_FREQUENCY_CHANGE)
+ {
+ setFrequency(event.getValue().longValue(), false);
+ }
+ }
+
+ /**
+ * Loads the frequency into the display and optionally fires a change event
+ * to all registered listeners
+ */
+ public void setFrequency(long frequency, boolean fireChangeEvent)
+ {
+ mFrequency = frequency;
+
+ for (Digit digit : mDigits.values())
+ {
+ digit.setFrequency(frequency, fireChangeEvent);
+ }
+ }
+
+ public long getFrequency()
+ {
+ return mFrequency;
+ }
+
+ private void updateFrequency()
+ {
+ long frequency = 0;
+
+ for (Digit digit : mDigits.values())
+ {
+ frequency += digit.getFrequency();
+ }
+
+ mFrequency = frequency;
+ }
+
+ private void fireFrequencyChanged() throws SourceException
+ {
+ updateFrequency();
+
+ Iterator it = mProcessors.iterator();
+
+ FrequencyChangeEvent event = new FrequencyChangeEvent(
+ Event.REQUEST_FREQUENCY_CHANGE, mFrequency);
+
+ while (it.hasNext())
+ {
+ it.next().frequencyChanged(event);
+ }
+ }
+
+ public void addListener(IFrequencyChangeProcessor processor)
+ {
+ mProcessors.add(processor);
+ }
+
+ public void removeListener(IFrequencyChangeProcessor processor)
+ {
+ mProcessors.remove(processor);
+ }
+
public class Digit extends JTextField
- {
+ {
private static final long serialVersionUID = 1L;
private int mPower = 0;
private long mValue = 0;
-
- private Digit( int position ) throws ParseException
- {
- super( "0" );
- mPower = position;
+ private Digit(int position) throws ParseException
+ {
+ super("0");
+
+ mPower = position;
Listener listener = new Listener();
- this.addKeyListener( listener );
- this.addMouseListener( listener );
- this.addMouseWheelListener( listener );
+ this.addKeyListener(listener);
+ this.addMouseListener(listener);
+ this.addMouseWheelListener(listener);
}
-
+
/**
* Sets this digit to the value of the column in frequency that corresponds
- * to the power (ie column) set for this digit. Optionally, fires a
+ * to the power (ie column) set for this digit. Optionally, fires a
* value change event to all listeners.
*/
- public void setFrequency( long frequency, boolean fireChangeEvent )
+ public void setFrequency(long frequency, boolean fireChangeEvent)
{
- //Strip the digits higher than this one
- long lower = frequency % (long)( Math.pow( 10, mPower + 1) );
+ //Strip the digits higher than this one
+ long lower = frequency % (long) (Math.pow(10, mPower + 1));
- //Set the value to int value of dividing by 10 to this power
- long value = (long)( lower / (long)( Math.pow( 10, mPower ) ) );
-
- set( value, fireChangeEvent );
+ //Set the value to int value of dividing by 10 to this power
+ long value = (long) (lower / (long) (Math.pow(10, mPower)));
+
+ set(value, fireChangeEvent);
}
-
+
public long getFrequency()
{
- return mValue * (long)Math.pow( 10, mPower );
+ return mValue * (long) Math.pow(10, mPower);
}
public void increment()
{
- increment( true );
+ increment(true);
}
- public void increment( boolean fireChangeEvent )
+ public void increment(boolean fireChangeEvent)
{
- if( isEnabled() )
- {
- set( mValue + 1, fireChangeEvent );
- }
+ if (isEnabled())
+ {
+ set(mValue + 1, fireChangeEvent);
+ }
}
public void decrement()
{
- decrement( true );
+ decrement(true);
}
-
- public void decrement( boolean fireChangeEvent )
+
+ public void decrement(boolean fireChangeEvent)
{
- if( isEnabled() )
- {
- set( mValue - 1, fireChangeEvent );
- }
+ if (isEnabled())
+ {
+ set(mValue - 1, fireChangeEvent);
+ }
}
/**
* Convenience wrapper to change amount and fire change event
*/
- private void set( long amount )
+ private void set(long amount)
{
- set( amount, true );
+ set(amount, true);
}
/**
* Changes the value and optionally fires change event to listeners
*/
- private void set( long amount, boolean fireChangeEvent )
+ private void set(long amount, boolean fireChangeEvent)
{
- mValue = amount;
+ long previous = mValue;
+ boolean higherDigitIncremented = false;
+ boolean higherDigitDecremented = false;
- while( mValue < 0 )
- {
- mValue += 10;
+ mValue = amount;
- Digit nextHigherDigit = mDigits.get( mPower + 1 );
-
- if( nextHigherDigit != null )
- {
- nextHigherDigit.decrement( false );
- }
-
- }
- while( mValue > 9 )
- {
- mValue -= 10;
+ while (mValue < 0)
+ {
+ mValue += 10;
- Digit nextHigherDigit = mDigits.get( mPower + 1 );
-
- if( nextHigherDigit != null )
- {
- nextHigherDigit.increment( false );
- }
- }
+ Digit nextHigherDigit = mDigits.get(mPower + 1);
- setText( String.valueOf( mValue ) );
+ if (nextHigherDigit != null)
+ {
+ nextHigherDigit.decrement(false);
+ higherDigitDecremented = true;
+ }
- repaint();
-
- if( fireChangeEvent )
- {
- fireFrequencyChanged();
- }
-
+ }
+
+ while (mValue > 9)
+ {
+ mValue -= 10;
+
+ Digit nextHigherDigit = mDigits.get(mPower + 1);
+
+ if (nextHigherDigit != null)
+ {
+ nextHigherDigit.increment(false);
+ higherDigitIncremented = true;
+ }
+ }
+
+ if (fireChangeEvent)
+ {
+ try
+ {
+ fireFrequencyChanged();
+ }
+ catch (SourceException se)
+ {
+ mValue = previous;
+
+ if (higherDigitIncremented)
+ {
+ Digit nextHigherDigit = mDigits.get(mPower + 1);
+
+ if (nextHigherDigit != null)
+ {
+ nextHigherDigit.decrement(false);
+ }
+ }
+
+ if (higherDigitDecremented)
+ {
+ Digit nextHigherDigit = mDigits.get(mPower + 1);
+
+ if (nextHigherDigit != null)
+ {
+ nextHigherDigit.increment(false);
+ }
+ }
+
+ if (se instanceof InvalidFrequencyException)
+ {
+ InvalidFrequencyException ife = (InvalidFrequencyException) se;
+
+ JOptionPane.showMessageDialog(this, "Frequency [" + ife.getInvalidFrequency() +
+ "] exceeds the frequency limit [" + ife.getValidFrequency() + "] for this tuner.");
+ }
+ }
+ }
+
+
+ setText(String.valueOf(mValue));
+
+ repaint();
}
private class Listener implements KeyListener,
- MouseListener,
- MouseWheelListener
+ MouseListener,
+ MouseWheelListener
{
- @Override
- public void keyReleased( KeyEvent e )
+ @Override
+ public void keyReleased(KeyEvent e)
{
- int key = e.getKeyCode();
+ int key = e.getKeyCode();
- switch( key )
- {
- case KeyEvent.VK_0:
- case KeyEvent.VK_NUMPAD0:
- set( 0 );
- Digit.this.transferFocus();
- break;
- case KeyEvent.VK_1:
- case KeyEvent.VK_NUMPAD1:
- set( 1 );
- Digit.this.transferFocus();
- break;
- case KeyEvent.VK_2:
- case KeyEvent.VK_NUMPAD2:
- set( 2 );
- Digit.this.transferFocus();
- break;
- case KeyEvent.VK_3:
- case KeyEvent.VK_NUMPAD3:
- set( 3 );
- Digit.this.transferFocus();
- break;
- case KeyEvent.VK_4:
- case KeyEvent.VK_NUMPAD4:
- set( 4 );
- Digit.this.transferFocus();
- break;
- case KeyEvent.VK_5:
- case KeyEvent.VK_NUMPAD5:
- set( 5 );
- Digit.this.transferFocus();
- break;
- case KeyEvent.VK_6:
- case KeyEvent.VK_NUMPAD6:
- set( 6 );
- Digit.this.transferFocus();
- break;
- case KeyEvent.VK_7:
- case KeyEvent.VK_NUMPAD7:
- set( 7 );
- Digit.this.transferFocus();
- break;
- case KeyEvent.VK_8:
- case KeyEvent.VK_NUMPAD8:
- set( 8 );
- Digit.this.transferFocus();
- break;
- case KeyEvent.VK_9:
- case KeyEvent.VK_NUMPAD9:
- set( 9 );
- Digit.this.transferFocus();
- break;
- case KeyEvent.VK_LEFT:
- Digit.this.transferFocusBackward();
- break;
- case KeyEvent.VK_RIGHT:
- Digit.this.transferFocus();
- break;
- case KeyEvent.VK_UP:
- increment();
- break;
- case KeyEvent.VK_DOWN:
- decrement();
- break;
- case KeyEvent.VK_TAB:
- break;
- default:
- set( mValue );
- break;
- }
-
- repaint();
- }
-
- @Override
- public void keyPressed( KeyEvent e ) {}
- @Override
- public void keyTyped( KeyEvent e ) {}
+ switch (key)
+ {
+ case KeyEvent.VK_0:
+ case KeyEvent.VK_NUMPAD0:
+ set(0);
+ Digit.this.transferFocus();
+ break;
+ case KeyEvent.VK_1:
+ case KeyEvent.VK_NUMPAD1:
+ set(1);
+ Digit.this.transferFocus();
+ break;
+ case KeyEvent.VK_2:
+ case KeyEvent.VK_NUMPAD2:
+ set(2);
+ Digit.this.transferFocus();
+ break;
+ case KeyEvent.VK_3:
+ case KeyEvent.VK_NUMPAD3:
+ set(3);
+ Digit.this.transferFocus();
+ break;
+ case KeyEvent.VK_4:
+ case KeyEvent.VK_NUMPAD4:
+ set(4);
+ Digit.this.transferFocus();
+ break;
+ case KeyEvent.VK_5:
+ case KeyEvent.VK_NUMPAD5:
+ set(5);
+ Digit.this.transferFocus();
+ break;
+ case KeyEvent.VK_6:
+ case KeyEvent.VK_NUMPAD6:
+ set(6);
+ Digit.this.transferFocus();
+ break;
+ case KeyEvent.VK_7:
+ case KeyEvent.VK_NUMPAD7:
+ set(7);
+ Digit.this.transferFocus();
+ break;
+ case KeyEvent.VK_8:
+ case KeyEvent.VK_NUMPAD8:
+ set(8);
+ Digit.this.transferFocus();
+ break;
+ case KeyEvent.VK_9:
+ case KeyEvent.VK_NUMPAD9:
+ set(9);
+ Digit.this.transferFocus();
+ break;
+ case KeyEvent.VK_LEFT:
+ Digit.this.transferFocusBackward();
+ break;
+ case KeyEvent.VK_RIGHT:
+ Digit.this.transferFocus();
+ break;
+ case KeyEvent.VK_UP:
+ increment();
+ break;
+ case KeyEvent.VK_DOWN:
+ decrement();
+ break;
+ case KeyEvent.VK_TAB:
+ break;
+ default:
+ set(mValue);
+ break;
+ }
- @Override
- public void mouseClicked( MouseEvent e )
- {
- switch( e.getButton() )
- {
- case MouseEvent.BUTTON1:
- increment();
- break;
- case MouseEvent.BUTTON2:
- break;
- case MouseEvent.BUTTON3:
- decrement();
- break;
- }
+ repaint();
}
- public void mousePressed( MouseEvent e ) {}
- public void mouseReleased( MouseEvent e ) {}
-
- @Override
- public void mouseEntered( MouseEvent e )
+ @Override
+ public void keyPressed(KeyEvent e)
{
- Digit.this.setBackground( mHighlightColor );
-
- setCursor( mBlankCursor );
-
- repaint();
}
- @Override
- public void mouseExited( MouseEvent e )
+ @Override
+ public void keyTyped(KeyEvent e)
{
- Digit.this.setBackground( Color.WHITE );
-
- setCursor( Cursor.getDefaultCursor() );
-
- repaint();
}
- @Override
- public void mouseWheelMoved( MouseWheelEvent e )
+ @Override
+ public void mouseClicked(MouseEvent e)
{
- set( mValue - e.getWheelRotation() );
+ switch (e.getButton())
+ {
+ case MouseEvent.BUTTON1:
+ increment();
+ break;
+ case MouseEvent.BUTTON2:
+ break;
+ case MouseEvent.BUTTON3:
+ decrement();
+ break;
+ }
+ }
+
+ public void mousePressed(MouseEvent e)
+ {
+ }
+
+ public void mouseReleased(MouseEvent e)
+ {
+ }
+
+ @Override
+ public void mouseEntered(MouseEvent e)
+ {
+ Digit.this.setBackground(mHighlightColor);
+
+ setCursor(mBlankCursor);
+
+ repaint();
+ }
+
+ @Override
+ public void mouseExited(MouseEvent e)
+ {
+ Digit.this.setBackground(Color.WHITE);
+
+ setCursor(Cursor.getDefaultCursor());
+
+ repaint();
+ }
+
+ @Override
+ public void mouseWheelMoved(MouseWheelEvent e)
+ {
+ set(mValue - e.getWheelRotation());
}
}
- }
+ }
}
diff --git a/src/source/InvalidFrequencyException.java b/src/source/InvalidFrequencyException.java
new file mode 100644
index 00000000..77e1bee7
--- /dev/null
+++ b/src/source/InvalidFrequencyException.java
@@ -0,0 +1,57 @@
+/*******************************************************************************
+ * sdrtrunk
+ * 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
+ *
+ ******************************************************************************/
+package source;
+
+public class InvalidFrequencyException extends SourceException
+{
+ private long mInvalidFrequency;
+ private long mValidFrequency;
+
+ /**
+ * Thrown when the user or the application requests to tune to an invalid frequency. Invalid means that the
+ * frequency is outside of the tunable range of the current tuner device. This class provides both the requested
+ * invalid frequency and the suggested valid frequency to use in lieu of the requested invalid frequency.
+ * @param message optional text
+ * @param invalidFrequency that was requested
+ * @param validFrequency that should be used instead
+ */
+ public InvalidFrequencyException( String message, long invalidFrequency, long validFrequency )
+ {
+ super( message );
+
+ mInvalidFrequency = invalidFrequency;
+ mValidFrequency = validFrequency;
+ }
+
+ /**
+ * The invalid requested frequency
+ */
+ public long getInvalidFrequency()
+ {
+ return mInvalidFrequency;
+ }
+
+ /**
+ * The valid frequency that should be used
+ */
+ public long getValidFrequency()
+ {
+ return mValidFrequency;
+ }
+}
diff --git a/src/source/recording/Recording.java b/src/source/recording/Recording.java
index c01d8566..9a228fc0 100644
--- a/src/source/recording/Recording.java
+++ b/src/source/recording/Recording.java
@@ -89,7 +89,7 @@ public class Recording implements Comparable,
}
@Override
- public void frequencyChanged( FrequencyChangeEvent event )
+ public void frequencyChanged( FrequencyChangeEvent event ) throws SourceException
{
if( event.getEvent() == Event.NOTIFICATION_FREQUENCY_CHANGE )
{
diff --git a/src/source/tuner/TunerChannelSource.java b/src/source/tuner/TunerChannelSource.java
index 61cc1b57..1e89e1b4 100644
--- a/src/source/tuner/TunerChannelSource.java
+++ b/src/source/tuner/TunerChannelSource.java
@@ -82,7 +82,6 @@ public class TunerChannelSource extends ComplexSource
* and thus the tuner might no longer be able to source this channel once it
* has been stopped.
*
- * @param threadPoolManager to use for decimation processing task
* @param tuner to obtain wideband IQ samples from
* @param tunerChannel specifying the center frequency for the DDC
* @throws RejectedExecutionException if the thread pool manager cannot
@@ -229,7 +228,7 @@ public class TunerChannelSource extends ComplexSource
* frequency correction events received from the channel consumer/listener
*/
@Override
- public void frequencyChanged( FrequencyChangeEvent event )
+ public void frequencyChanged( FrequencyChangeEvent event ) throws SourceException
{
// Echo the event to the registered event listener
if( mFrequencyChangeProcessor != null )
diff --git a/src/source/tuner/TunerController.java b/src/source/tuner/TunerController.java
index b0c240aa..017231bd 100644
--- a/src/source/tuner/TunerController.java
+++ b/src/source/tuner/TunerController.java
@@ -51,7 +51,7 @@ public abstract class TunerController implements Tunable, IFrequencyChangeProces
* @param minimumFrequency minimum uncorrected tunable frequency
* @param maximumFrequency maximum uncorrected tunable frequency
* @param middleUnusable is the +/- value center DC spike to avoid for channels
- * @param extantUnusable is the unusable space at the extreme ends of the spectrum
+ * @param usableBandwidthPercentage is the unusable space at the extreme ends of the spectrum
*
* @throws SourceException - for any issues related to constructing the
* class, tuning a frequency, or setting the bandwidth
@@ -79,18 +79,11 @@ public abstract class TunerController implements Tunable, IFrequencyChangeProces
* Responds to requests to set the frequency
*/
@Override
- public void frequencyChanged( FrequencyChangeEvent event )
+ public void frequencyChanged( FrequencyChangeEvent event ) throws SourceException
{
if( event.getEvent() == Event.REQUEST_FREQUENCY_CHANGE )
{
- try
- {
- setFrequency( event.getValue().longValue() );
- }
- catch ( SourceException e )
- {
- mLog.error( "Error setting frequency from external controller", e );
- }
+ setFrequency( event.getValue().longValue() );
}
}
@@ -212,7 +205,6 @@ public abstract class TunerController implements Tunable, IFrequencyChangeProces
* ensure all of the channels can be accomodated and any defined central DC
* spike avoided.
*
- * @param threadPoolManager for the channel to use for runnables
* @param tuner to source the channel from
* @param channel with defined center frequency and bandwidth
*
diff --git a/src/source/tuner/airspy/AirspyTunerController.java b/src/source/tuner/airspy/AirspyTunerController.java
index 4f130ab0..6e5d4d34 100644
--- a/src/source/tuner/airspy/AirspyTunerController.java
+++ b/src/source/tuner/airspy/AirspyTunerController.java
@@ -405,7 +405,7 @@ public class AirspyTunerController extends TunerController
* Sets the sample rate to the rate specified by the index value in the
* available sample rates map
*
- * @param index to a sample rate in the available samples rates map.
+ * @param rate to a sample rate in the available samples rates map.
*
* @throws IllegalArgumentException if index is not a valid rate index
* @throws LibUsbException if there was a read error or if this operation
@@ -414,7 +414,7 @@ public class AirspyTunerController extends TunerController
* @throws UsbException if there was a USB error
*/
public void setSampleRate( AirspySampleRate rate ) throws
- LibUsbException, UsbException
+ LibUsbException, UsbException, SourceException
{
if( rate.getRate() != mSampleRate )
{
diff --git a/src/source/tuner/airspy/AirspyTunerEditor.java b/src/source/tuner/airspy/AirspyTunerEditor.java
index 10e1e567..eda85985 100644
--- a/src/source/tuner/airspy/AirspyTunerEditor.java
+++ b/src/source/tuner/airspy/AirspyTunerEditor.java
@@ -167,7 +167,7 @@ public class AirspyTunerEditor extends TunerConfigurationEditor
mController.setSampleRate( rate );
save();
}
- catch ( LibUsbException | UsbException e1 )
+ catch ( LibUsbException | UsbException | SourceException e1 )
{
JOptionPane.showMessageDialog( AirspyTunerEditor.this,
"Couldn't set sample rate to " + rate.getLabel() );
diff --git a/src/source/tuner/fcd/FCDTunerController.java b/src/source/tuner/fcd/FCDTunerController.java
index 0f2d56fc..f782044e 100644
--- a/src/source/tuner/fcd/FCDTunerController.java
+++ b/src/source/tuner/fcd/FCDTunerController.java
@@ -76,9 +76,17 @@ public abstract class FCDTunerController extends TunerController
maxTunableFrequency,
DC_SPIKE_AVOID_BUFFER,
USABLE_BANDWIDTH_PERCENT );
- mFrequencyController.setSampleRate( sampleRate );
mDevice = device;
mDeviceDescriptor = descriptor;
+
+ try
+ {
+ mFrequencyController.setSampleRate( sampleRate );
+ }
+ catch( SourceException se )
+ {
+ mLog.error("Error setting sample rate to [" + sampleRate + "]", se );
+ }
}
/**
diff --git a/src/source/tuner/frequency/FrequencyChangeProcessorWrapper.java b/src/source/tuner/frequency/FrequencyChangeProcessorWrapper.java
index 1b96ae8b..8aa66445 100644
--- a/src/source/tuner/frequency/FrequencyChangeProcessorWrapper.java
+++ b/src/source/tuner/frequency/FrequencyChangeProcessorWrapper.java
@@ -1,10 +1,16 @@
package source.tuner.frequency;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
import sample.Listener;
+import source.SourceException;
+import source.tuner.hackrf.HackRFTunerEditor;
public class FrequencyChangeProcessorWrapper
implements IFrequencyChangeListener, Listener
{
+ private final static Logger mLog = LoggerFactory.getLogger( FrequencyChangeProcessorWrapper.class );
+
private IFrequencyChangeProcessor mProcessor;
/**
@@ -26,7 +32,14 @@ public class FrequencyChangeProcessorWrapper
{
if( mProcessor != null )
{
- mProcessor.frequencyChanged( event );
+ try
+ {
+ mProcessor.frequencyChanged( event );
+ }
+ catch( SourceException se )
+ {
+ mLog.error("Error sending frequency change event to embedded processor", se);
+ }
}
}
}
diff --git a/src/source/tuner/frequency/FrequencyController.java b/src/source/tuner/frequency/FrequencyController.java
index f1c6753d..7262317b 100644
--- a/src/source/tuner/frequency/FrequencyController.java
+++ b/src/source/tuner/frequency/FrequencyController.java
@@ -22,6 +22,8 @@ import java.util.ArrayList;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
+import source.InvalidFrequencyException;
+import source.Source;
import source.SourceException;
import source.tuner.frequency.FrequencyChangeEvent.Event;
@@ -61,7 +63,7 @@ public class FrequencyController
/**
* Set sample rate in hertz
*/
- public void setSampleRate( int sampleRate )
+ public void setSampleRate( int sampleRate ) throws SourceException
{
mSampleRate = sampleRate;
@@ -92,21 +94,22 @@ public class FrequencyController
* method supports changing the frequency correction value without
* broadcasting a frequency change event.
*/
- private void setFrequency( long frequency, boolean broadcastChange )
- throws SourceException
+ private void setFrequency( long frequency, boolean broadcastChange ) throws SourceException
{
long tunedFrequency = getTunedFrequency( frequency );
- if( tunedFrequency < mMinimumFrequency ||
- tunedFrequency > mMaximumFrequency )
+ if( tunedFrequency < mMinimumFrequency )
{
-//TODO: this should throw a frequency limit exception so that the frequency
-//controller can update its display to the last tuned frequency
- throw new SourceException( "Cannot tune frequency ( requested: " +
- frequency + " actual:" + tunedFrequency + "]" );
+ throw new InvalidFrequencyException( "Requested frequency not valid", frequency, mMinimumFrequency );
}
-
+
+ if( tunedFrequency > mMaximumFrequency )
+ {
+ throw new InvalidFrequencyException( "Requested frequency not valid", frequency, mMaximumFrequency );
+ }
+
mFrequency = frequency;
+
mTunedFrequency = tunedFrequency;
if( mTunable != null )
@@ -164,8 +167,7 @@ public class FrequencyController
return mFrequencyCorrection;
}
- public void setFrequencyCorrection( double correction )
- throws SourceException
+ public void setFrequencyCorrection( double correction ) throws SourceException
{
mFrequencyCorrection = correction;
@@ -202,7 +204,7 @@ public class FrequencyController
* Broadcasts a change/update to the current (uncorrected) frequency or the
* bandwidth/sample rate value.
*/
- protected void broadcastFrequencyChange()
+ protected void broadcastFrequencyChange() throws SourceException
{
broadcastFrequencyChangeEvent(
new FrequencyChangeEvent( Event.NOTIFICATION_FREQUENCY_CHANGE, mFrequency ) );
@@ -211,7 +213,7 @@ public class FrequencyController
/**
* Broadcast a frequency error/correction value change
*/
- protected void broadcastFrequencyErrorChange()
+ protected void broadcastFrequencyErrorChange() throws SourceException
{
broadcastFrequencyChangeEvent(
new FrequencyChangeEvent( Event.NOTIFICATION_FREQUENCY_CORRECTION_CHANGE, mFrequencyCorrection ) );
@@ -220,13 +222,13 @@ public class FrequencyController
/**
* Broadcasts a sample rate change
*/
- protected void broadcastSampleRateChange()
+ protected void broadcastSampleRateChange() throws SourceException
{
broadcastFrequencyChangeEvent(
new FrequencyChangeEvent( Event.NOTIFICATION_SAMPLE_RATE_CHANGE, mSampleRate ) );
}
- public void broadcastFrequencyChangeEvent( FrequencyChangeEvent event )
+ public void broadcastFrequencyChangeEvent( FrequencyChangeEvent event ) throws SourceException
{
for( IFrequencyChangeProcessor processor: mProcessors )
{
diff --git a/src/source/tuner/frequency/IFrequencyChangeProcessor.java b/src/source/tuner/frequency/IFrequencyChangeProcessor.java
index 479d8e8d..788c46ac 100644
--- a/src/source/tuner/frequency/IFrequencyChangeProcessor.java
+++ b/src/source/tuner/frequency/IFrequencyChangeProcessor.java
@@ -1,6 +1,8 @@
package source.tuner.frequency;
+import source.SourceException;
+
public interface IFrequencyChangeProcessor
{
- public void frequencyChanged( FrequencyChangeEvent event );
+ public void frequencyChanged( FrequencyChangeEvent event ) throws SourceException;
}
diff --git a/src/source/tuner/hackrf/HackRFTunerController.java b/src/source/tuner/hackrf/HackRFTunerController.java
index ef47b4c4..69698afe 100644
--- a/src/source/tuner/hackrf/HackRFTunerController.java
+++ b/src/source/tuner/hackrf/HackRFTunerController.java
@@ -515,7 +515,7 @@ public class HackRFTunerController extends TunerController
* sample rates. However, since we're only using integral sample rates, we
* simply invoke the setSampleRateManual method directly.
*/
- public void setSampleRate( HackRFSampleRate rate ) throws UsbException
+ public void setSampleRate( HackRFSampleRate rate ) throws UsbException, SourceException
{
setSampleRateManual( rate.getRate(), 1 );
diff --git a/src/source/tuner/hackrf/HackRFTunerEditor.java b/src/source/tuner/hackrf/HackRFTunerEditor.java
index 1b0095d1..8962be28 100644
--- a/src/source/tuner/hackrf/HackRFTunerEditor.java
+++ b/src/source/tuner/hackrf/HackRFTunerEditor.java
@@ -142,7 +142,7 @@ public class HackRFTunerEditor extends TunerConfigurationEditor
mController.setSampleRate( sampleRate );
save();
}
- catch ( UsbException e2 )
+ catch ( SourceException|UsbException e2 )
{
JOptionPane.showMessageDialog( HackRFTunerEditor.this, "HackRF Tuner Controller"
+ " - couldn't apply the sample rate setting [" + sampleRate.getLabel() +