diff --git a/config/53-hackrf.rules b/config/53-hackrf.rules
new file mode 100644
index 00000000..fcfa6d17
--- /dev/null
+++ b/config/53-hackrf.rules
@@ -0,0 +1,3 @@
+ATTR{idVendor}=="1d50", ATTR{idProduct}=="604b", SYMLINK+="hackrf-jawbreaker-%k", MODE="660", GROUP="plugdev"
+ATTR{idVendor}=="1d50", ATTR{idProduct}=="6089", SYMLINK+="hackrf-one-%k", MODE="660", GROUP="plugdev"
+ATTR{idVendor}=="1fc9", ATTR{idProduct}=="000c", SYMLINK+="nxp-dfu-%k", MODE="660", GROUP="plugdev"
\ No newline at end of file
diff --git a/imports/commons-io-2.4.jar b/imports/commons-io-2.4.jar
new file mode 100644
index 00000000..90035a4f
Binary files /dev/null and b/imports/commons-io-2.4.jar differ
diff --git a/src/settings/IntegerSetting.java b/src/settings/IntegerSetting.java
deleted file mode 100644
index f38541c5..00000000
--- a/src/settings/IntegerSetting.java
+++ /dev/null
@@ -1,30 +0,0 @@
-package settings;
-
-import javax.xml.bind.annotation.XmlAttribute;
-
-public class IntegerSetting extends Setting
-{
- private int mValue;
-
- public IntegerSetting()
- {
- }
-
- public IntegerSetting( String name, int value )
- {
- super( name );
-
- mValue = value;
- }
-
- @XmlAttribute
- public int getValue()
- {
- return mValue;
- }
-
- public void setValue( int value )
- {
- mValue = value;
- }
-}
diff --git a/src/settings/Settings.java b/src/settings/Settings.java
index d70cb8c2..fc9e1783 100644
--- a/src/settings/Settings.java
+++ b/src/settings/Settings.java
@@ -33,6 +33,7 @@ import source.tuner.TunerConfigurationAssignment;
import source.tuner.TunerType;
import source.tuner.fcd.proV1.FCD1TunerConfiguration;
import source.tuner.fcd.proplusV2.FCD2TunerConfiguration;
+import source.tuner.hackrf.HackRFTunerConfiguration;
import source.tuner.rtl.e4k.E4KTunerConfiguration;
import source.tuner.rtl.r820t.R820TTunerConfiguration;
@@ -45,7 +46,7 @@ import source.tuner.rtl.r820t.R820TTunerConfiguration;
FCD1TunerConfiguration.class,
FCD2TunerConfiguration.class,
FileSetting.class,
- IntegerSetting.class,
+ HackRFTunerConfiguration.class,
MapViewSetting.class,
MapIcon.class,
R820TTunerConfiguration.class,
@@ -179,20 +180,6 @@ public class Settings
return null;
}
- public IntegerSetting getIntegerSetting( String name )
- {
- for( Setting setting: mSettings )
- {
- if( setting instanceof IntegerSetting &&
- ((IntegerSetting)setting).getName().contentEquals( name ) )
- {
- return (IntegerSetting)setting;
- }
- }
-
- return null;
- }
-
public ColorSetting getColorSetting( ColorSettingName name )
{
for( Setting setting: mSettings )
diff --git a/src/settings/SettingsManager.java b/src/settings/SettingsManager.java
index 5dbe849d..475f98df 100644
--- a/src/settings/SettingsManager.java
+++ b/src/settings/SettingsManager.java
@@ -52,6 +52,7 @@ import source.tuner.TunerConfigurationAssignment;
import source.tuner.TunerType;
import source.tuner.fcd.proV1.FCD1TunerConfiguration;
import source.tuner.fcd.proplusV2.FCD2TunerConfiguration;
+import source.tuner.hackrf.HackRFTunerConfiguration;
import source.tuner.rtl.e4k.E4KTunerConfiguration;
import source.tuner.rtl.r820t.R820TTunerConfiguration;
@@ -147,33 +148,6 @@ public class SettingsManager
return mSettings.getSetting( name );
}
- public IntegerSetting getIntegerSetting( String name, int defaultValue )
- {
- IntegerSetting setting = mSettings.getIntegerSetting( name );
-
- if( setting == null )
- {
- setting = new IntegerSetting( name, defaultValue );
-
- mSettings.addSetting( setting );
-
- save();
- }
-
- return setting;
- }
-
- public void setIntegerSetting( String name, int value )
- {
- IntegerSetting setting = getIntegerSetting( name, value );
-
- setting.setValue( value );
-
- save();
-
- broadcastSettingChange( setting );
- }
-
/**
* Returns the current setting, or if the setting doesn't exist
* returns a newly created setting with the specified parameters
@@ -616,6 +590,15 @@ public class SettingsManager
save();
return configPlus;
+ case HACKRF:
+ HackRFTunerConfiguration hackConfig =
+ new HackRFTunerConfiguration( name );
+
+ getSettings().addTunerConfiguration( hackConfig );
+
+ save();
+
+ return hackConfig;
case RAFAELMICRO_R820T:
R820TTunerConfiguration r820TConfig =
new R820TTunerConfiguration( name );
diff --git a/src/source/tuner/Tuner.java b/src/source/tuner/Tuner.java
index 71d3afcb..46392840 100644
--- a/src/source/tuner/Tuner.java
+++ b/src/source/tuner/Tuner.java
@@ -48,6 +48,11 @@ public abstract class Tuner implements FrequencyChangeBroadcaster,
mName = name;
}
+ public void setName( String name )
+ {
+ mName = name;
+ }
+
/**
* Return an editor panel for the tuner
*/
diff --git a/src/source/tuner/TunerClass.java b/src/source/tuner/TunerClass.java
index dae3665b..d7339820 100644
--- a/src/source/tuner/TunerClass.java
+++ b/src/source/tuner/TunerClass.java
@@ -34,6 +34,7 @@ public enum TunerClass
FUNCUBE_DONGLE_PRO_PLUS( TunerType.FUNCUBE_DONGLE_PRO_PLUS, "04D8", "FB31", "Hamlincrest", "Funcube Dongle Pro Plus" ),
GIGABYTE_GTU7300( TunerType.FITIPOWER_FC0012, "1B80", "D393", "Gigabyte", "GT-U7300" ),
GTEK_T803( TunerType.FITIPOWER_FC0012, "1F4D", "B803", "GTek", "T803" ),
+ HACKRF_ONE( TunerType.HACKRF, "1D50", "6089", "Great Scott Gadgets", "HackRF One" ),
LIFEVIEW_LV5T_DELUXE( TunerType.FITIPOWER_FC0012, "1F4D", "C803", "Liveview", "LV5T Deluxe" ),
MYGICA_TD312( TunerType.FITIPOWER_FC0012, "1F4D", "D286", "MyGica", "TD312" ),
PEAK_102569AGPK( TunerType.FITIPOWER_FC0012, "1B80", "D395", "Peak", "102569AGPK" ),
@@ -174,6 +175,12 @@ public enum TunerClass
retVal = DEXATEK_5217_DVBT;
}
break;
+ case 7504: //1D50
+ if( productID == 24713 ) //6089
+ {
+ retVal = HACKRF_ONE;
+ }
+ break;
case 8013: //1F4D
if( productID == 47107 ) //B803
{
diff --git a/src/source/tuner/TunerManager.java b/src/source/tuner/TunerManager.java
index 0107b681..0693e72b 100644
--- a/src/source/tuner/TunerManager.java
+++ b/src/source/tuner/TunerManager.java
@@ -40,6 +40,8 @@ import source.tuner.ettus.B100Tuner;
import source.tuner.fcd.FCDTuner;
import source.tuner.fcd.proV1.FCD1TunerController;
import source.tuner.fcd.proplusV2.FCD2TunerController;
+import source.tuner.hackrf.HackRFTuner;
+import source.tuner.hackrf.HackRFTunerController;
import source.tuner.rtl.RTL2832Tuner;
import source.tuner.rtl.RTL2832TunerController;
import source.tuner.rtl.e4k.E4KTunerController;
@@ -361,6 +363,29 @@ public class TunerManager
status = sLOADED;
reason = null;
break;
+ case HACKRF_ONE:
+// try
+// {
+// HackRFTunerController hackRFController =
+// new HackRFTunerController( device );
+//
+// hackRFController.init();
+//
+// HackRFTuner hackRFTuner =
+// new HackRFTuner( hackRFController );
+//
+// mTuners.add( hackRFTuner );
+// name = hackRFTuner.getName();
+// status = sLOADED;
+// reason = null;
+// }
+// catch( SourceException se )
+// {
+// status = sNOT_LOADED;
+// reason = "Error constructing HackRF tuner "
+// + "controller - " + se.getLocalizedMessage();
+// }
+ break;
case UNKNOWN:
default:
break;
diff --git a/src/source/tuner/TunerNode.java b/src/source/tuner/TunerNode.java
index cbcf1b89..20f1dfe4 100644
--- a/src/source/tuner/TunerNode.java
+++ b/src/source/tuner/TunerNode.java
@@ -134,6 +134,7 @@ public class TunerNode extends BaseNode implements FrequencyChangeListener
mFrequency = frequency;
getModel().nodeChanged( TunerNode.this );
}
+ break;
case SAMPLE_RATE:
int sampleRate = (int)event.getValue();
diff --git a/src/source/tuner/TunerType.java b/src/source/tuner/TunerType.java
index 0714eb53..0245649a 100644
--- a/src/source/tuner/TunerType.java
+++ b/src/source/tuner/TunerType.java
@@ -27,6 +27,7 @@ public enum TunerType
FITIPOWER_FC0013( "FC0013" ),
FUNCUBE_DONGLE_PRO( "Funcube Dongle Pro" ),
FUNCUBE_DONGLE_PRO_PLUS( "Funcube Dongle Pro Plus" ),
+ HACKRF( "HackRF" ),
RAFAELMICRO_R820T( "R820T" ),
RAFAELMICRO_R828D( "R828D" ),
RTL2832_VARIOUS( "Generic" ),
diff --git a/src/source/tuner/hackrf/HackRFInformationPanel.java b/src/source/tuner/hackrf/HackRFInformationPanel.java
new file mode 100644
index 00000000..4a7ad795
--- /dev/null
+++ b/src/source/tuner/hackrf/HackRFInformationPanel.java
@@ -0,0 +1,86 @@
+package source.tuner.hackrf;
+
+import javax.swing.JLabel;
+import javax.swing.JPanel;
+
+import net.miginfocom.swing.MigLayout;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import source.tuner.hackrf.HackRFTunerController.Serial;
+
+public class HackRFInformationPanel extends JPanel
+{
+ private static final long serialVersionUID = 1L;
+
+ private final static Logger mLog =
+ LoggerFactory.getLogger( HackRFInformationPanel.class );
+
+ private HackRFTunerController mController;
+
+ /**
+ * Displays HackRF firmware, serial number and part identifier
+ */
+ public HackRFInformationPanel( HackRFTunerController controller )
+ {
+ mController = controller;
+
+ initGUI();
+ }
+
+ private void initGUI()
+ {
+ setLayout( new MigLayout( "fill,wrap 2",
+ "[right,grow][grow]",
+ "[][][][grow]" ) );
+
+ Serial serial = null;
+
+ try
+ {
+ serial = mController.getSerial();
+ }
+ catch( Exception e )
+ {
+ mLog.error( "couldn't read HackRF serial number", e );
+ }
+
+ if( serial != null )
+ {
+ add( new JLabel( "Serial:" ) );
+ add( new JLabel( serial.getSerialNumber() ) );
+ add( new JLabel( "Part:" ) );
+ add( new JLabel( serial.getPartID() ) );
+ }
+ else
+ {
+ add( new JLabel( "Serial:" ) );
+ add( new JLabel( "Unknown" ) );
+ add( new JLabel( "Part:" ) );
+ add( new JLabel( "Unknown" ) );
+ }
+
+ String firmware = null;
+
+ try
+ {
+ firmware = mController.getFirmwareVersion();
+ }
+ catch( Exception e )
+ {
+ mLog.error( "couldn't read HackRF firmware version", e );
+ }
+
+ add( new JLabel( "Firmware:" ) );
+
+ if( firmware != null )
+ {
+ add( new JLabel( firmware ) );
+ }
+ else
+ {
+ add( new JLabel( "Unknown" ) );
+ }
+ }
+}
diff --git a/src/source/tuner/hackrf/HackRFTuner.java b/src/source/tuner/hackrf/HackRFTuner.java
new file mode 100644
index 00000000..c7204b54
--- /dev/null
+++ b/src/source/tuner/hackrf/HackRFTuner.java
@@ -0,0 +1,161 @@
+/*******************************************************************************
+ * SDR Trunk
+ * Copyright (C) 2014 Dennis Sheirer
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see
+ ******************************************************************************/
+package source.tuner.hackrf;
+
+import java.util.concurrent.RejectedExecutionException;
+
+import javax.swing.JPanel;
+import javax.usb.UsbException;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import sample.Listener;
+import source.SourceException;
+import source.tuner.Tuner;
+import source.tuner.TunerChannel;
+import source.tuner.TunerChannelSource;
+import source.tuner.TunerClass;
+import source.tuner.TunerConfiguration;
+import source.tuner.TunerType;
+import source.tuner.hackrf.HackRFTunerController.BoardID;
+import source.tuner.hackrf.HackRFTunerController.Serial;
+import controller.ResourceManager;
+import controller.ThreadPoolManager;
+
+public class HackRFTuner extends Tuner
+{
+ private final static Logger mLog = LoggerFactory.getLogger( HackRFTuner.class );
+
+ private HackRFTunerController mController;
+
+ public HackRFTuner( HackRFTunerController controller ) throws SourceException
+ {
+ super( "HackRF" );
+
+ mController = controller;
+
+ /* Register for frequency/sample rate changes */
+ mController.addListener( this );
+
+ try
+ {
+ BoardID id = mController.getBoardID();
+ super.setName( id.getLabel() );
+
+ String version = mController.getFirmwareVersion();
+ mLog.info( "HackRF firmware: " + version );
+
+ Serial serial = mController.getSerial();
+ mLog.info( "HackRF Part ID: " + serial.getPartID() );
+ mLog.info( "HackRF Serial Number: " + serial.getSerialNumber() );
+ }
+ catch( UsbException e )
+ {
+ mLog.error( "couldn't read HackRF board id", e );
+ }
+ }
+
+ public HackRFTunerController getController()
+ {
+ return mController;
+ }
+
+ @Override
+ public TunerClass getTunerClass()
+ {
+ return TunerClass.HACKRF_ONE;
+ }
+
+ @Override
+ public TunerType getTunerType()
+ {
+ return TunerType.HACKRF;
+ }
+
+ @Override
+ public JPanel getEditor( ResourceManager resourceManager )
+ {
+ return new HackRFTunerEditorPanel( this, resourceManager );
+ }
+
+ @Override
+ public void apply( TunerConfiguration config ) throws SourceException
+ {
+ mLog.error( "B100 Tuner - can't apply tuner configuration" );
+ }
+
+ @Override
+ public int getSampleRate()
+ {
+ return mController.getSampleRate();
+ }
+
+ @Override
+ public long getFrequency() throws SourceException
+ {
+ return mController.getFrequency();
+ }
+
+ @Override
+ public TunerChannelSource getChannel( ThreadPoolManager threadPoolManager,
+ TunerChannel channel ) throws RejectedExecutionException, SourceException
+ {
+ return mController.getChannel( threadPoolManager, this, channel );
+ }
+
+ @Override
+ public void releaseChannel( TunerChannelSource source )
+ {
+ /* Unregister for receiving samples */
+ removeListener( (Listener)source );
+
+ /* Tell the controller to release the channel and cleanup */
+ if( source != null )
+ {
+ mController.releaseChannel( source );
+ }
+ }
+
+ @Override
+ public String getUniqueID()
+ {
+ try
+ {
+ return mController.getSerial().getSerialNumber();
+ }
+ catch( Exception e )
+ {
+ mLog.error( "error gettting serial number", e );
+ }
+
+ return BoardID.HACKRF_ONE.getLabel();
+ }
+
+ @Override
+ public void addListener( Listener listener )
+ {
+ mController.addListener( listener );
+ }
+
+ @Override
+ public void removeListener( Listener listener )
+ {
+ mController.removeListener( listener );
+ }
+}
diff --git a/src/source/tuner/hackrf/HackRFTunerConfiguration.java b/src/source/tuner/hackrf/HackRFTunerConfiguration.java
new file mode 100644
index 00000000..c3d5736f
--- /dev/null
+++ b/src/source/tuner/hackrf/HackRFTunerConfiguration.java
@@ -0,0 +1,98 @@
+/*******************************************************************************
+ * SDR Trunk
+ * Copyright (C) 2014 Dennis Sheirer
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see
+ ******************************************************************************/
+package source.tuner.hackrf;
+
+
+import javax.xml.bind.annotation.XmlAttribute;
+
+import source.tuner.TunerConfiguration;
+import source.tuner.TunerType;
+import source.tuner.hackrf.HackRFTunerController.HackRFLNAGain;
+import source.tuner.hackrf.HackRFTunerController.HackRFSampleRate;
+import source.tuner.hackrf.HackRFTunerController.HackRFVGAGain;
+
+public class HackRFTunerConfiguration extends TunerConfiguration
+{
+ private HackRFSampleRate mSampleRate = HackRFSampleRate.RATE2_016MHZ;
+ private HackRFLNAGain mLNAGain = HackRFLNAGain.GAIN_0;
+ private HackRFVGAGain mVGAGain = HackRFVGAGain.GAIN_10;
+ private double mFrequencyCorrection = 0.0d;
+
+ /**
+ * Default constructor for JAXB
+ */
+ public HackRFTunerConfiguration()
+ {
+ this( "Default" );
+ }
+
+ public HackRFTunerConfiguration( String name )
+ {
+ super( name );
+ }
+
+ @Override
+ public TunerType getTunerType()
+ {
+ return TunerType.HACKRF;
+ }
+
+ @XmlAttribute( name = "lna_gain" )
+ public HackRFLNAGain getLNAGain()
+ {
+ return mLNAGain;
+ }
+
+ public void setLNAGain( HackRFLNAGain lnaGain )
+ {
+ mLNAGain = lnaGain;
+ }
+
+ @XmlAttribute( name = "vga_gain" )
+ public HackRFVGAGain getVGAGain()
+ {
+ return mVGAGain;
+ }
+
+ public void setVGAGain( HackRFVGAGain vgaGain )
+ {
+ mVGAGain = vgaGain;
+ }
+
+ @XmlAttribute( name = "frequency_correction" )
+ public double getFrequencyCorrection()
+ {
+ return mFrequencyCorrection;
+ }
+
+ public void setFrequencyCorrection( double value )
+ {
+ mFrequencyCorrection = value;
+ }
+
+ @XmlAttribute( name = "sample_rate" )
+ public HackRFSampleRate getSampleRate()
+ {
+ return mSampleRate;
+ }
+
+ public void setSampleRate( HackRFSampleRate sampleRate )
+ {
+ mSampleRate = sampleRate;
+ }
+}
diff --git a/src/source/tuner/hackrf/HackRFTunerConfigurationPanel.java b/src/source/tuner/hackrf/HackRFTunerConfigurationPanel.java
new file mode 100644
index 00000000..462321bc
--- /dev/null
+++ b/src/source/tuner/hackrf/HackRFTunerConfigurationPanel.java
@@ -0,0 +1,529 @@
+/*******************************************************************************
+ * SDR Trunk
+ * Copyright (C) 2014 Dennis Sheirer
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see
+ ******************************************************************************/
+package source.tuner.hackrf;
+
+import java.awt.EventQueue;
+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.ArrayList;
+
+import javax.swing.BorderFactory;
+import javax.swing.ComboBoxModel;
+import javax.swing.DefaultComboBoxModel;
+import javax.swing.JButton;
+import javax.swing.JComboBox;
+import javax.swing.JLabel;
+import javax.swing.JOptionPane;
+import javax.swing.JPanel;
+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 source.SourceException;
+import source.tuner.TunerConfiguration;
+import source.tuner.TunerConfigurationAssignment;
+import source.tuner.TunerType;
+import source.tuner.hackrf.HackRFTunerController.HackRFLNAGain;
+import source.tuner.hackrf.HackRFTunerController.HackRFSampleRate;
+import source.tuner.hackrf.HackRFTunerController.HackRFVGAGain;
+import controller.ResourceManager;
+
+public class HackRFTunerConfigurationPanel extends JPanel
+{
+ private final static Logger mLog =
+ LoggerFactory.getLogger( HackRFTunerConfigurationPanel.class );
+
+ private static final long serialVersionUID = 1L;
+
+ private ResourceManager mResourceManager;
+ private HackRFTunerController mController;
+ private HackRFTunerConfiguration mSelectedConfig;
+
+ private JButton mNewConfiguration;
+ private JButton mDeleteConfiguration;
+ private JComboBox mComboConfigurations;
+
+ private JTextField mName;
+
+ private JSpinner mFrequencyCorrection;
+ private JComboBox mComboLNAGain;
+ private JComboBox mComboVGAGain;
+
+ private JComboBox mComboSampleRate;
+
+ public HackRFTunerConfigurationPanel( ResourceManager resourceManager,
+ HackRFTunerController controller )
+ {
+ mResourceManager = resourceManager;
+ mController = controller;
+
+ init();
+ }
+
+ /**
+ * Initializes the gui components
+ */
+ private void init()
+ {
+ setLayout( new MigLayout( "fill,wrap 2", "[grow,right][grow]", "[][][][][][][grow]" ) );
+
+ /**
+ * Tuner configuration selector
+ */
+ mComboConfigurations = new JComboBox();
+
+ mComboConfigurations.setModel( getModel() );
+
+ /* Determine which tuner configuration should be selected/displayed */
+ TunerConfigurationAssignment savedConfig = null;
+ String serial = null;
+
+ try
+ {
+ serial = mController.getSerial().getSerialNumber();
+ }
+ catch ( UsbException e2 )
+ {
+ mLog.error( "couldn't read hackrf serial number", e2 );
+ }
+
+ if( serial != null )
+ {
+ savedConfig = mResourceManager
+ .getSettingsManager().getSelectedTunerConfiguration(
+ TunerType.HACKRF, 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.HACKRF,
+ serial, mSelectedConfig );
+ }
+ }
+
+ mComboConfigurations.setSelectedItem( mSelectedConfig );
+
+ mComboConfigurations.addActionListener( new ActionListener()
+ {
+ @Override
+ public void actionPerformed( ActionEvent e )
+ {
+ HackRFTunerConfiguration selected =
+ (HackRFTunerConfiguration)mComboConfigurations
+ .getItemAt( mComboConfigurations.getSelectedIndex() );
+
+ if( selected != null )
+ {
+ update( selected );
+ }
+ }
+ });
+
+ add( new JLabel( "Config:" ) );
+ add( mComboConfigurations, "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, "growx,push" );
+
+ /**
+ * Frequency Correction
+ */
+ SpinnerModel model =
+ new SpinnerNumberModel( 0.0, //initial value
+ -1000.0, //min
+ 1000.0, //max
+ 0.1 ); //step
+
+ mFrequencyCorrection = new JSpinner( model );
+
+ JSpinner.NumberEditor editor =
+ (JSpinner.NumberEditor)mFrequencyCorrection.getEditor();
+
+ DecimalFormat format = editor.getFormat();
+ format.setMinimumFractionDigits( 1 );
+ editor.getTextField().setHorizontalAlignment( SwingConstants.CENTER );
+
+ mFrequencyCorrection.setValue( mSelectedConfig.getFrequencyCorrection() );
+
+ mFrequencyCorrection.addChangeListener( new ChangeListener()
+ {
+ @Override
+ public void stateChanged( ChangeEvent e )
+ {
+ final double value = ((SpinnerNumberModel)mFrequencyCorrection
+ .getModel()).getNumber().doubleValue();
+
+ EventQueue.invokeLater( new Runnable()
+ {
+ @Override
+ public void run()
+ {
+ try
+ {
+ mController.setFrequencyCorrection( value );
+ mSelectedConfig.setFrequencyCorrection( value );
+ save();
+ }
+ catch ( SourceException e1 )
+ {
+ JOptionPane.showMessageDialog(
+ HackRFTunerConfigurationPanel.this,
+ "HackRF Tuner Controller - couldn't apply "
+ + "frequency correction value: " + value +
+ e1.getLocalizedMessage() );
+
+ mLog.error( "HackRF Tuner Controller - couldn't apply "
+ + "frequency correction value: " + value, e1 );
+ }
+ }
+ } );
+ }
+ } );
+
+ add( new JLabel( "Correction PPM:" ) );
+ add( mFrequencyCorrection, "growx,push" );
+
+ /**
+ * Sample Rate
+ */
+ mComboSampleRate = new JComboBox<>( HackRFSampleRate.values() );
+ mComboSampleRate.setSelectedItem( mSelectedConfig.getSampleRate() );
+ mComboSampleRate.addActionListener( new ActionListener()
+ {
+ @Override
+ public void actionPerformed( ActionEvent e )
+ {
+ HackRFSampleRate sampleRate =
+ (HackRFSampleRate)mComboSampleRate.getSelectedItem();
+ try
+ {
+
+ mController.setSampleRate( sampleRate );
+
+ mSelectedConfig.setSampleRate( sampleRate );
+ save();
+ }
+ catch ( UsbException e2 )
+ {
+ JOptionPane.showMessageDialog(
+ HackRFTunerConfigurationPanel.this,
+ "HackRF Tuner Controller - couldn't apply the sample "
+ + "rate setting [" + sampleRate.getLabel() + "] " +
+ e2.getLocalizedMessage() );
+
+ mLog.error( "HackRF Tuner Controller - couldn't apply sample "
+ + "rate setting [" + sampleRate.getLabel() + "]", e );
+ }
+ }
+ } );
+ add( new JLabel( "Sample Rate:" ) );
+ add( mComboSampleRate, "growx,push" );
+
+ /**
+ * Gain Controls
+ */
+ JPanel gainPanel = new JPanel();
+ gainPanel.setLayout( new MigLayout( "", "[grow,fill]", "[grow,fill]" ) );
+ gainPanel.setBorder( BorderFactory.createTitledBorder( "Gain" ) );
+
+ /* LNA Gain Control */
+ mComboLNAGain = new JComboBox( HackRFLNAGain.values() );
+ mComboLNAGain.setSelectedItem( mSelectedConfig.getLNAGain() );
+ mComboLNAGain.addActionListener( new ActionListener()
+ {
+ @Override
+ public void actionPerformed( ActionEvent arg0 )
+ {
+ try
+ {
+ HackRFLNAGain lnaGain =
+ (HackRFLNAGain)mComboLNAGain.getSelectedItem();
+
+ if ( lnaGain == null )
+ {
+ lnaGain = HackRFLNAGain.GAIN_0;
+ }
+
+ if( mComboLNAGain.isEnabled() )
+ {
+ mController.setLNAGain( lnaGain );
+ }
+
+ mSelectedConfig.setLNAGain( lnaGain );
+ save();
+ }
+ catch ( UsbException e )
+ {
+ JOptionPane.showMessageDialog(
+ HackRFTunerConfigurationPanel.this,
+ "HackRF Tuner Controller - couldn't apply the LNA "
+ + "gain setting - " + e.getLocalizedMessage() );
+
+ mLog.error( "HackRF Tuner Controller - couldn't apply LNA "
+ + "gain setting - ", e );
+ }
+ }
+ } );
+ mComboLNAGain.setToolTipText( "LNA Gain. Set master gain "
+ + "to MANUAL to enable adjustment" );
+ gainPanel.add( new JLabel( "LNA" ) );
+ gainPanel.add( mComboLNAGain );
+
+ /* VGA Gain Control */
+ mComboVGAGain = new JComboBox( HackRFVGAGain.values() );
+ mComboVGAGain.setSelectedItem( mSelectedConfig.getVGAGain() );
+ mComboVGAGain.addActionListener( new ActionListener()
+ {
+ @Override
+ public void actionPerformed( ActionEvent arg0 )
+ {
+ try
+ {
+ HackRFVGAGain vgaGain = (HackRFVGAGain)mComboVGAGain.getSelectedItem();
+
+ if( vgaGain == null )
+ {
+ vgaGain = HackRFVGAGain.GAIN_4;
+ }
+
+ if( mComboVGAGain.isEnabled() )
+ {
+ mController.setVGAGain( vgaGain );
+ }
+
+ mSelectedConfig.setVGAGain( vgaGain );
+ save();
+ }
+ catch ( UsbException e )
+ {
+ JOptionPane.showMessageDialog(
+ HackRFTunerConfigurationPanel.this,
+ "HackRF Tuner Controller - couldn't apply the VGA "
+ + "gain setting - " + e.getLocalizedMessage() );
+
+ mLog.error( "HackRF Tuner Controller - couldn't apply VGA "
+ + "gain setting", e );
+ }
+ }
+ } );
+ mComboVGAGain.setToolTipText( "VGA Gain. Set master gain "
+ + "to MANUAL to enable adjustment" );
+ gainPanel.add( new JLabel( "VGA" ) );
+ gainPanel.add( mComboVGAGain, "wrap" );
+
+ add( gainPanel, "span" );
+
+ /**
+ * Create a new configuration
+ */
+ mNewConfiguration = new JButton( "New" );
+
+ mNewConfiguration.addActionListener( new ActionListener()
+ {
+ @Override
+ public void actionPerformed( ActionEvent e )
+ {
+ TunerConfiguration config =
+ mResourceManager.getSettingsManager()
+ .addNewTunerConfiguration(
+ TunerType.HACKRF,
+ "New Configuration" );
+
+ mComboConfigurations.setModel( getModel() );
+
+ mComboConfigurations.setSelectedItem( config );
+
+ repaint();
+ }
+ } );
+
+ add( mNewConfiguration, "growx,push" );
+
+ /**
+ * Delete the currently selected configuration
+ */
+ mDeleteConfiguration = new JButton( "Delete" );
+
+ mDeleteConfiguration.addActionListener( new ActionListener()
+ {
+ @Override
+ public void actionPerformed( ActionEvent e )
+ {
+ HackRFTunerConfiguration selected =
+ (HackRFTunerConfiguration)mComboConfigurations
+ .getItemAt( mComboConfigurations.getSelectedIndex() );
+
+ if( selected != null )
+ {
+ int n = JOptionPane.showConfirmDialog(
+ HackRFTunerConfigurationPanel.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, "growx,push,wrap" );
+ }
+
+ /**
+ * Updates gui controls with the values from the tuner configuration
+ * @param config - tuner configuration
+ */
+ private void update( HackRFTunerConfiguration config )
+ {
+ mSelectedConfig = config;
+
+ try
+ {
+ mController.apply( config );
+
+ mName.setText( config.getName() );
+ mFrequencyCorrection.setValue( config.getFrequencyCorrection() );
+
+ mComboLNAGain.setSelectedItem( mSelectedConfig.getLNAGain() );
+ mComboVGAGain.setSelectedItem( mSelectedConfig.getVGAGain() );
+
+ mComboSampleRate.setSelectedItem( mSelectedConfig.getSampleRate() );
+
+ mResourceManager.getSettingsManager().setSelectedTunerConfiguration(
+ TunerType.HACKRF, mController.getSerial().getSerialNumber(), config );
+ }
+ catch ( UsbException | SourceException e1 )
+ {
+ JOptionPane.showMessageDialog(
+ HackRFTunerConfigurationPanel.this,
+ "HackRF Tuner Controller - couldn't "
+ + "apply the tuner configuration settings - " +
+ e1.getLocalizedMessage() );
+
+ mLog.error( "HackRF 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 getModel()
+ {
+ ArrayList configs =
+ mResourceManager.getSettingsManager()
+ .getTunerConfigurations( TunerType.HACKRF );
+
+ DefaultComboBoxModel model =
+ new DefaultComboBoxModel();
+
+ for( TunerConfiguration config: configs )
+ {
+ model.addElement( (HackRFTunerConfiguration)config );
+ }
+
+ return model;
+ }
+
+ /**
+ * Retrieves a specific (named) tuner configuration
+ */
+ private HackRFTunerConfiguration getNamedConfiguration( String name )
+ {
+ ArrayList configs =
+ mResourceManager.getSettingsManager()
+ .getTunerConfigurations( TunerType.HACKRF );
+
+ for( TunerConfiguration config: configs )
+ {
+ if( config.getName().contentEquals( name ) )
+ {
+ return (HackRFTunerConfiguration)config;
+ }
+ }
+
+ return null;
+ }
+
+ /**
+ * Saves current tuner configuration settings
+ */
+ private void save()
+ {
+ mResourceManager.getSettingsManager().save();
+ }
+}
diff --git a/src/source/tuner/hackrf/HackRFTunerController.java b/src/source/tuner/hackrf/HackRFTunerController.java
new file mode 100644
index 00000000..38555d3e
--- /dev/null
+++ b/src/source/tuner/hackrf/HackRFTunerController.java
@@ -0,0 +1,1071 @@
+package source.tuner.hackrf;
+
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Iterator;
+import java.util.concurrent.CopyOnWriteArrayList;
+import java.util.concurrent.Executors;
+import java.util.concurrent.LinkedTransferQueue;
+import java.util.concurrent.ScheduledExecutorService;
+import java.util.concurrent.ScheduledFuture;
+import java.util.concurrent.TimeUnit;
+import java.util.concurrent.atomic.AtomicBoolean;
+import java.util.concurrent.atomic.AtomicInteger;
+
+import javax.usb.UsbClaimException;
+import javax.usb.UsbConfiguration;
+import javax.usb.UsbControlIrp;
+import javax.usb.UsbDevice;
+import javax.usb.UsbDisconnectedException;
+import javax.usb.UsbEndpoint;
+import javax.usb.UsbEndpointDescriptor;
+import javax.usb.UsbException;
+import javax.usb.UsbInterface;
+import javax.usb.UsbInterfacePolicy;
+import javax.usb.UsbIrp;
+import javax.usb.UsbNotActiveException;
+import javax.usb.UsbNotOpenException;
+import javax.usb.UsbPipe;
+import javax.usb.event.UsbPipeDataEvent;
+import javax.usb.event.UsbPipeErrorEvent;
+import javax.usb.event.UsbPipeListener;
+
+import org.apache.commons.io.EndianUtils;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.usb4java.LibUsb;
+
+import sample.Listener;
+import source.SourceException;
+import source.tuner.TunerConfiguration;
+import source.tuner.TunerController;
+import source.tuner.rtl.ByteSampleAdapter;
+import source.tuner.usb.USBTunerDevice;
+
+public class HackRFTunerController extends TunerController
+{
+ private final static Logger mLog =
+ LoggerFactory.getLogger( HackRFTunerController.class );
+
+ public static final byte USB_ENDPOINT = (byte)0x81;
+ public static final byte USB_INTERFACE = (byte)0x0;
+ public static final boolean USB_FORCE_CLAIM_INTERFACE = true;
+
+ public static final byte REQUEST_TYPE_IN =
+ (byte)( LibUsb.ENDPOINT_IN |
+ LibUsb.REQUEST_TYPE_VENDOR |
+ LibUsb.RECIPIENT_DEVICE );
+
+ public static final byte REQUEST_TYPE_OUT =
+ (byte)( LibUsb.ENDPOINT_OUT |
+ LibUsb.REQUEST_TYPE_VENDOR |
+ LibUsb.RECIPIENT_DEVICE );
+
+ public static final long MIN_FREQUENCY = 10000000l;
+ public static final long MAX_FREQUENCY = 6000000000l;
+ public static final long DEFAULT_FREQUENCY = 101100000;
+
+ public final static int USB_IRP_POOL_SIZE = 10;
+
+ private LinkedTransferQueue mReceivedBuffers =
+ new LinkedTransferQueue();
+
+ private CopyOnWriteArrayList> mSampleListeners =
+ new CopyOnWriteArrayList>();
+
+ private ByteSampleAdapter mSampleAdapter = new ByteSampleAdapter();
+ private BufferProcessor mBufferProcessor = new BufferProcessor();
+
+ private UsbDevice mUSBDevice;
+ private UsbInterface mUSBInterface;
+ private UsbPipe mUSBPipe;
+
+ private HackRFSampleRate mSampleRate = HackRFSampleRate.RATE4_464MHZ;
+ public int mBufferSize = mSampleRate.getBufferSize();
+
+ public HackRFTunerController( USBTunerDevice tunerDevice )
+ throws SourceException
+ {
+ super( MIN_FREQUENCY, MAX_FREQUENCY );
+
+ mUSBDevice = tunerDevice.getDevice();
+ }
+
+ public void init() throws SourceException
+ {
+ mLog.info( "HackRF Tuner Controller init() starting" );
+
+ UsbConfiguration config = mUSBDevice.getActiveUsbConfiguration();
+
+ mUSBInterface = config.getUsbInterface( USB_INTERFACE );
+
+ try
+ {
+ if( claim( mUSBInterface ) )
+ {
+ /* Get the USB endpoint */
+ UsbEndpoint endpoint = mUSBInterface.getUsbEndpoint( USB_ENDPOINT );
+
+ UsbEndpointDescriptor d = endpoint.getUsbEndpointDescriptor();
+ System.out.println( "Endpoint max packet size:" + d.wMaxPacketSize() );
+
+ mUSBPipe = endpoint.getUsbPipe();
+
+ setMode( Mode.RECEIVE );
+
+ setFrequency( DEFAULT_FREQUENCY );
+ }
+ else
+ {
+ throw new SourceException( "HackRF Tuner Controller - couldn't "
+ + "claim USB interface" );
+ }
+ }
+ catch( UsbException e )
+ {
+ throw new SourceException( "HackRF Tuner Controller - couldn't "
+ + "claim USB interface or get endpoint or pipe", e );
+ }
+ catch ( UsbDisconnectedException e )
+ {
+ throw new SourceException( "HackRF Tuner Controller - usb device "
+ + "is disconnected", e );
+ }
+
+ mLog.info( "HackRF Tuner Controller init() complete" );
+ }
+
+ /**
+ * Claims the USB interface. If another application currently has
+ * the interface claimed, the USB_FORCE_CLAIM_INTERFACE setting
+ * will dictate if the interface is forcibly claimed from the other
+ * application
+ */
+ public static boolean claim( UsbInterface iface ) throws UsbException,
+ UsbClaimException
+ {
+ if( !iface.isClaimed() )
+ {
+ iface.claim( new UsbInterfacePolicy()
+ {
+ @Override
+ public boolean forceClaim( UsbInterface arg0 )
+ {
+ return USB_FORCE_CLAIM_INTERFACE;
+ }
+ } );
+
+ return iface.isClaimed();
+ }
+ else
+ {
+ mLog.error( "attempt to claim USB interface failed - in use by "
+ + "another application" );
+ }
+
+ return false;
+ }
+
+ /**
+ * HackRF board identifier/type
+ */
+ public BoardID getBoardID() throws UsbException
+ {
+ int id = readByte( Request.BOARD_ID_READ, (byte)0, (byte)0, false );
+
+ return BoardID.lookup( id );
+ }
+
+ /**
+ * HackRF firmware version string
+ */
+ public String getFirmwareVersion() throws UsbException
+ {
+ byte[] data = readArray( Request.VERSION_STRING_READ, 0, 0, 255 );
+
+ StringBuilder sb = new StringBuilder();
+
+ for( byte b: data )
+ {
+ if( b != (byte)0 )
+ {
+ sb.append( (char)b );
+ }
+ }
+
+ return sb.toString();
+ }
+
+ /**
+ * HackRF part id number and serial number
+ */
+ public Serial getSerial() throws UsbException
+ {
+ byte[] data = readArray( Request.BOARD_PARTID_SERIALNO_READ, 0, 0, 24 );
+
+ return new Serial( data );
+ }
+
+ /**
+ * Sets the HackRF transceiver mode
+ */
+ public void setMode( Mode mode ) throws UsbException
+ {
+ write( Request.SET_TRANSCEIVER_MODE, mode.getNumber(), 0 );
+ }
+
+ /**
+ * Sets the HackRF baseband filter
+ */
+ public void setBasebandFilter( BasebandFilter filter ) throws UsbException
+ {
+ write( Request.BASEBAND_FILTER_BANDWIDTH_SET,
+ filter.getLowValue(),
+ filter.getHighValue() );
+ }
+
+ /**
+ * Enables (true) or disables (false) the amplifier
+ */
+ public void setAmplifierEnabled( boolean enabled ) throws UsbException
+ {
+ write( Request.AMP_ENABLE, ( enabled ? 1 : 0 ), 0 );
+ }
+
+ /**
+ * Sets the IF LNA Gain
+ */
+ public void setLNAGain( HackRFLNAGain gain ) throws UsbException
+ {
+ int result = readByte( Request.SET_LNA_GAIN, 0, gain.getValue(), true );
+
+ if( result != 1 )
+ {
+ throw new UsbException( "couldn't set lna gain to " + gain );
+ }
+ }
+
+ /**
+ * Sets the Baseband VGA Gain
+ */
+ public void setVGAGain( HackRFVGAGain gain ) throws UsbException
+ {
+ int result = readByte( Request.SET_VGA_GAIN, 0, gain.getValue(), true );
+
+ if( result != 1 )
+ {
+ throw new UsbException( "couldn't set vga gain to " + gain );
+ }
+ }
+
+ /**
+ * Not implemented
+ */
+ public long getTunedFrequency() throws SourceException
+ {
+ return 0;
+ }
+
+ @Override
+ public void setTunedFrequency( long frequency ) throws SourceException
+ {
+ int mhz = (int)( frequency / 1E6 );
+ int hz = (int)( frequency - ( mhz * 1E6 ) );
+
+ byte[] data = new byte[ 8 ];
+
+ EndianUtils.writeSwappedInteger( data, 0, mhz );
+ EndianUtils.writeSwappedInteger( data, 4, hz );
+
+ try
+ {
+ write( Request.SET_FREQUENCY, 0, 0, data );
+ }
+ catch( UsbException e )
+ {
+ mLog.error( "error setting frequency [" + frequency + "]", e );
+
+ throw new SourceException( "error setting frequency [" +
+ frequency + "]", e );
+ }
+
+ }
+
+ @Override
+ public int getCurrentSampleRate() throws SourceException
+ {
+ return mSampleRate.getRate();
+ }
+
+ @Override
+ public void apply( TunerConfiguration config ) throws SourceException
+ {
+ if( config instanceof HackRFTunerConfiguration )
+ {
+ HackRFTunerConfiguration hackConfig =
+ (HackRFTunerConfiguration)config;
+
+ try
+ {
+ setSampleRate( hackConfig.getSampleRate() );
+ setFrequencyCorrection( hackConfig.getFrequencyCorrection() );
+ setLNAGain( hackConfig.getLNAGain() );
+ setVGAGain( hackConfig.getVGAGain() );
+ setFrequency( getFrequency() );
+ }
+ catch ( UsbException e )
+ {
+ throw new SourceException( "Error while applying tuner "
+ + "configuration", e );
+ }
+ }
+ else
+ {
+ throw new IllegalArgumentException( "Invalid tuner configuration "
+ + "type [" + config.getClass() + "]" );
+ }
+ }
+
+ public byte[] readArray( Request request,
+ int value,
+ int index,
+ int length ) throws UsbException
+ {
+ UsbControlIrp irp = mUSBDevice.createUsbControlIrp( REQUEST_TYPE_IN,
+ request.getRequestNumber(), (short)value, (short)index );
+
+ byte[] data = new byte[ length ];
+
+ irp.setData( data );
+
+ mUSBDevice.syncSubmit( irp );
+
+ return data;
+ }
+
+ public int read( Request request, int value, int index, int length )
+ throws UsbException
+ {
+ if( !( length == 1 || length == 2 || length == 4 ) )
+ {
+ throw new IllegalArgumentException( "invalid length [" + length +
+ "] must be: byte=1, short=2, int=3 to read a primitive" );
+ }
+
+ byte[] data = readArray( request, value, index, length );
+
+ switch( data.length )
+ {
+ case 1:
+ return data[ 0 ];
+ case 2:
+ return EndianUtils.readSwappedShort( data, 0 );
+ case 4:
+ return EndianUtils.readSwappedInteger( data, 0 );
+ default:
+ throw new UsbException( "read() primitive returned an "
+ + "unrecognized byte array " + Arrays.toString( data ) );
+ }
+ }
+
+ public int readByte( Request request, int value, int index, boolean signed )
+ throws UsbException
+ {
+ byte[] data = readArray( request, value, index, 1 );
+
+ if( signed )
+ {
+ return (int)( data[ 0 ] );
+ }
+ else
+ {
+ return (int)( data[ 0 ] & 0xFF );
+ }
+ }
+
+ public void write( Request request,
+ int value,
+ int index,
+ byte[] data ) throws UsbException
+ {
+ UsbControlIrp irp = mUSBDevice.createUsbControlIrp( REQUEST_TYPE_OUT,
+ request.getRequestNumber(), (short)value, (short)index );
+
+ irp.setData( data );
+
+ mUSBDevice.syncSubmit( irp );
+ }
+
+ /**
+ * Sends a request that doesn't have a data payload
+ */
+ public void write( Request request,
+ int value,
+ int index ) throws UsbException
+ {
+ write( request, value, index, new byte[ 0 ] );
+ }
+
+ /**
+ * Sample Rate
+ *
+ * Note: this is direct translation of the libhackrf code, because I still
+ * can't figure out how it works ... one day, maybe.
+ */
+ public void setSampleRate( HackRFSampleRate rate ) throws UsbException
+ {
+// int MAX_N = 32;
+//
+// double freq = (double)rate.getRate() / 1E6d;
+//
+// double freq_frac = 1.0d + freq - (int)freq;
+//
+// long u64 = Double.doubleToLongBits( freq );
+//
+// int e = (int)( ( u64 >> 52 ) - 1023 );
+//
+// long m = (long)( 1l << 52 ) - 1l;
+//
+// u64 = Double.doubleToLongBits( freq_frac );
+//
+// u64 &= m;
+//
+// m &= ~( ( 1 << ( e + 4 ) ) - 1 );
+//
+// long a = 0;
+//
+// int x;
+//
+// for( x = 1; x < MAX_N; x++ )
+// {
+// a += u64;
+//
+// if( ( ( a & m ) == 0 ) || ( ( ~a & m ) == 0 ) )
+// {
+// break;
+// }
+// }
+//
+// if( x == MAX_N )
+// {
+// x = 1;
+// }
+//
+// int freq_hz = (int)( freq * (double)x * 0.5d );
+//
+// setSampleRateManual( freq_hz, x );
+
+ setSampleRateManual( rate.getRate(), 1 );
+
+ mFrequencyController.setSampleRate( rate.getRate() );
+
+ mBufferSize = rate.getBufferSize();
+
+ setBasebandFilter( rate.getFilter() );
+
+ mSampleRate = rate;
+ }
+
+ public void setSampleRateManual( int frequency, int divider )
+ throws UsbException
+ {
+ byte[] data = new byte[ 8 ];
+
+ EndianUtils.writeSwappedInteger( data, 0, frequency );
+ EndianUtils.writeSwappedInteger( data, 4, divider );
+
+ write( Request.SET_SAMPLE_RATE, 0, 0, data );
+ }
+
+ public int getSampleRate()
+ {
+ return mSampleRate.getRate();
+ }
+
+ public enum Request
+ {
+ SET_TRANSCEIVER_MODE( 1 ),
+ MAX2837_TRANSCEIVER_WRITE( 2 ),
+ MAX2837_TRANSCEIVER_READ( 3 ),
+ SI5351C_CLOCK_GENERATOR_WRITE( 4 ),
+ SI5351C_CLOCK_GENERATOR_READ( 5 ),
+ SET_SAMPLE_RATE( 6 ),
+ BASEBAND_FILTER_BANDWIDTH_SET( 7 ),
+ RFFC5071_MIXER_WRITE( 8 ),
+ RFFC5071_MIXER_READ( 9 ),
+ SPIFLASH_ERASE( 10 ),
+ SPIFLASH_WRITE( 11 ),
+ SPIFLASH_READ( 12 ),
+ BOARD_ID_READ( 14 ),
+ VERSION_STRING_READ( 15 ),
+ SET_FREQUENCY( 16 ),
+ AMP_ENABLE( 17 ),
+ BOARD_PARTID_SERIALNO_READ( 18 ),
+ SET_LNA_GAIN( 19 ),
+ SET_VGA_GAIN( 20 ),
+ SET_TXVGA_GAIN( 21 ),
+ ANTENNA_ENABLE( 23 ),
+ SET_FREQUENCY_EXPLICIT( 24 );
+
+ private byte mRequestNumber;
+
+ private Request( int number )
+ {
+ mRequestNumber = (byte)number;
+ }
+
+ public byte getRequestNumber()
+ {
+ return mRequestNumber;
+ }
+ }
+
+ public enum HackRFSampleRate
+ {
+ RATE2_016MHZ( 2016000, 65536, "2.016 MHz", BasebandFilter.F2_50 ),
+ RATE3_024MHZ( 3024000, 98304, "3.024 MHz", BasebandFilter.F3_50 ),
+ RATE4_464MHZ( 4464000, 131072, "4.464 MHz", BasebandFilter.F5_00 ),
+ RATE5_472MHZ( 5472000, 196608, "5.472 MHz", BasebandFilter.F6_00 ),
+ RATE7_488MHZ( 7488000, 262144, "7.488 MHz", BasebandFilter.F8_00 ),
+ RATE10_032MHZ( 9984000, 131072, " 9.984 MHz", BasebandFilter.F10_00 ),
+ RATE12_000MHZ( 12000000, 262144, "12.000 MHz", BasebandFilter.F12_00 ),
+ RATE13_488MHZ( 13488000, 262144, "13.488 MHz", BasebandFilter.F14_00 ),
+ RATE14_976MHZ( 14976000, 262144, "14.976 MHz", BasebandFilter.F15_00 ),
+ RATE19_968MHZ( 19968000, 262144, "19.968 MHz", BasebandFilter.F20_00 );
+
+ private int mRate;
+ private int mBufferSize;
+ private String mLabel;
+ private BasebandFilter mFilter;
+
+ private HackRFSampleRate( int rate,
+ int bufferSize,
+ String label,
+ BasebandFilter filter )
+ {
+ mRate = rate;
+ mBufferSize = bufferSize;
+ mLabel = label;
+ mFilter = filter;
+ }
+
+ public int getRate()
+ {
+ return mRate;
+ }
+
+ public int getBufferSize()
+ {
+ return mBufferSize;
+ }
+
+ public String getLabel()
+ {
+ return mLabel;
+ }
+
+ public String toString()
+ {
+ return mLabel;
+ }
+
+ public BasebandFilter getFilter()
+ {
+ return mFilter;
+ }
+ }
+
+ public enum BasebandFilter
+ {
+ F1_75( 1750000, "1.75 MHz" ),
+ F2_50( 2500000, "2.50 MHz" ),
+ F3_50( 3500000, "3.50 MHz" ),
+ F5_00( 5000000, "5.00 MHz" ),
+ F5_50( 5500000, "5.50 MHz" ),
+ F6_00( 6000000, "6.00 MHz" ),
+ F7_00( 7000000, "7.00 MHz" ),
+ F8_00( 8000000, "8.00 MHz" ),
+ F9_00( 9000000, "9.00 MHz" ),
+ F10_00( 10000000, "10.00 MHz" ),
+ F12_00( 12000000, "12.00 MHz" ),
+ F14_00( 14000000, "14.00 MHz" ),
+ F15_00( 15000000, "15.00 MHz" ),
+ F20_00( 20000000, "20.00 MHz" ),
+ F24_00( 24000000, "24.00 MHz" ),
+ F28_00( 28000000, "28.00 MHz" );
+
+ private int mBandwidth;
+ private String mLabel;
+
+ private BasebandFilter( int bandwidth, String label )
+ {
+ mBandwidth = bandwidth;
+ mLabel = label;
+ }
+
+ public int getBandwidth()
+ {
+ return mBandwidth;
+ }
+
+ public int getHighValue()
+ {
+ return mBandwidth >> 16;
+ }
+
+ public int getLowValue()
+ {
+ return mBandwidth & 0xFFFF;
+ }
+
+ public String getLabel()
+ {
+ return mLabel;
+ }
+ }
+
+ public enum BoardID
+ {
+ JELLYBEAN( 0x00, "HackRF Jelly Bean" ),
+ JAWBREAKER( 0x01, "HackRF Jaw Breaker" ),
+ HACKRF_ONE( 0x02, "HackRF One" ),
+ INVALID( 0xFF, "HackRF Unknown Board" );
+
+ private byte mIDNumber;
+ private String mLabel;
+
+ private BoardID( int number, String label )
+ {
+ mIDNumber = (byte)number;
+ mLabel = label;
+ }
+
+ public String toString()
+ {
+ return mLabel;
+ }
+
+ public String getLabel()
+ {
+ return mLabel;
+ }
+
+ public byte getNumber()
+ {
+ return mIDNumber;
+ }
+
+ public static BoardID lookup( int value )
+ {
+ switch( value )
+ {
+ case 0:
+ return JELLYBEAN;
+ case 1:
+ return JAWBREAKER;
+ case 2:
+ return HACKRF_ONE;
+ default:
+ return INVALID;
+ }
+ }
+ }
+
+ public enum Mode
+ {
+ OFF( 0, "Off" ),
+ RECEIVE( 1, "Receive" ),
+ TRANSMIT( 2, "Transmit" ),
+ SS( 3, "SS" );
+
+ private byte mNumber;
+ private String mLabel;
+
+ private Mode( int number, String label )
+ {
+ mNumber = (byte)number;
+ mLabel = label;
+ }
+
+ public byte getNumber()
+ {
+ return mNumber;
+ }
+
+ public String getLabel()
+ {
+ return mLabel;
+ }
+
+ public String toString()
+ {
+ return mLabel;
+ }
+ }
+
+ public enum HackRFLNAGain
+ {
+ GAIN_0( 0 ),
+ GAIN_8( 8 ),
+ GAIN_16( 16 ),
+ GAIN_24( 24 ),
+ GAIN_32( 32 ),
+ GAIN_40( 40 );
+
+ private int mValue;
+
+ private HackRFLNAGain( int value )
+ {
+ mValue = value;
+ }
+
+ public int getValue()
+ {
+ return mValue;
+ }
+
+ public String toString()
+ {
+ return String.valueOf( mValue ) + " dB";
+ }
+ }
+
+ /**
+ * Receive (baseband) VGA Gain values
+ */
+ public enum HackRFVGAGain
+ {
+ GAIN_0( 0 ),
+ GAIN_2( 2 ),
+ GAIN_4( 4 ),
+ GAIN_6( 6 ),
+ GAIN_8( 8 ),
+ GAIN_10( 10 ),
+ GAIN_12( 12 ),
+ GAIN_14( 14 ),
+ GAIN_16( 16 ),
+ GAIN_18( 18 ),
+ GAIN_20( 20 ),
+ GAIN_22( 22 ),
+ GAIN_23( 24 ),
+ GAIN_26( 26 ),
+ GAIN_28( 28 ),
+ GAIN_30( 30 ),
+ GAIN_32( 32 ),
+ GAIN_34( 34 ),
+ GAIN_36( 36 ),
+ GAIN_38( 38 ),
+ GAIN_40( 40 ),
+ GAIN_42( 42 ),
+ GAIN_44( 44 ),
+ GAIN_46( 46 ),
+ GAIN_48( 48 ),
+ GAIN_50( 50 ),
+ GAIN_52( 52 ),
+ GAIN_54( 54 ),
+ GAIN_56( 56 ),
+ GAIN_58( 58 ),
+ GAIN_60( 60 ),
+ GAIN_62( 62 );
+
+ private int mValue;
+
+ private HackRFVGAGain( int value )
+ {
+ mValue = value;
+ }
+
+ public int getValue()
+ {
+ return mValue;
+ }
+
+ public String toString()
+ {
+ return String.valueOf( mValue ) + " dB";
+ }
+ }
+
+ /**
+ * HackRF part id and serial number parsing class
+ */
+ public class Serial
+ {
+ private byte[] mData;
+
+ public Serial( byte[] data )
+ {
+ mData = data;
+ }
+
+ public String getPartID()
+ {
+ int part0 = EndianUtils.readSwappedInteger( mData, 0 );
+ int part1 = EndianUtils.readSwappedInteger( mData, 4 );
+
+ StringBuilder sb = new StringBuilder();
+
+ sb.append( String.format( "%08X", part0 ) );
+ sb.append( "-" );
+ sb.append( String.format( "%08X", part1 ) );
+
+ return sb.toString();
+ }
+
+ public String getSerialNumber()
+ {
+ int serial0 = EndianUtils.readSwappedInteger( mData, 8 );
+ int serial1 = EndianUtils.readSwappedInteger( mData, 12 );
+ int serial2 = EndianUtils.readSwappedInteger( mData, 16 );
+ int serial3 = EndianUtils.readSwappedInteger( mData, 20 );
+
+ StringBuilder sb = new StringBuilder();
+
+ sb.append( String.format( "%08X", serial0 ) );
+ sb.append( "-" );
+ sb.append( String.format( "%08X", serial1 ) );
+ sb.append( "-" );
+ sb.append( String.format( "%08X", serial2 ) );
+ sb.append( "-" );
+ sb.append( String.format( "%08X", serial3 ) );
+
+ return sb.toString();
+ }
+ }
+
+ /**
+ * Adds a sample listener. If the buffer processing thread is
+ * not currently running, starts it running in a new thread.
+ */
+ public void addListener( Listener listener )
+ {
+ mSampleListeners.add( listener );
+
+ System.out.println( "HackRF - listener added - count:" + mSampleListeners.size() );
+ mBufferProcessor.start();
+ }
+
+ /**
+ * Removes the sample listener. If this is the last registered listener,
+ * shuts down the buffer processing thread.
+ */
+ public void removeListener( Listener listener )
+ {
+ mSampleListeners.remove( listener );
+
+ if( mSampleListeners.isEmpty() )
+ {
+ mBufferProcessor.stop();
+ }
+ }
+
+ /**
+ * Dispatches the sample array to each registered listener. If there is more
+ * than one listener, they receive a copy of the samples. If there is only
+ * one listener, or the last listener, they receive the original sample array.
+ *
+ * This is to facilitate garbage collection of the array when the listener
+ * is done processing the samples.
+ */
+ public void broadcast( Float[] samples )
+ {
+ Iterator> it = mSampleListeners.iterator();
+
+ while( it.hasNext() )
+ {
+ Listener next = it.next();
+
+ /* if this is the last (or only) listener, send the original
+ * buffer, otherwise send a copy of the buffer */
+ if( it.hasNext() )
+ {
+ next.receive( Arrays.copyOf( samples, samples.length ) );
+ }
+ else
+ {
+ next.receive( samples );
+ }
+ }
+ }
+
+ /**
+ * Buffer processing thread. Fetches samples from the RTL2832 Tuner and
+ * dispatches them to all registered listeners
+ */
+ public class BufferProcessor implements UsbPipeListener
+ {
+ private ScheduledExecutorService mExecutor =
+ Executors.newScheduledThreadPool( 2 );
+ private ScheduledFuture> mSampleDispatcherTask;
+// private ScheduledFuture> mSampleRateCounterTask;
+
+ private AtomicBoolean mRunning = new AtomicBoolean();
+ private AtomicBoolean mResetting = new AtomicBoolean();
+ private Boolean mTransitioning = false;
+
+ public void start()
+ {
+ synchronized( mTransitioning )
+ {
+ if( mRunning.compareAndSet( false, true ) )
+ {
+ mLog.debug( "HackRF - starting sample fetch thread" );
+
+ ArrayList irps = new ArrayList();
+
+ for( int x = 0; x < USB_IRP_POOL_SIZE; x++ )
+ {
+ UsbIrp irp = mUSBPipe.createUsbIrp();
+ irp.setData( new byte[ mBufferSize ] );
+ irps.add( irp );
+ }
+
+ try
+ {
+ if( mUSBPipe.isActive() )
+ {
+ if( !mUSBPipe.isOpen() )
+ {
+ mUSBPipe.open();
+
+ mUSBPipe.addUsbPipeListener( this );
+ }
+
+ if( mUSBPipe.isOpen() )
+ {
+ mSampleDispatcherTask = mExecutor
+ .scheduleAtFixedRate( new BufferDispatcher(),
+ 0, 20, TimeUnit.MILLISECONDS );
+
+// mSampleRateMonitor =
+// new SampleRateMonitor( mSampleRate.getRate() );
+
+// mSampleRateCounterTask = mExecutor
+// .scheduleAtFixedRate( mSampleRateMonitor,
+// 10, 10, TimeUnit.SECONDS );
+
+ mUSBPipe.asyncSubmit( irps );
+ }
+ }
+ }
+ catch ( Exception e )
+ {
+ mLog.error( "Error in buffer processor thread", e );
+ }
+ }
+ }
+ }
+
+ /**
+ * Stops the sample fetching thread
+ */
+ public void stop()
+ {
+ synchronized( mTransitioning )
+ {
+ if( mRunning.compareAndSet( true, false ) )
+ {
+ mLog.debug( "HackRF - stopping sample fetch thread" );
+
+ mUSBPipe.abortAllSubmissions();
+
+ if( mSampleDispatcherTask != null )
+ {
+ mSampleDispatcherTask.cancel( true );
+// mSampleRateCounterTask.cancel( true );
+// mRawSampleBuffer.clear();
+// mSampleCounter.set( 0 );
+ }
+ }
+ }
+ }
+
+ /**
+ * Indicates if this thread is running
+ */
+ public boolean isRunning()
+ {
+ return mRunning.get();
+ }
+
+ /**
+ * Receives filled data buffers and places them in the queue for the
+ * BufferDispatcher to process
+ */
+ @Override
+ public synchronized void dataEventOccurred( UsbPipeDataEvent event )
+ {
+ mReceivedBuffers.add( event.getUsbIrp() );
+ }
+
+ @Override
+ public void errorEventOccurred( UsbPipeErrorEvent e )
+ {
+ /* When an error occurs, we'll get errors on all of the
+ * queued IRPS in succession. We use the mResetting to control
+ * the reset process and ignore all subsequent errors */
+ if( mResetting.compareAndSet( false, true ) )
+ {
+ mLog.error( "error during data transfer resetting USB pipe to "
+ + "HackRF", e );
+
+ stop();
+
+ if( !mSampleListeners.isEmpty() )
+ {
+ start();
+ }
+
+ mResetting.set( false );
+ }
+ }
+ }
+
+ /**
+ * Fetches received UsbIrp buffers from the received queue, dispatches them
+ * and resubmits the processed buffer for more samples
+ */
+ public class BufferDispatcher implements Runnable
+ {
+ @Override
+ public void run()
+ {
+ ArrayList buffers = new ArrayList();
+
+ mReceivedBuffers.drainTo( buffers );
+
+ for( UsbIrp buffer: buffers )
+ {
+ Float[] samples = mSampleAdapter.convert( buffer.getData() );
+
+ broadcast( samples );
+
+ if( mBufferProcessor != null && mBufferProcessor.isRunning() )
+ {
+ try
+ {
+ /* We adjust the buffer size according to sample rate.
+ * If this byte array matches the current buffer size
+ * then we reuse the byte array, otherwise create a
+ * new one. */
+ if( buffer.getData().length == mBufferSize )
+ {
+ mUSBPipe.asyncSubmit( buffer.getData() );
+ }
+ else
+ {
+ mUSBPipe.asyncSubmit( new byte[ mBufferSize ] );
+ }
+ }
+ catch ( UsbNotActiveException | UsbNotOpenException
+ | IllegalArgumentException | UsbDisconnectedException
+ | UsbException e )
+ {
+ mLog.error( "error submitting a byte array to the usb "
+ + "pipe for samples", e );
+ }
+ }
+ }
+ }
+ }
+}
diff --git a/src/source/tuner/hackrf/HackRFTunerEditorPanel.java b/src/source/tuner/hackrf/HackRFTunerEditorPanel.java
new file mode 100644
index 00000000..5f4dec78
--- /dev/null
+++ b/src/source/tuner/hackrf/HackRFTunerEditorPanel.java
@@ -0,0 +1,125 @@
+/*******************************************************************************
+ * SDR Trunk
+ * Copyright (C) 2014 Dennis Sheirer
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see
+ ******************************************************************************/
+package source.tuner.hackrf;
+
+import gui.control.JFrequencyControl;
+
+import java.awt.Color;
+
+import javax.swing.JLabel;
+import javax.swing.JPanel;
+import javax.usb.UsbException;
+
+import net.miginfocom.swing.MigLayout;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import source.SourceException;
+import source.tuner.FrequencyChangeEvent;
+import source.tuner.FrequencyChangeEvent.Attribute;
+import source.tuner.FrequencyChangeListener;
+import source.tuner.hackrf.HackRFTunerController.BoardID;
+
+import com.jidesoft.swing.JideTabbedPane;
+
+import controller.ResourceManager;
+
+public class HackRFTunerEditorPanel extends JPanel
+ implements FrequencyChangeListener
+{
+ private static final long serialVersionUID = 1L;
+
+ private final static Logger mLog =
+ LoggerFactory.getLogger( HackRFTunerEditorPanel.class );
+
+ private JFrequencyControl mFrequencyControl;
+
+ private HackRFTuner mTuner;
+ private HackRFTunerController mController;
+ private ResourceManager mResourceManager;
+
+ public HackRFTunerEditorPanel( HackRFTuner tuner,
+ ResourceManager resourceManager )
+ {
+ mTuner = tuner;
+ mController = mTuner.getController();
+ mResourceManager = resourceManager;
+
+ initGUI();
+ }
+
+ private void initGUI()
+ {
+ setLayout( new MigLayout( "fill,wrap 2",
+ "[right,grow][grow]",
+ "[][][][][][grow]" ) );
+
+ BoardID board = BoardID.INVALID;
+
+ try
+ {
+ board = mTuner.getController().getBoardID();
+ }
+ catch ( UsbException e )
+ {
+ mLog.error( "couldn't read HackRF board identifier", e );
+ }
+
+ add( new JLabel( board.getLabel() ), "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 HackRFTunerConfigurationPanel(
+ mResourceManager, mTuner.getController() ) );
+
+ tabs.add( "Info", new HackRFInformationPanel( mTuner.getController() ) );
+ }
+
+ @Override
+ public void frequencyChanged( FrequencyChangeEvent event )
+ {
+ if( event.getAttribute() == Attribute.FREQUENCY )
+ {
+ try
+ {
+ mController.setFrequency( event.getValue() );
+ }
+ catch ( SourceException e )
+ {
+ mLog.error( "error setting frequency [" + event.getValue() + "]", e );
+ }
+ }
+ }
+}
diff --git a/src/source/tuner/rtl/RTL2832SampleAdapter.java b/src/source/tuner/rtl/ByteSampleAdapter.java
similarity index 82%
rename from src/source/tuner/rtl/RTL2832SampleAdapter.java
rename to src/source/tuner/rtl/ByteSampleAdapter.java
index d11fdfd6..cecfe182 100644
--- a/src/source/tuner/rtl/RTL2832SampleAdapter.java
+++ b/src/source/tuner/rtl/ByteSampleAdapter.java
@@ -19,9 +19,9 @@ package source.tuner.rtl;
import source.mixer.SampleAdapter;
-public class RTL2832SampleAdapter extends SampleAdapter
+public class ByteSampleAdapter extends SampleAdapter
{
- private final static float[] mLOOKUP_VALUES;
+ private final static float[] LOOKUP_VALUES;
/**
* Creates a static lookup table that converts the 8-bit valued range
@@ -29,14 +29,14 @@ public class RTL2832SampleAdapter extends SampleAdapter
*/
static
{
- mLOOKUP_VALUES = new float[ 256 ];
+ LOOKUP_VALUES = new float[ 256 ];
for( int x = 0; x < 256; x++ )
{
- mLOOKUP_VALUES[ x ] = (float)( x - 128 ) * 256.0f;
+ LOOKUP_VALUES[ x ] = (float)( x - 128 ) * 256.0f;
}
- mLOOKUP_VALUES[ 128 ] = 0.0000001f;
+ LOOKUP_VALUES[ 128 ] = 0.0000001f;
}
@Override
@@ -48,7 +48,7 @@ public class RTL2832SampleAdapter extends SampleAdapter
for( byte sample: samples )
{
/* Convert byte value into float from the lookup table */
- convertedSamples[ pointer++ ] = mLOOKUP_VALUES[ ( sample & 0xFF ) ];
+ convertedSamples[ pointer++ ] = LOOKUP_VALUES[ ( sample & 0xFF ) ];
}
return convertedSamples;
diff --git a/src/source/tuner/rtl/RTL2832TunerController.java b/src/source/tuner/rtl/RTL2832TunerController.java
index 5d090bb4..0ea89eb1 100644
--- a/src/source/tuner/rtl/RTL2832TunerController.java
+++ b/src/source/tuner/rtl/RTL2832TunerController.java
@@ -155,7 +155,7 @@ public abstract class RTL2832TunerController extends TunerController
private BufferProcessor mBufferProcessor = new BufferProcessor();
- private RTL2832SampleAdapter mSampleAdapter = new RTL2832SampleAdapter();
+ private ByteSampleAdapter mSampleAdapter = new ByteSampleAdapter();
private CopyOnWriteArrayList> mSampleListeners =
new CopyOnWriteArrayList>();
diff --git a/src/spectrum/ChannelSpectrumPanel.java b/src/spectrum/ChannelSpectrumPanel.java
index 90229687..628e18cc 100644
--- a/src/spectrum/ChannelSpectrumPanel.java
+++ b/src/spectrum/ChannelSpectrumPanel.java
@@ -77,8 +77,9 @@ public class ChannelSpectrumPanel extends JPanel
mOverlayPanel = new ChannelOverlayPanel( mResourceManager );
- mSpectrumAveragingSize = mResourceManager.getSettingsManager()
- .getIntegerSetting( CHANNEL_SPECTRUM_AVERAGING_SIZE, 10 ).getValue();
+ mSpectrumAveragingSize = 10;
+// mSpectrumAveragingSize = mResourceManager.getSettingsManager()
+// .getIntegerSetting( CHANNEL_SPECTRUM_AVERAGING_SIZE, 10 ).getValue();
mSpectrumPanel.setAveraging( mSpectrumAveragingSize );
diff --git a/src/spectrum/SpectrumPanel.java b/src/spectrum/SpectrumPanel.java
index f757db15..f34646a1 100644
--- a/src/spectrum/SpectrumPanel.java
+++ b/src/spectrum/SpectrumPanel.java
@@ -34,7 +34,6 @@ import org.slf4j.LoggerFactory;
import settings.ColorSetting;
import settings.ColorSetting.ColorSettingName;
-import settings.IntegerSetting;
import settings.Setting;
import settings.SettingChangeListener;
import buffer.FloatArrayCircularAveragingBuffer;
@@ -97,8 +96,8 @@ public class SpectrumPanel extends JPanel
{
mAveraging = size;
- mResourceManager.getSettingsManager().setIntegerSetting(
- SPECTRUM_AVERAGING_SIZE, mAveraging );
+// mResourceManager.getSettingsManager().setIntegerSetting(
+// SPECTRUM_AVERAGING_SIZE, mAveraging );
mFFTAveragingBuffer =
new FloatArrayCircularAveragingBuffer( mAveraging );
@@ -149,16 +148,17 @@ public class SpectrumPanel extends JPanel
mColorSpectrumLine = getColor( ColorSettingName.SPECTRUM_LINE );
- mAveraging = getIntegerSetting( "spectrum_averaging_size", 4 );
+ mAveraging = 4;
+// mAveraging = getIntegerSetting( "spectrum_averaging_size", 4 );
}
- private int getIntegerSetting( String name, int defaultValue )
- {
- IntegerSetting setting = mResourceManager.getSettingsManager()
- .getIntegerSetting( name, defaultValue );
-
- return setting.getValue();
- }
+// private int getIntegerSetting( String name, int defaultValue )
+// {
+// IntegerSetting setting = mResourceManager.getSettingsManager()
+// .getIntegerSetting( name, defaultValue );
+//
+// return setting.getValue();
+// }
private Color getColor( ColorSettingName name )
{
diff --git a/src/util/Oscillator.java b/src/util/Oscillator.java
index 302beda4..f6dba831 100644
--- a/src/util/Oscillator.java
+++ b/src/util/Oscillator.java
@@ -69,7 +69,6 @@ public class Oscillator
*/
public void setSampleRate( int sampleRate )
{
- System.out.println( "Oscillator - setting sampleRate to:" + sampleRate );
mSampleRate = (double)sampleRate;
update();
}