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
This commit is contained in:
Denny
2016-06-04 08:21:28 -04:00
parent bf5ded53e2
commit 078a6fddce
14 changed files with 516 additions and 391 deletions

View File

@@ -1,6 +1,6 @@
<component name="CopyrightManager">
<copyright>
<option name="myName" value="sdrtrunk" />
<option name="notice" value="/*******************************************************************************&#10; * sdrtrunk &#10; * Copyright (C) 2014-&amp;#36;today.year Dennis Sheirer&#10; * &#10; * This program is free software: you can redistribute it and/or modify&#10; * it under the terms of the GNU General Public License as published by&#10; * the Free Software Foundation, either version 3 of the License, or&#10; * (at your option) any later version.&#10; * &#10; * This program is distributed in the hope that it will be useful,&#10; * but WITHOUT ANY WARRANTY; without even the implied warranty of&#10; * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the&#10; * GNU General Public License for more details.&#10; * &#10; * You should have received a copy of the GNU General Public License&#10; * along with this program. If not, see &lt;http://www.gnu.org/licenses/&gt;&#10; ******************************************************************************/&#10;" />
<option name="notice" value="sdrtrunk &#10;Copyright (C) 2014-&amp;#36;today.year Dennis Sheirer&#10;&#10;This program is free software: you can redistribute it and/or modify&#10;it under the terms of the GNU General Public License as published by&#10;the Free Software Foundation, either version 3 of the License, or&#10;(at your option) any later version.&#10;&#10;This program is distributed in the hope that it will be useful,&#10;but WITHOUT ANY WARRANTY; without even the implied warranty of&#10;MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the&#10;GNU General Public License for more details.&#10; &#10;You should have received a copy of the GNU General Public License&#10;along with this program. If not, see &lt;http://www.gnu.org/licenses/&gt;&#10;" />
</copyright>
</component>

View File

@@ -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 <http://www.gnu.org/licenses/>
* SDR Trunk
* Copyright (C) 2014 Dennis Sheirer
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>
******************************************************************************/
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<IFrequencyChangeProcessor> mProcessors = new ArrayList<>();
private List<IFrequencyChangeProcessor> mProcessors = new ArrayList<>();
private Color mHighlightColor = Color.YELLOW;
private long mFrequency;
private Cursor mBlankCursor;
private HashMap<Integer,Digit> mDigits = new HashMap<Integer,Digit>();
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<Integer, Digit> mDigits = new HashMap<Integer, Digit>();
/**
* 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<IFrequencyChangeProcessor> 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<IFrequencyChangeProcessor> 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());
}
}
}
}
}

View File

@@ -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 <http://www.gnu.org/licenses/>
*
******************************************************************************/
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;
}
}

View File

@@ -89,7 +89,7 @@ public class Recording implements Comparable<Recording>,
}
@Override
public void frequencyChanged( FrequencyChangeEvent event )
public void frequencyChanged( FrequencyChangeEvent event ) throws SourceException
{
if( event.getEvent() == Event.NOTIFICATION_FREQUENCY_CHANGE )
{

View File

@@ -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 )

View File

@@ -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
*

View File

@@ -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 )
{

View File

@@ -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() );

View File

@@ -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 );
}
}
/**

View File

@@ -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<FrequencyChangeEvent>
{
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);
}
}
}
}

View File

@@ -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 )
{

View File

@@ -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;
}

View File

@@ -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 );

View File

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