From 078a6fddce69b01f50962b7747b57d7bbe146657 Mon Sep 17 00:00:00 2001 From: Denny Date: Sat, 4 Jun 2016 08:21:28 -0400 Subject: [PATCH] Closes #71 - frequency controller throws exception when exceeding min/max tuning limits of a tuner. Updated code to show dialog to user whenever the tuning limit has been exceeded. Added new InvalidFrequencyException that includes the requested invalid frequency and the valid frequency limit that was exceeded --- .idea/copyright/sdrtrunk.xml | 2 +- src/gui/control/JFrequencyControl.java | 756 ++++++++++-------- src/source/InvalidFrequencyException.java | 57 ++ src/source/recording/Recording.java | 2 +- src/source/tuner/TunerChannelSource.java | 3 +- src/source/tuner/TunerController.java | 14 +- .../tuner/airspy/AirspyTunerController.java | 4 +- .../tuner/airspy/AirspyTunerEditor.java | 2 +- src/source/tuner/fcd/FCDTunerController.java | 10 +- .../FrequencyChangeProcessorWrapper.java | 15 +- .../tuner/frequency/FrequencyController.java | 34 +- .../frequency/IFrequencyChangeProcessor.java | 4 +- .../tuner/hackrf/HackRFTunerController.java | 2 +- .../tuner/hackrf/HackRFTunerEditor.java | 2 +- 14 files changed, 516 insertions(+), 391 deletions(-) create mode 100644 src/source/InvalidFrequencyException.java 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() +