mirror of
https://github.com/DSheirer/sdrtrunk.git
synced 2026-11-13 17:17:29 -05:00
Merges #34 Major redesign of Tuner, Channel and Alias management.
Changes to model, view and controller components and updates all gui editors. Removes the configuration panel and tree and replaces with 3 new panels. Updates playlist.xml to a new playlist_v2.xml format.
This commit is contained in:
@@ -1,77 +0,0 @@
|
||||
package source.tuner.airspy;
|
||||
|
||||
/*******************************************************************************
|
||||
* SDR Trunk
|
||||
* Copyright (C) 2015 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/>
|
||||
******************************************************************************/
|
||||
|
||||
import javax.swing.JLabel;
|
||||
import javax.swing.JPanel;
|
||||
|
||||
import net.miginfocom.swing.MigLayout;
|
||||
|
||||
public class AirspyInformationPanel extends JPanel
|
||||
{
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
private AirspyTunerController mController;
|
||||
|
||||
/**
|
||||
* Displays Airspy firmware, serial number and part identifier
|
||||
*/
|
||||
public AirspyInformationPanel( AirspyTunerController controller )
|
||||
{
|
||||
mController = controller;
|
||||
|
||||
initGUI();
|
||||
}
|
||||
|
||||
private void initGUI()
|
||||
{
|
||||
setLayout( new MigLayout( "fill,wrap 2",
|
||||
"[right,grow][grow]",
|
||||
"[][][][][grow]" ) );
|
||||
|
||||
AirspyDeviceInformation info = mController.getDeviceInfo();
|
||||
|
||||
add( new JLabel( "Serial:" ) );
|
||||
add( new JLabel( info.getSerialNumber() ) );
|
||||
add( new JLabel( "Firmware:" ) );
|
||||
|
||||
//Split the firmware on spaces and use first value -- expose full
|
||||
//string in a tool tip
|
||||
String[] firmware = info.getVersion().split( " " );
|
||||
|
||||
JLabel firmwareLabel;
|
||||
|
||||
if( firmware.length > 1 )
|
||||
{
|
||||
firmwareLabel = new JLabel( firmware[ 0 ] );
|
||||
}
|
||||
else
|
||||
{
|
||||
firmwareLabel = new JLabel( info.getVersion() );
|
||||
}
|
||||
|
||||
firmwareLabel.setToolTipText( info.getVersion() );
|
||||
|
||||
add( firmwareLabel );
|
||||
add( new JLabel( "Part:" ) );
|
||||
add( new JLabel( info.getPartNumber() ) );
|
||||
add( new JLabel( "Board ID:" ) );
|
||||
add( new JLabel( info.getBoardID().getLabel() ) );
|
||||
}
|
||||
}
|
||||
@@ -18,15 +18,10 @@ package source.tuner.airspy;
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>
|
||||
******************************************************************************/
|
||||
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import sample.adapter.ISampleAdapter;
|
||||
|
||||
public class AirspySampleAdapter implements ISampleAdapter
|
||||
{
|
||||
private final static Logger mLog = LoggerFactory.getLogger( AirspySampleAdapter.class );
|
||||
|
||||
private static final float SCALE_SIGNED_12_BIT_TO_FLOAT = 1.0f / 2048.0f;
|
||||
|
||||
private boolean mSamplePacking = false;
|
||||
|
||||
@@ -19,8 +19,6 @@ package source.tuner.airspy;
|
||||
|
||||
import java.util.concurrent.RejectedExecutionException;
|
||||
|
||||
import javax.swing.JPanel;
|
||||
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
@@ -31,44 +29,22 @@ import source.tuner.Tuner;
|
||||
import source.tuner.TunerChannel;
|
||||
import source.tuner.TunerChannelSource;
|
||||
import source.tuner.TunerClass;
|
||||
import source.tuner.TunerConfiguration;
|
||||
import source.tuner.TunerEvent;
|
||||
import source.tuner.TunerType;
|
||||
import source.tuner.airspy.AirspyTunerController.BoardID;
|
||||
import controller.ResourceManager;
|
||||
import controller.ThreadPoolManager;
|
||||
|
||||
public class AirspyTuner extends Tuner
|
||||
{
|
||||
private final static Logger mLog = LoggerFactory.getLogger( AirspyTuner.class );
|
||||
|
||||
AirspyTunerController mController;
|
||||
|
||||
public AirspyTuner( AirspyTunerController controller )
|
||||
{
|
||||
super( "Airspy" );
|
||||
|
||||
mController = controller;
|
||||
|
||||
/* Register for frequency/sample rate changes so that we can rebroadcast
|
||||
* to any registered listeners */
|
||||
mController.addListener( this );
|
||||
}
|
||||
|
||||
@Override
|
||||
public JPanel getEditor( ResourceManager resourceManager )
|
||||
{
|
||||
return new AirspyTunerEditorPanel( this, resourceManager );
|
||||
super( "Airspy " + controller.getDeviceInfo().getSerialNumber(), controller );
|
||||
}
|
||||
|
||||
public AirspyTunerController getController()
|
||||
{
|
||||
return mController;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void apply( TunerConfiguration config ) throws SourceException
|
||||
{
|
||||
mController.apply( config );
|
||||
return (AirspyTunerController)getTunerController();
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -76,11 +52,11 @@ public class AirspyTuner extends Tuner
|
||||
{
|
||||
try
|
||||
{
|
||||
return mController.getDeviceInfo().getSerialNumber();
|
||||
return getController().getDeviceInfo().getSerialNumber();
|
||||
}
|
||||
catch( Exception e )
|
||||
{
|
||||
mLog.error( "error gettting serial number", e );
|
||||
mLog.error( "error getting serial number", e );
|
||||
}
|
||||
|
||||
return BoardID.AIRSPY.getLabel();
|
||||
@@ -98,35 +74,12 @@ public class AirspyTuner extends Tuner
|
||||
return TunerType.AIRSPY_R820T;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getSampleRate()
|
||||
{
|
||||
int rate = 0;
|
||||
|
||||
try
|
||||
{
|
||||
rate = mController.getCurrentSampleRate();
|
||||
}
|
||||
catch ( SourceException e )
|
||||
{
|
||||
mLog.error( "Error while getting sample rate from controller", e );
|
||||
}
|
||||
|
||||
return rate;
|
||||
}
|
||||
|
||||
@Override
|
||||
public double getSampleSize()
|
||||
{
|
||||
return 13.0;
|
||||
}
|
||||
|
||||
@Override
|
||||
public long getFrequency() throws SourceException
|
||||
{
|
||||
return mController.getFrequency();
|
||||
}
|
||||
|
||||
@Override
|
||||
public TunerChannelSource getChannel( TunerChannel channel )
|
||||
throws RejectedExecutionException, SourceException
|
||||
@@ -138,9 +91,16 @@ public class AirspyTuner extends Tuner
|
||||
//Consider implementing a fractional resampler to get a correct 48 kHz
|
||||
//output sample rate
|
||||
|
||||
return mController.getChannel( this, channel );
|
||||
}
|
||||
TunerChannelSource source = getController().getChannel( this, channel );
|
||||
|
||||
if( source != null )
|
||||
{
|
||||
broadcast( new TunerEvent( this, TunerEvent.Event.CHANNEL_COUNT ) );
|
||||
}
|
||||
|
||||
return source;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void releaseChannel( TunerChannelSource source )
|
||||
{
|
||||
@@ -150,19 +110,19 @@ public class AirspyTuner extends Tuner
|
||||
/* Tell the controller to release the channel and cleanup */
|
||||
if( source != null )
|
||||
{
|
||||
mController.releaseChannel( source );
|
||||
getController().releaseChannel( source );
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void addListener( Listener<ComplexBuffer> listener )
|
||||
{
|
||||
mController.addListener( listener );
|
||||
getController().addListener( listener );
|
||||
}
|
||||
|
||||
@Override
|
||||
public void removeListener( Listener<ComplexBuffer> listener )
|
||||
{
|
||||
mController.removeListener( listener );
|
||||
getController().removeListener( listener );
|
||||
}
|
||||
}
|
||||
|
||||
@@ -19,9 +19,9 @@ package source.tuner.airspy;
|
||||
|
||||
import javax.xml.bind.annotation.XmlAttribute;
|
||||
|
||||
import source.tuner.TunerConfiguration;
|
||||
import source.tuner.TunerType;
|
||||
import source.tuner.airspy.AirspyTunerController.Gain;
|
||||
import source.tuner.configuration.TunerConfiguration;
|
||||
|
||||
public class AirspyTunerConfiguration extends TunerConfiguration
|
||||
{
|
||||
@@ -30,6 +30,7 @@ public class AirspyTunerConfiguration extends TunerConfiguration
|
||||
private int mIFGain = AirspyTunerController.IF_GAIN_DEFAULT;
|
||||
private int mMixerGain = AirspyTunerController.MIXER_GAIN_DEFAULT;
|
||||
private int mLNAGain = AirspyTunerController.LNA_GAIN_DEFAULT;
|
||||
private double mFrequencyCorrection = 0.0d;
|
||||
|
||||
private boolean mMixerAGC = false;
|
||||
private boolean mLNAAGC = false;
|
||||
@@ -39,12 +40,11 @@ public class AirspyTunerConfiguration extends TunerConfiguration
|
||||
*/
|
||||
public AirspyTunerConfiguration()
|
||||
{
|
||||
this( "Default" );
|
||||
}
|
||||
|
||||
public AirspyTunerConfiguration( String name )
|
||||
public AirspyTunerConfiguration( String uniqueID, String name )
|
||||
{
|
||||
super( name );
|
||||
super( uniqueID, name );
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -129,4 +129,16 @@ public class AirspyTunerConfiguration extends TunerConfiguration
|
||||
{
|
||||
mLNAAGC = enabled;
|
||||
}
|
||||
|
||||
@XmlAttribute( name = "frequency_correction" )
|
||||
public double getFrequencyCorrection()
|
||||
{
|
||||
return mFrequencyCorrection;
|
||||
}
|
||||
|
||||
public void setFrequencyCorrection( double value )
|
||||
{
|
||||
mFrequencyCorrection = value;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -1,705 +0,0 @@
|
||||
/*******************************************************************************
|
||||
* 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 source.tuner.airspy;
|
||||
|
||||
import java.awt.event.ActionEvent;
|
||||
import java.awt.event.ActionListener;
|
||||
import java.awt.event.FocusEvent;
|
||||
import java.awt.event.FocusListener;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import javax.swing.ComboBoxModel;
|
||||
import javax.swing.DefaultComboBoxModel;
|
||||
import javax.swing.JButton;
|
||||
import javax.swing.JCheckBox;
|
||||
import javax.swing.JComboBox;
|
||||
import javax.swing.JLabel;
|
||||
import javax.swing.JOptionPane;
|
||||
import javax.swing.JPanel;
|
||||
import javax.swing.JSeparator;
|
||||
import javax.swing.JSlider;
|
||||
import javax.swing.JTextField;
|
||||
import javax.swing.event.ChangeEvent;
|
||||
import javax.swing.event.ChangeListener;
|
||||
import javax.usb.UsbException;
|
||||
|
||||
import net.miginfocom.swing.MigLayout;
|
||||
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import org.usb4java.LibUsbException;
|
||||
|
||||
import source.SourceException;
|
||||
import source.tuner.TunerConfiguration;
|
||||
import source.tuner.TunerConfigurationAssignment;
|
||||
import source.tuner.TunerType;
|
||||
import source.tuner.airspy.AirspyTunerController.Gain;
|
||||
import source.tuner.airspy.AirspyTunerController.GainMode;
|
||||
import controller.ResourceManager;
|
||||
|
||||
public class AirspyTunerConfigurationPanel extends JPanel
|
||||
{
|
||||
private final static Logger mLog =
|
||||
LoggerFactory.getLogger( AirspyTunerConfigurationPanel.class );
|
||||
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
private ResourceManager mResourceManager;
|
||||
private AirspyTunerController mController;
|
||||
private AirspyTunerConfiguration mSelectedConfig;
|
||||
|
||||
private JButton mNewConfiguration;
|
||||
private JButton mDeleteConfiguration;
|
||||
private JComboBox<AirspyTunerConfiguration> mComboConfigurations;
|
||||
|
||||
private JTextField mName;
|
||||
|
||||
private JComboBox<AirspySampleRate> mSampleRateCombo;
|
||||
|
||||
private JComboBox<GainMode> mGainModeCombo;
|
||||
private JLabel mGainLabel;
|
||||
private JLabel mGainFillerLabel;
|
||||
private JLabel mGainValueLabel;
|
||||
private JSlider mGain;
|
||||
|
||||
private JLabel mIFGainLabel;
|
||||
private JLabel mIFGainFillerLabel;
|
||||
private JLabel mIFGainValueLabel;
|
||||
private JSlider mIFGain;
|
||||
|
||||
private JLabel mLNAGainLabel;
|
||||
private JCheckBox mLNAAGC;
|
||||
private JLabel mLNAGainValueLabel;
|
||||
private JSlider mLNAGain;
|
||||
|
||||
private JLabel mMixerGainValueLabel;
|
||||
private JCheckBox mMixerAGC;
|
||||
private JLabel mMixerGainLabel;
|
||||
private JSlider mMixerGain;
|
||||
|
||||
|
||||
public AirspyTunerConfigurationPanel( ResourceManager resourceManager,
|
||||
AirspyTunerController controller )
|
||||
{
|
||||
mResourceManager = resourceManager;
|
||||
mController = controller;
|
||||
|
||||
init();
|
||||
}
|
||||
|
||||
/**
|
||||
* Initializes the gui components
|
||||
*/
|
||||
private void init()
|
||||
{
|
||||
setLayout( new MigLayout( "fill,wrap 4", "[left][grow][grow][right]",
|
||||
"[][][][][][][grow]" ) );
|
||||
|
||||
/**
|
||||
* Tuner configuration selector
|
||||
*/
|
||||
mComboConfigurations = new JComboBox<AirspyTunerConfiguration>();
|
||||
|
||||
mComboConfigurations.setModel( getModel() );
|
||||
|
||||
/* Determine which tuner configuration should be selected/displayed */
|
||||
TunerConfigurationAssignment savedConfig = null;
|
||||
String serial = null;
|
||||
|
||||
serial = mController.getDeviceInfo().getSerialNumber();
|
||||
|
||||
if( serial != null )
|
||||
{
|
||||
savedConfig = mResourceManager
|
||||
.getSettingsManager().getSelectedTunerConfiguration(
|
||||
TunerType.AIRSPY_R820T, serial );
|
||||
}
|
||||
|
||||
if( savedConfig != null )
|
||||
{
|
||||
mSelectedConfig = getNamedConfiguration(
|
||||
savedConfig.getTunerConfigurationName() );
|
||||
}
|
||||
|
||||
/* If we couldn't determine the saved/selected config, use the first one */
|
||||
if( mSelectedConfig == null )
|
||||
{
|
||||
mSelectedConfig = mComboConfigurations.getItemAt( 0 );
|
||||
|
||||
//Store this config as the default for this tuner at this address
|
||||
|
||||
if( serial != null )
|
||||
{
|
||||
mResourceManager.getSettingsManager()
|
||||
.setSelectedTunerConfiguration( TunerType.AIRSPY_R820T,
|
||||
serial, mSelectedConfig );
|
||||
}
|
||||
}
|
||||
|
||||
mComboConfigurations.setSelectedItem( mSelectedConfig );
|
||||
|
||||
mComboConfigurations.addActionListener( new ActionListener()
|
||||
{
|
||||
@Override
|
||||
public void actionPerformed( ActionEvent e )
|
||||
{
|
||||
AirspyTunerConfiguration selected =
|
||||
(AirspyTunerConfiguration)mComboConfigurations
|
||||
.getItemAt( mComboConfigurations.getSelectedIndex() );
|
||||
|
||||
if( selected != null )
|
||||
{
|
||||
update( selected );
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
add( new JLabel( "Config:" ) );
|
||||
add( mComboConfigurations, "span,growx,push" );
|
||||
|
||||
add( new JSeparator(), "span,growx,push" );
|
||||
|
||||
|
||||
/**
|
||||
* Tuner Configuration Name
|
||||
*/
|
||||
mName = new JTextField();
|
||||
mName.setText( mSelectedConfig.getName() );
|
||||
|
||||
mName.addFocusListener( new FocusListener()
|
||||
{
|
||||
@Override
|
||||
public void focusLost( FocusEvent e )
|
||||
{
|
||||
mSelectedConfig.setName( mName.getText() );
|
||||
save();
|
||||
}
|
||||
@Override
|
||||
public void focusGained( FocusEvent e ) {}
|
||||
} );
|
||||
|
||||
add( new JLabel( "Name:" ) );
|
||||
add( mName, "span,growx,push" );
|
||||
|
||||
/**
|
||||
* Sample Rate
|
||||
*/
|
||||
add( new JLabel( "Sample Rate:" ) );
|
||||
|
||||
List<AirspySampleRate> rates = mController.getSampleRates();
|
||||
|
||||
mSampleRateCombo = new JComboBox<AirspySampleRate>(
|
||||
new DefaultComboBoxModel<AirspySampleRate>( rates.toArray(
|
||||
new AirspySampleRate[ rates.size() ] ) ) );
|
||||
|
||||
mSampleRateCombo.setSelectedItem( mController.getSampleRate() );
|
||||
|
||||
mSampleRateCombo.addActionListener( new ActionListener()
|
||||
{
|
||||
@Override
|
||||
public void actionPerformed( ActionEvent e )
|
||||
{
|
||||
AirspySampleRate rate = (AirspySampleRate)mSampleRateCombo.getSelectedItem();
|
||||
|
||||
try
|
||||
{
|
||||
mController.setSampleRate( rate );
|
||||
mSelectedConfig.setSampleRate( rate.getRate() );
|
||||
save();
|
||||
}
|
||||
catch ( LibUsbException | UsbException e1 )
|
||||
{
|
||||
JOptionPane.showMessageDialog( AirspyTunerConfigurationPanel.this,
|
||||
"Couldn't set sample rate to " + rate.getLabel() );
|
||||
|
||||
mLog.error( "Error setting airspy sample rate", e1 );
|
||||
}
|
||||
}
|
||||
} );
|
||||
|
||||
add( mSampleRateCombo, "span 3,growx" );
|
||||
|
||||
add( new JSeparator(), "span,growx,push" );
|
||||
|
||||
/**
|
||||
* Gain Mode
|
||||
*/
|
||||
add( new JLabel( "Gain Mode:" ) );
|
||||
mGainModeCombo = new JComboBox<AirspyTunerController.GainMode>( GainMode.values() );
|
||||
mGainModeCombo.setSelectedItem( Gain.getGainMode( mSelectedConfig.getGain() ) );
|
||||
mGainModeCombo.addActionListener( new ActionListener()
|
||||
{
|
||||
@Override
|
||||
public void actionPerformed( ActionEvent e )
|
||||
{
|
||||
GainMode mode = (GainMode)mGainModeCombo.getSelectedItem();
|
||||
updateGainComponents( mode );
|
||||
|
||||
switch( mode )
|
||||
{
|
||||
case LINEARITY:
|
||||
mGain.setValue( AirspyTunerController.LINEARITY_GAIN_DEFAULT.getValue() );
|
||||
mSelectedConfig.setGain( AirspyTunerController.LINEARITY_GAIN_DEFAULT );
|
||||
break;
|
||||
case SENSITIVITY:
|
||||
mGain.setValue( AirspyTunerController.SENSITIVITY_GAIN_DEFAULT.getValue() );
|
||||
mSelectedConfig.setGain( AirspyTunerController.SENSITIVITY_GAIN_DEFAULT );
|
||||
break;
|
||||
case CUSTOM:
|
||||
default:
|
||||
mLNAGain.setValue( mSelectedConfig.getLNAGain() );
|
||||
mMixerGain.setValue( mSelectedConfig.getMixerGain() );
|
||||
mIFGain.setValue( mSelectedConfig.getIFGain() );
|
||||
mSelectedConfig.setGain( Gain.CUSTOM );
|
||||
break;
|
||||
}
|
||||
|
||||
save();
|
||||
}
|
||||
} );
|
||||
|
||||
add( mGainModeCombo, "wrap" );
|
||||
|
||||
/**
|
||||
* Gain
|
||||
*/
|
||||
mGainLabel = new JLabel( "Gain" );
|
||||
add( mGainLabel );
|
||||
mGainFillerLabel = new JLabel( "" );
|
||||
add( mGainFillerLabel, "span 2" );
|
||||
mGainValueLabel = new JLabel( String.valueOf( mSelectedConfig.getGain().getValue() ) );
|
||||
add( mGainValueLabel, "wrap" );
|
||||
mGain = new JSlider( JSlider.HORIZONTAL,
|
||||
AirspyTunerController.GAIN_MIN,
|
||||
AirspyTunerController.GAIN_MAX,
|
||||
mSelectedConfig.getGain().getValue() );
|
||||
mGain.setMajorTickSpacing( 1 );
|
||||
mGain.setPaintTicks( true );
|
||||
|
||||
mGain.addChangeListener( new ChangeListener()
|
||||
{
|
||||
@Override
|
||||
public void stateChanged( ChangeEvent event )
|
||||
{
|
||||
GainMode mode = (GainMode)mGainModeCombo.getSelectedItem();
|
||||
int value = mGain.getValue();
|
||||
Gain gain = Gain.getGain( mode, value );
|
||||
|
||||
try
|
||||
{
|
||||
mController.setGain( gain );
|
||||
mSelectedConfig.setGain( gain );
|
||||
save();
|
||||
mGainValueLabel.setText( String.valueOf( gain.getValue() ) );
|
||||
}
|
||||
catch ( Exception e )
|
||||
{
|
||||
mLog.error( "Couldn't set airspy gain to:" + gain.name(), e );
|
||||
|
||||
JOptionPane.showMessageDialog( mGain,
|
||||
"Couldn't set gain value to " + gain.getValue() );
|
||||
|
||||
mGain.setValue( mSelectedConfig.getGain().getValue() );
|
||||
}
|
||||
}
|
||||
} );
|
||||
|
||||
add( mGain, "span,grow" );
|
||||
|
||||
/**
|
||||
* IF/VGA Gain
|
||||
*/
|
||||
mIFGainLabel = new JLabel( "IF Gain" );
|
||||
add( mIFGainLabel );
|
||||
mIFGainFillerLabel = new JLabel( "" );
|
||||
add( mIFGainFillerLabel, "span 2" );
|
||||
mIFGainValueLabel = new JLabel( String.valueOf( mSelectedConfig.getIFGain() ) );
|
||||
add( mIFGainValueLabel, "wrap" );
|
||||
|
||||
mIFGain = new JSlider( JSlider.HORIZONTAL,
|
||||
AirspyTunerController.IF_GAIN_MIN,
|
||||
AirspyTunerController.IF_GAIN_MAX,
|
||||
mSelectedConfig.getIFGain() );
|
||||
|
||||
mIFGain.setMajorTickSpacing( 1 );
|
||||
mIFGain.setPaintTicks( true );
|
||||
|
||||
mIFGain.addChangeListener( new ChangeListener()
|
||||
{
|
||||
@Override
|
||||
public void stateChanged( ChangeEvent event )
|
||||
{
|
||||
int gain = mIFGain.getValue();
|
||||
|
||||
try
|
||||
{
|
||||
mController.setIFGain( gain );
|
||||
mSelectedConfig.setIFGain( gain );
|
||||
save();
|
||||
mIFGainValueLabel.setText( String.valueOf( gain ) );
|
||||
}
|
||||
catch ( Exception e )
|
||||
{
|
||||
mLog.error( "Couldn't set airspy IF gain to:" + gain, e );
|
||||
|
||||
JOptionPane.showMessageDialog( mIFGain,
|
||||
"Couldn't set IF gain value to " + gain );
|
||||
|
||||
mIFGain.setValue( mSelectedConfig.getIFGain() );
|
||||
}
|
||||
}
|
||||
} );
|
||||
|
||||
add( mIFGain, "span,grow" );
|
||||
|
||||
/**
|
||||
* Mixer Gain
|
||||
*/
|
||||
mMixerGainLabel = new JLabel( "Mixer Gain" );
|
||||
add( mMixerGainLabel );
|
||||
|
||||
mMixerAGC = new JCheckBox( "AGC" );
|
||||
mMixerAGC.setSelected( mSelectedConfig.isMixerAGC() );
|
||||
mMixerAGC.addActionListener( new ActionListener()
|
||||
{
|
||||
@Override
|
||||
public void actionPerformed( ActionEvent e )
|
||||
{
|
||||
try
|
||||
{
|
||||
mController.setMixerAGC( !mSelectedConfig.isMixerAGC() );
|
||||
mSelectedConfig.setMixerAGC( !mSelectedConfig.isMixerAGC() );
|
||||
save();
|
||||
}
|
||||
catch ( Exception e1 )
|
||||
{
|
||||
mLog.error( "Error setting Mixer AGC Enabled:" + !mSelectedConfig.isMixerAGC() );
|
||||
mMixerAGC.setSelected( mSelectedConfig.isMixerAGC() );
|
||||
}
|
||||
}
|
||||
} );
|
||||
|
||||
|
||||
add( mMixerAGC, "span 2,center" );
|
||||
|
||||
mMixerGainValueLabel = new JLabel( String.valueOf( mSelectedConfig.getMixerGain() ) );
|
||||
add( mMixerGainValueLabel, "wrap" );
|
||||
|
||||
mMixerGain = new JSlider( JSlider.HORIZONTAL,
|
||||
AirspyTunerController.MIXER_GAIN_MIN,
|
||||
AirspyTunerController.MIXER_GAIN_MAX,
|
||||
mSelectedConfig.getMixerGain() );
|
||||
|
||||
mMixerGain.setMajorTickSpacing( 1 );
|
||||
mMixerGain.setPaintTicks( true );
|
||||
|
||||
mMixerGain.addChangeListener( new ChangeListener()
|
||||
{
|
||||
@Override
|
||||
public void stateChanged( ChangeEvent event )
|
||||
{
|
||||
int gain = mMixerGain.getValue();
|
||||
|
||||
try
|
||||
{
|
||||
mController.setMixerGain( gain );
|
||||
mSelectedConfig.setMixerGain( gain );
|
||||
save();
|
||||
mMixerGainValueLabel.setText( String.valueOf( gain ) );
|
||||
}
|
||||
catch ( Exception e )
|
||||
{
|
||||
mLog.error( "Couldn't set airspy Mixer gain to:" + gain, e );
|
||||
|
||||
JOptionPane.showMessageDialog( mIFGain, "Couldn't set Mixer gain value to " + gain );
|
||||
|
||||
mMixerGain.setValue( mSelectedConfig.getMixerGain() );
|
||||
}
|
||||
}
|
||||
} );
|
||||
|
||||
add( mMixerGain, "span,grow" );
|
||||
|
||||
/**
|
||||
* LNA Gain
|
||||
*/
|
||||
mLNAGainLabel = new JLabel( "LNA Gain" );
|
||||
add( mLNAGainLabel );
|
||||
|
||||
mLNAAGC = new JCheckBox( "AGC" );
|
||||
mLNAAGC.setSelected( mSelectedConfig.isLNAAGC() );
|
||||
mLNAAGC.addActionListener( new ActionListener()
|
||||
{
|
||||
@Override
|
||||
public void actionPerformed( ActionEvent e )
|
||||
{
|
||||
try
|
||||
{
|
||||
mController.setLNAAGC( !mSelectedConfig.isLNAAGC() );
|
||||
mSelectedConfig.setLNAAGC( !mSelectedConfig.isLNAAGC() );
|
||||
save();
|
||||
}
|
||||
catch ( Exception e1 )
|
||||
{
|
||||
mLog.error( "Error setting LNA AGC Enabled:" + !mSelectedConfig.isLNAAGC() );
|
||||
mLNAAGC.setSelected( mSelectedConfig.isLNAAGC() );
|
||||
}
|
||||
|
||||
}
|
||||
} );
|
||||
|
||||
add( mLNAAGC, "span 2,center" );
|
||||
|
||||
mLNAGainValueLabel = new JLabel( String.valueOf( mSelectedConfig.getLNAGain() ) );
|
||||
add( mLNAGainValueLabel, "wrap" );
|
||||
|
||||
mLNAGain = new JSlider( JSlider.HORIZONTAL,
|
||||
AirspyTunerController.LNA_GAIN_MIN,
|
||||
AirspyTunerController.LNA_GAIN_MAX,
|
||||
mSelectedConfig.getLNAGain() );
|
||||
|
||||
mLNAGain.setMajorTickSpacing( 1 );
|
||||
mLNAGain.setPaintTicks( true );
|
||||
|
||||
mLNAGain.addChangeListener( new ChangeListener()
|
||||
{
|
||||
@Override
|
||||
public void stateChanged( ChangeEvent event )
|
||||
{
|
||||
int gain = mLNAGain.getValue();
|
||||
|
||||
try
|
||||
{
|
||||
mController.setLNAGain( gain );
|
||||
mSelectedConfig.setLNAGain( gain );
|
||||
save();
|
||||
mLNAGainValueLabel.setText( String.valueOf( gain ) );
|
||||
}
|
||||
catch ( Exception e )
|
||||
{
|
||||
mLog.error( "Couldn't set airspy LNA gain to:" + gain, e );
|
||||
|
||||
JOptionPane.showMessageDialog( mIFGain, "Couldn't set LNA gain value to " + gain );
|
||||
|
||||
mLNAGain.setValue( mSelectedConfig.getLNAGain() );
|
||||
}
|
||||
}
|
||||
} );
|
||||
|
||||
add( mLNAGain, "span,grow" );
|
||||
|
||||
//Set the enabled state of each of the gain controls
|
||||
updateGainComponents( (GainMode)mGainModeCombo.getSelectedItem() );
|
||||
|
||||
/**
|
||||
* Create a new configuration
|
||||
*/
|
||||
mNewConfiguration = new JButton( "New" );
|
||||
|
||||
mNewConfiguration.addActionListener( new ActionListener()
|
||||
{
|
||||
@Override
|
||||
public void actionPerformed( ActionEvent e )
|
||||
{
|
||||
TunerConfiguration config =
|
||||
mResourceManager.getSettingsManager()
|
||||
.addNewTunerConfiguration(
|
||||
TunerType.AIRSPY_R820T,
|
||||
"New Configuration" );
|
||||
|
||||
mComboConfigurations.setModel( getModel() );
|
||||
|
||||
mComboConfigurations.setSelectedItem( config );
|
||||
|
||||
repaint();
|
||||
}
|
||||
} );
|
||||
|
||||
add( mNewConfiguration, "span 2,growx,push" );
|
||||
|
||||
/**
|
||||
* Delete the currently selected configuration
|
||||
*/
|
||||
mDeleteConfiguration = new JButton( "Delete" );
|
||||
|
||||
mDeleteConfiguration.addActionListener( new ActionListener()
|
||||
{
|
||||
@Override
|
||||
public void actionPerformed( ActionEvent e )
|
||||
{
|
||||
AirspyTunerConfiguration selected =
|
||||
(AirspyTunerConfiguration)mComboConfigurations
|
||||
.getItemAt( mComboConfigurations.getSelectedIndex() );
|
||||
|
||||
if( selected != null )
|
||||
{
|
||||
int n = JOptionPane.showConfirmDialog(
|
||||
AirspyTunerConfigurationPanel.this,
|
||||
"Are you sure you want to delete '"
|
||||
+ selected.getName() + "'?",
|
||||
"Are you sure?",
|
||||
JOptionPane.YES_NO_OPTION );
|
||||
|
||||
if( n == JOptionPane.YES_OPTION )
|
||||
{
|
||||
mResourceManager.getSettingsManager()
|
||||
.deleteTunerConfiguration( selected );
|
||||
|
||||
mComboConfigurations.setModel( getModel() );
|
||||
|
||||
mComboConfigurations.setSelectedIndex( 0 );
|
||||
|
||||
repaint();
|
||||
}
|
||||
}
|
||||
}
|
||||
} );
|
||||
|
||||
add( mDeleteConfiguration, "span 2,growx,push" );
|
||||
}
|
||||
|
||||
/**
|
||||
* Updates the enabled state of each of the gain controls according to the
|
||||
* specified gain mode. The overall gain controls are enabled for linearity
|
||||
* and sensitivity and the individual gain controls are disabled, and
|
||||
* vice-versa for custom mode.
|
||||
*/
|
||||
private void updateGainComponents( GainMode mode )
|
||||
{
|
||||
boolean isCustom = ( mode == GainMode.CUSTOM );
|
||||
|
||||
mGainLabel.setEnabled( !isCustom );
|
||||
mGainFillerLabel.setEnabled( !isCustom );
|
||||
mGainValueLabel.setEnabled( !isCustom );
|
||||
mGain.setEnabled( !isCustom );
|
||||
mIFGainLabel.setEnabled( isCustom );
|
||||
mIFGainFillerLabel.setEnabled( isCustom );
|
||||
mIFGainValueLabel.setEnabled( isCustom );
|
||||
mIFGain.setEnabled( isCustom );
|
||||
mLNAGainLabel.setEnabled( isCustom );
|
||||
mLNAAGC.setEnabled( isCustom );
|
||||
mLNAGainValueLabel.setEnabled( isCustom );
|
||||
mLNAGain.setEnabled( isCustom );
|
||||
mMixerGainValueLabel.setEnabled( isCustom );
|
||||
mMixerAGC.setEnabled( isCustom );
|
||||
mMixerGainLabel.setEnabled( isCustom );
|
||||
mMixerGain.setEnabled( isCustom );
|
||||
}
|
||||
|
||||
/**
|
||||
* Updates gui controls with the values from the tuner configuration
|
||||
* @param config - tuner configuration
|
||||
*/
|
||||
private void update( AirspyTunerConfiguration config )
|
||||
{
|
||||
mSelectedConfig = config;
|
||||
|
||||
try
|
||||
{
|
||||
mController.apply( config );
|
||||
|
||||
mName.setText( config.getName() );
|
||||
|
||||
AirspySampleRate rate = mController.getSampleRate(
|
||||
mSelectedConfig.getSampleRate() );
|
||||
|
||||
if( rate != null )
|
||||
{
|
||||
mSampleRateCombo.setSelectedItem( rate );
|
||||
}
|
||||
|
||||
mIFGain.setValue( mSelectedConfig.getIFGain() );
|
||||
mMixerGain.setValue( mSelectedConfig.getMixerGain() );
|
||||
mLNAGain.setValue( mSelectedConfig.getLNAGain() );
|
||||
|
||||
mMixerAGC.setSelected( mSelectedConfig.isMixerAGC() );
|
||||
mLNAAGC.setSelected( mSelectedConfig.isLNAAGC() );
|
||||
|
||||
Gain gain = mSelectedConfig.getGain();
|
||||
mGainModeCombo.setSelectedItem( Gain.getGainMode( gain ) );
|
||||
mGain.setValue( gain.getValue() );
|
||||
|
||||
mResourceManager.getSettingsManager().setSelectedTunerConfiguration(
|
||||
TunerType.AIRSPY_R820T, mController.getDeviceInfo().getSerialNumber(), config );
|
||||
|
||||
save();
|
||||
}
|
||||
catch ( /*UsbException |*/ SourceException e1 )
|
||||
{
|
||||
JOptionPane.showMessageDialog(
|
||||
AirspyTunerConfigurationPanel.this,
|
||||
"Airspy Tuner Controller - couldn't "
|
||||
+ "apply the tuner configuration settings - " +
|
||||
e1.getLocalizedMessage() );
|
||||
|
||||
mLog.error( "Airspy Tuner Controller - couldn't apply "
|
||||
+ "config [" + config.getName() + "]", e1 );
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructs a combo box model for the tuner configuration combo component
|
||||
* by assembling a list of the tuner configurations appropriate for this
|
||||
* specific tuner
|
||||
*/
|
||||
private ComboBoxModel<AirspyTunerConfiguration> getModel()
|
||||
{
|
||||
ArrayList<TunerConfiguration> configs =
|
||||
mResourceManager.getSettingsManager()
|
||||
.getTunerConfigurations( TunerType.AIRSPY_R820T );
|
||||
|
||||
DefaultComboBoxModel<AirspyTunerConfiguration> model =
|
||||
new DefaultComboBoxModel<AirspyTunerConfiguration>();
|
||||
|
||||
for( TunerConfiguration config: configs )
|
||||
{
|
||||
model.addElement( (AirspyTunerConfiguration)config );
|
||||
}
|
||||
|
||||
return model;
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieves a specific (named) tuner configuration
|
||||
*/
|
||||
private AirspyTunerConfiguration getNamedConfiguration( String name )
|
||||
{
|
||||
ArrayList<TunerConfiguration> configs =
|
||||
mResourceManager.getSettingsManager()
|
||||
.getTunerConfigurations( TunerType.AIRSPY_R820T );
|
||||
|
||||
for( TunerConfiguration config: configs )
|
||||
{
|
||||
if( config.getName().contentEquals( name ) )
|
||||
{
|
||||
return (AirspyTunerConfiguration)config;
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Saves current tuner configuration settings
|
||||
*/
|
||||
private void save()
|
||||
{
|
||||
mResourceManager.getSettingsManager().save();
|
||||
}
|
||||
}
|
||||
@@ -6,7 +6,6 @@ import java.text.DecimalFormat;
|
||||
import java.util.ArrayList;
|
||||
import java.util.EnumSet;
|
||||
import java.util.List;
|
||||
import java.util.concurrent.CopyOnWriteArrayList;
|
||||
import java.util.concurrent.LinkedTransferQueue;
|
||||
import java.util.concurrent.ScheduledFuture;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
@@ -28,8 +27,8 @@ import sample.Broadcaster;
|
||||
import sample.Listener;
|
||||
import sample.complex.ComplexBuffer;
|
||||
import source.SourceException;
|
||||
import source.tuner.TunerConfiguration;
|
||||
import source.tuner.TunerController;
|
||||
import source.tuner.configuration.TunerConfiguration;
|
||||
import controller.ThreadPoolManager;
|
||||
import controller.ThreadPoolManager.ThreadType;
|
||||
import dsp.filter.dc.DCRemovalFilter_RB;
|
||||
@@ -262,30 +261,31 @@ public class AirspyTunerController extends TunerController
|
||||
}
|
||||
}
|
||||
|
||||
public static String getTransferStatus( int status )
|
||||
{
|
||||
switch( status )
|
||||
{
|
||||
case 0:
|
||||
return "TRANSFER COMPLETED (0)";
|
||||
case 1:
|
||||
return "TRANSFER ERROR (1)";
|
||||
case 2:
|
||||
return "TRANSFER TIMED OUT (2)";
|
||||
case 3:
|
||||
return "TRANSFER CANCELLED (3)";
|
||||
case 4:
|
||||
return "TRANSFER STALL (4)";
|
||||
case 5:
|
||||
return "TRANSFER NO DEVICE (5)";
|
||||
case 6:
|
||||
return "TRANSFER OVERFLOW (6)";
|
||||
default:
|
||||
return "UNKNOWN TRANSFER STATUS (" + status + ")";
|
||||
}
|
||||
}
|
||||
public static String getTransferStatus( int status )
|
||||
{
|
||||
switch( status )
|
||||
{
|
||||
case 0:
|
||||
return "TRANSFER COMPLETED (0)";
|
||||
case 1:
|
||||
return "TRANSFER ERROR (1)";
|
||||
case 2:
|
||||
return "TRANSFER TIMED OUT (2)";
|
||||
case 3:
|
||||
return "TRANSFER CANCELLED (3)";
|
||||
case 4:
|
||||
return "TRANSFER STALL (4)";
|
||||
case 5:
|
||||
return "TRANSFER NO DEVICE (5)";
|
||||
case 6:
|
||||
return "TRANSFER OVERFLOW (6)";
|
||||
default:
|
||||
return "UNKNOWN TRANSFER STATUS (" + status + ")";
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@Override
|
||||
public void apply( TunerConfiguration config ) throws SourceException
|
||||
{
|
||||
if( config instanceof AirspyTunerConfiguration )
|
||||
@@ -426,7 +426,7 @@ public class AirspyTunerController extends TunerController
|
||||
/**
|
||||
* Airspy sample rate object that matches the current sample rate setting.
|
||||
*/
|
||||
public AirspySampleRate getSampleRate()
|
||||
public AirspySampleRate getAirspySampleRate()
|
||||
{
|
||||
return getSampleRate( mSampleRate );
|
||||
}
|
||||
@@ -1215,8 +1215,8 @@ public class AirspyTunerController extends TunerController
|
||||
*/
|
||||
public void addListener( Listener<ComplexBuffer> listener )
|
||||
{
|
||||
synchronized( mComplexBufferBroadcaster )
|
||||
{
|
||||
synchronized ( mComplexBufferBroadcaster )
|
||||
{
|
||||
mComplexBufferBroadcaster.addListener( listener );
|
||||
|
||||
if( mBufferProcessor == null || !mBufferProcessor.isRunning() )
|
||||
@@ -1229,7 +1229,7 @@ public class AirspyTunerController extends TunerController
|
||||
|
||||
thread.start();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -1238,15 +1238,15 @@ public class AirspyTunerController extends TunerController
|
||||
*/
|
||||
public void removeListener( Listener<ComplexBuffer> listener )
|
||||
{
|
||||
synchronized( mComplexBufferBroadcaster )
|
||||
{
|
||||
synchronized ( mComplexBufferBroadcaster )
|
||||
{
|
||||
mComplexBufferBroadcaster.removeListener( listener );
|
||||
|
||||
if( !mComplexBufferBroadcaster.hasListeners() )
|
||||
{
|
||||
mBufferProcessor.stop();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -1273,31 +1273,31 @@ public class AirspyTunerController extends TunerController
|
||||
ThreadType.SOURCE_SAMPLE_PROCESSING, new BufferDispatcher(),
|
||||
20, TimeUnit.MILLISECONDS );
|
||||
|
||||
mLibUsbHandlerStatus = ByteBuffer.allocateDirect( 4 );
|
||||
|
||||
mLibUsbHandlerStatus = ByteBuffer.allocateDirect( 4 );
|
||||
|
||||
List<Transfer> transfers = new ArrayList<>();
|
||||
|
||||
mCancel = false;
|
||||
|
||||
while( mRunning.get() )
|
||||
while( mRunning.get() )
|
||||
{
|
||||
mAvailableTransfers.drainTo( transfers );
|
||||
|
||||
for( Transfer transfer: transfers )
|
||||
{
|
||||
int result = LibUsb.submitTransfer( transfer );
|
||||
|
||||
if( result == LibUsb.SUCCESS )
|
||||
{
|
||||
mTransfersInProgress.add( transfer );
|
||||
}
|
||||
mAvailableTransfers.drainTo( transfers );
|
||||
|
||||
for( Transfer transfer: transfers )
|
||||
{
|
||||
int result = LibUsb.submitTransfer( transfer );
|
||||
|
||||
if( result == LibUsb.SUCCESS )
|
||||
{
|
||||
mTransfersInProgress.add( transfer );
|
||||
}
|
||||
else
|
||||
{
|
||||
mLog.error( "error submitting transfer [" +
|
||||
LibUsb.errorName( result ) + "]" );
|
||||
}
|
||||
}
|
||||
|
||||
mLog.error( "error submitting transfer [" +
|
||||
LibUsb.errorName( result ) + "]" );
|
||||
}
|
||||
}
|
||||
|
||||
int result = LibUsb.handleEventsTimeoutCompleted(
|
||||
null, USB_TIMEOUT_MS, mLibUsbHandlerStatus.asIntBuffer() );
|
||||
|
||||
@@ -1310,20 +1310,20 @@ public class AirspyTunerController extends TunerController
|
||||
|
||||
mLibUsbHandlerStatus.rewind();
|
||||
}
|
||||
|
||||
if( mCancel )
|
||||
{
|
||||
for( Transfer transfer: mTransfersInProgress )
|
||||
{
|
||||
LibUsb.cancelTransfer( transfer );
|
||||
}
|
||||
|
||||
int result = LibUsb.handleEventsTimeoutCompleted( null,
|
||||
USB_TIMEOUT_MS, mLibUsbHandlerStatus.asIntBuffer() );
|
||||
|
||||
if( mCancel )
|
||||
{
|
||||
for( Transfer transfer: mTransfersInProgress )
|
||||
{
|
||||
LibUsb.cancelTransfer( transfer );
|
||||
}
|
||||
|
||||
int result = LibUsb.handleEventsTimeoutCompleted( null,
|
||||
USB_TIMEOUT_MS, mLibUsbHandlerStatus.asIntBuffer() );
|
||||
|
||||
if( result != LibUsb.SUCCESS )
|
||||
{
|
||||
mLog.error( "error handling events for libusb" );
|
||||
mLog.error( "error handling events for libusb during cancel" );
|
||||
}
|
||||
|
||||
mLibUsbHandlerStatus.rewind();
|
||||
|
||||
770
src/source/tuner/airspy/AirspyTunerEditor.java
Normal file
770
src/source/tuner/airspy/AirspyTunerEditor.java
Normal file
@@ -0,0 +1,770 @@
|
||||
/*******************************************************************************
|
||||
* SDR Trunk
|
||||
* Copyright (C) 2015-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.tuner.airspy;
|
||||
|
||||
import java.awt.event.ActionEvent;
|
||||
import java.awt.event.ActionListener;
|
||||
import java.awt.event.FocusEvent;
|
||||
import java.awt.event.FocusListener;
|
||||
import java.text.DecimalFormat;
|
||||
import java.util.List;
|
||||
|
||||
import javax.swing.DefaultComboBoxModel;
|
||||
import javax.swing.JButton;
|
||||
import javax.swing.JCheckBox;
|
||||
import javax.swing.JComboBox;
|
||||
import javax.swing.JLabel;
|
||||
import javax.swing.JOptionPane;
|
||||
import javax.swing.JSeparator;
|
||||
import javax.swing.JSlider;
|
||||
import javax.swing.JSpinner;
|
||||
import javax.swing.JTextField;
|
||||
import javax.swing.SpinnerModel;
|
||||
import javax.swing.SpinnerNumberModel;
|
||||
import javax.swing.SwingConstants;
|
||||
import javax.swing.event.ChangeEvent;
|
||||
import javax.swing.event.ChangeListener;
|
||||
import javax.usb.UsbException;
|
||||
|
||||
import net.miginfocom.swing.MigLayout;
|
||||
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import org.usb4java.LibUsbException;
|
||||
|
||||
import source.SourceException;
|
||||
import source.tuner.airspy.AirspyTunerController.Gain;
|
||||
import source.tuner.airspy.AirspyTunerController.GainMode;
|
||||
import source.tuner.configuration.TunerConfiguration;
|
||||
import source.tuner.configuration.TunerConfigurationEditor;
|
||||
import source.tuner.configuration.TunerConfigurationEvent;
|
||||
import source.tuner.configuration.TunerConfigurationModel;
|
||||
import source.tuner.configuration.TunerConfigurationEvent.Event;
|
||||
|
||||
public class AirspyTunerEditor extends TunerConfigurationEditor
|
||||
{
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
private final static Logger mLog =
|
||||
LoggerFactory.getLogger( AirspyTunerEditor.class );
|
||||
|
||||
private JTextField mConfigurationName;
|
||||
private JButton mTunerInfo;
|
||||
|
||||
private JComboBox<AirspySampleRate> mSampleRateCombo;
|
||||
private JSpinner mFrequencyCorrection;
|
||||
|
||||
private JComboBox<GainMode> mGainModeCombo;
|
||||
|
||||
private JSlider mMasterGain;
|
||||
private JLabel mMasterGainValueLabel;
|
||||
|
||||
private JSlider mIFGain;
|
||||
private JLabel mIFGainValueLabel;
|
||||
|
||||
private JSlider mLNAGain;
|
||||
private JLabel mLNAGainValueLabel;
|
||||
|
||||
private JSlider mMixerGain;
|
||||
private JLabel mMixerGainValueLabel;
|
||||
|
||||
private JCheckBox mLNAAGC;
|
||||
private JCheckBox mMixerAGC;
|
||||
|
||||
private AirspyTunerController mController;
|
||||
private boolean mLoading;
|
||||
|
||||
public AirspyTunerEditor( TunerConfigurationModel tunerConfigurationModel,
|
||||
AirspyTuner tuner )
|
||||
{
|
||||
super( tunerConfigurationModel );
|
||||
mController = tuner.getController();
|
||||
|
||||
init();
|
||||
}
|
||||
|
||||
private AirspyTunerConfiguration getConfiguration()
|
||||
{
|
||||
if( hasItem() )
|
||||
{
|
||||
return (AirspyTunerConfiguration)getItem();
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
private void init()
|
||||
{
|
||||
setLayout( new MigLayout( "fill,wrap 4", "[right][grow,fill][right][grow,fill]",
|
||||
"[][][][][][grow]" ) );
|
||||
|
||||
add( new JLabel( "Airspy Tuner Configuration" ), "span,align center" );
|
||||
|
||||
mConfigurationName = new JTextField();
|
||||
mConfigurationName.setEnabled( false );
|
||||
mConfigurationName.addFocusListener( new FocusListener()
|
||||
{
|
||||
@Override
|
||||
public void focusLost( FocusEvent e )
|
||||
{
|
||||
save();
|
||||
}
|
||||
@Override
|
||||
public void focusGained( FocusEvent e ) {}
|
||||
} );
|
||||
|
||||
add( new JLabel( "Name:" ) );
|
||||
add( mConfigurationName, "span 2" );
|
||||
|
||||
mTunerInfo = new JButton( "Tuner Info" );
|
||||
mTunerInfo.setEnabled( false );
|
||||
mTunerInfo.addActionListener( new ActionListener()
|
||||
{
|
||||
@Override
|
||||
public void actionPerformed( ActionEvent e )
|
||||
{
|
||||
JOptionPane.showMessageDialog( AirspyTunerEditor.this, getTunerInfo(),
|
||||
"Tuner Info", JOptionPane.INFORMATION_MESSAGE );
|
||||
}
|
||||
} );
|
||||
add( mTunerInfo );
|
||||
|
||||
/**
|
||||
* Sample Rate
|
||||
*/
|
||||
add( new JLabel( "Sample Rate:" ) );
|
||||
|
||||
List<AirspySampleRate> rates = mController.getSampleRates();
|
||||
|
||||
mSampleRateCombo = new JComboBox<AirspySampleRate>(
|
||||
new DefaultComboBoxModel<AirspySampleRate>( rates.toArray(
|
||||
new AirspySampleRate[ rates.size() ] ) ) );
|
||||
mSampleRateCombo.setEnabled( false );
|
||||
mSampleRateCombo.addActionListener( new ActionListener()
|
||||
{
|
||||
@Override
|
||||
public void actionPerformed( ActionEvent e )
|
||||
{
|
||||
AirspySampleRate rate = (AirspySampleRate)mSampleRateCombo.getSelectedItem();
|
||||
|
||||
try
|
||||
{
|
||||
mController.setSampleRate( rate );
|
||||
save();
|
||||
}
|
||||
catch ( LibUsbException | UsbException e1 )
|
||||
{
|
||||
JOptionPane.showMessageDialog( AirspyTunerEditor.this,
|
||||
"Couldn't set sample rate to " + rate.getLabel() );
|
||||
|
||||
mLog.error( "Error setting airspy sample rate", e1 );
|
||||
}
|
||||
}
|
||||
} );
|
||||
|
||||
add( mSampleRateCombo );
|
||||
|
||||
/**
|
||||
* Frequency Correction
|
||||
*/
|
||||
SpinnerModel model =
|
||||
new SpinnerNumberModel( 0.0, //initial value
|
||||
-1000.0, //min
|
||||
1000.0, //max
|
||||
0.1 ); //step
|
||||
|
||||
mFrequencyCorrection = new JSpinner( model );
|
||||
mFrequencyCorrection.setEnabled( false );
|
||||
|
||||
JSpinner.NumberEditor editor =
|
||||
(JSpinner.NumberEditor)mFrequencyCorrection.getEditor();
|
||||
|
||||
DecimalFormat format = editor.getFormat();
|
||||
format.setMinimumFractionDigits( 1 );
|
||||
editor.getTextField().setHorizontalAlignment( SwingConstants.CENTER );
|
||||
|
||||
mFrequencyCorrection.addChangeListener( new ChangeListener()
|
||||
{
|
||||
@Override
|
||||
public void stateChanged( ChangeEvent e )
|
||||
{
|
||||
final double value = ((SpinnerNumberModel)mFrequencyCorrection
|
||||
.getModel()).getNumber().doubleValue();
|
||||
|
||||
try
|
||||
{
|
||||
mController.setFrequencyCorrection( value );
|
||||
}
|
||||
catch ( SourceException e1 )
|
||||
{
|
||||
mLog.error( "Error setting frequency correction value", e1 );
|
||||
}
|
||||
|
||||
save();
|
||||
}
|
||||
} );
|
||||
|
||||
add( new JLabel( "PPM:" ) );
|
||||
add( mFrequencyCorrection );
|
||||
|
||||
add( new JSeparator(), "span,growx,push" );
|
||||
|
||||
/**
|
||||
* Gain Mode
|
||||
*/
|
||||
add( new JLabel( "Gain Mode:" ) );
|
||||
mGainModeCombo = new JComboBox<AirspyTunerController.GainMode>( GainMode.values() );
|
||||
mGainModeCombo.setEnabled( false );
|
||||
mGainModeCombo.addActionListener( new ActionListener()
|
||||
{
|
||||
@Override
|
||||
public void actionPerformed( ActionEvent e )
|
||||
{
|
||||
GainMode mode = (GainMode)mGainModeCombo.getSelectedItem();
|
||||
|
||||
updateGainComponents( mode );
|
||||
|
||||
if( hasItem() )
|
||||
{
|
||||
AirspyTunerConfiguration airspy = getConfiguration();
|
||||
|
||||
Gain gain = airspy.getGain();
|
||||
|
||||
if( mode == GainMode.CUSTOM )
|
||||
{
|
||||
mIFGain.setValue( airspy.getIFGain() );
|
||||
mMixerGain.setValue( airspy.getMixerGain() );
|
||||
mMixerAGC.setSelected( airspy.isMixerAGC() );
|
||||
mLNAGain.setValue( airspy.getLNAGain() );
|
||||
mLNAAGC.setSelected( airspy.isLNAAGC() );
|
||||
}
|
||||
else
|
||||
{
|
||||
mMixerAGC.setSelected( false );
|
||||
mLNAAGC.setSelected( false );
|
||||
mMasterGain.setValue( gain.getValue() );
|
||||
mIFGain.setValue( gain.getIF() );
|
||||
mMixerGain.setValue( gain.getMixer() );
|
||||
mLNAGain.setValue( gain.getLNA() );
|
||||
}
|
||||
}
|
||||
|
||||
save();
|
||||
}
|
||||
} );
|
||||
|
||||
add( mGainModeCombo, "wrap" );
|
||||
|
||||
/**
|
||||
* Gain
|
||||
*/
|
||||
add( new JLabel( "Master:" ) );
|
||||
|
||||
mMasterGain = new JSlider( JSlider.HORIZONTAL,
|
||||
AirspyTunerController.GAIN_MIN,
|
||||
AirspyTunerController.GAIN_MAX,
|
||||
AirspyTunerController.GAIN_MIN );
|
||||
mMasterGain.setMajorTickSpacing( 1 );
|
||||
mMasterGain.setPaintTicks( true );
|
||||
|
||||
mMasterGain.addChangeListener( new ChangeListener()
|
||||
{
|
||||
@Override
|
||||
public void stateChanged( ChangeEvent event )
|
||||
{
|
||||
GainMode mode = (GainMode)mGainModeCombo.getSelectedItem();
|
||||
int value = mMasterGain.getValue();
|
||||
Gain gain = Gain.getGain( mode, value );
|
||||
|
||||
try
|
||||
{
|
||||
mController.setGain( gain );
|
||||
save();
|
||||
mMasterGainValueLabel.setText( String.valueOf( gain.getValue() ) );
|
||||
}
|
||||
catch ( Exception e )
|
||||
{
|
||||
mLog.error( "Couldn't set airspy gain to:" + gain.name(), e );
|
||||
JOptionPane.showMessageDialog( mMasterGain, "Couldn't set gain value to " +
|
||||
gain.getValue() );
|
||||
}
|
||||
}
|
||||
} );
|
||||
|
||||
add( mMasterGain, "span 2" );
|
||||
|
||||
mMasterGainValueLabel = new JLabel( "0" );
|
||||
add( mMasterGainValueLabel );
|
||||
|
||||
add( new JLabel( "IF:" ) );
|
||||
|
||||
mIFGain = new JSlider( JSlider.HORIZONTAL,
|
||||
AirspyTunerController.IF_GAIN_MIN,
|
||||
AirspyTunerController.IF_GAIN_MAX,
|
||||
AirspyTunerController.IF_GAIN_MIN );
|
||||
|
||||
mIFGain.setMajorTickSpacing( 1 );
|
||||
mIFGain.setPaintTicks( true );
|
||||
|
||||
mIFGain.addChangeListener( new ChangeListener()
|
||||
{
|
||||
@Override
|
||||
public void stateChanged( ChangeEvent event )
|
||||
{
|
||||
int gain = mIFGain.getValue();
|
||||
|
||||
try
|
||||
{
|
||||
mController.setIFGain( gain );
|
||||
save();
|
||||
mIFGainValueLabel.setText( String.valueOf( gain ) );
|
||||
}
|
||||
catch ( Exception e )
|
||||
{
|
||||
mLog.error( "Couldn't set airspy IF gain to:" + gain, e );
|
||||
|
||||
JOptionPane.showMessageDialog( mIFGain, "Couldn't set IF gain value to " + gain );
|
||||
}
|
||||
}
|
||||
} );
|
||||
|
||||
add( mIFGain, "span 2" );
|
||||
|
||||
mIFGainValueLabel = new JLabel( "0" );
|
||||
add( mIFGainValueLabel );
|
||||
|
||||
/**
|
||||
* Mixer Gain
|
||||
*/
|
||||
add( new JLabel( "Mixer:" ) );
|
||||
|
||||
mMixerGain = new JSlider( JSlider.HORIZONTAL,
|
||||
AirspyTunerController.MIXER_GAIN_MIN,
|
||||
AirspyTunerController.MIXER_GAIN_MAX,
|
||||
AirspyTunerController.MIXER_GAIN_MIN );
|
||||
|
||||
mMixerGain.setMajorTickSpacing( 1 );
|
||||
mMixerGain.setPaintTicks( true );
|
||||
|
||||
mMixerGain.addChangeListener( new ChangeListener()
|
||||
{
|
||||
@Override
|
||||
public void stateChanged( ChangeEvent event )
|
||||
{
|
||||
int gain = mMixerGain.getValue();
|
||||
|
||||
try
|
||||
{
|
||||
mController.setMixerGain( gain );
|
||||
save();
|
||||
mMixerGainValueLabel.setText( String.valueOf( gain ) );
|
||||
}
|
||||
catch ( Exception e )
|
||||
{
|
||||
mLog.error( "Couldn't set airspy Mixer gain to:" + gain, e );
|
||||
JOptionPane.showMessageDialog( mIFGain, "Couldn't set Mixer gain value to " + gain );
|
||||
}
|
||||
}
|
||||
} );
|
||||
|
||||
add( mMixerGain, "span 2" );
|
||||
|
||||
mMixerGainValueLabel = new JLabel( "0" );
|
||||
add( mMixerGainValueLabel );
|
||||
|
||||
add( new JLabel( "LNA:" ) );
|
||||
|
||||
mLNAGain = new JSlider( JSlider.HORIZONTAL,
|
||||
AirspyTunerController.LNA_GAIN_MIN,
|
||||
AirspyTunerController.LNA_GAIN_MAX,
|
||||
AirspyTunerController.LNA_GAIN_MIN );
|
||||
|
||||
mLNAGain.setMajorTickSpacing( 1 );
|
||||
mLNAGain.setPaintTicks( true );
|
||||
|
||||
mLNAGain.addChangeListener( new ChangeListener()
|
||||
{
|
||||
@Override
|
||||
public void stateChanged( ChangeEvent event )
|
||||
{
|
||||
int gain = mLNAGain.getValue();
|
||||
|
||||
try
|
||||
{
|
||||
mController.setLNAGain( gain );
|
||||
save();
|
||||
mLNAGainValueLabel.setText( String.valueOf( gain ) );
|
||||
}
|
||||
catch ( Exception e )
|
||||
{
|
||||
mLog.error( "Couldn't set airspy LNA gain to:" + gain, e );
|
||||
JOptionPane.showMessageDialog( mIFGain, "Couldn't set LNA gain value to " + gain );
|
||||
}
|
||||
}
|
||||
} );
|
||||
|
||||
add( mLNAGain, "span 2" );
|
||||
|
||||
mLNAGainValueLabel = new JLabel( "0" );
|
||||
add( mLNAGainValueLabel );
|
||||
|
||||
mMixerAGC = new JCheckBox( "Mixer AGC" );
|
||||
mMixerAGC.addActionListener( new ActionListener()
|
||||
{
|
||||
@Override
|
||||
public void actionPerformed( ActionEvent e )
|
||||
{
|
||||
try
|
||||
{
|
||||
mController.setMixerAGC( mMixerAGC.isSelected() );
|
||||
mMixerGain.setEnabled( !mMixerAGC.isSelected() );
|
||||
|
||||
save();
|
||||
}
|
||||
catch ( Exception e1 )
|
||||
{
|
||||
mLog.error( "Error setting Mixer AGC Enabled" );
|
||||
}
|
||||
}
|
||||
} );
|
||||
|
||||
add( mMixerAGC, "span 2,center" );
|
||||
|
||||
mLNAAGC = new JCheckBox( "LNA AGC" );
|
||||
mLNAAGC.addActionListener( new ActionListener()
|
||||
{
|
||||
@Override
|
||||
public void actionPerformed( ActionEvent e )
|
||||
{
|
||||
try
|
||||
{
|
||||
mController.setLNAAGC( mLNAAGC.isSelected() );
|
||||
mLNAGain.setEnabled( !mLNAAGC.isSelected() );
|
||||
|
||||
save();
|
||||
}
|
||||
catch ( Exception e1 )
|
||||
{
|
||||
mLog.error( "Error setting LNA AGC Enabled" );
|
||||
}
|
||||
|
||||
}
|
||||
} );
|
||||
|
||||
add( mLNAAGC, "span 2,center" );
|
||||
}
|
||||
|
||||
/**
|
||||
* Updates the enabled state of each of the gain controls according to the
|
||||
* specified gain mode. The master gain control is enabled for linearity
|
||||
* and sensitivity and the individual gain controls are disabled, and
|
||||
* vice-versa for custom mode.
|
||||
*/
|
||||
private void updateGainComponents( GainMode mode )
|
||||
{
|
||||
switch( mode )
|
||||
{
|
||||
case LINEARITY:
|
||||
if( !mMasterGain.isEnabled() )
|
||||
{
|
||||
mMasterGain.setEnabled( true );
|
||||
mMasterGainValueLabel.setEnabled( true );
|
||||
}
|
||||
if( mIFGain.isEnabled() )
|
||||
{
|
||||
mIFGain.setEnabled( false );
|
||||
mIFGainValueLabel.setEnabled( false );
|
||||
}
|
||||
if( mLNAGain.isEnabled() )
|
||||
{
|
||||
mLNAAGC.setEnabled( false );
|
||||
mLNAGainValueLabel.setEnabled( false );
|
||||
mLNAGain.setEnabled( false );
|
||||
}
|
||||
if( mMixerGain.isEnabled() )
|
||||
{
|
||||
mMixerGainValueLabel.setEnabled( false );
|
||||
mMixerAGC.setEnabled( false );
|
||||
mMixerGain.setEnabled( false );
|
||||
}
|
||||
break;
|
||||
case SENSITIVITY:
|
||||
if( !mMasterGain.isEnabled() )
|
||||
{
|
||||
mMasterGain.setEnabled( true );
|
||||
mMasterGainValueLabel.setEnabled( true );
|
||||
}
|
||||
if( mIFGain.isEnabled() )
|
||||
{
|
||||
mIFGain.setEnabled( false );
|
||||
mIFGainValueLabel.setEnabled( false );
|
||||
}
|
||||
if( mLNAGain.isEnabled() )
|
||||
{
|
||||
mLNAAGC.setEnabled( false );
|
||||
mLNAGainValueLabel.setEnabled( false );
|
||||
mLNAGain.setEnabled( false );
|
||||
}
|
||||
if( mMixerGain.isEnabled() )
|
||||
{
|
||||
mMixerGainValueLabel.setEnabled( false );
|
||||
mMixerAGC.setEnabled( false );
|
||||
mMixerGain.setEnabled( false );
|
||||
}
|
||||
break;
|
||||
case CUSTOM:
|
||||
if( mMasterGain.isEnabled() )
|
||||
{
|
||||
mMasterGain.setEnabled( false );
|
||||
mMasterGainValueLabel.setEnabled( false );
|
||||
}
|
||||
if( !mIFGain.isEnabled() )
|
||||
{
|
||||
mIFGain.setEnabled( true );
|
||||
mIFGainValueLabel.setEnabled( true );
|
||||
}
|
||||
if( !mLNAGain.isEnabled() )
|
||||
{
|
||||
mLNAAGC.setEnabled( true );
|
||||
mLNAGainValueLabel.setEnabled( true );
|
||||
mLNAGain.setEnabled( true );
|
||||
}
|
||||
if( !mMixerGain.isEnabled() )
|
||||
{
|
||||
mMixerGainValueLabel.setEnabled( true );
|
||||
mMixerAGC.setEnabled( true );
|
||||
mMixerGain.setEnabled( true );
|
||||
}
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void save()
|
||||
{
|
||||
if( hasItem() && !mLoading )
|
||||
{
|
||||
AirspyTunerConfiguration config = getConfiguration();
|
||||
config.setName( mConfigurationName.getText() );
|
||||
config.setSampleRate( ((AirspySampleRate)mSampleRateCombo.getSelectedItem()).getRate() );
|
||||
|
||||
double value = ((SpinnerNumberModel)mFrequencyCorrection.getModel()).getNumber().doubleValue();
|
||||
config.setFrequencyCorrection( value );
|
||||
|
||||
Gain gain = Gain.getGain( (GainMode)mGainModeCombo.getSelectedItem(), mMasterGain.getValue() );
|
||||
|
||||
config.setGain( gain );
|
||||
config.setIFGain( mIFGain.getValue() );
|
||||
config.setMixerGain( mMixerGain.getValue() );
|
||||
config.setLNAGain( mLNAGain.getValue() );
|
||||
config.setMixerAGC( mMixerAGC.isSelected() );
|
||||
config.setLNAAGC( mLNAAGC.isSelected() );
|
||||
|
||||
getTunerConfigurationModel().broadcast( new TunerConfigurationEvent( config, Event.CHANGE ) );
|
||||
}
|
||||
}
|
||||
|
||||
private AirspySampleRate fromValue( int value )
|
||||
{
|
||||
List<AirspySampleRate> rates = mController.getSampleRates();
|
||||
|
||||
for( AirspySampleRate rate: rates )
|
||||
{
|
||||
if( rate.getRate() == value )
|
||||
{
|
||||
return rate;
|
||||
}
|
||||
}
|
||||
|
||||
if( rates.size() > 0 )
|
||||
{
|
||||
return rates.get( 0 );
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets all controls to the argument enabled state
|
||||
*/
|
||||
private void setControlsEnabled( boolean enabled )
|
||||
{
|
||||
if( mConfigurationName.isEnabled() != enabled )
|
||||
{
|
||||
mConfigurationName.setEnabled( enabled );
|
||||
}
|
||||
|
||||
if( mTunerInfo.isEnabled() != enabled )
|
||||
{
|
||||
mTunerInfo.setEnabled( enabled );
|
||||
}
|
||||
|
||||
if( mSampleRateCombo.isEnabled() != enabled )
|
||||
{
|
||||
mSampleRateCombo.setEnabled( enabled );
|
||||
}
|
||||
|
||||
if( mFrequencyCorrection.isEnabled() != enabled )
|
||||
{
|
||||
mFrequencyCorrection.setEnabled( enabled );
|
||||
}
|
||||
|
||||
if( mGainModeCombo.isEnabled() != enabled )
|
||||
{
|
||||
mGainModeCombo.setEnabled( enabled );
|
||||
}
|
||||
|
||||
if( mMasterGain.isEnabled() != enabled )
|
||||
{
|
||||
mMasterGain.setEnabled( enabled );
|
||||
}
|
||||
|
||||
if( mIFGain.isEnabled() != enabled )
|
||||
{
|
||||
mIFGain.setEnabled( enabled );
|
||||
}
|
||||
|
||||
if( mMixerGain.isEnabled() != enabled )
|
||||
{
|
||||
mMixerGain.setEnabled( enabled );
|
||||
}
|
||||
|
||||
if( mMixerAGC.isEnabled() != enabled )
|
||||
{
|
||||
mMixerAGC.setEnabled( enabled );
|
||||
}
|
||||
|
||||
if( mLNAGain.isEnabled() != enabled )
|
||||
{
|
||||
mLNAGain.setEnabled( enabled );
|
||||
}
|
||||
|
||||
if( mLNAAGC.isEnabled() != enabled )
|
||||
{
|
||||
mLNAAGC.setEnabled( enabled );
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Applies the tuner configuration to the editor. If the configuration is assigned to the
|
||||
* currently selected tuner, then the settings are applied.
|
||||
*/
|
||||
@Override
|
||||
public void setItem( TunerConfiguration config )
|
||||
{
|
||||
super.setItem( config );
|
||||
|
||||
mLoading = true;
|
||||
|
||||
if( hasItem() && getItem().isAssigned() )
|
||||
{
|
||||
AirspyTunerConfiguration airspy = getConfiguration();
|
||||
|
||||
setControlsEnabled( true );
|
||||
|
||||
mConfigurationName.setText( airspy.getName() );
|
||||
|
||||
AirspySampleRate rate = fromValue( airspy.getSampleRate() );
|
||||
|
||||
if( rate != null )
|
||||
{
|
||||
mSampleRateCombo.setSelectedItem( rate );
|
||||
}
|
||||
|
||||
mFrequencyCorrection.setValue( airspy.getFrequencyCorrection() );
|
||||
|
||||
GainMode mode = Gain.getGainMode( airspy.getGain() );
|
||||
|
||||
//This will set the master, IF, Mixer, LNA and AGC controls
|
||||
mGainModeCombo.setSelectedItem( mode );
|
||||
|
||||
if( mode == GainMode.CUSTOM )
|
||||
{
|
||||
mMasterGain.setValue( airspy.getGain().getValue() );
|
||||
mIFGain.setValue( airspy.getIFGain() );
|
||||
|
||||
if( airspy.isMixerAGC() )
|
||||
{
|
||||
mMixerAGC.setSelected( airspy.isMixerAGC() );
|
||||
mMixerGain.setEnabled( false );
|
||||
}
|
||||
else
|
||||
{
|
||||
mMixerGain.setValue( airspy.getMixerGain() );
|
||||
}
|
||||
|
||||
if( airspy.isLNAAGC() )
|
||||
{
|
||||
mLNAAGC.setSelected( airspy.isLNAAGC() );
|
||||
mLNAGain.setEnabled( false );
|
||||
}
|
||||
else
|
||||
{
|
||||
mLNAGain.setValue( airspy.getLNAGain() );
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
mMixerAGC.setSelected( false );
|
||||
mLNAAGC.setSelected( false );
|
||||
|
||||
Gain gain = airspy.getGain();
|
||||
|
||||
mMasterGain.setValue( gain.getValue() );
|
||||
mIFGain.setValue( gain.getIF() );
|
||||
mMixerGain.setValue( gain.getMixer() );
|
||||
mLNAGain.setValue( gain.getLNA() );
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
setControlsEnabled( false );
|
||||
mConfigurationName.setText( hasItem() ? getItem().getName() : "" );
|
||||
}
|
||||
|
||||
mLoading = false;
|
||||
}
|
||||
|
||||
private String getTunerInfo()
|
||||
{
|
||||
StringBuilder sb = new StringBuilder();
|
||||
|
||||
AirspyDeviceInformation info = mController.getDeviceInfo();
|
||||
|
||||
sb.append( "<html><h3>Airspy Tuner</h3>" );
|
||||
sb.append( "<b>Serial: </b>" );
|
||||
sb.append( info.getSerialNumber() );
|
||||
sb.append( "<br>" );
|
||||
|
||||
sb.append( "<b>Firmware: </b>" );
|
||||
String[] firmware = info.getVersion().split( " " );
|
||||
sb.append( firmware.length > 1 ? firmware[ 0 ] : info.getVersion() );
|
||||
sb.append( "<br>" );
|
||||
|
||||
sb.append( "<b>Part: </b>" );
|
||||
sb.append( info.getPartNumber() );
|
||||
sb.append( "<br>" );
|
||||
|
||||
sb.append( "<b>Board ID: </b>" );
|
||||
sb.append( info.getBoardID().getLabel() );
|
||||
sb.append( "<br>" );
|
||||
|
||||
return sb.toString();
|
||||
}
|
||||
}
|
||||
@@ -1,113 +0,0 @@
|
||||
/*******************************************************************************
|
||||
* SDR Trunk
|
||||
* Copyright (C) 2015 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.tuner.airspy;
|
||||
|
||||
import gui.control.JFrequencyControl;
|
||||
|
||||
import java.awt.Color;
|
||||
|
||||
import javax.swing.JLabel;
|
||||
import javax.swing.JPanel;
|
||||
|
||||
import net.miginfocom.swing.MigLayout;
|
||||
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import source.SourceException;
|
||||
import source.tuner.frequency.FrequencyChangeEvent;
|
||||
import source.tuner.frequency.FrequencyChangeEvent.Event;
|
||||
import source.tuner.frequency.FrequencyChangeListener;
|
||||
|
||||
import com.jidesoft.swing.JideTabbedPane;
|
||||
|
||||
import controller.ResourceManager;
|
||||
|
||||
public class AirspyTunerEditorPanel extends JPanel
|
||||
implements FrequencyChangeListener
|
||||
{
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
private final static Logger mLog =
|
||||
LoggerFactory.getLogger( AirspyTunerEditorPanel.class );
|
||||
|
||||
private JFrequencyControl mFrequencyControl;
|
||||
|
||||
private AirspyTuner mTuner;
|
||||
private AirspyTunerController mController;
|
||||
private ResourceManager mResourceManager;
|
||||
|
||||
public AirspyTunerEditorPanel( AirspyTuner tuner,
|
||||
ResourceManager resourceManager )
|
||||
{
|
||||
mTuner = tuner;
|
||||
mController = mTuner.getController();
|
||||
mResourceManager = resourceManager;
|
||||
|
||||
initGUI();
|
||||
}
|
||||
|
||||
private void initGUI()
|
||||
{
|
||||
setLayout( new MigLayout( "fill,wrap 2",
|
||||
"[right,grow][grow]",
|
||||
"[][][][][][grow]" ) );
|
||||
|
||||
add( new JLabel( "Airspy Tuner" ), "span,align center" );
|
||||
|
||||
mFrequencyControl = new JFrequencyControl();
|
||||
|
||||
mFrequencyControl.addListener( this );
|
||||
|
||||
/* Add frequency control as frequency change listener. This creates a
|
||||
* feedback loop, so the control does not rebroadcast the event */
|
||||
mTuner.addListener( mFrequencyControl );
|
||||
|
||||
mFrequencyControl.setFrequency( mController.getFrequency(), false );
|
||||
|
||||
add( mFrequencyControl, "span,align center" );
|
||||
|
||||
JideTabbedPane tabs = new JideTabbedPane();
|
||||
tabs.setFont( this.getFont() );
|
||||
tabs.setForeground( Color.BLACK );
|
||||
|
||||
add( tabs, "span,grow,push" );
|
||||
|
||||
tabs.add( "Config", new AirspyTunerConfigurationPanel(
|
||||
mResourceManager, mTuner.getController() ) );
|
||||
|
||||
tabs.add( "Info", new AirspyInformationPanel( mTuner.getController() ) );
|
||||
}
|
||||
|
||||
@Override
|
||||
public void frequencyChanged( FrequencyChangeEvent event )
|
||||
{
|
||||
if( event.getEvent() == Event.FREQUENCY_CHANGE_NOTIFICATION )
|
||||
{
|
||||
try
|
||||
{
|
||||
mController.setFrequency( event.getValue().longValue() );
|
||||
}
|
||||
catch ( SourceException e )
|
||||
{
|
||||
mLog.error( "error setting frequency [" +
|
||||
event.getValue().longValue() + "]", e );
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user