diff --git a/src/main/java/io/github/dsheirer/source/tuner/sdrplay/ControlRsp.java b/src/main/java/io/github/dsheirer/source/tuner/sdrplay/ControlRsp.java index 6e2be696..bd65b20f 100644 --- a/src/main/java/io/github/dsheirer/source/tuner/sdrplay/ControlRsp.java +++ b/src/main/java/io/github/dsheirer/source/tuner/sdrplay/ControlRsp.java @@ -31,6 +31,8 @@ import io.github.dsheirer.source.tuner.sdrplay.api.parameter.control.AgcMode; import io.github.dsheirer.source.tuner.sdrplay.api.parameter.tuner.GainReduction; import io.github.dsheirer.source.tuner.sdrplay.api.parameter.tuner.IfMode; import io.github.dsheirer.source.tuner.sdrplay.api.parameter.tuner.LoMode; +import io.github.dsheirer.util.ThreadPool; +import java.lang.ref.WeakReference; import java.util.concurrent.locks.ReentrantLock; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -46,6 +48,7 @@ public abstract class ControlRsp implements IControlRsp protected int mGain; private IDeviceEventListener mDeviceEventListener; private IStreamListener mStreamListener; + protected WeakReference mGainOverloadReference; //Streaming control lock and boolean status indicator. Access to the boolean indicator is protected by the lock. protected ReentrantLock mStreamingLock = new ReentrantLock(); @@ -77,8 +80,7 @@ public abstract class ControlRsp implements IControlRsp getDevice().getCompositeParameters().getControlAParameters().getDcOffset().setDC(true); getDevice().getCompositeParameters().getControlAParameters().getDcOffset().setIQ(true); - //Setup IF, LO, and AGC Mode - getDevice().getCompositeParameters().getControlAParameters().getAgc().setAgcMode(AgcMode.DISABLE); + //Setup IF & LO Mode getDevice().setIfMode(IfMode.IF_ZERO); getDevice().setLoMode(LoMode.AUTO); } @@ -257,6 +259,20 @@ public abstract class ControlRsp implements IControlRsp } } + /** + * Registers the listener to receive gain overload notifications. + * @param listener to register + */ + @Override + public void setGainOverloadListener(IGainOverloadListener listener) + { + if(mGainOverloadReference != null && mGainOverloadReference.get() != null) + { + mGainOverloadReference.clear(); + } + + mGainOverloadReference = new WeakReference<>(listener); + } @Override public void acknowledgePowerOverload(TunerSelect tunerSelect) throws SDRPlayException @@ -269,6 +285,17 @@ public abstract class ControlRsp implements IControlRsp { throw new SDRPlayException("Device is not initialized"); } + + //Notify an optional weakly referenced, registered listener that gain overload has been acknowledged. + if(mGainOverloadReference != null) + { + IGainOverloadListener listener = mGainOverloadReference.get(); + + if(listener != null) + { + ThreadPool.CACHED.submit(() -> listener.notifyGainOverload(tunerSelect)); + } + } } @Override @@ -339,6 +366,27 @@ public abstract class ControlRsp implements IControlRsp } } + /** + * Current IF AGC mode setting. + * @return AGC mode. + */ + @Override + public AgcMode getAgcMode() + { + return getDevice().getCompositeParameters().getControlAParameters().getAgc().getAgcMode(); + } + + /** + * Sets the IF AGC mode + * @param mode to set. + */ + @Override + public void setAgcMode(AgcMode mode) throws SDRPlayException + { + getDevice().getCompositeParameters().getControlAParameters().getAgc().setAgcMode(mode); + getDevice().update(getTunerSelect(), UpdateReason.CONTROL_AGC); + } + /** * Registers listeners to receive device events and sample streams. * @param deviceEventListener to receive device events diff --git a/src/main/java/io/github/dsheirer/source/tuner/sdrplay/IControlRsp.java b/src/main/java/io/github/dsheirer/source/tuner/sdrplay/IControlRsp.java index 61b20e65..3484a044 100644 --- a/src/main/java/io/github/dsheirer/source/tuner/sdrplay/IControlRsp.java +++ b/src/main/java/io/github/dsheirer/source/tuner/sdrplay/IControlRsp.java @@ -25,6 +25,7 @@ import io.github.dsheirer.source.tuner.sdrplay.api.callback.IDeviceEventListener import io.github.dsheirer.source.tuner.sdrplay.api.callback.IStreamListener; import io.github.dsheirer.source.tuner.sdrplay.api.device.Device; import io.github.dsheirer.source.tuner.sdrplay.api.device.TunerSelect; +import io.github.dsheirer.source.tuner.sdrplay.api.parameter.control.AgcMode; /** * Control interface for base RSP device @@ -125,4 +126,22 @@ public interface IControlRsp * @return gain index value (0 - 28) */ int getGain(); + + /** + * Current IF AGC mode setting. + * @return IF agc mode + */ + AgcMode getAgcMode(); + + /** + * Sets the IF AGC mode + * @param mode to set. + */ + void setAgcMode(AgcMode mode) throws SDRPlayException; + + /** + * Registers a listener to receive notifications of gain overload. + * @param listener to register + */ + void setGainOverloadListener(IGainOverloadListener listener); } diff --git a/src/main/java/io/github/dsheirer/source/tuner/sdrplay/IGainOverloadListener.java b/src/main/java/io/github/dsheirer/source/tuner/sdrplay/IGainOverloadListener.java new file mode 100644 index 00000000..18c24372 --- /dev/null +++ b/src/main/java/io/github/dsheirer/source/tuner/sdrplay/IGainOverloadListener.java @@ -0,0 +1,30 @@ +/* + * ***************************************************************************** + * Copyright (C) 2014-2023 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 io.github.dsheirer.source.tuner.sdrplay; + +import io.github.dsheirer.source.tuner.sdrplay.api.device.TunerSelect; + +/** + * Listener interface to receive notifications of gain overload in the RSP device. + */ +public interface IGainOverloadListener +{ + void notifyGainOverload(TunerSelect tunerSelect); +} diff --git a/src/main/java/io/github/dsheirer/source/tuner/sdrplay/RspSampleRate.java b/src/main/java/io/github/dsheirer/source/tuner/sdrplay/RspSampleRate.java index 6da40b5f..deeae0b2 100644 --- a/src/main/java/io/github/dsheirer/source/tuner/sdrplay/RspSampleRate.java +++ b/src/main/java/io/github/dsheirer/source/tuner/sdrplay/RspSampleRate.java @@ -25,16 +25,16 @@ import java.util.EnumSet; /** * RSP device Sample Rate, Bandwidth and Decimation enumeration - * * Note: final effective sample rate must be greater than IF bandwidth setting to avoid aliasing. The available IF * bandwidth values effectively dictate the available sample rates */ public enum RspSampleRate { - RATE_0_250(8_000_000, 016_000, Bandwidth.BW_0_300, Decimate.X32, "0.250 MHz (0.234 usable)"), - RATE_0_500(8_000_000, 024_000, Bandwidth.BW_0_600, Decimate.X16, "0.500 MHz (0.476 usable)"), + RATE_0_250(8_000_000, 16_000, Bandwidth.BW_0_300, Decimate.X32, "0.250 MHz (0.234 usable)"), + RATE_0_500(8_000_000, 24_000, Bandwidth.BW_0_600, Decimate.X16, "0.500 MHz (0.476 usable)"), RATE_1_000(8_000_000, 100_000, Bandwidth.BW_1_536, Decimate.X8, "1.000 MHz (0.900 usable)"), RATE_1_500(6_000_000, 140_000, Bandwidth.BW_1_536, Decimate.X4, "1.500 MHz (1.360 usable)"), + RATE_2_048(8_192_000, 248_000, Bandwidth.BW_1_536, Decimate.X4, "2.048 MHz (1.800 usable)"), RATE_3_000(6_000_000, 300_000, Bandwidth.BW_5_000, Decimate.X2, "3.000 MHz (2.700 usable)"), RATE_4_000(8_000_000, 340_000, Bandwidth.BW_5_000, Decimate.X2, "4.000 MHz (3.560 usable)"), RATE_5_000(5_000_000, 880_000, Bandwidth.BW_5_000, Decimate.X1, "5.000 MHz (4.120 usable)"), @@ -55,11 +55,11 @@ public enum RspSampleRate UNDEFINED(0, 0, Bandwidth.UNDEFINED, Decimate.X1, "UNDEFINED"); - private long mSampleRate; - private long mUnusable; - private Bandwidth mBandwidth; - private Decimate mDecimation; - private String mDescription; + private final long mSampleRate; + private final long mUnusable; + private final Bandwidth mBandwidth; + private final Decimate mDecimation; + private final String mDescription; /** * Constructs an instance @@ -81,12 +81,12 @@ public enum RspSampleRate /** * Single tuner sample rates for all devices operating in single tuner mode */ - public static EnumSet SINGLE_TUNER_SAMPLE_RATES = EnumSet.range(RATE_0_250, RATE_10_000); + public static final EnumSet SINGLE_TUNER_SAMPLE_RATES = EnumSet.range(RATE_0_250, RATE_10_000); /** * RSPduo dual-tuner mode sample rates */ - public static EnumSet DUAL_TUNER_SAMPLE_RATES = EnumSet.range(DUO_RATE_0_500, DUO_RATE_2_000); + public static final EnumSet DUAL_TUNER_SAMPLE_RATES = EnumSet.range(DUO_RATE_0_500, DUO_RATE_2_000); /** * Sample Rate @@ -137,14 +137,6 @@ public enum RspSampleRate return mDecimation; } - /** - * Indicates if this sample rate specifies decimation - */ - public boolean hasDecimation() - { - return getDecimation().isEnabled(); - } - /** * Effective Sample Rate (sample rate / decimation). Note: for RSPduo operating in dual-tuner mode, an * inherent x4 decimation is applied in the hardware. diff --git a/src/main/java/io/github/dsheirer/source/tuner/sdrplay/RspTunerConfiguration.java b/src/main/java/io/github/dsheirer/source/tuner/sdrplay/RspTunerConfiguration.java index 21e9521f..1e265324 100644 --- a/src/main/java/io/github/dsheirer/source/tuner/sdrplay/RspTunerConfiguration.java +++ b/src/main/java/io/github/dsheirer/source/tuner/sdrplay/RspTunerConfiguration.java @@ -23,6 +23,7 @@ import com.fasterxml.jackson.annotation.JsonSubTypes; import com.fasterxml.jackson.annotation.JsonTypeInfo; import com.fasterxml.jackson.dataformat.xml.annotation.JacksonXmlProperty; import io.github.dsheirer.source.tuner.configuration.TunerConfiguration; +import io.github.dsheirer.source.tuner.sdrplay.api.parameter.control.AgcMode; import io.github.dsheirer.source.tuner.sdrplay.api.parameter.tuner.GainReduction; import io.github.dsheirer.source.tuner.sdrplay.rsp1a.Rsp1aTunerConfiguration; import io.github.dsheirer.source.tuner.sdrplay.rsp2.Rsp2TunerConfiguration; @@ -33,7 +34,7 @@ import io.github.dsheirer.source.tuner.sdrplay.rspDx.RspDxTunerConfiguration; /** * Abstract RSP tuner configuration */ -@JsonTypeInfo(use = JsonTypeInfo.Id.NAME, include = JsonTypeInfo.As.PROPERTY, property = "type") +@JsonTypeInfo(use = JsonTypeInfo.Id.NAME, property = "type") @JsonSubTypes({ @JsonSubTypes.Type(value = Rsp1aTunerConfiguration.class, name = "rsp1aTunerConfiguration"), @JsonSubTypes.Type(value = Rsp2TunerConfiguration.class, name = "rsp2TunerConfiguration"), @@ -47,7 +48,8 @@ public abstract class RspTunerConfiguration extends TunerConfiguration public static final RspSampleRate DEFAULT_DUAL_TUNER_SAMPLE_RATE = RspSampleRate.DUO_RATE_2_000; private RspSampleRate mRspSampleRate = DEFAULT_SINGLE_TUNER_SAMPLE_RATE; - private int mGain = 14; + private int mGain = 24; + private AgcMode mAgcMode = AgcMode.ENABLE; /** * JAXB Constructor @@ -103,4 +105,23 @@ public abstract class RspTunerConfiguration extends TunerConfiguration mGain = gain; } } + + /** + * IF AGC mode + * @return mode + */ + @JacksonXmlProperty(isAttribute = true, localName = "agcMode") + public AgcMode getAgcMode() + { + return mAgcMode; + } + + /** + * Sets the IF AGC mode + * @param mode to set + */ + public void setAgcMode(AgcMode mode) + { + mAgcMode = mode; + } } diff --git a/src/main/java/io/github/dsheirer/source/tuner/sdrplay/RspTunerEditor.java b/src/main/java/io/github/dsheirer/source/tuner/sdrplay/RspTunerEditor.java index d5e8ffd4..8b5060c9 100644 --- a/src/main/java/io/github/dsheirer/source/tuner/sdrplay/RspTunerEditor.java +++ b/src/main/java/io/github/dsheirer/source/tuner/sdrplay/RspTunerEditor.java @@ -21,11 +21,21 @@ package io.github.dsheirer.source.tuner.sdrplay; import io.github.dsheirer.preference.UserPreferences; import io.github.dsheirer.source.tuner.manager.TunerManager; +import io.github.dsheirer.source.tuner.sdrplay.api.SDRPlayException; +import io.github.dsheirer.source.tuner.sdrplay.api.device.TunerSelect; +import io.github.dsheirer.source.tuner.sdrplay.api.parameter.control.AgcMode; import io.github.dsheirer.source.tuner.sdrplay.api.parameter.tuner.GainReduction; import io.github.dsheirer.source.tuner.ui.TunerEditor; +import io.github.dsheirer.util.ThreadPool; +import java.awt.Color; +import java.awt.EventQueue; +import java.util.concurrent.TimeUnit; +import java.util.concurrent.atomic.AtomicBoolean; import org.slf4j.Logger; import org.slf4j.LoggerFactory; +import javax.swing.JButton; +import javax.swing.JComboBox; import javax.swing.JLabel; import javax.swing.JOptionPane; import javax.swing.JSlider; @@ -33,11 +43,14 @@ import javax.swing.JSlider; /** * Abstract RSP tuner editor */ -public abstract class RspTunerEditor extends TunerEditor +public abstract class RspTunerEditor extends TunerEditor implements IGainOverloadListener { private Logger mLog = LoggerFactory.getLogger(RspTunerEditor.class); private JSlider mGainSlider; private JLabel mGainValueLabel; + private JComboBox mAgcModeCombo; + private JButton mGainOverloadButton; + private AtomicBoolean mGainOverloadAlert = new AtomicBoolean(); /** * Constructs an instance @@ -105,4 +118,87 @@ public abstract class RspTunerEditor extends Tu return mGainValueLabel; } + + /** + * IF AGC mode combobox control + */ + protected JComboBox getAgcModeCombo() + { + if(mAgcModeCombo == null) + { + mAgcModeCombo = new JComboBox<>(AgcMode.values()); + mAgcModeCombo.setEnabled(false); + mAgcModeCombo.addActionListener(e -> { + if(hasTuner() && !isLoading()) + { + AgcMode selected = (AgcMode)mAgcModeCombo.getSelectedItem(); + try + { + getTunerController().getControlRsp().setAgcMode(selected); + save(); + } + catch(SDRPlayException se) + { + mLog.error("Error setting AGC mode on RSP device"); + } + save(); + } + }); + } + + return mAgcModeCombo; + } + + /** + * Gain overload button. Used in a disabled state to indicate (e.g. flashing color) that gain overload is detected. + */ + protected JButton getGainOverloadButton() + { + if(mGainOverloadButton == null) + { + mGainOverloadButton = new JButton("Gain Overload"); + mGainOverloadButton.setToolTipText("Notification that manual gain is set too high and causing power overload. Reduce manual gain when this flashes."); + mGainOverloadButton.setEnabled(false); + } + + return mGainOverloadButton; + } + + @Override + public void notifyGainOverload(TunerSelect tunerSelect) + { + if(hasTuner() && getTuner().getRspTunerController().getTunerSelect() == tunerSelect) + { + //Set overload alert + EventQueue.invokeLater(() -> setGainOverloadAlert(true)); + + //Schedule a reset to happen 1 second later + ThreadPool.SCHEDULED.schedule((Runnable) () -> setGainOverloadAlert(false), 600, TimeUnit.MILLISECONDS); + } + } + + /** + * Toggles the alert styling of the disabled gain overload button to indicate an alert condition or a normal + * operating condition. + * @param alert true to apply alert styling or false to reset. + */ + private void setGainOverloadAlert(boolean alert) + { + if(alert && mGainOverloadAlert.compareAndSet(false, true)) + { + getGainOverloadButton().setEnabled(true); + getGainOverloadButton().setForeground(Color.YELLOW); + getGainOverloadButton().setBackground(Color.RED); + } + else if(!alert && mGainOverloadAlert.compareAndSet(true, false)) + { + getGainOverloadButton().setEnabled(false); + getGainOverloadButton().setForeground(getForeground()); + getGainOverloadButton().setBackground(getBackground()); + } + else + { + mLog.info("Ignoring duplicate gain alerting - alert[" + alert + "] atomic [" + mGainOverloadAlert.get() + "]"); + } + } } diff --git a/src/main/java/io/github/dsheirer/source/tuner/sdrplay/api/SDRplay.java b/src/main/java/io/github/dsheirer/source/tuner/sdrplay/api/SDRplay.java index 9ac5be84..e605a551 100644 --- a/src/main/java/io/github/dsheirer/source/tuner/sdrplay/api/SDRplay.java +++ b/src/main/java/io/github/dsheirer/source/tuner/sdrplay/api/SDRplay.java @@ -61,7 +61,8 @@ import org.slf4j.LoggerFactory; public class SDRplay { public static final String SDRPLAY_API_LIBRARY_NAME = "sdrplay_api"; - public static final String SDRPLAY_API_PATH_LINUX_AND_OSX = "/usr/local/lib/libsdrplay_api.so"; + public static final String SDRPLAY_API_PATH_LINUX = "/usr/local/lib/libsdrplay_api.so"; + public static final String SDRPLAY_API_PATH_MAC_OS = "/usr/local/lib/libsdrplay_api.dylib"; public static final String SDRPLAY_API_PATH_WINDOWS = System.getenv("ProgramFiles") + "\\SDRplay\\API\\" + (System.getProperty("sun.arch.data.model").contentEquals("64") ? "x64" : "x86") + "\\" + SDRPLAY_API_LIBRARY_NAME; @@ -671,11 +672,11 @@ public class SDRplay } else if(SystemUtils.IS_OS_LINUX) { - return SDRPLAY_API_PATH_LINUX_AND_OSX; + return SDRPLAY_API_PATH_LINUX; } else if(SystemUtils.IS_OS_MAC_OSX) { - return SDRPLAY_API_PATH_LINUX_AND_OSX; + return SDRPLAY_API_PATH_MAC_OS; } mLog.error("Unrecognized operating system. Cannot identify sdrplay api library path"); diff --git a/src/main/java/io/github/dsheirer/source/tuner/sdrplay/rsp1/Rsp1TunerController.java b/src/main/java/io/github/dsheirer/source/tuner/sdrplay/rsp1/Rsp1TunerController.java index 68c17427..88500141 100644 --- a/src/main/java/io/github/dsheirer/source/tuner/sdrplay/rsp1/Rsp1TunerController.java +++ b/src/main/java/io/github/dsheirer/source/tuner/sdrplay/rsp1/Rsp1TunerController.java @@ -24,6 +24,7 @@ import io.github.dsheirer.source.tuner.ITunerErrorListener; import io.github.dsheirer.source.tuner.TunerType; import io.github.dsheirer.source.tuner.configuration.TunerConfiguration; import io.github.dsheirer.source.tuner.sdrplay.RspTunerController; +import io.github.dsheirer.source.tuner.sdrplay.api.SDRPlayException; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -54,9 +55,18 @@ public class Rsp1TunerController extends RspTunerController @Override public void apply(TunerConfiguration config) throws SourceException { - if(config instanceof Rsp1TunerConfiguration) + if(config instanceof Rsp1TunerConfiguration rtc) { super.apply(config); + + try + { + getControlRsp().setAgcMode(rtc.getAgcMode()); + } + catch(SDRPlayException se) + { + mLog.error("Error setting RSP IF AGC Mode to " + rtc.getAgcMode()); + } } else { diff --git a/src/main/java/io/github/dsheirer/source/tuner/sdrplay/rsp1/Rsp1TunerEditor.java b/src/main/java/io/github/dsheirer/source/tuner/sdrplay/rsp1/Rsp1TunerEditor.java index 1c658ab9..737b6b24 100644 --- a/src/main/java/io/github/dsheirer/source/tuner/sdrplay/rsp1/Rsp1TunerEditor.java +++ b/src/main/java/io/github/dsheirer/source/tuner/sdrplay/rsp1/Rsp1TunerEditor.java @@ -25,12 +25,14 @@ import io.github.dsheirer.source.tuner.sdrplay.DiscoveredRspTuner; import io.github.dsheirer.source.tuner.sdrplay.RspSampleRate; import io.github.dsheirer.source.tuner.sdrplay.RspTunerEditor; import io.github.dsheirer.source.tuner.sdrplay.api.SDRPlayException; +import io.github.dsheirer.source.tuner.sdrplay.api.parameter.control.AgcMode; import net.miginfocom.swing.MigLayout; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import javax.swing.JComboBox; import javax.swing.JLabel; +import javax.swing.JPanel; import javax.swing.JSeparator; import javax.swing.SpinnerNumberModel; @@ -59,7 +61,7 @@ public class Rsp1TunerEditor extends RspTunerEditor private void init() { setLayout(new MigLayout("fill,wrap 3", "[right][grow,fill][fill]", - "[][][][][][][][][][][][grow]")); + "[][][][][][][][][][][][][grow]")); add(new JLabel("Tuner:")); add(getTunerIdLabel(), "wrap"); @@ -77,6 +79,13 @@ public class Rsp1TunerEditor extends RspTunerEditor add(new JLabel("Sample Rate:")); add(getSampleRateCombo(), "wrap"); + add(new JLabel("IF AGC Mode:")); + JPanel gainPanel = new JPanel(); + gainPanel.setLayout(new MigLayout("insets 0","[grow,fill][]","")); + gainPanel.add(getAgcModeCombo()); + gainPanel.add(getGainOverloadButton()); + add(gainPanel, "wrap"); + add(new JLabel("Gain:")); add(getGainSlider()); add(getGainValueLabel()); @@ -116,6 +125,14 @@ public class Rsp1TunerEditor extends RspTunerEditor getSampleRateCombo().setEnabled(hasTuner() && !getTuner().getTunerController().isLockedSampleRate()); getSampleRateCombo().setSelectedItem(hasTuner() ? getTunerController().getControlRsp().getSampleRateEnumeration() : null); + getAgcModeCombo().setEnabled(hasTuner()); + if(hasTuner()) + { + getAgcModeCombo().setSelectedItem(getTunerController().getControlRsp().getAgcMode()); + //Register to receive gain overload notifications + getTunerController().getControlRsp().setGainOverloadListener(this); + } + getGainSlider().setEnabled(hasTuner()); getGainValueLabel().setEnabled(hasTuner()); getGainSlider().setValue(hasTuner() ? getTunerController().getControlRsp().getGain() : 0); @@ -134,6 +151,7 @@ public class Rsp1TunerEditor extends RspTunerEditor getConfiguration().setAutoPPMCorrectionEnabled(getAutoPPMCheckBox().isSelected()); getConfiguration().setSampleRate((RspSampleRate)getSampleRateCombo().getSelectedItem()); getConfiguration().setGain(getGainSlider().getValue()); + getConfiguration().setAgcMode((AgcMode)getAgcModeCombo().getSelectedItem()); saveConfiguration(); } diff --git a/src/main/java/io/github/dsheirer/source/tuner/sdrplay/rsp1a/Rsp1aTunerController.java b/src/main/java/io/github/dsheirer/source/tuner/sdrplay/rsp1a/Rsp1aTunerController.java index 4b269058..eb1e490a 100644 --- a/src/main/java/io/github/dsheirer/source/tuner/sdrplay/rsp1a/Rsp1aTunerController.java +++ b/src/main/java/io/github/dsheirer/source/tuner/sdrplay/rsp1a/Rsp1aTunerController.java @@ -59,6 +59,15 @@ public class Rsp1aTunerController extends RspTunerController { super.apply(config); + try + { + getControlRsp().setAgcMode(rtc.getAgcMode()); + } + catch(SDRPlayException se) + { + mLog.error("Error setting RSP IF AGC Mode to " + rtc.getAgcMode()); + } + try { getControlRsp().setBiasT(rtc.isBiasT()); diff --git a/src/main/java/io/github/dsheirer/source/tuner/sdrplay/rsp1a/Rsp1aTunerEditor.java b/src/main/java/io/github/dsheirer/source/tuner/sdrplay/rsp1a/Rsp1aTunerEditor.java index 1121d61b..c8bfae37 100644 --- a/src/main/java/io/github/dsheirer/source/tuner/sdrplay/rsp1a/Rsp1aTunerEditor.java +++ b/src/main/java/io/github/dsheirer/source/tuner/sdrplay/rsp1a/Rsp1aTunerEditor.java @@ -25,6 +25,7 @@ import io.github.dsheirer.source.tuner.sdrplay.DiscoveredRspTuner; import io.github.dsheirer.source.tuner.sdrplay.RspSampleRate; import io.github.dsheirer.source.tuner.sdrplay.RspTunerEditor; import io.github.dsheirer.source.tuner.sdrplay.api.SDRPlayException; +import io.github.dsheirer.source.tuner.sdrplay.api.parameter.control.AgcMode; import net.miginfocom.swing.MigLayout; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -32,6 +33,7 @@ import org.slf4j.LoggerFactory; import javax.swing.JCheckBox; import javax.swing.JComboBox; import javax.swing.JLabel; +import javax.swing.JPanel; import javax.swing.JSeparator; import javax.swing.SpinnerNumberModel; @@ -63,7 +65,7 @@ public class Rsp1aTunerEditor extends RspTunerEditor private void init() { setLayout(new MigLayout("fill,wrap 3", "[right][grow,fill][fill]", - "[][][][][][][][][][][][grow]")); + "[][][][][][][][][][][][][grow]")); add(new JLabel("Tuner:")); add(getTunerIdLabel(), "wrap"); @@ -81,6 +83,13 @@ public class Rsp1aTunerEditor extends RspTunerEditor add(new JLabel("Sample Rate:")); add(getSampleRateCombo(), "wrap"); + add(new JLabel("IF AGC Mode:")); + JPanel gainPanel = new JPanel(); + gainPanel.setLayout(new MigLayout("insets 0","[grow,fill][]","")); + gainPanel.add(getAgcModeCombo()); + gainPanel.add(getGainOverloadButton()); + add(gainPanel, "wrap"); + add(new JLabel("Gain:")); add(getGainSlider()); add(getGainValueLabel()); @@ -127,6 +136,14 @@ public class Rsp1aTunerEditor extends RspTunerEditor getSampleRateCombo().setEnabled(hasTuner() && !getTuner().getTunerController().isLockedSampleRate()); getSampleRateCombo().setSelectedItem(hasTuner() ? getTunerController().getControlRsp().getSampleRateEnumeration() : null); + getAgcModeCombo().setEnabled(hasTuner()); + if(hasTuner()) + { + getAgcModeCombo().setSelectedItem(getTunerController().getControlRsp().getAgcMode()); + //Register to receive gain overload notifications + getTunerController().getControlRsp().setGainOverloadListener(this); + } + getGainSlider().setEnabled(hasTuner()); getGainValueLabel().setEnabled(hasTuner()); getGainSlider().setValue(hasTuner() ? getTunerController().getControlRsp().getGain() : 0); @@ -178,6 +195,7 @@ public class Rsp1aTunerEditor extends RspTunerEditor getConfiguration().setRfNotch(getRfNotchCheckBox().isSelected()); getConfiguration().setRfDabNotch(getRfDabNotchCheckBox().isSelected()); getConfiguration().setGain(getGainSlider().getValue()); + getConfiguration().setAgcMode((AgcMode)getAgcModeCombo().getSelectedItem()); saveConfiguration(); } diff --git a/src/main/java/io/github/dsheirer/source/tuner/sdrplay/rsp2/Rsp2TunerController.java b/src/main/java/io/github/dsheirer/source/tuner/sdrplay/rsp2/Rsp2TunerController.java index 30983ac0..954ba38f 100644 --- a/src/main/java/io/github/dsheirer/source/tuner/sdrplay/rsp2/Rsp2TunerController.java +++ b/src/main/java/io/github/dsheirer/source/tuner/sdrplay/rsp2/Rsp2TunerController.java @@ -59,6 +59,15 @@ public class Rsp2TunerController extends RspTunerController { super.apply(config); + try + { + getControlRsp().setAgcMode(rtc.getAgcMode()); + } + catch(SDRPlayException se) + { + mLog.error("Error setting RSP IF AGC Mode to " + rtc.getAgcMode()); + } + try { getControlRsp().setBiasT(rtc.isBiasT()); diff --git a/src/main/java/io/github/dsheirer/source/tuner/sdrplay/rsp2/Rsp2TunerEditor.java b/src/main/java/io/github/dsheirer/source/tuner/sdrplay/rsp2/Rsp2TunerEditor.java index d8d31389..2cba4791 100644 --- a/src/main/java/io/github/dsheirer/source/tuner/sdrplay/rsp2/Rsp2TunerEditor.java +++ b/src/main/java/io/github/dsheirer/source/tuner/sdrplay/rsp2/Rsp2TunerEditor.java @@ -25,6 +25,7 @@ import io.github.dsheirer.source.tuner.sdrplay.DiscoveredRspTuner; import io.github.dsheirer.source.tuner.sdrplay.RspSampleRate; import io.github.dsheirer.source.tuner.sdrplay.RspTunerEditor; import io.github.dsheirer.source.tuner.sdrplay.api.SDRPlayException; +import io.github.dsheirer.source.tuner.sdrplay.api.parameter.control.AgcMode; import io.github.dsheirer.source.tuner.sdrplay.api.parameter.tuner.Rsp2AntennaSelection; import net.miginfocom.swing.MigLayout; import org.slf4j.Logger; @@ -33,6 +34,7 @@ import org.slf4j.LoggerFactory; import javax.swing.JCheckBox; import javax.swing.JComboBox; import javax.swing.JLabel; +import javax.swing.JPanel; import javax.swing.JSeparator; import javax.swing.SpinnerNumberModel; @@ -65,7 +67,7 @@ public class Rsp2TunerEditor extends RspTunerEditor private void init() { setLayout(new MigLayout("fill,wrap 3", "[right][grow,fill][fill]", - "[][][][][][][][][][][][grow]")); + "[][][][][][][][][][][][][grow]")); add(new JLabel("Tuner:")); add(getTunerIdLabel(), "wrap"); @@ -83,6 +85,13 @@ public class Rsp2TunerEditor extends RspTunerEditor add(new JLabel("Sample Rate:")); add(getSampleRateCombo(), "wrap"); + add(new JLabel("IF AGC Mode:")); + JPanel gainPanel = new JPanel(); + gainPanel.setLayout(new MigLayout("insets 0","[grow,fill][]","")); + gainPanel.add(getAgcModeCombo()); + gainPanel.add(getGainOverloadButton()); + add(gainPanel, "wrap"); + add(new JLabel("Gain:")); add(getGainSlider()); add(getGainValueLabel()); @@ -131,6 +140,14 @@ public class Rsp2TunerEditor extends RspTunerEditor getSampleRateCombo().setEnabled(hasTuner() && !getTuner().getTunerController().isLockedSampleRate()); getSampleRateCombo().setSelectedItem(hasTuner() ? getTunerController().getControlRsp().getSampleRateEnumeration() : null); + getAgcModeCombo().setEnabled(hasTuner()); + if(hasTuner()) + { + getAgcModeCombo().setSelectedItem(getTunerController().getControlRsp().getAgcMode()); + //Register to receive gain overload notifications + getTunerController().getControlRsp().setGainOverloadListener(this); + } + getGainSlider().setEnabled(hasTuner()); getGainValueLabel().setEnabled(hasTuner()); getGainSlider().setValue(hasTuner() ? getTunerController().getControlRsp().getGain() : 0); @@ -192,6 +209,7 @@ public class Rsp2TunerEditor extends RspTunerEditor getConfiguration().setRfNotch(getRfNotchCheckBox().isSelected()); getConfiguration().setAntennaSelection((Rsp2AntennaSelection)getAntennaSelectionCombo().getSelectedItem()); getConfiguration().setGain(getGainSlider().getValue()); + getConfiguration().setAgcMode((AgcMode)getAgcModeCombo().getSelectedItem()); saveConfiguration(); } diff --git a/src/main/java/io/github/dsheirer/source/tuner/sdrplay/rspDuo/ControlRspDuo.java b/src/main/java/io/github/dsheirer/source/tuner/sdrplay/rspDuo/ControlRspDuo.java index 5ed8f151..1e12ca59 100644 --- a/src/main/java/io/github/dsheirer/source/tuner/sdrplay/rspDuo/ControlRspDuo.java +++ b/src/main/java/io/github/dsheirer/source/tuner/sdrplay/rspDuo/ControlRspDuo.java @@ -20,6 +20,7 @@ package io.github.dsheirer.source.tuner.sdrplay.rspDuo; import io.github.dsheirer.source.tuner.sdrplay.ControlRsp; +import io.github.dsheirer.source.tuner.sdrplay.IGainOverloadListener; import io.github.dsheirer.source.tuner.sdrplay.RspSampleRate; import io.github.dsheirer.source.tuner.sdrplay.api.DeviceSelectionMode; import io.github.dsheirer.source.tuner.sdrplay.api.SDRPlayException; @@ -28,11 +29,11 @@ import io.github.dsheirer.source.tuner.sdrplay.api.UpdateReason; import io.github.dsheirer.source.tuner.sdrplay.api.device.RspDuoDevice; import io.github.dsheirer.source.tuner.sdrplay.api.device.RspDuoTuner; import io.github.dsheirer.source.tuner.sdrplay.api.device.TunerSelect; -import io.github.dsheirer.source.tuner.sdrplay.api.parameter.control.AgcMode; import io.github.dsheirer.source.tuner.sdrplay.api.parameter.control.ControlParameters; import io.github.dsheirer.source.tuner.sdrplay.api.parameter.tuner.IfMode; import io.github.dsheirer.source.tuner.sdrplay.api.parameter.tuner.LoMode; import io.github.dsheirer.source.tuner.sdrplay.api.parameter.tuner.TunerParameters; +import io.github.dsheirer.util.ThreadPool; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -97,8 +98,7 @@ public abstract class ControlRspDuo extends ControlRsp extends ControlRsp listener.notifyGainOverload(tunerSelect)); + } + } } @Override diff --git a/src/main/java/io/github/dsheirer/source/tuner/sdrplay/rspDuo/ControlRspDuoTuner2.java b/src/main/java/io/github/dsheirer/source/tuner/sdrplay/rspDuo/ControlRspDuoTuner2.java index 6eacd120..942e1c73 100644 --- a/src/main/java/io/github/dsheirer/source/tuner/sdrplay/rspDuo/ControlRspDuoTuner2.java +++ b/src/main/java/io/github/dsheirer/source/tuner/sdrplay/rspDuo/ControlRspDuoTuner2.java @@ -20,9 +20,11 @@ package io.github.dsheirer.source.tuner.sdrplay.rspDuo; import io.github.dsheirer.source.tuner.sdrplay.api.SDRPlayException; +import io.github.dsheirer.source.tuner.sdrplay.api.UpdateReason; import io.github.dsheirer.source.tuner.sdrplay.api.device.RspDuoDevice; import io.github.dsheirer.source.tuner.sdrplay.api.device.RspDuoTuner2; import io.github.dsheirer.source.tuner.sdrplay.api.device.TunerSelect; +import io.github.dsheirer.source.tuner.sdrplay.api.parameter.control.AgcMode; import io.github.dsheirer.source.tuner.sdrplay.api.parameter.control.ControlParameters; import io.github.dsheirer.source.tuner.sdrplay.api.parameter.tuner.TunerParameters; import org.slf4j.Logger; @@ -103,4 +105,25 @@ public abstract class ControlRspDuoTuner2 extends ControlRspDuo im throw new SDRPlayException("Device is not initialized"); } } + + /** + * Current IF AGC mode setting. + * @return AGC mode. + */ + @Override + public AgcMode getAgcMode() + { + return getDevice().getCompositeParameters().getControlBParameters().getAgc().getAgcMode(); + } + + /** + * Sets the IF AGC mode + * @param mode to set. + */ + @Override + public void setAgcMode(AgcMode mode) throws SDRPlayException + { + getDevice().getCompositeParameters().getControlBParameters().getAgc().setAgcMode(mode); + getDevice().update(getTunerSelect(), UpdateReason.CONTROL_AGC); + } } diff --git a/src/main/java/io/github/dsheirer/source/tuner/sdrplay/rspDuo/RspDuoTuner1Controller.java b/src/main/java/io/github/dsheirer/source/tuner/sdrplay/rspDuo/RspDuoTuner1Controller.java index 73e53a15..f35ab827 100644 --- a/src/main/java/io/github/dsheirer/source/tuner/sdrplay/rspDuo/RspDuoTuner1Controller.java +++ b/src/main/java/io/github/dsheirer/source/tuner/sdrplay/rspDuo/RspDuoTuner1Controller.java @@ -57,53 +57,62 @@ public class RspDuoTuner1Controller extends RspTunerController { super.apply(config); + try + { + getControlRsp().setAgcMode(rtc.getAgcMode()); + } + catch(SDRPlayException se) + { + mLog.error("Error setting RSP IF AGC Mode to " + rtc.getAgcMode()); + } + try { getControlRsp().setAntenna(rtc.getAntenna()); diff --git a/src/main/java/io/github/dsheirer/source/tuner/sdrplay/rspDx/RspDxTunerEditor.java b/src/main/java/io/github/dsheirer/source/tuner/sdrplay/rspDx/RspDxTunerEditor.java index 8286a3f6..6ffb16a9 100644 --- a/src/main/java/io/github/dsheirer/source/tuner/sdrplay/rspDx/RspDxTunerEditor.java +++ b/src/main/java/io/github/dsheirer/source/tuner/sdrplay/rspDx/RspDxTunerEditor.java @@ -25,6 +25,7 @@ import io.github.dsheirer.source.tuner.sdrplay.DiscoveredRspTuner; import io.github.dsheirer.source.tuner.sdrplay.RspSampleRate; import io.github.dsheirer.source.tuner.sdrplay.RspTunerEditor; import io.github.dsheirer.source.tuner.sdrplay.api.SDRPlayException; +import io.github.dsheirer.source.tuner.sdrplay.api.parameter.control.AgcMode; import io.github.dsheirer.source.tuner.sdrplay.api.parameter.tuner.HdrModeBandwidth; import io.github.dsheirer.source.tuner.sdrplay.api.parameter.tuner.RspDxAntenna; import net.miginfocom.swing.MigLayout; @@ -34,6 +35,7 @@ import org.slf4j.LoggerFactory; import javax.swing.JCheckBox; import javax.swing.JComboBox; import javax.swing.JLabel; +import javax.swing.JPanel; import javax.swing.JSeparator; import javax.swing.SpinnerNumberModel; @@ -86,6 +88,13 @@ public class RspDxTunerEditor extends RspTunerEditor add(new JLabel("Sample Rate:")); add(getSampleRateCombo(), "wrap"); + add(new JLabel("IF AGC Mode:")); + JPanel gainPanel = new JPanel(); + gainPanel.setLayout(new MigLayout("insets 0","[grow,fill][]","")); + gainPanel.add(getAgcModeCombo()); + gainPanel.add(getGainOverloadButton()); + add(gainPanel, "wrap"); + add(new JLabel("Gain:")); add(getGainSlider()); add(getGainValueLabel()); @@ -140,6 +149,14 @@ public class RspDxTunerEditor extends RspTunerEditor getSampleRateCombo().setEnabled(hasTuner() && !getTuner().getTunerController().isLockedSampleRate()); getSampleRateCombo().setSelectedItem(hasTuner() ? getTunerController().getControlRsp().getSampleRateEnumeration() : null); + getAgcModeCombo().setEnabled(hasTuner()); + if(hasTuner()) + { + getAgcModeCombo().setSelectedItem(getTunerController().getControlRsp().getAgcMode()); + //Register to receive gain overload notifications + getTunerController().getControlRsp().setGainOverloadListener(this); + } + getGainSlider().setEnabled(hasTuner()); getGainValueLabel().setEnabled(hasTuner()); getGainSlider().setValue(hasTuner() ? getTunerController().getControlRsp().getGain() : 0); @@ -213,6 +230,7 @@ public class RspDxTunerEditor extends RspTunerEditor getConfiguration().setRfNotch(getRfNotchCheckBox().isSelected()); getConfiguration().setAntenna((RspDxAntenna) getAntennaCombo().getSelectedItem()); getConfiguration().setGain(getGainSlider().getValue()); + getConfiguration().setAgcMode((AgcMode)getAgcModeCombo().getSelectedItem()); saveConfiguration(); }