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() +