diff --git a/jsdrplay/src/main/java/com/github/dsheirer/sdrplay/DeviceDescriptor.java b/jsdrplay/src/main/java/com/github/dsheirer/sdrplay/DeviceDescriptor.java
deleted file mode 100644
index f87172cb9..000000000
--- a/jsdrplay/src/main/java/com/github/dsheirer/sdrplay/DeviceDescriptor.java
+++ /dev/null
@@ -1,111 +0,0 @@
-/*
- * *****************************************************************************
- * Copyright (C) 2014-2022 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 com.github.dsheirer.sdrplay;
-
-import com.github.dsheirer.sdrplay.device.Device;
-import com.github.dsheirer.sdrplay.device.DeviceType;
-import java.util.Collections;
-import java.util.List;
-
-/**
- * Descriptor that provides limited details for an RSP device and the available selection modes.
- */
-public class DeviceDescriptor
-{
- private Device mDevice;
- private List mDeviceSelectionModes;
-
- /**
- * Constructs a device descriptor
- * @param device to be described
- * @param deviceSelectionModes that are available for the device
- */
- public DeviceDescriptor(Device device, List deviceSelectionModes)
- {
- mDevice = device;
- mDeviceSelectionModes = deviceSelectionModes;
- }
-
- /**
- * Device that backs this descriptor.
- *
- * Note: package private. This method is not intended to be exposed to the library user.
- */
- Device getDevice()
- {
- return mDevice;
- }
-
- /**
- * Serial number for the device
- */
- public String getSerialNumber()
- {
- return mDevice.getSerialNumber();
- }
-
- /**
- * Indicates if this device descriptor's serial number matches the specified serial number
- * @param serialNumber to compare
- * @return true if there is a match
- */
- public boolean matches(String serialNumber)
- {
- return getSerialNumber() != null && getSerialNumber().equalsIgnoreCase(serialNumber);
- }
-
- /**
- * Type of RSP device
- */
- public DeviceType getDeviceType()
- {
- return mDevice.getDeviceType();
- }
-
- /**
- * List of selection modes available for this device. Most RSP devices will only be available for selection as
- * as single tuner. The RSPduo has several selection modes available, depending on how the device is currently
- * being used.
- */
- public List getDeviceSelectionModes()
- {
- return Collections.unmodifiableList(mDeviceSelectionModes);
- }
-
- /**
- * Indicates if the device supports the device selection mode
- * @param deviceSelectionMode
- * @return true if supported
- */
- public boolean supports(DeviceSelectionMode deviceSelectionMode)
- {
- return mDeviceSelectionModes.contains(deviceSelectionMode);
- }
-
- @Override
- public String toString()
- {
- StringBuilder sb = new StringBuilder();
- sb.append("Device: ").append(getDeviceType());
- sb.append(" Serial #:").append(getSerialNumber());
- sb.append(" Available Selection Modes ").append(getDeviceSelectionModes());
- return sb.toString();
- }
-}
diff --git a/jsdrplay/src/main/java/com/github/dsheirer/sdrplay/DeviceSelectionMode.java b/jsdrplay/src/main/java/com/github/dsheirer/sdrplay/DeviceSelectionMode.java
index 85745a903..cdfc76c67 100644
--- a/jsdrplay/src/main/java/com/github/dsheirer/sdrplay/DeviceSelectionMode.java
+++ b/jsdrplay/src/main/java/com/github/dsheirer/sdrplay/DeviceSelectionMode.java
@@ -1,6 +1,6 @@
/*
* *****************************************************************************
- * Copyright (C) 2014-2022 Dennis Sheirer
+ * 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
@@ -19,7 +19,6 @@
package com.github.dsheirer.sdrplay;
-
import com.github.dsheirer.sdrplay.device.RspDuoMode;
import com.github.dsheirer.sdrplay.device.TunerSelect;
import java.util.EnumSet;
@@ -32,15 +31,7 @@ public enum DeviceSelectionMode
//All RSP devices
SINGLE_TUNER_1("Single Tuner 1", RspDuoMode.SINGLE_TUNER, TunerSelect.TUNER_1),
SINGLE_TUNER_2("Single Tuner 2", RspDuoMode.SINGLE_TUNER, TunerSelect.TUNER_2),
-
- //RSPduo devices only
- //Note: dual independent tuners - the device is first claimed as master/tuner1, then a second api instance is
- //created and the second tuner is claimed as slave/tuner2
- DUAL_INDEPENDENT_TUNERS("Dual Independent Tuners", RspDuoMode.MASTER, TunerSelect.TUNER_1),
- DUAL_SYNCHRONIZED_TUNERS("Dual Synchronized Tuners", RspDuoMode.DUAL_TUNER, TunerSelect.TUNER_BOTH),
MASTER_TUNER_1("Master - Tuner 1", RspDuoMode.MASTER, TunerSelect.TUNER_1),
- MASTER_TUNER_2("Master - Tuner 2", RspDuoMode.MASTER, TunerSelect.TUNER_2),
- SLAVE_TUNER_1("Slave - Tuner 1", RspDuoMode.SLAVE, TunerSelect.TUNER_1),
SLAVE_TUNER_2("Slave - Tuner 2", RspDuoMode.SLAVE, TunerSelect.TUNER_2);
private String mDescription;
@@ -63,9 +54,8 @@ public enum DeviceSelectionMode
/**
* Set of all selection modes available for the RSPduo
*/
- public static final EnumSet ALL_DUO_SELECTION_MODES = EnumSet.range(DUAL_INDEPENDENT_TUNERS, SLAVE_TUNER_2);
- public static final EnumSet MASTER_MODES = EnumSet.of(MASTER_TUNER_1, MASTER_TUNER_2);
- public static final EnumSet SLAVE_MODES = EnumSet.of(SLAVE_TUNER_1, SLAVE_TUNER_2);
+ public static final EnumSet MASTER_MODES = EnumSet.of(MASTER_TUNER_1);
+ public static final EnumSet SLAVE_MODES = EnumSet.of(SLAVE_TUNER_2);
public static final EnumSet SINGLE_TUNER_MODES = EnumSet.of(SINGLE_TUNER_1, SINGLE_TUNER_2);
/**
diff --git a/jsdrplay/src/main/java/com/github/dsheirer/sdrplay/SDRplay.java b/jsdrplay/src/main/java/com/github/dsheirer/sdrplay/SDRplay.java
index ce3efa5f4..fd0548f4b 100644
--- a/jsdrplay/src/main/java/com/github/dsheirer/sdrplay/SDRplay.java
+++ b/jsdrplay/src/main/java/com/github/dsheirer/sdrplay/SDRplay.java
@@ -1,6 +1,6 @@
/*
* *****************************************************************************
- * Copyright (C) 2014-2022 Dennis Sheirer
+ * 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
@@ -27,30 +27,27 @@
import com.github.dsheirer.sdrplay.callback.IStreamListener;
import com.github.dsheirer.sdrplay.device.Device;
import com.github.dsheirer.sdrplay.device.DeviceFactory;
+import com.github.dsheirer.sdrplay.device.DeviceInfo;
import com.github.dsheirer.sdrplay.device.DeviceType;
-import com.github.dsheirer.sdrplay.device.RspDuoDevice;
-import com.github.dsheirer.sdrplay.device.RspDuoDualIndependentTunerDevice;
-import com.github.dsheirer.sdrplay.device.RspDuoMode;
+import com.github.dsheirer.sdrplay.device.IDeviceStruct;
import com.github.dsheirer.sdrplay.device.TunerSelect;
import com.github.dsheirer.sdrplay.error.DebugLevel;
import com.github.dsheirer.sdrplay.error.ErrorInformation;
import com.github.dsheirer.sdrplay.parameter.composite.CompositeParameters;
import com.github.dsheirer.sdrplay.parameter.composite.CompositeParametersFactory;
import com.github.dsheirer.sdrplay.util.Flag;
-import org.apache.commons.lang3.SystemUtils;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
import java.lang.foreign.MemoryAddress;
import java.lang.foreign.MemorySegment;
import java.lang.foreign.MemorySession;
import java.lang.foreign.ValueLayout;
import java.util.ArrayList;
import java.util.Arrays;
-import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
+import org.apache.commons.lang3.SystemUtils;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
/**
* SDRplay API wrapper.
@@ -90,19 +87,19 @@ public class SDRplay
private boolean mAvailable;
/**
- * RSP tuner devices (potentially) available for use
+ * Map of (reusable) callback functions for each device. Key value is the device handle memory address
*/
- private final List mDevices = new ArrayList<>();
+ private final Map mDeviceCallbackFunctionsMap = new HashMap<>();
/**
- * Map of (reusable) callback functions for each device.
+ * Detected version of the API installed on the local system.
*/
- private final Map mDeviceCallbackFunctionsMap = new HashMap<>();
+ private Version mVersion;
/**
- * Detected version of the API installed on the local system.
+ * Controls logging of library load status so that it only gets logged once. Set to false once initial logging complete
*/
- private Version mVersion;
+ private static boolean sLibraryLoadStatusLogging = true;
/**
* Constructs an instance of the SDRPLay API
@@ -114,28 +111,37 @@ public SDRplay()
if(mSdrplayLibraryLoaded)
{
Status openStatus = open();
- mLog.info("SDRPlay open() status: " + openStatus);
+ if(sLibraryLoadStatusLogging)
+ {
+ mLog.info("API library - open status: " + openStatus);
+ }
mAvailable = openStatus.success() && getVersion().isSupported();
}
else
{
- mLog.info("SDRPlay API library was not loaded");
+ if(sLibraryLoadStatusLogging)
+ {
+ mLog.info("API library was not loaded");
+ }
mAvailable = false;
}
if(isAvailable())
{
- mLog.info("SDRPlay API library v" + getVersion() + " - loaded");
- //TODO: this class should maintain a list of devices and it should register as a listener for the device
- //to detect when the device is disconnected, so that the device can be removed from the list, in addition
- //to providing that event to any other users of the device.
-
- loadDevices();
+ if(sLibraryLoadStatusLogging)
+ {
+ mLog.info("API library v" + getVersion() + " - loaded");
+ }
}
else
{
- mLog.info("SDRPlay API library is not available.");
+ if(sLibraryLoadStatusLogging)
+ {
+ mLog.info("API library is not available.");
+ }
}
+
+ sLibraryLoadStatusLogging = false;
}
/**
@@ -156,14 +162,16 @@ private boolean loadLibrary()
try
{
String libraryPath = getSDRplayLibraryPath();
- mLog.info("Loading SDRplay Library from default install path: " + libraryPath);
-// System.load(libraryPath);
+ if(sLibraryLoadStatusLogging)
+ {
+ mLog.info("Loading API Library from default install path: " + libraryPath);
+ }
System.loadLibrary(SDRPLAY_API_LIBRARY_NAME);
return true;
}
catch(Throwable t)
{
- mLog.error("Unable to load SDRplay library from default install path. Loading from java system library path", t);
+ mLog.error("Unable to load SDRplay API library from default install path. Loading from java system library path", t);
try
{
@@ -173,10 +181,14 @@ private boolean loadLibrary()
catch(Throwable t2)
{
String name = System.mapLibraryName(SDRPLAY_API_LIBRARY_NAME);
- mLog.warn("SDRPlay API library not found/installed on this system. Ensure the API is installed either " +
- "in the default install location or the install location is included in the " +
- "'java.library.path' JVM property contains path to the library file [" + name +
- "]. Current library path property contents: " + System.getProperty(JAVA_LIBRARY_PATH_KEY), t);
+
+ if(sLibraryLoadStatusLogging)
+ {
+ mLog.warn("SDRPlay API library not found/installed on this system. Ensure the API is installed either " +
+ "in the default install location or the install location is included in the " +
+ "'java.library.path' JVM property contains path to the library file [" + name +
+ "]. Current library path property contents: " + System.getProperty(JAVA_LIBRARY_PATH_KEY), t);
+ }
}
}
@@ -184,12 +196,26 @@ private boolean loadLibrary()
}
/**
- * Loads the list of devices from the API
+ * List of devices available via the API
+ * @return list of device infos.
+ * @throws SDRPlayException if there is an error
*/
- public void loadDevices()
+ public List getDeviceInfos() throws SDRPlayException
{
+ return DeviceFactory.parseDeviceInfos(getDeviceStructures());
+ }
+
+ /**
+ * List of device structures for devices available from the API
+ * @return list of device structures
+ * @throws SDRPlayException if there is an error
+ */
+ public List getDeviceStructures() throws SDRPlayException
+ {
+ List deviceStructs = new ArrayList<>();
+
//Get a version-correct array of DeviceT structures
- MemorySegment devicesArray = DeviceFactory.createForeignDeviceArray(getVersion(), getGlobalMemorySession());
+ MemorySegment devicesArray = DeviceFactory.createDeviceArray(getVersion(), getGlobalMemorySession());
MemorySegment deviceCount = getGlobalMemorySession().allocate(ValueLayout.JAVA_INT, 0);
@@ -199,43 +225,29 @@ public void loadDevices()
if(status.success())
{
int count = deviceCount.get(ValueLayout.JAVA_INT, 0);
- mDevices.clear();
- mDevices.addAll(DeviceFactory.parseDevices(getVersion(), SDRplay.this, devicesArray, count));
- mLog.info("Loaded Device Count: " + mDevices.size());
+ deviceStructs.addAll(DeviceFactory.parseDeviceStructs(getVersion(), devicesArray, count));
}
else
{
- mLog.error("Couldn't load devices. Status: " + status);
- }
- }
-
- /**
- * List of RSP tuner device descriptors available from this SDRplay instance.
- */
- public List getDevices()
- {
- List descriptors = new ArrayList<>();
-
- for(Device device : mDevices)
- {
- descriptors.add(getDeviceDescriptor(device));
+ mLog.error("Couldn't load RSP devices from API. Status: " + status);
}
- return Collections.unmodifiableList(descriptors);
+ return deviceStructs;
}
/**
* Find an RSP device descriptor by serial number.
* @param serialNumber to search for
* @return matching device descriptor, or null.
+ * @throws SDRPlayException if there is an error parsing the device structures
*/
- public DeviceDescriptor getDevice(String serialNumber)
+ public DeviceInfo getDevice(String serialNumber) throws SDRPlayException
{
- for(DeviceDescriptor deviceDescriptor: getDevices())
+ for(DeviceInfo deviceInfo: getDeviceInfos())
{
- if(deviceDescriptor.matches(serialNumber))
+ if(deviceInfo.getSerialNumber().equals(serialNumber))
{
- return deviceDescriptor;
+ return deviceInfo;
}
}
@@ -243,93 +255,68 @@ public DeviceDescriptor getDevice(String serialNumber)
}
/**
- * Creates a device descriptor for the specified device
- *
- * @param device to describe
- * @return descriptor
+ * Obtains the device that matches the device info argument.
+ * @param deviceInfo to match
+ * @return non-null device
+ * @throws SDRPlayException
*/
- private DeviceDescriptor getDeviceDescriptor(Device device)
+ public Device getDevice(DeviceInfo deviceInfo) throws SDRPlayException
{
- List deviceSelectionModes = new ArrayList<>();
+ Device device = null;
- if(device.getDeviceType().equals(DeviceType.RSPduo) && device instanceof RspDuoDevice rsp)
+ if(isAvailable())
{
- RspDuoMode mode = rsp.getRspDuoMode();
- TunerSelect tunerSelect = rsp.getTunerSelect();
+ List deviceStructs = getDeviceStructures();
- switch(mode)
+ for(IDeviceStruct deviceStruct: deviceStructs)
{
- case SLAVE -> {
- if(tunerSelect.equals(TunerSelect.TUNER_1))
- {
- deviceSelectionModes.add(DeviceSelectionMode.SLAVE_TUNER_1);
- }
- else if(tunerSelect.equals(TunerSelect.TUNER_2))
- {
- deviceSelectionModes.add(DeviceSelectionMode.SLAVE_TUNER_2);
- }
- }
- case MASTER -> {
- if(tunerSelect.equals(TunerSelect.TUNER_1))
- {
- deviceSelectionModes.add(DeviceSelectionMode.MASTER_TUNER_1);
- }
- else if(tunerSelect.equals(TunerSelect.TUNER_2))
- {
- deviceSelectionModes.add(DeviceSelectionMode.MASTER_TUNER_2);
- }
+ if(deviceInfo.matches(deviceStruct))
+ {
+ device = DeviceFactory.createDevice(this, deviceStruct);
+ break;
}
- case UNKNOWN -> deviceSelectionModes.addAll(Arrays.stream(DeviceSelectionMode.values()).toList());
}
-
}
- else
+
+ if(device == null)
{
- deviceSelectionModes.add(DeviceSelectionMode.SINGLE_TUNER_1);
+ throw new SDRPlayException("Unable to find RSP device");
}
- return new DeviceDescriptor(device, deviceSelectionModes);
+ return device;
}
+
/**
* Finds the first device that matches the specified device type.
*
* @param deviceType to find
* @return the specified device type or null.
*/
- public DeviceDescriptor getDevice(DeviceType deviceType)
+ public DeviceInfo getDeviceInfo(DeviceType deviceType) throws SDRPlayException
{
- for(DeviceDescriptor deviceDescriptor : getDevices())
+ for(DeviceInfo deviceInfo : getDeviceInfos())
{
- if(deviceDescriptor.getDeviceType() == deviceType)
+ if(deviceInfo.getDeviceType() == deviceType)
{
- return deviceDescriptor;
+ return deviceInfo;
}
}
return null;
}
- //TODO: can we segment off the API calls that should only used by/from the device instance, so that a user of
- //TODO: this API doesn't have access to those methods? Thinking of using a private final inner class that can be
- //TODO: passed to the device constructor.
-
/**
* Selects the device for exclusive use. This method is invoked by the device instance.
*
- * @param device to select
* @param memorySegment of the device in foreign memory
* @throws SDRPlayException if the device argument was not created by this API instance or if unable to lock or
* unlock the device API for exclusive use, or if unable to select the device.
*/
- public void select(Device device, MemorySegment memorySegment) throws SDRPlayException
+ public void select(MemorySegment memorySegment) throws SDRPlayException
{
- checkValidDevice(device);
-
lockDeviceApi();
-
Status selectStatus = Status.fromValue(sdrplay_api_h.sdrplay_api_SelectDevice(memorySegment));
-
unlockDeviceApi();
if(selectStatus.fail())
@@ -338,73 +325,15 @@ public void select(Device device, MemorySegment memorySegment) throws SDRPlayExc
}
}
- /**
- * Configures the device for the specified selection mode and selects it for use.
- *
- * @param deviceDescriptor to select
- * @param deviceSelectionMode to configure
- * @throws SDRPlayException if the device cannot be selected for the specified selection mode
- */
- public Device select(DeviceDescriptor deviceDescriptor, DeviceSelectionMode deviceSelectionMode) throws SDRPlayException
- {
- Device device = deviceDescriptor.getDevice();
-
- if(deviceDescriptor.supports(deviceSelectionMode))
- {
- if(device instanceof RspDuoDevice duo)
- {
- mLog.info("RSPduo device - setting duo mode and tuner select: " + deviceSelectionMode.getTunerSelect());
- duo.setRspDuoMode(deviceSelectionMode.getRspDuoMode());
- duo.setTunerSelect(deviceSelectionMode.getTunerSelect());
-
- //In master mode, we have to set the sample rate here, before we select the device
- if(deviceSelectionMode.isMasterMode())
- {
- duo.setRspDuoSampleFrequency(8_000_000);
- }
-
- if(deviceSelectionMode.equals(DeviceSelectionMode.DUAL_INDEPENDENT_TUNERS))
- {
- //Select the first device as Master/Tuner 1.
- device.select();
-
- //Create a second API instance and find the matching device by serial number
- SDRplay api2 = new SDRplay();
- DeviceDescriptor slaveDeviceDescriptor = api2.getDevice(deviceDescriptor.getSerialNumber());
-
- if(slaveDeviceDescriptor != null && slaveDeviceDescriptor.getDevice() instanceof RspDuoDevice slaveDevice)
- {
- slaveDevice.setRspDuoMode(RspDuoMode.SLAVE);
- slaveDevice.setTunerSelect(TunerSelect.TUNER_2);
- slaveDevice.select();
- return new RspDuoDualIndependentTunerDevice(duo, slaveDevice, slaveDeviceDescriptor);
- }
-
- //Release the first instance and throw an exception to indicate we couldn't configure as requested
- device.release();
- throw new SDRPlayException("Unable to acquire second device instance for RSPduo to configure as " +
- "dual-independent tuners");
- }
- }
-
- device.select();
- return device;
- }
-
- throw new SDRPlayException("Selection mode [" + deviceSelectionMode + "] is not supported by " + deviceDescriptor);
- }
-
/**
* Releases the device from exclusive use. This method is invoked by the device instance.
*
- * @param device to release
* @param memorySegment of the device in foreign memory
* @throws SDRPlayException if the device argument was not created by this API instance or if unable to release
* the device
*/
- public void release(Device device, MemorySegment memorySegment) throws SDRPlayException
+ public void release(MemorySegment memorySegment) throws SDRPlayException
{
- checkValidDevice(device);
Status status = Status.fromValue(sdrplay_api_h.sdrplay_api_ReleaseDevice(memorySegment));
if(status.fail())
@@ -417,14 +346,12 @@ public void release(Device device, MemorySegment memorySegment) throws SDRPlayEx
* Retrieves the initial composite parameters for each device. This should only be invoked once, on
* startup, for each device. Changes made to the device parameters should invoke update() method to apply changes.
*
- * @param device to load parameters
+ * @param deviceType to load parameters
* @param deviceHandle to device
* @return constructed device composite paramaters
*/
- public CompositeParameters getCompositeParameters(Device device, MemoryAddress deviceHandle) throws SDRPlayException
+ public CompositeParameters getCompositeParameters(DeviceType deviceType, MemoryAddress deviceHandle) throws SDRPlayException
{
- checkValidDevice(device);
-
//Allocate a pointer that the api will fill with the memory address of the device parameters in memory.
MemorySegment pointer = getGlobalMemorySession().allocate(ValueLayout.ADDRESS);
Status status = Status.fromValue(sdrplay_api_h.sdrplay_api_GetDeviceParams(deviceHandle, pointer));
@@ -436,7 +363,7 @@ public CompositeParameters getCompositeParameters(Device device, MemoryAddress d
//The structure's memory is already allocated ... wrap a memory segment around it
MemorySegment memorySegment = sdrplay_api_DeviceT.ofAddress(memoryAddress, mGlobalMemorySession);
- return CompositeParametersFactory.create(device.getDeviceType(), memorySegment, mGlobalMemorySession);
+ return CompositeParametersFactory.create(deviceType, memorySegment, mGlobalMemorySession);
}
else
{
@@ -447,15 +374,12 @@ public CompositeParameters getCompositeParameters(Device device, MemoryAddress d
/**
* Initializes a device for use.
*
- * @param device to initialize
* @param deviceHandle to the device
* @param callbackFunctions to receive stream data from A and (optionally) B channels and events.
* @throws SDRPlayException if the device is not selected of if unable to init the device
*/
- private void init(Device device, MemoryAddress deviceHandle, MemorySegment callbackFunctions) throws SDRPlayException
+ private void init(MemoryAddress deviceHandle, MemorySegment callbackFunctions) throws SDRPlayException
{
- checkValidDevice(device);
-
//Since we don't need/use the callback context ... setup as a pointer to the callback functions
MemorySegment contextPointer = getGlobalMemorySession().allocate(ValueLayout.ADDRESS, callbackFunctions);
Status status = Status.fromValue(sdrplay_api_h.sdrplay_api_Init(deviceHandle, callbackFunctions, contextPointer));
@@ -478,13 +402,13 @@ private void init(Device device, MemoryAddress deviceHandle, MemorySegment callb
public void initA(Device device, MemoryAddress deviceHandle, IDeviceEventListener eventListener,
IStreamListener streamListener) throws SDRPlayException
{
- CallbackFunctions callbackFunctions = mDeviceCallbackFunctionsMap.get(device);
+ CallbackFunctions callbackFunctions = mDeviceCallbackFunctionsMap.get(deviceHandle);
if(callbackFunctions == null)
{
callbackFunctions = new CallbackFunctions(getGlobalMemorySession(), eventListener, streamListener,
device.getStreamCallbackListener());
- mDeviceCallbackFunctionsMap.put(device, callbackFunctions);
+ mDeviceCallbackFunctionsMap.put(deviceHandle, callbackFunctions);
}
else
{
@@ -492,7 +416,7 @@ public void initA(Device device, MemoryAddress deviceHandle, IDeviceEventListene
callbackFunctions.setStreamAListener(streamListener);
}
- init(device, deviceHandle, callbackFunctions.getCallbackFunctionsMemorySegment());
+ init(deviceHandle, callbackFunctions.getCallbackFunctionsMemorySegment());
}
/**
@@ -507,13 +431,13 @@ public void initA(Device device, MemoryAddress deviceHandle, IDeviceEventListene
public void initB(Device device, MemoryAddress deviceHandle, IDeviceEventListener eventListener,
IStreamListener streamListener) throws SDRPlayException
{
- CallbackFunctions callbackFunctions = mDeviceCallbackFunctionsMap.get(device);
+ CallbackFunctions callbackFunctions = mDeviceCallbackFunctionsMap.get(deviceHandle);
if(callbackFunctions == null)
{
callbackFunctions = new CallbackFunctions(getGlobalMemorySession(), eventListener, streamListener, streamListener,
device.getStreamCallbackListener());
- mDeviceCallbackFunctionsMap.put(device, callbackFunctions);
+ mDeviceCallbackFunctionsMap.put(deviceHandle, callbackFunctions);
}
else
{
@@ -521,19 +445,17 @@ public void initB(Device device, MemoryAddress deviceHandle, IDeviceEventListene
callbackFunctions.setStreamAListener(streamListener);
}
- init(device, deviceHandle, callbackFunctions.getCallbackFunctionsMemorySegment());
+ init(deviceHandle, callbackFunctions.getCallbackFunctionsMemorySegment());
}
/**
* Un-Initializes a device from use.
*
- * @param device to un-initialize
* @param deviceHandle to the device
* @throws SDRPlayException if error during uninit or if device is not selected
*/
- public void uninit(Device device, MemoryAddress deviceHandle) throws SDRPlayException
+ public void uninit(MemoryAddress deviceHandle) throws SDRPlayException
{
- checkValidDevice(device);
Status status = Status.fromValue(sdrplay_api_h.sdrplay_api_Uninit(deviceHandle));
if(status.fail() && status != Status.NOT_INITIALIZED)
@@ -558,8 +480,6 @@ public void uninit(Device device, MemoryAddress deviceHandle) throws SDRPlayExce
public synchronized void update(Device device, MemoryAddress deviceHandle, TunerSelect tunerSelect,
UpdateReason... updateReasons) throws SDRPlayException
{
- checkValidDevice(device);
-
int reasons = UpdateReason.getReasons(updateReasons);
int extendedReasons = UpdateReason.getExtendedReasons(updateReasons);
@@ -588,15 +508,12 @@ private ErrorInformation getLastError(MemorySegment deviceSegment)
/**
* Sets the debug level logging for the specified device
*
- * @param device to set debug level on
* @param deviceHandle for the device
* @param debugLevel to set
* @throws SDRPlayException if the device is not selected or if unable to set/change the debug level.
*/
- public void setDebugLevel(Device device, MemoryAddress deviceHandle, DebugLevel debugLevel) throws SDRPlayException
+ public void setDebugLevel(MemoryAddress deviceHandle, DebugLevel debugLevel) throws SDRPlayException
{
- checkValidDevice(device);
-
Status status = Status.UNKNOWN;
if(getVersion() == Version.V3_07)
@@ -617,19 +534,6 @@ else if(getVersion().gte(Version.V3_08))
}
}
- /**
- * Checks that the device was constructed by this API instance and continues to be a usable device.
- *
- * @param device to check
- */
- private void checkValidDevice(Device device) throws SDRPlayException
- {
- if(!mDevices.contains(device))
- {
- throw new SDRPlayException("Unrecognized device argument -- must be device created by this API instance");
- }
- }
-
/**
* Indicates if the SDRplay API is available and that the API library has been located and loaded for use and
* it the API version is supported by this jsdrplay library.
@@ -649,6 +553,11 @@ private Status open()
/**
* Closes the API service. MUST be invoked before shutdown, after all SDRPlay API operations are completed.
+ *
+ * Note: when using multiple instances of this class, only invoke close() on a single instance. With linux API
+ * version 3.07, if you invoked close() on one instance, then all of the other instances become unusable for
+ * performing device operations (e.g. release(), etc). This may be an artifact of the way that the Java
+ * Foreign Function support is implemented, but not sure. dls 1-Jan-2023
*/
public Status close()
{
@@ -781,9 +690,16 @@ public static void main(String[] args)
Status status = sdrplay.open();
mLog.info("Open Status: " + status);
- for(DeviceDescriptor deviceDescriptor: sdrplay.getDevices())
+ try
+ {
+ for(DeviceInfo deviceInfo: sdrplay.getDeviceInfos())
+ {
+ mLog.info("Found: " + deviceInfo);
+ }
+ }
+ catch(SDRPlayException se)
{
- mLog.info("Found: " + deviceDescriptor);
+ mLog.info("Error", se);
}
Status closeStatus = sdrplay.close();
diff --git a/jsdrplay/src/main/java/com/github/dsheirer/sdrplay/device/Device.java b/jsdrplay/src/main/java/com/github/dsheirer/sdrplay/device/Device.java
index e725037d9..dfd95f7f8 100644
--- a/jsdrplay/src/main/java/com/github/dsheirer/sdrplay/device/Device.java
+++ b/jsdrplay/src/main/java/com/github/dsheirer/sdrplay/device/Device.java
@@ -1,6 +1,6 @@
/*
* *****************************************************************************
- * Copyright (C) 2014-2022 Dennis Sheirer
+ * 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
@@ -29,6 +29,7 @@
import com.github.dsheirer.sdrplay.callback.IStreamCallbackListener;
import com.github.dsheirer.sdrplay.callback.IStreamListener;
import com.github.dsheirer.sdrplay.callback.StreamCallbackParameters;
+import com.github.dsheirer.sdrplay.error.DebugLevel;
import com.github.dsheirer.sdrplay.parameter.composite.CompositeParameters;
import com.github.dsheirer.sdrplay.parameter.tuner.IfMode;
import com.github.dsheirer.sdrplay.parameter.tuner.LoMode;
@@ -50,7 +51,7 @@ public abstract class Device, R extends RspTu
{
private static final Logger mLog = LoggerFactory.getLogger(Device.class);
- private final SDRplay mSDRplay;
+ private SDRplay mSDRplay;
private final UpdateRequestManager mUpdateRequestManager = new UpdateRequestManager();
private final IDeviceStruct mDeviceStruct;
protected boolean mSelected = false;
@@ -100,7 +101,23 @@ private void loadDeviceParameters() throws SDRPlayException
{
if(selected())
{
- mCompositeParameters = (T)getAPI().getCompositeParameters(Device.this, getDeviceHandle());
+ mCompositeParameters = (T)getAPI().getCompositeParameters(getDeviceType(), getDeviceHandle());
+ }
+ }
+
+ /**
+ * Sets the debug logging level for this device.
+ * @param debugLevel to set
+ */
+ public void setDebugLevel(DebugLevel debugLevel)
+ {
+ try
+ {
+ mSDRplay.setDebugLevel(getDeviceHandle(), debugLevel);
+ }
+ catch(SDRPlayException se)
+ {
+ mLog.info("Unable to set debug level [" + debugLevel + "] for device - not selected", se);
}
}
@@ -112,7 +129,7 @@ public void select() throws SDRPlayException
{
if(!selected())
{
- getAPI().select(Device.this, getDeviceMemorySegment());
+ getAPI().select(getDeviceMemorySegment());
mSelected = true;
loadDeviceParameters();
}
@@ -142,7 +159,7 @@ public void release() throws SDRPlayException
if(selected())
{
mSelected = false;
- getAPI().release(Device.this, getDeviceMemorySegment());
+ getAPI().release(getDeviceMemorySegment());
}
}
@@ -220,7 +237,7 @@ public void uninitialize() throws SDRPlayException
{
if(isInitialized())
{
- getAPI().uninit(this, getDeviceHandle());
+ getAPI().uninit(getDeviceHandle());
mInitialized = false;
}
else
@@ -314,7 +331,8 @@ private void submitUpdate(TunerSelect tunerSelect, UpdateReason ... updateReason
*/
public void acknowledgePowerOverload(TunerSelect tunerSelect) throws SDRPlayException
{
- mLog.info("Acknowledging power overload message for tuner [" + tunerSelect + "]");
+// mLog.info("Acknowledging power overload message for tuner [" + tunerSelect + "]");
+
//There's a bug (feature?) in the API ... when you un-initialize the device, it causes a power overload event
// and if you acknowledge it, you get an error that the device is not initialized.
if(isInitialized())
diff --git a/jsdrplay/src/main/java/com/github/dsheirer/sdrplay/device/DeviceFactory.java b/jsdrplay/src/main/java/com/github/dsheirer/sdrplay/device/DeviceFactory.java
index 9c70d1a70..1d3cc4cf8 100644
--- a/jsdrplay/src/main/java/com/github/dsheirer/sdrplay/device/DeviceFactory.java
+++ b/jsdrplay/src/main/java/com/github/dsheirer/sdrplay/device/DeviceFactory.java
@@ -1,6 +1,6 @@
/*
* *****************************************************************************
- * Copyright (C) 2014-2022 Dennis Sheirer
+ * 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
@@ -19,28 +19,32 @@
package com.github.dsheirer.sdrplay.device;
+import com.github.dsheirer.sdrplay.SDRPlayException;
import com.github.dsheirer.sdrplay.SDRplay;
import com.github.dsheirer.sdrplay.Version;
import com.github.dsheirer.sdrplay.api.v3_07.sdrplay_api_DeviceT;
import com.github.dsheirer.sdrplay.api.v3_07.sdrplay_api_h;
-
import java.lang.foreign.MemorySegment;
import java.lang.foreign.SegmentAllocator;
import java.util.ArrayList;
import java.util.List;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
/**
- * Factory methods for creating new Device instances
+ * Factory methods for creating new RSP Device instances
*/
public class DeviceFactory
{
+ private static final Logger mLog = LoggerFactory.getLogger(DeviceFactory.class);
+
/**
* Creates a foreign memory segment for a DeviceT array, appropriate for the specified version.
* @param version value
* @param segmentAllocator to allocate the foreign memory
* @return devices array
*/
- public static MemorySegment createForeignDeviceArray(Version version, SegmentAllocator segmentAllocator)
+ public static MemorySegment createDeviceArray(Version version, SegmentAllocator segmentAllocator)
{
if(version.gte(Version.V3_08))
{
@@ -55,37 +59,53 @@ else if(version == Version.V3_07)
}
/**
- * Parses individual device memory segments from the devices array and creates Device instances for each
- * RSP model detected.
- * @param version of the API being used
- * @param sdrplay instance
- * @param devicesArray foreign memory segment
- * @param count of devices contained in the foreign memory segment devices array
- * @return zero or more RSP devices
+ * Parses device information from a list of device structures
+ * @param deviceStructs representing devices to parse
+ * @return a list of device infos
+ */
+ public static List parseDeviceInfos(List deviceStructs)
+ {
+ List deviceInfos = new ArrayList<>();
+
+ for(IDeviceStruct deviceStruct: deviceStructs)
+ {
+ deviceInfos.add(new DeviceInfo(deviceStruct));
+ }
+
+ return deviceInfos;
+ }
+
+ /**
+ * Parses device information from a memory segment containing an array of device structures.
+ * @param version of the API
+ * @param devicesArray memory segment
+ * @param count of device structures in the devicesArray.
+ * @return a list of device infos
+ * @throws exception if version is unrecognized or unsupported
*/
- public static List parseDevices(Version version, SDRplay sdrplay, MemorySegment devicesArray, int count)
+ public static List parseDeviceStructs(Version version, MemorySegment devicesArray, int count) throws SDRPlayException
{
- List devices = new ArrayList<>();
+ List deviceStructs = new ArrayList<>();
if(version.gte(Version.V3_08))
{
devicesArray.elements(com.github.dsheirer.sdrplay.api.v3_08.sdrplay_api_DeviceT.$LAYOUT())
.limit(count).forEach(memorySegment ->
- devices.add(DeviceFactory.createDevice(sdrplay, memorySegment)));
+ deviceStructs.add(DeviceFactory.createDeviceStruct(version, memorySegment)));
}
else if(version == Version.V3_07)
{
devicesArray.elements(sdrplay_api_DeviceT.$LAYOUT()).limit(count).forEach(memorySegment ->
{
- devices.add(DeviceFactory.createDevice(sdrplay, memorySegment));
+ deviceStructs.add(DeviceFactory.createDeviceStruct(version, memorySegment));
});
}
else
{
- throw new IllegalArgumentException("Unrecognized version: " + version);
+ throw new SDRPlayException("Unrecognized version: " + version);
}
- return devices;
+ return deviceStructs;
}
/**
@@ -94,10 +114,8 @@ else if(version == Version.V3_07)
* @param deviceMemorySegment instance for the device
* @return correctly typed device
*/
- public static Device createDevice(SDRplay sdrPlay, MemorySegment deviceMemorySegment)
+ public static Device createDevice(SDRplay sdrPlay, IDeviceStruct deviceStruct)
{
- IDeviceStruct deviceStruct = createDeviceStruct(sdrPlay.getVersion(), deviceMemorySegment);
-
switch(deviceStruct.getDeviceType())
{
case RSP1 -> {
diff --git a/jsdrplay/src/main/java/com/github/dsheirer/sdrplay/device/DeviceInfo.java b/jsdrplay/src/main/java/com/github/dsheirer/sdrplay/device/DeviceInfo.java
new file mode 100644
index 000000000..977533c35
--- /dev/null
+++ b/jsdrplay/src/main/java/com/github/dsheirer/sdrplay/device/DeviceInfo.java
@@ -0,0 +1,140 @@
+/*
+ * *****************************************************************************
+ * 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 com.github.dsheirer.sdrplay.device;
+
+import com.github.dsheirer.sdrplay.DeviceSelectionMode;
+import java.util.Objects;
+import org.apache.commons.lang3.Validate;
+
+/**
+ * RSP device information to support device selection.
+ */
+public class DeviceInfo
+{
+ private DeviceSelectionMode mDeviceSelectionMode = DeviceSelectionMode.SINGLE_TUNER_1;
+ private DeviceType mDeviceType;
+ private String mSerialNumber;
+
+ /**
+ * Constructs an instance
+ * @param deviceType of the RSP device
+ * @param serialNumber for the device
+ */
+ public DeviceInfo(DeviceType deviceType, String serialNumber)
+ {
+ Validate.notNull(deviceType, "Device type cannot be null");
+ Validate.notNull(serialNumber, "Device serial number cannot be null");
+
+ mDeviceType = deviceType;
+ mSerialNumber = serialNumber;
+ }
+
+ /**
+ * Alternate constructor where we get the parameters from a device structure.
+ * @param deviceStruct containing device type and serial number values.
+ */
+ public DeviceInfo(IDeviceStruct deviceStruct)
+ {
+ this(deviceStruct.getDeviceType(), deviceStruct.getSerialNumber());
+ }
+
+ /**
+ * Device type for this RSP device
+ * @return type
+ */
+ public DeviceType getDeviceType()
+ {
+ return mDeviceType;
+ }
+
+ /**
+ * Serial number for this RSP device
+ * @return serial number
+ */
+ public String getSerialNumber()
+ {
+ return mSerialNumber;
+ }
+
+ /**
+ * Device selection mode for this RSP device
+ * @return device selection mode where single tuner 1 is default
+ */
+ public DeviceSelectionMode getDeviceSelectionMode()
+ {
+ return mDeviceSelectionMode;
+ }
+
+ /**
+ * Sets the device selection mode. This should be left as default of single tuner 1 unless this device is an RSPduo.
+ * @param deviceSelectionMode to use for this device.
+ */
+ public void setDeviceSelectionMode(DeviceSelectionMode deviceSelectionMode)
+ {
+ Validate.notNull(deviceSelectionMode, "Device selection mode cannot be null");
+ mDeviceSelectionMode = deviceSelectionMode;
+ }
+
+ /**
+ * Clones this instance
+ * @return deep copy.
+ */
+ public DeviceInfo clone()
+ {
+ return new DeviceInfo(mDeviceType, mSerialNumber);
+ }
+
+ /**
+ * Indicates if this device type and serial number matches the details of the device structure.
+ * @param deviceStruct to compare
+ * @return true if the device type and serial number match.
+ */
+ public boolean matches(IDeviceStruct deviceStruct)
+ {
+ return deviceStruct != null && getDeviceType().equals(deviceStruct.getDeviceType()) && getSerialNumber().equals(deviceStruct.getSerialNumber());
+ }
+
+ @Override
+ public String toString()
+ {
+ return "Device: " + getDeviceType() + " Serial Number: " + getSerialNumber() + " Selection Mode: " + getDeviceSelectionMode();
+ }
+
+ @Override
+ public boolean equals(Object o)
+ {
+ if(this == o)
+ {
+ return true;
+ }
+ if(o == null || getClass() != o.getClass())
+ {
+ return false;
+ }
+ DeviceInfo that = (DeviceInfo) o;
+ return mDeviceSelectionMode == that.mDeviceSelectionMode && mDeviceType == that.mDeviceType && mSerialNumber.equals(that.mSerialNumber);
+ }
+
+ @Override
+ public int hashCode()
+ {
+ return Objects.hash(mDeviceSelectionMode, mDeviceType, mSerialNumber);
+ }
+}
diff --git a/jsdrplay/src/main/java/com/github/dsheirer/sdrplay/device/RspDuoDualIndependentTunerDevice.java b/jsdrplay/src/main/java/com/github/dsheirer/sdrplay/device/RspDuoDualIndependentTunerDevice.java
deleted file mode 100644
index b93344f4d..000000000
--- a/jsdrplay/src/main/java/com/github/dsheirer/sdrplay/device/RspDuoDualIndependentTunerDevice.java
+++ /dev/null
@@ -1,259 +0,0 @@
-/*
- * *****************************************************************************
- * Copyright (C) 2014-2022 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 com.github.dsheirer.sdrplay.device;
-
-import com.github.dsheirer.sdrplay.DeviceDescriptor;
-import com.github.dsheirer.sdrplay.SDRPlayException;
-import com.github.dsheirer.sdrplay.callback.IDeviceEventListener;
-import com.github.dsheirer.sdrplay.callback.IStreamListener;
-import com.github.dsheirer.sdrplay.parameter.composite.RspDuoCompositeParameters;
-import com.github.dsheirer.sdrplay.parameter.tuner.Bandwidth;
-import com.github.dsheirer.sdrplay.util.Retry;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-/**
- * Composite device encapsulating two RSPduo device instances, one configured as master for tuner 1 and the other
- * configured as slave for tuner 2.
- *
- * In this configuration, both tuners are initialized and de-initialized at the same time to ensure that the master
- * device is initialized first so that tuner 2 can be accessed. Likewise, it ensures that the slave device is
- * de-initialized first, so that tuner 1 can be de-initialized.
- */
-public class RspDuoDualIndependentTunerDevice extends Device
-{
- private Logger mLog = LoggerFactory.getLogger(RspDuoDualIndependentTunerDevice.class);
- private RspDuoDevice mMasterDevice;
- private RspDuoDevice mSlaveDevice;
- private DeviceDescriptor mSlaveDeviceDescriptor;
-
- /**
- * Constructs a composite SDRPlay RSPduo device with support for dual independent tuners.
- */
- public RspDuoDualIndependentTunerDevice(RspDuoDevice masterDevice, RspDuoDevice slaveDevice, DeviceDescriptor slaveDeviceDescriptor)
- {
- super(masterDevice.getAPI(), masterDevice.getDeviceStruct());
-
- mMasterDevice = masterDevice;
- mSlaveDevice = slaveDevice;
- mSlaveDeviceDescriptor = slaveDeviceDescriptor;
-
- if(!mMasterDevice.isSelected() || !mSlaveDevice.isSelected())
- {
- throw new IllegalStateException("Master and Slave devices must both be selected prior to constructing " +
- "composite device");
- }
-
- mSelected = true;
- }
-
- /**
- * Device descriptor for the slave tuner 2 device. Note: this is a convenience accessor since the second device
- * descriptor isn't accessible from the API select call.
- * @return slave tuner 2 device descriptor
- */
- public DeviceDescriptor getSlaveDeviceDescriptor()
- {
- return mSlaveDeviceDescriptor;
- }
-
- /**
- * Tuner 1 configured as master
- * @return tuner 1
- * @throws SDRPlayException if there is an issue accessing the tuner
- */
- @Override
- public RspDuoTuner1 getTuner() throws SDRPlayException
- {
- return (RspDuoTuner1) mMasterDevice.getTuner();
- }
-
- /**
- * Tuner 2 configured as the slave device
- * @return tuner 2
- * @throws SDRPlayException if there is an issue accessing the tuner
- */
- public RspDuoTuner2 getTuner2() throws SDRPlayException
- {
- return (RspDuoTuner2) mSlaveDevice.getTuner();
- }
-
- /**
- * Overrides the parent select() method to be a non-operation. Both master and slave devices should already be
- * selected before they are joined via this composite device.
- * @throws SDRPlayException always.
- */
- @Override
- public void select() throws SDRPlayException
- {
- throw new SDRPlayException("Device has already been selected");
- }
-
- /**
- * Indicates if the master device is initialized
- * @return true if initialized
- */
- private boolean isMasterInitialized()
- {
- return mMasterDevice.isInitialized();
- }
-
- /**
- * Indicates if the slave device is initialized
- * @return true if initialized
- */
- private boolean isSlaveInitialized()
- {
- return mSlaveDevice.isInitialized();
- }
-
- /**
- * Un-initializes both the master and slave devices
- * @throws SDRPlayException if there is an error
- */
- @Override
- public void uninitialize() throws SDRPlayException
- {
- throw new SDRPlayException("Use either uninitializeMaster() or uninitializeSlave() to stop sample stream");
- }
-
- /**
- * Uninitializes the master device and stops the sample stream
- * @throws SDRPlayException if there is an error.
- */
- public void uninitializeMaster() throws SDRPlayException
- {
- mMasterDevice.uninitialize();
- }
-
- /**
- * Uninitializes the slave device and stops the sample stream
- * @throws SDRPlayException if there is an error.
- */
- public void uninitializeSlave() throws SDRPlayException
- {
- mSlaveDevice.uninitialize();
- }
-
- /**
- * Overrides default behavior and throws an exception. Use initMaster() or initSlave() instead.
- * @param eventListener to receive device event notifications
- * @param streamListener to receive samples from stream. Stream is from either Tuner 1 or Tuner 2 when
- * the device is selected for single-tuner mode.
- * @throws SDRPlayException
- */
- @Override
- public void initStreamA(IDeviceEventListener eventListener, IStreamListener streamListener) throws SDRPlayException
- {
- throw new SDRPlayException("Use either initMaster() or initSlave() to start sample stream");
- }
-
- /**
- * Initializes the master device for use and starts providing raw signal samples to the stream listener and
- * device events to the event listener.
- *
- * @param eventListener to receive device event notifications
- * @param streamListeners two stream listeners to receive samples from the tuner where the first listener
- * will receive samples from tuner 1 and the second listener will receive samples from tuner 2.
- *
- * @throws SDRPlayException if there is an error
- */
- public void initMaster(IDeviceEventListener eventListener, IStreamListener streamListener) throws SDRPlayException
- {
- if(!isSelected())
- {
- throw new SDRPlayException("Device must be selected before it can be initialized");
- }
-
- if(isInitialized())
- {
- throw new SDRPlayException("Device has already been initialized with listeners");
- }
-
- mMasterDevice.initStreamA(eventListener, streamListener);
- mInitialized = true;
- }
-
- @Override
- public void release() throws SDRPlayException
- {
- if(selected())
- {
- mSelected = false;
- mSlaveDevice.release();
- Retry.quietly(5, 20, () -> mMasterDevice.release());
- }
- }
-
- /**
- * Sets the tuner bandwidth and final decimation for both the master and the slave devices.
- *
- * Note: this does not set the initial sample rate which can only be 6 or 8 MHz and which must also be set on the
- * master device before the device is selected.
- *
- * @param sampleRate to apply only the bandwidth and final decimation values
- * @throws SDRPlayException if there is an error
- */
- public void setSampleRate(double sampleRate) throws SDRPlayException
- {
- mMasterDevice.setRspDuoSampleFrequency(sampleRate);
- }
-
- /**
- * Sets the bandwidth on both the master and slave devices.
- * @param bandwidth to use
- * @throws SDRPlayException if there is an error
- */
- public void setBandwidth(Bandwidth bandwidth) throws SDRPlayException
- {
- mMasterDevice.getTuner().setBandwidth(bandwidth);
- mSlaveDevice.getTuner().setBandwidth(bandwidth);
- }
-
- /**
- * Sets the decimation value to use for both master and slave devices.
- * @param decimate value where X1 is no decimation and all others are decimation enabled values.
- * @throws SDRPlayException
- */
- public void setDecimation(Decimate decimate) throws SDRPlayException
- {
- mMasterDevice.setDecimation(decimate);
- mSlaveDevice.setDecimation(decimate);
- }
-
- /**
- * Acknowledge tuner power overload events
- * @param tunerSelect identifying which tuner(s)
- * @throws SDRPlayException on error
- */
- public void acknowledgePowerOverload(TunerSelect tunerSelect) throws SDRPlayException
- {
- switch(tunerSelect)
- {
- case TUNER_1 -> mMasterDevice.acknowledgePowerOverload(tunerSelect);
- case TUNER_2 -> mSlaveDevice.acknowledgePowerOverload(tunerSelect);
- case TUNER_BOTH -> {
- mMasterDevice.acknowledgePowerOverload(TunerSelect.TUNER_1);
- mSlaveDevice.acknowledgePowerOverload(TunerSelect.TUNER_2);
- }
- case NEITHER -> {}
- }
- }
-}
diff --git a/jsdrplay/src/test/java/io/github/dsherer/sdrplay/test/RspDeviceTest.java b/jsdrplay/src/test/java/io/github/dsherer/sdrplay/test/RspDeviceTest.java
index 35bc71e7d..e2309ca79 100644
--- a/jsdrplay/src/test/java/io/github/dsherer/sdrplay/test/RspDeviceTest.java
+++ b/jsdrplay/src/test/java/io/github/dsherer/sdrplay/test/RspDeviceTest.java
@@ -1,6 +1,6 @@
/*
* *****************************************************************************
- * Copyright (C) 2014-2022 Dennis Sheirer
+ * 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
@@ -19,11 +19,11 @@
package io.github.dsherer.sdrplay.test;
-import com.github.dsheirer.sdrplay.DeviceDescriptor;
import com.github.dsheirer.sdrplay.DeviceSelectionMode;
import com.github.dsheirer.sdrplay.SDRPlayException;
import com.github.dsheirer.sdrplay.SDRplay;
import com.github.dsheirer.sdrplay.device.Device;
+import com.github.dsheirer.sdrplay.device.DeviceInfo;
import com.github.dsheirer.sdrplay.device.DeviceType;
import io.github.dsherer.sdrplay.test.listener.LoggingStreamConsumer;
import org.junit.jupiter.api.DisplayName;
@@ -43,13 +43,14 @@ public class RspDeviceTest
public void listDevices()
{
SDRplay api = new SDRplay();
- for(DeviceDescriptor deviceDescriptor: api.getDevices())
- {
- mLog.info(deviceDescriptor.toString());
- }
try
{
+ for(DeviceInfo deviceInfo: api.getDeviceInfos())
+ {
+ mLog.info(deviceInfo.toString());
+ }
+
api.close();
}
catch(Exception se)
@@ -86,52 +87,39 @@ private void testDevice(DeviceType deviceType, DeviceSelectionMode deviceSelecti
{
SDRplay api = new SDRplay();
mLog.info("Version: " + api.getVersion());
-
- DeviceDescriptor deviceDescriptor = api.getDevice(deviceType);
-
- if(deviceDescriptor != null)
+ try
{
- mLog.info("Testing: " + deviceDescriptor + " With Device Selection Mode: " + deviceSelectionMode);
- mLog.info("Available Selection Modes: " + deviceDescriptor.getDeviceSelectionModes());
- if(deviceDescriptor.getDeviceSelectionModes().contains(deviceSelectionMode))
- {
- try
- {
- Device device = api.select(deviceDescriptor, deviceSelectionMode);
+ DeviceInfo deviceInfo = api.getDeviceInfo(deviceType);
+ mLog.info("Testing: " + deviceInfo + " With Device Selection Mode: " + deviceSelectionMode);
+ Device device = api.getDevice(deviceInfo);
+ device.select();
+ mLog.info("Device: " + device.toString());
- mLog.info("Device: " + device.toString());
+ mLog.info("Selected: " + device.getClass());
- mLog.info("Selected: " + device.getClass());
-
- mLog.info("Setting Sample Rate");
+ mLog.info("Setting Sample Rate");
// device.setSampleRate(SampleRate.RATE_0_250);
- mLog.info("Setting Frequencies");
- device.getTuner().setFrequency(460_450_000);
+ mLog.info("Setting Frequencies");
+ device.getTuner().setFrequency(460_450_000);
- mLog.info("Gain Reduction: " + device.getTuner().getGainReduction());
- mLog.info("AGC Mode: " + device.getTuner().getAGC());
- mLog.info("Gain: " + device.getTuner().getGain());
- mLog.info("LO Mode:" + device.getTuner().getLoMode());
- mLog.info("IF Mode:" + device.getTuner().getIfMode());
+ mLog.info("Gain Reduction: " + device.getTuner().getGainReduction());
+ mLog.info("AGC Mode: " + device.getTuner().getAGC());
+ mLog.info("Gain: " + device.getTuner().getGain());
+ mLog.info("LO Mode:" + device.getTuner().getLoMode());
+ mLog.info("IF Mode:" + device.getTuner().getIfMode());
- mLog.info("Capturing Samples ...");
- LoggingStreamConsumer loggingStreamConsumer = new LoggingStreamConsumer(device);
- loggingStreamConsumer.process(5);
+ mLog.info("Capturing Samples ...");
+ LoggingStreamConsumer loggingStreamConsumer = new LoggingStreamConsumer(device);
+ loggingStreamConsumer.process(5);
// loggingStreamConsumer.logSpectrum1();
- device.release();
- mLog.info("Released");
- }
- catch(SDRPlayException se)
- {
- mLog.error("Error testing device", se);
- }
- }
+ device.release();
+ mLog.info("Released");
}
- else
+ catch(SDRPlayException se)
{
- mLog.info("Unable to obtain RSP device to test");
+ mLog.error("Error testing device", se);
}
try
diff --git a/jsdrplay/src/test/java/io/github/dsherer/sdrplay/test/RspDuoTest.java b/jsdrplay/src/test/java/io/github/dsherer/sdrplay/test/RspDuoTest.java
index c86caa525..eeb1dca1d 100644
--- a/jsdrplay/src/test/java/io/github/dsherer/sdrplay/test/RspDuoTest.java
+++ b/jsdrplay/src/test/java/io/github/dsherer/sdrplay/test/RspDuoTest.java
@@ -1,6 +1,6 @@
/*
* *****************************************************************************
- * Copyright (C) 2014-2022 Dennis Sheirer
+ * 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
@@ -19,18 +19,6 @@
package io.github.dsherer.sdrplay.test;
-import com.github.dsheirer.sdrplay.DeviceDescriptor;
-import com.github.dsheirer.sdrplay.DeviceSelectionMode;
-import com.github.dsheirer.sdrplay.SDRPlayException;
-import com.github.dsheirer.sdrplay.SDRplay;
-import com.github.dsheirer.sdrplay.device.Device;
-import com.github.dsheirer.sdrplay.device.DeviceType;
-import com.github.dsheirer.sdrplay.device.RspDuoDevice;
-import com.github.dsheirer.sdrplay.device.RspDuoDualIndependentTunerDevice;
-import com.github.dsheirer.sdrplay.parameter.tuner.IfMode;
-import io.github.dsherer.sdrplay.test.listener.LoggingStreamConsumer;
-import org.junit.jupiter.api.DisplayName;
-import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.TestInstance;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@@ -43,174 +31,114 @@ public class RspDuoTest
{
private static Logger mLog = LoggerFactory.getLogger(RspDuoTest.class);
- /**
- * Tests an RSPduo configured for dual independent tuners, each controlled by a separate SDRplay API instance.
- */
- @Test
- @DisplayName("Test an RSPduo device using dual independent tuners")
- public void testDualIndependentTuners()
- {
- testDuo(DeviceSelectionMode.DUAL_INDEPENDENT_TUNERS);
- }
-
- /**
- * Tests an RSPduo configured for dual synchronized tuners (ie diversity mode).
- */
- @Test
- @DisplayName("Test an RSPduo device using dual synchronized tuners")
- public void testDualSynchronizedTuners()
- {
- testDuo(DeviceSelectionMode.DUAL_SYNCHRONIZED_TUNERS);
- }
-
- /**
- * Tests an RSPduo configured for single tuner 1.
- */
- @Test
- @DisplayName("Test an RSPduo device using single tuner mode with tuner 1")
- public void testSingleTuner1()
- {
- testDuo(DeviceSelectionMode.SINGLE_TUNER_1);
- }
-
- /**
- * Tests an RSPduo configured for single tuner 2.
- */
- @Test
- @DisplayName("Test an RSPduo device using single tuner mode with tuner 2")
- public void testSingleTuner2()
- {
- testDuo(DeviceSelectionMode.SINGLE_TUNER_2);
- }
-
- /**
- * Tests an RSPduo configured for master with tuner 1.
- */
- @Test
- @DisplayName("Test an RSPduo device using master tuner mode with tuner 1")
- public void testMasterTuner1()
- {
- testDuo(DeviceSelectionMode.MASTER_TUNER_1);
- }
-
- /**
- * Tests an RSPduo configured for master with tuner 2.
- */
- @Test
- @DisplayName("Test an RSPduo device using master tuner mode with tuner 2")
- public void testMasterTuner2()
- {
- testDuo(DeviceSelectionMode.MASTER_TUNER_2);
- }
-
- /**
- * Tests the RSPduo with the specified device selection mode
- * @param deviceSelectionMode
- */
- private void testDuo(DeviceSelectionMode deviceSelectionMode)
- {
- SDRplay api = new SDRplay();
-
- DeviceDescriptor deviceDescriptor = api.getDevice(DeviceType.RSPduo);
-
- if(deviceDescriptor != null)
- {
- mLog.info("Testing: " + deviceDescriptor + " With Device Selection Mode: " + deviceSelectionMode);
-
- if(deviceDescriptor.getDeviceSelectionModes().contains(deviceSelectionMode))
- {
- try
- {
- Device device = api.select(deviceDescriptor, deviceSelectionMode);
-
- if(device instanceof RspDuoDevice)
- {
- mLog.info("Selected: " + device.getClass());
-
- if(deviceSelectionMode.isMasterMode())
- {
- mLog.info("Setting IF Mode");
- device.getTuner().setIfMode(IfMode.IF_2048);
-
- mLog.info("Setting Sample Rate");
-// device.setSampleRate(SampleRate.DUO_RATE_0_500);
- }
- else if(deviceSelectionMode.equals(DeviceSelectionMode.DUAL_SYNCHRONIZED_TUNERS))
- {
- mLog.info("Setting Sample Rate");
-// device.setSampleRate(SampleRate.RATE_0_600);
- }
- else
- {
- mLog.info("Setting Sample Rate");
-// device.setSampleRate(SampleRate.RATE_10_000);
- }
-
- mLog.info("Setting Frequencies");
- device.getTuner().setFrequency(460_450_000);
-
- mLog.info("Gain Reduction: " + device.getTuner().getGainReduction());
- mLog.info("AGC Mode: " + device.getTuner().getAGC());
- mLog.info("Gain: " + device.getTuner().getGain());
- mLog.info("LO Mode:" + device.getTuner().getLoMode());
- mLog.info("IF Mode:" + device.getTuner().getIfMode());
-
- mLog.info("Capturing Samples ...");
- LoggingStreamConsumer loggingStreamConsumer = new LoggingStreamConsumer(device);
- loggingStreamConsumer.process(5);
- loggingStreamConsumer.logSpectrumA();
-
- if(deviceSelectionMode.equals(DeviceSelectionMode.DUAL_SYNCHRONIZED_TUNERS))
- {
- loggingStreamConsumer.logSpectrumB();
- }
- }
- else if(device instanceof RspDuoDualIndependentTunerDevice dual)
- {
- mLog.info("Selected: " + device.getClass());
-
- //IF Mode 2048 is the correct mode for master/slave configurations with 2.0 MHz sample rate
- device.getTuner().setIfMode(IfMode.IF_2048);
-
- mLog.info("Setting Sample Rate");
-// device.setSampleRate(SampleRate.DUO_RATE_2_000);
-
- mLog.info("Setting Frequencies");
- device.getTuner().setFrequency(460_250_000);
- dual.getTuner2().setFrequency(453_250_000);
-
- mLog.info("Capturing Samples ...");
- LoggingStreamConsumer loggingStreamConsumer = new LoggingStreamConsumer(device);
- loggingStreamConsumer.process(5);
- loggingStreamConsumer.logSpectrumA();
- loggingStreamConsumer.logSpectrumB();
- }
- else
- {
- mLog.error("Unrecognized Device Type: " + device.getClass());
- }
-
- device.release();
- mLog.info("Released");
- }
- catch(SDRPlayException se)
- {
- mLog.error("Error testing device", se);
- }
- }
- }
- else
- {
- mLog.info("Unable to obtain RSPduo device to test");
- }
-
- try
- {
- api.close();
- }
- catch(Exception se)
- {
- mLog.error("Error closing api");
- }
- }
+// /**
+// * Tests an RSPduo configured for single tuner 1.
+// */
+// @Test
+// @DisplayName("Test an RSPduo device using single tuner mode with tuner 1")
+// public void testSingleTuner1()
+// {
+// testDuo(DeviceSelectionMode.SINGLE_TUNER_1);
+// }
+//
+// /**
+// * Tests an RSPduo configured for single tuner 2.
+// */
+// @Test
+// @DisplayName("Test an RSPduo device using single tuner mode with tuner 2")
+// public void testSingleTuner2()
+// {
+// testDuo(DeviceSelectionMode.SINGLE_TUNER_2);
+// }
+//
+// /**
+// * Tests an RSPduo configured for master with tuner 1.
+// */
+// @Test
+// @DisplayName("Test an RSPduo device using master tuner mode with tuner 1")
+// public void testMasterTuner1()
+// {
+// testDuo(DeviceSelectionMode.MASTER_TUNER_1);
+// }
+//
+// /**
+// * Tests the RSPduo with the specified device selection mode
+// * @param deviceSelectionMode
+// */
+// private void testDuo(DeviceSelectionMode deviceSelectionMode)
+// {
+// SDRplay api = new SDRplay();
+//
+// DeviceInfo deviceInfo = api.getDeviceInfo(DeviceType.RSPduo);
+//
+// if(deviceInfo != null)
+// {
+// mLog.info("Testing: " + deviceInfo + " With Device Selection Mode: " + deviceSelectionMode);
+//
+// if(deviceInfo.getDeviceSelectionModes().contains(deviceSelectionMode))
+// {
+// try
+// {
+// Device device = api.select(deviceInfo, deviceSelectionMode);
+//
+// if(device instanceof RspDuoDevice)
+// {
+// mLog.info("Selected: " + device.getClass());
+//
+// if(deviceSelectionMode.isMasterMode())
+// {
+// mLog.info("Setting IF Mode");
+// device.getTuner().setIfMode(IfMode.IF_2048);
+//
+// mLog.info("Setting Sample Rate");
+//// device.setSampleRate(SampleRate.DUO_RATE_0_500);
+// }
+// else
+// {
+// mLog.info("Setting Sample Rate");
+//// device.setSampleRate(SampleRate.RATE_10_000);
+// }
+//
+// mLog.info("Setting Frequencies");
+// device.getTuner().setFrequency(460_450_000);
+//
+// mLog.info("Gain Reduction: " + device.getTuner().getGainReduction());
+// mLog.info("AGC Mode: " + device.getTuner().getAGC());
+// mLog.info("Gain: " + device.getTuner().getGain());
+// mLog.info("LO Mode:" + device.getTuner().getLoMode());
+// mLog.info("IF Mode:" + device.getTuner().getIfMode());
+//
+// mLog.info("Capturing Samples ...");
+// LoggingStreamConsumer loggingStreamConsumer = new LoggingStreamConsumer(device);
+// loggingStreamConsumer.process(5);
+// loggingStreamConsumer.logSpectrumA();
+// }
+// else
+// {
+// mLog.error("Unrecognized Device Type: " + device.getClass());
+// }
+//
+// device.release();
+// mLog.info("Released");
+// }
+// catch(SDRPlayException se)
+// {
+// mLog.error("Error testing device", se);
+// }
+// }
+// }
+// else
+// {
+// mLog.info("Unable to obtain RSPduo device to test");
+// }
+//
+// try
+// {
+// api.close();
+// }
+// catch(Exception se)
+// {
+// mLog.error("Error closing api");
+// }
+// }
}
diff --git a/src/main/java/io/github/dsheirer/source/tuner/TunerFactory.java b/src/main/java/io/github/dsheirer/source/tuner/TunerFactory.java
index 6a6113dcf..b748f81ce 100644
--- a/src/main/java/io/github/dsheirer/source/tuner/TunerFactory.java
+++ b/src/main/java/io/github/dsheirer/source/tuner/TunerFactory.java
@@ -1,6 +1,6 @@
/*
* *****************************************************************************
- * Copyright (C) 2014-2022 Dennis Sheirer
+ * 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
@@ -19,9 +19,16 @@
package io.github.dsheirer.source.tuner;
-import com.github.dsheirer.sdrplay.DeviceDescriptor;
import com.github.dsheirer.sdrplay.DeviceSelectionMode;
+import com.github.dsheirer.sdrplay.SDRPlayException;
import com.github.dsheirer.sdrplay.SDRplay;
+import com.github.dsheirer.sdrplay.device.Device;
+import com.github.dsheirer.sdrplay.device.DeviceInfo;
+import com.github.dsheirer.sdrplay.device.Rsp1aDevice;
+import com.github.dsheirer.sdrplay.device.Rsp2Device;
+import com.github.dsheirer.sdrplay.device.RspDuoDevice;
+import com.github.dsheirer.sdrplay.device.RspDxDevice;
+import io.github.dsheirer.gui.preference.tuner.RspDuoSelectionMode;
import io.github.dsheirer.preference.UserPreferences;
import io.github.dsheirer.preference.source.ChannelizerType;
import io.github.dsheirer.source.SourceException;
@@ -57,16 +64,19 @@
import io.github.dsheirer.source.tuner.rtl.r820t.R820TTunerConfiguration;
import io.github.dsheirer.source.tuner.rtl.r820t.R820TTunerEditor;
import io.github.dsheirer.source.tuner.sdrplay.DiscoveredRspTuner;
+import io.github.dsheirer.source.tuner.sdrplay.RspTuner;
import io.github.dsheirer.source.tuner.sdrplay.rsp1.Rsp1TunerConfiguration;
import io.github.dsheirer.source.tuner.sdrplay.rsp1a.ControlRsp1a;
import io.github.dsheirer.source.tuner.sdrplay.rsp1a.DiscoveredRsp1aTuner;
import io.github.dsheirer.source.tuner.sdrplay.rsp1a.IControlRsp1a;
import io.github.dsheirer.source.tuner.sdrplay.rsp1a.Rsp1aTunerConfiguration;
+import io.github.dsheirer.source.tuner.sdrplay.rsp1a.Rsp1aTunerController;
import io.github.dsheirer.source.tuner.sdrplay.rsp1a.Rsp1aTunerEditor;
import io.github.dsheirer.source.tuner.sdrplay.rsp2.ControlRsp2;
import io.github.dsheirer.source.tuner.sdrplay.rsp2.DiscoveredRsp2Tuner;
import io.github.dsheirer.source.tuner.sdrplay.rsp2.IControlRsp2;
import io.github.dsheirer.source.tuner.sdrplay.rsp2.Rsp2TunerConfiguration;
+import io.github.dsheirer.source.tuner.sdrplay.rsp2.Rsp2TunerController;
import io.github.dsheirer.source.tuner.sdrplay.rsp2.Rsp2TunerEditor;
import io.github.dsheirer.source.tuner.sdrplay.rspDuo.ControlRspDuoTuner1Master;
import io.github.dsheirer.source.tuner.sdrplay.rspDuo.ControlRspDuoTuner1Single;
@@ -78,15 +88,20 @@
import io.github.dsheirer.source.tuner.sdrplay.rspDuo.IControlRspDuoTuner2;
import io.github.dsheirer.source.tuner.sdrplay.rspDuo.MasterSlaveBridge;
import io.github.dsheirer.source.tuner.sdrplay.rspDuo.RspDuoTuner1Configuration;
+import io.github.dsheirer.source.tuner.sdrplay.rspDuo.RspDuoTuner1Controller;
import io.github.dsheirer.source.tuner.sdrplay.rspDuo.RspDuoTuner1Editor;
import io.github.dsheirer.source.tuner.sdrplay.rspDuo.RspDuoTuner2Configuration;
+import io.github.dsheirer.source.tuner.sdrplay.rspDuo.RspDuoTuner2Controller;
import io.github.dsheirer.source.tuner.sdrplay.rspDuo.RspDuoTuner2Editor;
import io.github.dsheirer.source.tuner.sdrplay.rspDx.ControlRspDx;
import io.github.dsheirer.source.tuner.sdrplay.rspDx.DiscoveredRspDxTuner;
import io.github.dsheirer.source.tuner.sdrplay.rspDx.IControlRspDx;
import io.github.dsheirer.source.tuner.sdrplay.rspDx.RspDxTunerConfiguration;
+import io.github.dsheirer.source.tuner.sdrplay.rspDx.RspDxTunerController;
import io.github.dsheirer.source.tuner.sdrplay.rspDx.RspDxTunerEditor;
import io.github.dsheirer.source.tuner.ui.TunerEditor;
+import java.util.ArrayList;
+import java.util.List;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@@ -99,82 +114,166 @@ public class TunerFactory
{
private static final Logger mLog = LoggerFactory.getLogger(TunerFactory.class);
-
/**
- * Creates an RSP tuner, or two tuners for RSPduo devices.
- * @param api for communicating with the tuner
- * @param deviceDescriptor representing the tuner
- * @param channelizerType to use for the tuner
- * @param selectionMode for selecting the tuner
- * @return one or two constructed RSP tuners
+ * Creates one or two (e.g. RSPduo) Discovered RSP tuner instances for the RSP device.
+ * @param deviceInfo describing the RSP device
+ * @param channelizerType to use with the device
+ * @param selectionMode to specify how to configure an RSPduo dual-tuner device.
+ * @return zero or more discovered RSP tuners.
*/
- public static DiscoveredRspTuner getRspTuner(SDRplay api, DeviceDescriptor deviceDescriptor,
- ChannelizerType channelizerType, DeviceSelectionMode selectionMode)
+ public static List getRspTuners(DeviceInfo deviceInfo, ChannelizerType channelizerType, RspDuoSelectionMode selectionMode)
{
- return getRspTuner(api, deviceDescriptor, channelizerType, selectionMode, null);
- }
+ List tuners = new ArrayList<>();
- /**
- * Creates an RSP tuner and optionally registers the tuner with a master-slave bridge.
- * @param api for communicating with the tuner
- * @param deviceDescriptor representing the tuner
- * @param channelizerType to use for the tuner
- * @param selectionMode for selecting the tuner
- * @param bridge (optional) bridging device between Tuner1/Master and Tuner2/Slave RSPduo configuration.
- * @return one or two constructed RSP tuners
- */
- public static DiscoveredRspTuner getRspTuner(SDRplay api, DeviceDescriptor deviceDescriptor,
- ChannelizerType channelizerType, DeviceSelectionMode selectionMode,
- MasterSlaveBridge bridge)
- {
- //Configure RSPduo to user preference - either single (wide) tuner or dual (narrow) tuners
- switch(deviceDescriptor.getDeviceType())
+ switch(deviceInfo.getDeviceType())
{
case RSP1A:
- IControlRsp1a controlRsp1a = new ControlRsp1a(api, deviceDescriptor);
- return new DiscoveredRsp1aTuner(controlRsp1a, channelizerType);
+ tuners.add(new DiscoveredRsp1aTuner(deviceInfo, channelizerType));
+ break;
case RSP2:
- IControlRsp2 controlRsp2 = new ControlRsp2(api, deviceDescriptor);
- return new DiscoveredRsp2Tuner(controlRsp2, channelizerType);
+ tuners.add(new DiscoveredRsp2Tuner(deviceInfo, channelizerType));
+ break;
case RSPdx:
- IControlRspDx controlRspDx = new ControlRspDx(api, deviceDescriptor);
- return new DiscoveredRspDxTuner(controlRspDx, channelizerType);
+ tuners.add(new DiscoveredRspDxTuner(deviceInfo, channelizerType));
+ break;
case RSPduo:
- if(deviceDescriptor.supports(selectionMode))
+ switch(selectionMode)
{
- switch(selectionMode)
+ case SINGLE_1:
+ deviceInfo.setDeviceSelectionMode(DeviceSelectionMode.SINGLE_TUNER_1);
+ tuners.add(new DiscoveredRspDuoTuner1(deviceInfo, channelizerType));
+ break;
+ case SINGLE_2:
+ deviceInfo.setDeviceSelectionMode(DeviceSelectionMode.SINGLE_TUNER_2);
+ tuners.add(new DiscoveredRspDuoTuner2(deviceInfo, channelizerType));
+ break;
+ case DUAL:
+ MasterSlaveBridge bridge = new MasterSlaveBridge();
+ deviceInfo.setDeviceSelectionMode(DeviceSelectionMode.MASTER_TUNER_1);
+ tuners.add(new DiscoveredRspDuoTuner1(deviceInfo, channelizerType, bridge));
+
+ DeviceInfo deviceInfoTuner2 = deviceInfo.clone();
+ deviceInfoTuner2.setDeviceSelectionMode(DeviceSelectionMode.SLAVE_TUNER_2);
+ tuners.add(new DiscoveredRspDuoTuner2(deviceInfoTuner2, channelizerType, bridge));
+ break;
+ }
+ break;
+ }
+
+ return tuners;
+ }
+
+ /**
+ * Locates the matching RSP device described by the device info object and creates an RSP tuner instance.
+ * @param deviceInfo to match
+ * @param channelizerType for the tuner
+ * @param tunerErrorListener to monitor the tuner's status
+ * @return constructed RSP tuner instance
+ * @throws SDRPlayException if the device is not available or is not supported
+ */
+ public static RspTuner getRspTuner(DeviceInfo deviceInfo, ChannelizerType channelizerType,
+ ITunerErrorListener tunerErrorListener) throws SDRPlayException
+ {
+ //API instance is retained across the lifecycle of the constructed device, so we only close it if we don't get
+ //a device from it.
+ SDRplay api = new SDRplay();
+
+ if(api.isAvailable())
+ {
+ Device device = api.getDevice(deviceInfo);
+
+ switch(device.getDeviceType())
+ {
+ case RSP1A:
+ if(device instanceof Rsp1aDevice rsp1aDevice)
{
- case SINGLE_TUNER_1 ->
- {
- IControlRspDuoTuner1 controlTuner1Single = new ControlRspDuoTuner1Single(api, deviceDescriptor);
- return new DiscoveredRspDuoTuner1(controlTuner1Single, channelizerType);
- }
- case SINGLE_TUNER_2 ->
- {
- IControlRspDuoTuner2 controlTuner2Single = new ControlRspDuoTuner2Single(api, deviceDescriptor);
- return new DiscoveredRspDuoTuner2(controlTuner2Single, channelizerType);
- }
- case MASTER_TUNER_1 ->
+ IControlRsp1a controlRsp1a = new ControlRsp1a(rsp1aDevice);
+ Rsp1aTunerController rsp1aTunerController = new Rsp1aTunerController(controlRsp1a, tunerErrorListener);
+ return new RspTuner(rsp1aTunerController, tunerErrorListener, channelizerType);
+ }
+ break;
+ case RSP2:
+ if(device instanceof Rsp2Device rsp2Device)
+ {
+ IControlRsp2 controlRsp2 = new ControlRsp2(rsp2Device);
+ Rsp2TunerController rsp2TunerController = new Rsp2TunerController(controlRsp2, tunerErrorListener);
+ return new RspTuner(rsp2TunerController, tunerErrorListener, channelizerType);
+ }
+ break;
+ case RSPdx:
+ if(device instanceof RspDxDevice rspDxDevice)
+ {
+ IControlRspDx controlRspDx = new ControlRspDx(rspDxDevice);
+ RspDxTunerController rspDxTunerController = new RspDxTunerController(controlRspDx, tunerErrorListener);
+ return new RspTuner(rspDxTunerController, tunerErrorListener, channelizerType);
+ }
+ break;
+ case RSPduo:
+ if(device instanceof RspDuoDevice rspDuoDevice)
+ {
+ switch(deviceInfo.getDeviceSelectionMode())
{
- ControlRspDuoTuner1Master controlTuner1Master = new ControlRspDuoTuner1Master(api, deviceDescriptor);
- //Cross register the master with the master-slave bridge
- controlTuner1Master.setBridge(bridge);
- return new DiscoveredRspDuoTuner1(controlTuner1Master, channelizerType);
+ case SINGLE_TUNER_1:
+ IControlRspDuoTuner1 controlRspDuoTuner1 = new ControlRspDuoTuner1Single(rspDuoDevice);
+ RspDuoTuner1Controller rspDuoTuner1Controller = new RspDuoTuner1Controller(controlRspDuoTuner1, tunerErrorListener);
+ return new RspTuner(rspDuoTuner1Controller, tunerErrorListener, channelizerType);
+ case SINGLE_TUNER_2:
+ IControlRspDuoTuner2 controlRspDuoTuner2 = new ControlRspDuoTuner2Single(rspDuoDevice);
+ RspDuoTuner2Controller rspDuoTuner2Controller = new RspDuoTuner2Controller(controlRspDuoTuner2, tunerErrorListener);
+ return new RspTuner(rspDuoTuner2Controller, tunerErrorListener, channelizerType);
+ default:
+ throw new SDRPlayException("This method only supports RSPduo single tuner configurations");
}
- case SLAVE_TUNER_2 ->
+ }
+ break;
+ }
+ }
+
+ throw new SDRPlayException("Unable to obtain RSP tuner");
+ }
+
+ /**
+ * Locates the matching RSP device described by the device info object and creates an RSP tuner instance.
+ * @param deviceInfo to match
+ * @param channelizerType for the tuner
+ * @param tunerErrorListener to monitor the tuner's status
+ * @param bridge to link master/slave instances together
+ * @return constructed RSP tuner instance
+ * @throws SDRPlayException if the device is not available or is not supported
+ */
+ public static RspTuner getRspDuoTuner(DeviceInfo deviceInfo, ChannelizerType channelizerType,
+ ITunerErrorListener tunerErrorListener, MasterSlaveBridge bridge) throws SDRPlayException
+ {
+ SDRplay api = new SDRplay();
+
+ if(api.isAvailable())
+ {
+ Device device = api.getDevice(deviceInfo);
+
+ switch(device.getDeviceType())
+ {
+ case RSPduo:
+ if(device instanceof RspDuoDevice rspDuoDevice)
+ {
+ switch(deviceInfo.getDeviceSelectionMode())
{
- ControlRspDuoTuner2Slave controlTuner2Slave = new ControlRspDuoTuner2Slave(api, deviceDescriptor);
- //Cross register the slave with the master-slave bridge
- controlTuner2Slave.setBridge(bridge);
- return new DiscoveredRspDuoTuner2(controlTuner2Slave, channelizerType);
+ case MASTER_TUNER_1:
+ IControlRspDuoTuner1 controlRspDuoTuner1 = new ControlRspDuoTuner1Master(rspDuoDevice, bridge);
+ RspDuoTuner1Controller rspDuoTuner1Controller = new RspDuoTuner1Controller(controlRspDuoTuner1, tunerErrorListener);
+ return new RspTuner(rspDuoTuner1Controller, tunerErrorListener, channelizerType);
+ case SLAVE_TUNER_2:
+ IControlRspDuoTuner2 controlRspDuoTuner2 = new ControlRspDuoTuner2Slave(rspDuoDevice, bridge);
+ RspDuoTuner2Controller rspDuoTuner2Controller = new RspDuoTuner2Controller(controlRspDuoTuner2, tunerErrorListener);
+ return new RspTuner(rspDuoTuner2Controller, tunerErrorListener, channelizerType);
+ default:
+ throw new SDRPlayException("This method only supports RSPduo single tuner configurations");
}
- default -> mLog.warn("Unrecognized RSPduo device selection mode: " + selectionMode);
}
- }
- break;
+ break;
+ }
}
- return null;
+ throw new SDRPlayException("Unable to obtain RSPduo tuner");
}
/**
diff --git a/src/main/java/io/github/dsheirer/source/tuner/manager/TunerManager.java b/src/main/java/io/github/dsheirer/source/tuner/manager/TunerManager.java
index 224ea58b9..a65c4b004 100644
--- a/src/main/java/io/github/dsheirer/source/tuner/manager/TunerManager.java
+++ b/src/main/java/io/github/dsheirer/source/tuner/manager/TunerManager.java
@@ -1,6 +1,6 @@
/*
* *****************************************************************************
- * Copyright (C) 2014-2022 Dennis Sheirer
+ * 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
@@ -19,9 +19,9 @@
package io.github.dsheirer.source.tuner.manager;
-import com.github.dsheirer.sdrplay.DeviceSelectionMode;
+import com.github.dsheirer.sdrplay.SDRPlayException;
import com.github.dsheirer.sdrplay.SDRplay;
-import com.github.dsheirer.sdrplay.device.DeviceType;
+import com.github.dsheirer.sdrplay.device.DeviceInfo;
import io.github.dsheirer.gui.preference.tuner.RspDuoSelectionMode;
import io.github.dsheirer.preference.UserPreferences;
import io.github.dsheirer.preference.source.ChannelizerType;
@@ -42,11 +42,7 @@
import io.github.dsheirer.source.tuner.configuration.TunerConfigurationManager;
import io.github.dsheirer.source.tuner.recording.RecordingTunerConfiguration;
import io.github.dsheirer.source.tuner.sdrplay.DiscoveredRspTuner;
-import io.github.dsheirer.source.tuner.sdrplay.rspDuo.ControlRspDuoTuner1Master;
import io.github.dsheirer.source.tuner.sdrplay.rspDuo.DiscoveredRspDuoTuner1;
-import io.github.dsheirer.source.tuner.sdrplay.rspDuo.MasterSlaveBridge;
-import io.github.dsheirer.source.tuner.sdrplay.rspDuo.RspDuoTuner1Controller;
-import io.github.dsheirer.source.tuner.sdrplay.rspDuo.RspDuoTuner2Controller;
import io.github.dsheirer.source.tuner.ui.DiscoveredTunerModel;
import io.github.dsheirer.util.ThreadPool;
import java.nio.ByteBuffer;
@@ -74,16 +70,13 @@
public class TunerManager implements IDiscoveredTunerStatusListener
{
private static final Logger mLog = LoggerFactory.getLogger(TunerManager.class);
- private static final int MAXIMUM_USB_2_DATA_RATE = 480000000;
-
private UserPreferences mUserPreferences;
private DiscoveredTunerModel mDiscoveredTunerModel = new DiscoveredTunerModel();
private TunerConfigurationManager mTunerConfigurationManager;
private HotplugEventSupport mHotplugEventSupport = new HotplugEventSupport();
private Context mLibUsbApplicationContext = new Context();
- private SDRplay mSdrplayApi1;
- private SDRplay mSdrplayApi2;
private boolean mLibUsbInitialized = false;
+ private SDRplay mSDRplay;
/**
* Constructs an instance
@@ -155,6 +148,13 @@ public void stop()
//Stop all tuners
mDiscoveredTunerModel.releaseDiscoveredTuners();
+ //Shutdown SDRplay API instance
+ if(mSDRplay != null)
+ {
+ mSDRplay.close();
+ mSDRplay = null;
+ }
+
//Shutdown LibUsb
if(mLibUsbInitialized)
{
@@ -162,19 +162,6 @@ public void stop()
LibUsb.exit(mLibUsbApplicationContext);
mLibUsbInitialized = false;
}
-
- //Close SDRPlay API instance(s)
- if(mSdrplayApi1 != null)
- {
- mSdrplayApi1.close();
- mSdrplayApi1 = null;
- }
-
- if(mSdrplayApi2 != null)
- {
- mSdrplayApi2.close();
- mSdrplayApi2 = null;
- }
}
/**
@@ -308,139 +295,47 @@ private void startAndConfigureTuner(DiscoveredTuner discoveredTuner)
private void discoverSdrPlayTuners()
{
ChannelizerType channelizerType = mUserPreferences.getTunerPreference().getChannelizerType();
+ RspDuoSelectionMode duoSelectionMode = mUserPreferences.getTunerPreference().getRspDuoTunerMode();
- RspDuoSelectionMode preferredSelectionMode = mUserPreferences.getTunerPreference().getRspDuoTunerMode();
+ //Note: we have to keep this first API instance open while we use any RSP tuners, otherwise the additional API
+ //instance(s) used by the individual tuners become unresponsive. Note sure why.
+ mSDRplay = new SDRplay();
- if(getSdrplayApi1().isAvailable())
+ if(mSDRplay.isAvailable())
{
- List deviceDescriptors = getSdrplayApi1().getDevices();
-
- mLog.info("SDRPlay found [" + deviceDescriptors.size() + "] device descriptors");
- for(com.github.dsheirer.sdrplay.DeviceDescriptor deviceDescriptor: deviceDescriptors)
+ try
{
- if(deviceDescriptor.getDeviceType() == DeviceType.RSPduo)
- {
- switch(preferredSelectionMode)
- {
- case SINGLE_1:
- DiscoveredRspTuner singleTuner1 = TunerFactory.getRspTuner(getSdrplayApi1(), deviceDescriptor,
- channelizerType, DeviceSelectionMode.SINGLE_TUNER_1);
- if(singleTuner1 == null)
- {
- mLog.warn("Unable to create tuner 1 for RSP device: " + deviceDescriptor.getDeviceType() +
- " " + deviceDescriptor.getSerialNumber());
- }
- else
- {
- startAndConfigureTuner(singleTuner1);
- }
- break;
- case SINGLE_2:
- DiscoveredRspTuner singleTuner2 = TunerFactory.getRspTuner(getSdrplayApi1(), deviceDescriptor,
- channelizerType, DeviceSelectionMode.SINGLE_TUNER_2);
- if(singleTuner2 == null)
- {
- mLog.warn("Unable to create tuner 2 for RSP device: " + deviceDescriptor.getDeviceType() +
- " " + deviceDescriptor.getSerialNumber());
- }
- else
- {
- startAndConfigureTuner(singleTuner2);
- }
- break;
- case DUAL:
- //Create a bridge across the master and slave tuners.
- MasterSlaveBridge bridge = new MasterSlaveBridge();
-
- DiscoveredRspTuner masterTuner1 = TunerFactory.getRspTuner(getSdrplayApi1(), deviceDescriptor,
- channelizerType, DeviceSelectionMode.MASTER_TUNER_1, bridge);
-
- if(masterTuner1 == null)
- {
- mLog.warn("Unable to create master tuner 1 device: " + deviceDescriptor.getDeviceType() + " " +
- deviceDescriptor.getSerialNumber());
- continue;
- }
- else
- {
- startAndConfigureTuner(masterTuner1);
- }
-
- String serialNumber = deviceDescriptor.getSerialNumber();
-
- com.github.dsheirer.sdrplay.DeviceDescriptor slaveDescriptor = getSdrplayApi2().getDevice(serialNumber);
- DiscoveredRspTuner slaveTuner2 = TunerFactory.getRspTuner(getSdrplayApi2(), slaveDescriptor,
- channelizerType, DeviceSelectionMode.SLAVE_TUNER_2, bridge);
+ List deviceInfos = mSDRplay.getDeviceInfos();
- if(slaveTuner2 == null)
- {
- mLog.warn("Unable to create slave tuner 2 device: " + deviceDescriptor.getDeviceType() + " " +
- deviceDescriptor.getSerialNumber());
- continue;
- }
- else
- {
- startAndConfigureTuner(slaveTuner2);
- }
+ mLog.info("Discovered [" + deviceInfos.size() + "] RSP devices from SDRplay API");
- //Setup two-way linking between tuner bridge and tuners
- if(masterTuner1 != null && masterTuner1.hasTuner())
- {
- bridge.setMaster((RspDuoTuner1Controller)masterTuner1.getTuner().getTunerController());
- }
- if(slaveTuner2 != null && slaveTuner2.hasTuner())
- {
- bridge.setSlave((RspDuoTuner2Controller)slaveTuner2.getTuner().getTunerController());
- }
- break;
- }
+ if(deviceInfos.isEmpty())
+ {
+ mSDRplay.close();
+ mSDRplay = null;
+ return;
}
- else
+
+ for(DeviceInfo deviceInfo: deviceInfos)
{
- DiscoveredRspTuner tuner = TunerFactory.getRspTuner(getSdrplayApi1(), deviceDescriptor, channelizerType,
- DeviceSelectionMode.SINGLE_TUNER_1);
- if(tuner == null)
- {
- mLog.warn("Unable to create tuner for RSP device: " + deviceDescriptor.getDeviceType() + " " +
- deviceDescriptor.getSerialNumber());
- }
- else
+ List tuners = TunerFactory.getRspTuners(deviceInfo, channelizerType, duoSelectionMode);
+
+ for(DiscoveredRspTuner tuner: tuners)
{
startAndConfigureTuner(tuner);
}
}
}
+ catch(SDRPlayException se)
+ {
+ mLog.info("Unable to get list of devices from SDRplay API");
+ }
}
- }
-
- /**
- * Access SDRPlay API instance #1.
- * @return api
- */
- private SDRplay getSdrplayApi1()
- {
- if(mSdrplayApi1 == null)
- {
- mLog.info("Creating SDRPlay API instance #1");
- mSdrplayApi1 = new SDRplay();
- }
-
- return mSdrplayApi1;
- }
-
- /**
- * Access SDRPlay API instance #2.
- * @return api
- */
- private SDRplay getSdrplayApi2()
- {
- if(mSdrplayApi2 == null)
+ else
{
- mLog.info("Creating SDRPlay API instance #2");
- mSdrplayApi2 = new SDRplay();
+ mSDRplay.close();
+ mSDRplay = null;
}
-
- return mSdrplayApi2;
}
/**
@@ -482,15 +377,13 @@ private void discoverRecordingTuners()
@Override
public void tunerStatusUpdated(DiscoveredTuner discoveredTuner, TunerStatus previous, TunerStatus current)
{
- mLog.info("Tuner status updated - previous [" + previous + "] current [" + current + "] tuner: " + discoveredTuner.getId());
if(current == TunerStatus.ENABLED)
{
discoveredTuner.start();
}
//Special handling for RSPduo to auto-update enabled state for slave device when configured for master/slave operation
- if(discoveredTuner instanceof DiscoveredRspDuoTuner1 rspDuoTuner1 &&
- rspDuoTuner1.getControlRsp() instanceof ControlRspDuoTuner1Master)
+ if(discoveredTuner instanceof DiscoveredRspDuoTuner1 rspDuoTuner1 && rspDuoTuner1.getDeviceInfo().getDeviceSelectionMode().isMasterMode())
{
String id = rspDuoTuner1.getId();
id = id.replace(DiscoveredRspDuoTuner1.RSP_DUO_ID_PREFIX + "1", DiscoveredRspDuoTuner1.RSP_DUO_ID_PREFIX + "2");
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 79271bcc6..566071e81 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
@@ -1,6 +1,6 @@
/*
* *****************************************************************************
- * Copyright (C) 2014-2022 Dennis Sheirer
+ * 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
@@ -19,23 +19,28 @@
package io.github.dsheirer.source.tuner.sdrplay;
-import com.github.dsheirer.sdrplay.DeviceDescriptor;
import com.github.dsheirer.sdrplay.DeviceSelectionMode;
import com.github.dsheirer.sdrplay.SDRPlayException;
-import com.github.dsheirer.sdrplay.SDRplay;
+import com.github.dsheirer.sdrplay.UpdateReason;
import com.github.dsheirer.sdrplay.callback.IDeviceEventListener;
import com.github.dsheirer.sdrplay.callback.IStreamListener;
+import com.github.dsheirer.sdrplay.device.Device;
+import com.github.dsheirer.sdrplay.device.TunerSelect;
+import com.github.dsheirer.sdrplay.parameter.control.AgcMode;
import com.github.dsheirer.sdrplay.parameter.tuner.GainReduction;
-
+import com.github.dsheirer.sdrplay.parameter.tuner.IfMode;
+import com.github.dsheirer.sdrplay.parameter.tuner.LoMode;
import java.util.concurrent.locks.ReentrantLock;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
/**
* Base RSP control implementation
*/
-public abstract class ControlRsp implements IControlRsp
+public abstract class ControlRsp implements IControlRsp
{
- private SDRplay mSDRplayApi;
- private DeviceDescriptor mDeviceDescriptor;
+ private static final Logger mLog = LoggerFactory.getLogger(ControlRsp.class);
+ private T mDevice;
protected RspSampleRate mSampleRate = RspSampleRate.RATE_8_000;
protected int mGain;
private IDeviceEventListener mDeviceEventListener;
@@ -47,13 +52,110 @@ public abstract class ControlRsp implements IControlRsp
/**
* Constructs an instance
- * @param sdrplayApi to use
- * @param deviceDescriptor for the device, obtained from the API
+ * @param device for the device, obtained from the API
*/
- public ControlRsp(SDRplay sdrplayApi, DeviceDescriptor deviceDescriptor)
+ public ControlRsp(T device)
+ {
+ mDevice = device;
+ }
+
+ @Override
+ public TunerSelect getTunerSelect()
+ {
+ return TunerSelect.TUNER_1;
+ }
+
+ @Override
+ public void start() throws SDRPlayException
+ {
+ if(hasDevice())
+ {
+ getDevice().select();
+
+ //Enable automatic DC and I/Q correction
+ 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);
+ getDevice().setIfMode(IfMode.IF_ZERO);
+ getDevice().setLoMode(LoMode.AUTO);
+ }
+ else
+ {
+ throw new SDRPlayException("Unable to start - device is null");
+ }
+ }
+
+ @Override
+ public void stop() throws SDRPlayException
+ {
+ if(hasDevice())
+ {
+ stopStream();
+ getDevice().release();
+ clearDevice();
+ }
+ }
+
+ @Override
+ public void startStream()
+ {
+ mStreamingLock.lock();
+
+ try
+ {
+ if(hasDevice())
+ {
+ if(!mStreaming)
+ {
+ getDevice().initStreamA(getDeviceEventListener(), getStreamListener());
+ mStreaming = true;
+ }
+ }
+ else
+ {
+ mLog.error("Unable to start RSP1A sample stream - device not started");
+ }
+ }
+ catch(SDRPlayException se)
+ {
+ mLog.error("Unable to initialize/start streaming for RSP1A");
+ }
+ finally
+ {
+ mStreamingLock.unlock();
+ }
+ }
+
+ @Override
+ public void stopStream()
{
- mSDRplayApi = sdrplayApi;
- mDeviceDescriptor = deviceDescriptor;
+ mStreamingLock.lock();
+
+ try
+ {
+ if(hasDevice())
+ {
+ if(mStreaming)
+ {
+ getDevice().uninitialize();
+ mStreaming = false;
+ }
+ }
+ else
+ {
+ mLog.error("Unable to stop RSP sample stream - device not started");
+ }
+ }
+ catch(SDRPlayException se)
+ {
+ mLog.error("Unable to uninitialize/stop streaming for RSP1A");
+ }
+ finally
+ {
+ mStreamingLock.unlock();
+ }
}
@Override
@@ -64,19 +166,110 @@ public DeviceSelectionMode getDeviceSelectionMode()
}
/**
- * SDRplay API for controlling the device
+ * Device descriptor for this device
*/
- protected SDRplay getApi()
+ public T getDevice()
{
- return mSDRplayApi;
+ return mDevice;
}
/**
- * Device descriptor for this device
+ * Clears/nullifies the device. This should be invoked after stopping the device to prevent reuse.
*/
- public DeviceDescriptor getDeviceDescriptor()
+ public void clearDevice()
{
- return mDeviceDescriptor;
+ mDevice = null;
+ }
+
+ /**
+ * Indicates if this control has a non-null device.
+ * @return true if non-null device.
+ */
+ public boolean hasDevice()
+ {
+ return getDevice() != null;
+ }
+
+ /**
+ * Sets the sample rate
+ * @param sampleRate enumeration value.
+ * @throws SDRPlayException
+ */
+ @Override
+ public void setSampleRate(RspSampleRate sampleRate) throws SDRPlayException
+ {
+ if(hasDevice() && !sampleRate.equals(mSampleRate))
+ {
+ mSampleRate = sampleRate;
+
+ getDevice().getTuner().setBandwidth(sampleRate.getBandwidth());
+ getDevice().getCompositeParameters().getDeviceParameters().getSamplingFrequency()
+ .setSampleRate(sampleRate.getSampleRate());
+ getDevice().update(getTunerSelect(), UpdateReason.DEVICE_SAMPLE_RATE);
+ getDevice().getCompositeParameters().getControlAParameters().getDecimation().setWideBandSignal(true);
+ getDevice().setDecimation(sampleRate.getDecimation());
+ }
+ else
+ {
+ throw new SDRPlayException("Device is not initialized");
+ }
+ }
+
+ /**
+ * Sets the gain index
+ * @param gain index value (0 - 28)
+ * @throws SDRPlayException
+ */
+ @Override
+ public void setGain(int gain) throws SDRPlayException
+ {
+ validateGain(gain);
+
+ if(gain != mGain)
+ {
+ mGain = gain;
+ getDevice().getTuner().setGain(mGain);
+ }
+ }
+
+
+ @Override
+ public void acknowledgePowerOverload(TunerSelect tunerSelect) throws SDRPlayException
+ {
+ if(hasDevice())
+ {
+ getDevice().acknowledgePowerOverload(tunerSelect);
+ }
+ else
+ {
+ throw new SDRPlayException("Device is not initialized");
+ }
+ }
+
+ @Override
+ public long getTunedFrequency() throws SDRPlayException
+ {
+ if(hasDevice())
+ {
+ return getDevice().getTuner().getFrequency();
+ }
+ else
+ {
+ throw new SDRPlayException("Device is not initialized");
+ }
+ }
+
+ @Override
+ public void setTunedFrequency(long frequency) throws SDRPlayException
+ {
+ if(hasDevice())
+ {
+ getDevice().getTuner().setFrequency(frequency);
+ }
+ else
+ {
+ throw new SDRPlayException("Device is not initialized");
+ }
}
/**
diff --git a/src/main/java/io/github/dsheirer/source/tuner/sdrplay/DiscoveredRspTuner.java b/src/main/java/io/github/dsheirer/source/tuner/sdrplay/DiscoveredRspTuner.java
index 6c82ca8e0..af990cfe9 100644
--- a/src/main/java/io/github/dsheirer/source/tuner/sdrplay/DiscoveredRspTuner.java
+++ b/src/main/java/io/github/dsheirer/source/tuner/sdrplay/DiscoveredRspTuner.java
@@ -1,6 +1,6 @@
/*
* *****************************************************************************
- * Copyright (C) 2014-2022 Dennis Sheirer
+ * 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
@@ -19,9 +19,11 @@
package io.github.dsheirer.source.tuner.sdrplay;
+import com.github.dsheirer.sdrplay.device.DeviceInfo;
import com.github.dsheirer.sdrplay.device.DeviceType;
import io.github.dsheirer.preference.source.ChannelizerType;
import io.github.dsheirer.source.tuner.TunerClass;
+import io.github.dsheirer.source.tuner.TunerFactory;
import io.github.dsheirer.source.tuner.manager.DiscoveredTuner;
/**
@@ -29,33 +31,34 @@
*/
public abstract class DiscoveredRspTuner extends DiscoveredTuner
{
- private final R mControlRsp;
+ private final DeviceInfo mDeviceInfo;
private final ChannelizerType mChannelizerType;
/**
* Constructs an instance
- * @param controlRsp wrapper around device descriptor
+ * @param deviceInfo to select the device from the API
*/
- public DiscoveredRspTuner(R controlRsp, ChannelizerType channelizerType)
+ public DiscoveredRspTuner(DeviceInfo deviceInfo, ChannelizerType channelizerType)
{
- mControlRsp = controlRsp;
+ mDeviceInfo = deviceInfo;
mChannelizerType = channelizerType;
}
/**
- * Channelizer type to use for the tuner
+ * Information about the discovered RSP device
+ * @return device info
*/
- protected ChannelizerType getChannelizerType()
+ public DeviceInfo getDeviceInfo()
{
- return mChannelizerType;
+ return mDeviceInfo;
}
/**
- * RSP control
+ * Channelizer type to use for the tuner
*/
- public R getControlRsp()
+ protected ChannelizerType getChannelizerType()
{
- return mControlRsp;
+ return mChannelizerType;
}
@Override
@@ -69,7 +72,46 @@ public TunerClass getTunerClass()
*/
public DeviceType getDeviceType()
{
- return getControlRsp().getDeviceDescriptor().getDeviceType();
+ return mDeviceInfo.getDeviceType();
+ }
+
+ /**
+ * Constructs and starts the tuner
+ */
+ @Override
+ public void start()
+ {
+ if(isAvailable() && !hasTuner())
+ {
+ try
+ {
+ mTuner = TunerFactory.getRspTuner(getDeviceInfo(), getChannelizerType(), this);
+ }
+ catch(Exception se)
+ {
+ setErrorMessage("Tuner unavailable [" + getId() + "]");
+ mTuner = null;
+ }
+
+ if(hasTuner())
+ {
+ try
+ {
+ mTuner.start();
+ }
+ catch(Exception se)
+ {
+ setErrorMessage("Error starting tuner [" + getId() + "]");
+ mTuner = null;
+ }
+ }
+ }
+ }
+
+ @Override
+ public String getId()
+ {
+ return getDeviceType().name() + " SER#" + getDeviceInfo().getSerialNumber();
}
@Override
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 4a99f7f86..43faf9d22 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
@@ -1,6 +1,6 @@
/*
* *****************************************************************************
- * Copyright (C) 2014-2022 Dennis Sheirer
+ * 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
@@ -19,11 +19,11 @@
package io.github.dsheirer.source.tuner.sdrplay;
-import com.github.dsheirer.sdrplay.DeviceDescriptor;
import com.github.dsheirer.sdrplay.DeviceSelectionMode;
import com.github.dsheirer.sdrplay.SDRPlayException;
import com.github.dsheirer.sdrplay.callback.IDeviceEventListener;
import com.github.dsheirer.sdrplay.callback.IStreamListener;
+import com.github.dsheirer.sdrplay.device.Device;
import com.github.dsheirer.sdrplay.device.TunerSelect;
/**
@@ -37,7 +37,7 @@ public interface IControlRsp
* Device descriptor for this RSP
* @return device descriptor
*/
- DeviceDescriptor getDeviceDescriptor();
+ Device getDevice();
/**
* Selected tuner for this RSP.
diff --git a/src/main/java/io/github/dsheirer/source/tuner/sdrplay/RspTuner.java b/src/main/java/io/github/dsheirer/source/tuner/sdrplay/RspTuner.java
index 94291ccf7..59a7762be 100644
--- a/src/main/java/io/github/dsheirer/source/tuner/sdrplay/RspTuner.java
+++ b/src/main/java/io/github/dsheirer/source/tuner/sdrplay/RspTuner.java
@@ -1,6 +1,6 @@
/*
* *****************************************************************************
- * Copyright (C) 2014-2022 Dennis Sheirer
+ * 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
@@ -52,7 +52,7 @@ public int getMaximumUSBBitsPerSecond()
@Override
public String getUniqueID()
{
- return getRspTunerController().getControlRsp().getDeviceDescriptor().getSerialNumber();
+ return getRspTunerController().getControlRsp().getDevice().getSerialNumber();
}
@Override
@@ -74,18 +74,18 @@ public String getPreferredName()
{
if(getRspTunerController().getControlRsp() instanceof IControlRspDuoTuner1)
{
- return getRspTunerController().getControlRsp().getDeviceDescriptor().getDeviceType() +
- " SER:" + getRspTunerController().getControlRsp().getDeviceDescriptor().getSerialNumber() + " Tuner 1";
+ return getRspTunerController().getControlRsp().getDevice().getDeviceType() +
+ " SER:" + getRspTunerController().getControlRsp().getDevice().getSerialNumber() + " Tuner 1";
}
else if(getRspTunerController().getControlRsp() instanceof IControlRspDuoTuner2)
{
- return getRspTunerController().getControlRsp().getDeviceDescriptor().getDeviceType() +
- " SER:" + getRspTunerController().getControlRsp().getDeviceDescriptor().getSerialNumber() + " Tuner 2";
+ return getRspTunerController().getControlRsp().getDevice().getDeviceType() +
+ " SER:" + getRspTunerController().getControlRsp().getDevice().getSerialNumber() + " Tuner 2";
}
else
{
- return getRspTunerController().getControlRsp().getDeviceDescriptor().getDeviceType() +
- " SER:" + getRspTunerController().getControlRsp().getDeviceDescriptor().getSerialNumber();
+ return getRspTunerController().getControlRsp().getDevice().getDeviceType() +
+ " SER:" + getRspTunerController().getControlRsp().getDevice().getSerialNumber();
}
}
diff --git a/src/main/java/io/github/dsheirer/source/tuner/sdrplay/RspTunerController.java b/src/main/java/io/github/dsheirer/source/tuner/sdrplay/RspTunerController.java
index 670c04a1d..ca84002ae 100644
--- a/src/main/java/io/github/dsheirer/source/tuner/sdrplay/RspTunerController.java
+++ b/src/main/java/io/github/dsheirer/source/tuner/sdrplay/RspTunerController.java
@@ -1,6 +1,6 @@
/*
* *****************************************************************************
- * Copyright (C) 2014-2022 Dennis Sheirer
+ * 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
@@ -242,7 +242,6 @@ public long getTunedFrequency() throws SourceException
@Override
public void setTunedFrequency(long frequency) throws SourceException
{
- mLog.info("Setting tuned frequency to [" + frequency + "] tuner: " + getClass());
try
{
getControlRsp().setTunedFrequency(frequency);
diff --git a/src/main/java/io/github/dsheirer/source/tuner/sdrplay/rsp1a/ControlRsp1a.java b/src/main/java/io/github/dsheirer/source/tuner/sdrplay/rsp1a/ControlRsp1a.java
index aecfb44ff..af1dd02c3 100644
--- a/src/main/java/io/github/dsheirer/source/tuner/sdrplay/rsp1a/ControlRsp1a.java
+++ b/src/main/java/io/github/dsheirer/source/tuner/sdrplay/rsp1a/ControlRsp1a.java
@@ -1,6 +1,6 @@
/*
* *****************************************************************************
- * Copyright (C) 2014-2022 Dennis Sheirer
+ * 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
@@ -19,234 +19,26 @@
package io.github.dsheirer.source.tuner.sdrplay.rsp1a;
-import com.github.dsheirer.sdrplay.DeviceDescriptor;
-import com.github.dsheirer.sdrplay.DeviceSelectionMode;
import com.github.dsheirer.sdrplay.SDRPlayException;
-import com.github.dsheirer.sdrplay.SDRplay;
-import com.github.dsheirer.sdrplay.UpdateReason;
-import com.github.dsheirer.sdrplay.device.Device;
import com.github.dsheirer.sdrplay.device.Rsp1aDevice;
-import com.github.dsheirer.sdrplay.device.TunerSelect;
-import com.github.dsheirer.sdrplay.parameter.control.AgcMode;
-import com.github.dsheirer.sdrplay.parameter.tuner.IfMode;
-import com.github.dsheirer.sdrplay.parameter.tuner.LoMode;
import io.github.dsheirer.source.tuner.sdrplay.ControlRsp;
-import io.github.dsheirer.source.tuner.sdrplay.RspSampleRate;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
/**
* Control wrapper for an RSP1A Device
*/
-public class ControlRsp1a extends ControlRsp implements IControlRsp1a
+public class ControlRsp1a extends ControlRsp implements IControlRsp1a
{
private Logger mLog = LoggerFactory.getLogger(ControlRsp1a.class);
- private Rsp1aDevice mDevice;
/**
* Constructs an instance
- * @param sdrplayApi to control the device
- * @param deviceDescriptor for the device
+ * @param device for the device
*/
- public ControlRsp1a(SDRplay sdrplayApi, DeviceDescriptor deviceDescriptor)
+ public ControlRsp1a(Rsp1aDevice device)
{
- super(sdrplayApi, deviceDescriptor);
- }
-
- /**
- * Indicates if this control has been started and has a non-null device
- */
- private boolean hasDevice()
- {
- return getDevice() != null;
- }
-
- /**
- * Access the device.
- * @return device or null.
- */
- private Rsp1aDevice getDevice()
- {
- return mDevice;
- }
-
- @Override
- public TunerSelect getTunerSelect()
- {
- return TunerSelect.TUNER_1;
- }
-
- @Override
- public void start() throws SDRPlayException
- {
- Device device = getApi().select(getDeviceDescriptor(), DeviceSelectionMode.SINGLE_TUNER_1);
-
- if(device instanceof Rsp1aDevice rsp1aDevice)
- {
- mDevice = rsp1aDevice;
- getDevice().select();
-
- //Enable automatic DC and I/Q correction
- 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);
- getDevice().setIfMode(IfMode.IF_ZERO);
- getDevice().setLoMode(LoMode.AUTO);
- }
- }
-
- @Override
- public void stop() throws SDRPlayException
- {
- if(hasDevice())
- {
- getDevice().release();
- mDevice = null;
- }
- }
-
- @Override
- public void startStream()
- {
- mStreamingLock.lock();
-
- try
- {
- if(hasDevice())
- {
- if(!mStreaming)
- {
- getDevice().initStreamA(getDeviceEventListener(), getStreamListener());
- mStreaming = true;
- }
- }
- else
- {
- mLog.error("Unable to start RSP1A sample stream - device not started");
- }
- }
- catch(SDRPlayException se)
- {
- mLog.error("Unable to initialize/start streaming for RSP1A");
- }
- finally
- {
- mStreamingLock.unlock();
- }
- }
-
- @Override
- public void stopStream()
- {
- mStreamingLock.lock();
-
- try
- {
- if(hasDevice())
- {
- if(mStreaming)
- {
- getDevice().uninitialize();
- mStreaming = false;
- }
- }
- else
- {
- mLog.error("Unable to stop RSP1A sample stream - device not started");
- }
- }
- catch(SDRPlayException se)
- {
- mLog.error("Unable to uninitialize/stop streaming for RSP1A");
- }
- finally
- {
- mStreamingLock.unlock();
- }
- }
-
- /**
- * Sets the sample rate
- * @param sampleRate enumeration value.
- * @throws SDRPlayException
- */
- @Override
- public void setSampleRate(RspSampleRate sampleRate) throws SDRPlayException
- {
- if(hasDevice() && !sampleRate.equals(mSampleRate))
- {
- mSampleRate = sampleRate;
-
- getDevice().getTuner().setBandwidth(sampleRate.getBandwidth());
- getDevice().getCompositeParameters().getDeviceParameters().getSamplingFrequency()
- .setSampleRate(sampleRate.getSampleRate());
- getDevice().update(getTunerSelect(), UpdateReason.DEVICE_SAMPLE_RATE);
- getDevice().getCompositeParameters().getControlAParameters().getDecimation().setWideBandSignal(true);
- getDevice().setDecimation(sampleRate.getDecimation());
- }
- else
- {
- throw new SDRPlayException("Device is not initialized");
- }
- }
-
- /**
- * Sets the gain index
- * @param gain index value (0 - 28)
- * @throws SDRPlayException
- */
- @Override
- public void setGain(int gain) throws SDRPlayException
- {
- validateGain(gain);
-
- if(gain != mGain)
- {
- mGain = gain;
- getDevice().getTuner().setGain(mGain);
- }
- }
-
-
- @Override
- public void acknowledgePowerOverload(TunerSelect tunerSelect) throws SDRPlayException
- {
- if(hasDevice())
- {
- getDevice().acknowledgePowerOverload(tunerSelect);
- }
- else
- {
- throw new SDRPlayException("Device is not initialized");
- }
- }
-
- @Override
- public long getTunedFrequency() throws SDRPlayException
- {
- if(hasDevice())
- {
- return getDevice().getTuner().getFrequency();
- }
- else
- {
- throw new SDRPlayException("Device is not initialized");
- }
- }
-
- @Override
- public void setTunedFrequency(long frequency) throws SDRPlayException
- {
- if(hasDevice())
- {
- getDevice().getTuner().setFrequency(frequency);
- }
- else
- {
- throw new SDRPlayException("Device is not initialized");
- }
+ super(device);
}
@Override
diff --git a/src/main/java/io/github/dsheirer/source/tuner/sdrplay/rsp1a/DiscoveredRsp1aTuner.java b/src/main/java/io/github/dsheirer/source/tuner/sdrplay/rsp1a/DiscoveredRsp1aTuner.java
index 58677b447..c2994f0ab 100644
--- a/src/main/java/io/github/dsheirer/source/tuner/sdrplay/rsp1a/DiscoveredRsp1aTuner.java
+++ b/src/main/java/io/github/dsheirer/source/tuner/sdrplay/rsp1a/DiscoveredRsp1aTuner.java
@@ -1,6 +1,6 @@
/*
* *****************************************************************************
- * Copyright (C) 2014-2022 Dennis Sheirer
+ * 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
@@ -19,10 +19,9 @@
package io.github.dsheirer.source.tuner.sdrplay.rsp1a;
+import com.github.dsheirer.sdrplay.device.DeviceInfo;
import io.github.dsheirer.preference.source.ChannelizerType;
-import io.github.dsheirer.source.SourceException;
import io.github.dsheirer.source.tuner.sdrplay.DiscoveredRspTuner;
-import io.github.dsheirer.source.tuner.sdrplay.RspTuner;
/**
* RSP1A discovered tuner.
@@ -31,39 +30,11 @@ public class DiscoveredRsp1aTuner extends DiscoveredRspTuner
{
/**
* Constructs an instance
- * @param controlRsp1a for controlling the RSP1A after it's been started
+ * @param deviceInfo for controlling the RSP1A after it's been started
* @param channelizerType to use for the tuner once started
*/
- public DiscoveredRsp1aTuner(IControlRsp1a controlRsp1a, ChannelizerType channelizerType)
+ public DiscoveredRsp1aTuner(DeviceInfo deviceInfo, ChannelizerType channelizerType)
{
- super(controlRsp1a, channelizerType);
- }
-
- /**
- * Constructs and starts the tuner
- */
- @Override
- public void start()
- {
- if(isAvailable() && !hasTuner())
- {
- Rsp1aTunerController tunerController = new Rsp1aTunerController(getControlRsp(), this);
- mTuner = new RspTuner(tunerController, this, getChannelizerType());
- try
- {
- mTuner.start();
- }
- catch(SourceException se)
- {
- setErrorMessage("Error starting RSP1A [" + getId() + "]");
- mTuner = null;
- }
- }
- }
-
- @Override
- public String getId()
- {
- return "RSP1A SER#" + getControlRsp().getDeviceDescriptor().getSerialNumber();
+ super(deviceInfo, channelizerType);
}
}
diff --git a/src/main/java/io/github/dsheirer/source/tuner/sdrplay/rsp2/ControlRsp2.java b/src/main/java/io/github/dsheirer/source/tuner/sdrplay/rsp2/ControlRsp2.java
index 0e2cf8beb..33b6dd7da 100644
--- a/src/main/java/io/github/dsheirer/source/tuner/sdrplay/rsp2/ControlRsp2.java
+++ b/src/main/java/io/github/dsheirer/source/tuner/sdrplay/rsp2/ControlRsp2.java
@@ -1,6 +1,6 @@
/*
* *****************************************************************************
- * Copyright (C) 2014-2022 Dennis Sheirer
+ * 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
@@ -19,236 +19,29 @@
package io.github.dsheirer.source.tuner.sdrplay.rsp2;
-import com.github.dsheirer.sdrplay.DeviceDescriptor;
-import com.github.dsheirer.sdrplay.DeviceSelectionMode;
import com.github.dsheirer.sdrplay.SDRPlayException;
-import com.github.dsheirer.sdrplay.SDRplay;
-import com.github.dsheirer.sdrplay.UpdateReason;
-import com.github.dsheirer.sdrplay.device.Device;
import com.github.dsheirer.sdrplay.device.Rsp2Device;
-import com.github.dsheirer.sdrplay.device.TunerSelect;
-import com.github.dsheirer.sdrplay.parameter.control.AgcMode;
-import com.github.dsheirer.sdrplay.parameter.tuner.IfMode;
-import com.github.dsheirer.sdrplay.parameter.tuner.LoMode;
import com.github.dsheirer.sdrplay.parameter.tuner.Rsp2AntennaSelection;
import io.github.dsheirer.source.tuner.sdrplay.ControlRsp;
-import io.github.dsheirer.source.tuner.sdrplay.RspSampleRate;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
/**
* Control wrapper for an RSP2 Device
*/
-public class ControlRsp2 extends ControlRsp implements IControlRsp2
+public class ControlRsp2 extends ControlRsp implements IControlRsp2
{
private Logger mLog = LoggerFactory.getLogger(ControlRsp2.class);
- private Rsp2Device mDevice;
private Rsp2AntennaSelection mAntennaSelection = Rsp2AntennaSelection.ANT_A;
/**
* Constructs an instance
* @param sdrplayApi to control the device
- * @param deviceDescriptor for the device
+ * @param device to control
*/
- public ControlRsp2(SDRplay sdrplayApi, DeviceDescriptor deviceDescriptor)
+ public ControlRsp2(Rsp2Device device)
{
- super(sdrplayApi, deviceDescriptor);
- }
-
- /**
- * Indicates if this control has been started and has a non-null device
- */
- private boolean hasDevice()
- {
- return getDevice() != null;
- }
-
- /**
- * Access the device.
- * @return device or null.
- */
- private Rsp2Device getDevice()
- {
- return mDevice;
- }
-
- @Override
- public TunerSelect getTunerSelect()
- {
- return TunerSelect.TUNER_1;
- }
-
- @Override
- public void start() throws SDRPlayException
- {
- Device device = getApi().select(getDeviceDescriptor(), DeviceSelectionMode.SINGLE_TUNER_1);
-
- if(device instanceof Rsp2Device rsp2Device)
- {
- mDevice = rsp2Device;
- getDevice().select();
-
- //Enable automatic DC and I/Q correction
- 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);
- getDevice().setIfMode(IfMode.IF_ZERO);
- getDevice().setLoMode(LoMode.AUTO);
- }
- }
-
- @Override
- public void stop() throws SDRPlayException
- {
- if(hasDevice())
- {
- getDevice().release();
- mDevice = null;
- }
- }
-
- @Override
- public void startStream()
- {
- mStreamingLock.lock();
-
- try
- {
- if(hasDevice())
- {
- if(!mStreaming)
- {
- getDevice().initStreamA(getDeviceEventListener(), getStreamListener());
- mStreaming = true;
- }
- }
- else
- {
- mLog.error("Unable to start RSP1A sample stream - device not started");
- }
- }
- catch(SDRPlayException se)
- {
- mLog.error("Unable to initialize/start streaming for RSP1A");
- }
- finally
- {
- mStreamingLock.unlock();
- }
- }
-
- @Override
- public void stopStream()
- {
- mStreamingLock.lock();
-
- try
- {
- if(hasDevice())
- {
- if(mStreaming)
- {
- getDevice().uninitialize();
- mStreaming = false;
- }
- }
- else
- {
- mLog.error("Unable to stop RSP1A sample stream - device not started");
- }
- }
- catch(SDRPlayException se)
- {
- mLog.error("Unable to uninitialize/stop streaming for RSP1A");
- }
- finally
- {
- mStreamingLock.unlock();
- }
- }
-
- /**
- * Sets the sample rate
- * @param sampleRate enumeration value.
- * @throws SDRPlayException
- */
- @Override
- public void setSampleRate(RspSampleRate sampleRate) throws SDRPlayException
- {
- if(hasDevice() && !sampleRate.equals(mSampleRate))
- {
- mSampleRate = sampleRate;
-
- getDevice().getTuner().setBandwidth(sampleRate.getBandwidth());
- getDevice().getCompositeParameters().getDeviceParameters().getSamplingFrequency()
- .setSampleRate(sampleRate.getSampleRate());
- getDevice().update(getTunerSelect(), UpdateReason.DEVICE_SAMPLE_RATE);
- getDevice().getCompositeParameters().getControlAParameters().getDecimation().setWideBandSignal(true);
- getDevice().setDecimation(sampleRate.getDecimation());
- }
- else
- {
- throw new SDRPlayException("Device is not initialized");
- }
- }
-
- /**
- * Sets the gain index
- * @param gain index value (0 - 28)
- * @throws SDRPlayException
- */
- @Override
- public void setGain(int gain) throws SDRPlayException
- {
- validateGain(gain);
-
- if(gain != mGain)
- {
- mGain = gain;
- getDevice().getTuner().setGain(mGain);
- }
- }
-
-
- @Override
- public void acknowledgePowerOverload(TunerSelect tunerSelect) throws SDRPlayException
- {
- if(hasDevice())
- {
- getDevice().acknowledgePowerOverload(tunerSelect);
- }
- else
- {
- throw new SDRPlayException("Device is not initialized");
- }
- }
-
- @Override
- public long getTunedFrequency() throws SDRPlayException
- {
- if(hasDevice())
- {
- return getDevice().getTuner().getFrequency();
- }
- else
- {
- throw new SDRPlayException("Device is not initialized");
- }
- }
-
- @Override
- public void setTunedFrequency(long frequency) throws SDRPlayException
- {
- if(hasDevice())
- {
- getDevice().getTuner().setFrequency(frequency);
- }
- else
- {
- throw new SDRPlayException("Device is not initialized");
- }
+ super(device);
}
@Override
diff --git a/src/main/java/io/github/dsheirer/source/tuner/sdrplay/rsp2/DiscoveredRsp2Tuner.java b/src/main/java/io/github/dsheirer/source/tuner/sdrplay/rsp2/DiscoveredRsp2Tuner.java
index cd648b554..9032a87d3 100644
--- a/src/main/java/io/github/dsheirer/source/tuner/sdrplay/rsp2/DiscoveredRsp2Tuner.java
+++ b/src/main/java/io/github/dsheirer/source/tuner/sdrplay/rsp2/DiscoveredRsp2Tuner.java
@@ -1,6 +1,6 @@
/*
* *****************************************************************************
- * Copyright (C) 2014-2022 Dennis Sheirer
+ * 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
@@ -19,10 +19,9 @@
package io.github.dsheirer.source.tuner.sdrplay.rsp2;
+import com.github.dsheirer.sdrplay.device.DeviceInfo;
import io.github.dsheirer.preference.source.ChannelizerType;
-import io.github.dsheirer.source.SourceException;
import io.github.dsheirer.source.tuner.sdrplay.DiscoveredRspTuner;
-import io.github.dsheirer.source.tuner.sdrplay.RspTuner;
/**
* RSP2 discovered tuner.
@@ -31,39 +30,11 @@ public class DiscoveredRsp2Tuner extends DiscoveredRspTuner
{
/**
* Constructs an instance
- * @param controlRsp2 for controlling the RSP2 after it's been started
+ * @param deviceInfo for the tuner
* @param channelizerType to use for the tuner once started
*/
- public DiscoveredRsp2Tuner(IControlRsp2 controlRsp2, ChannelizerType channelizerType)
+ public DiscoveredRsp2Tuner(DeviceInfo deviceInfo, ChannelizerType channelizerType)
{
- super(controlRsp2, channelizerType);
- }
-
- /**
- * Constructs and starts the tuner
- */
- @Override
- public void start()
- {
- if(isAvailable() && !hasTuner())
- {
- Rsp2TunerController tunerController = new Rsp2TunerController(getControlRsp(), this);
- mTuner = new RspTuner(tunerController, this, getChannelizerType());
- try
- {
- mTuner.start();
- }
- catch(SourceException se)
- {
- setErrorMessage("Error starting RSP2 [" + getId() + "]");
- mTuner = null;
- }
- }
- }
-
- @Override
- public String getId()
- {
- return "RSP2 SER#" + getControlRsp().getDeviceDescriptor().getSerialNumber();
+ super(deviceInfo, channelizerType);
}
}
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 7b73a1a67..6fd63520d 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
@@ -1,6 +1,6 @@
/*
* *****************************************************************************
- * Copyright (C) 2014-2022 Dennis Sheirer
+ * 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
@@ -19,12 +19,9 @@
package io.github.dsheirer.source.tuner.sdrplay.rspDuo;
-import com.github.dsheirer.sdrplay.DeviceDescriptor;
import com.github.dsheirer.sdrplay.DeviceSelectionMode;
import com.github.dsheirer.sdrplay.SDRPlayException;
-import com.github.dsheirer.sdrplay.SDRplay;
import com.github.dsheirer.sdrplay.UpdateReason;
-import com.github.dsheirer.sdrplay.device.Device;
import com.github.dsheirer.sdrplay.device.RspDuoDevice;
import com.github.dsheirer.sdrplay.device.RspDuoTuner;
import com.github.dsheirer.sdrplay.device.TunerSelect;
@@ -41,20 +38,18 @@
/**
* Base control wrapper for an RSPduo operating in either single-tuner or master or slave mode.
*/
-public abstract class ControlRspDuo extends ControlRsp implements IControlRspDuo
+public abstract class ControlRspDuo extends ControlRsp implements IControlRspDuo
{
private final Logger mLog = LoggerFactory.getLogger(ControlRspDuo.class);
- protected RspDuoDevice mDevice;
/**
* Constructs an instance
*
- * @param sdrplayApi to use
- * @param deviceDescriptor for the device, obtained from the API
+ * @param device for the device, obtained from the API
*/
- public ControlRspDuo(SDRplay sdrplayApi, DeviceDescriptor deviceDescriptor)
+ public ControlRspDuo(RspDuoDevice device)
{
- super(sdrplayApi, deviceDescriptor);
+ super(device);
}
/**
@@ -81,32 +76,20 @@ public ControlRspDuo(SDRplay sdrplayApi, DeviceDescriptor deviceDescriptor)
*/
protected abstract TunerParameters getTunerParameters();
- /**
- * Indicates if this control has been started and has a non-null device
- */
- protected boolean hasDevice()
- {
- return getDevice() != null;
- }
-
- /**
- * Access the device.
- * @return device or null.
- */
- protected RspDuoDevice getDevice()
- {
- return mDevice;
- }
-
@Override
public void start() throws SDRPlayException
{
- Device device = getApi().select(getDeviceDescriptor(), getDeviceSelectionMode());
-
- if(device instanceof RspDuoDevice rspDuoDevice)
+ if(hasDevice())
{
- mLog.info("*** Starting ControlRspDuo ....");
- mDevice = rspDuoDevice;
+ getDevice().setRspDuoMode(getDeviceSelectionMode().getRspDuoMode());
+ getDevice().setTunerSelect(getDeviceSelectionMode().getTunerSelect());
+
+ //In master mode, we have to set the sample rate here, before we select the device
+ if(getDeviceSelectionMode().isMasterMode())
+ {
+ getDevice().setRspDuoSampleFrequency(8_000_000);
+ }
+
getDevice().select();
//Enable automatic DC and I/Q correction
@@ -127,16 +110,9 @@ public void start() throws SDRPlayException
getTunerParameters().setIfMode(IfMode.IF_2048);
}
}
- }
-
- @Override
- public void stop() throws SDRPlayException
- {
- if(hasDevice())
+ else
{
- stopStream();
- getDevice().release();
- mDevice = null;
+ throw new SDRPlayException("Unable to start - no device");
}
}
@@ -202,25 +178,20 @@ public void stopStream()
@Override
public void setSampleRate(RspSampleRate sampleRate) throws SDRPlayException
{
- mLog.info("Setting sample rate to: " + sampleRate.name() + " device: " + this.getClass());
if(hasDevice())
{
mSampleRate = sampleRate;
- mLog.info("Setting bandwidth: " + sampleRate.getBandwidth().name());
getDevice().getTuner().setBandwidth(sampleRate.getBandwidth());
- mLog.info("Setting sample rate: " + sampleRate.getSampleRate());
getDevice().getCompositeParameters().getDeviceParameters().getSamplingFrequency()
.setSampleRate(sampleRate.getSampleRate());
//Only send an update if we're in single-tuner mode ... not sure why we don't have to for dual-tuner mode.
if(getDeviceSelectionMode() != DeviceSelectionMode.MASTER_TUNER_1)
{
- mLog.info("Sending update for tuner select [" + getTunerSelect() + "]");
getDevice().update(getTunerSelect(), UpdateReason.DEVICE_SAMPLE_RATE);
}
- mLog.info("Setting wideband signal to true");
+
getControlParameters().getDecimation().setWideBandSignal(true);
- mLog.info("Setting decimation to: " + sampleRate.getDecimation());
getDevice().setDecimation(sampleRate.getDecimation());
}
else
diff --git a/src/main/java/io/github/dsheirer/source/tuner/sdrplay/rspDuo/ControlRspDuoTuner1.java b/src/main/java/io/github/dsheirer/source/tuner/sdrplay/rspDuo/ControlRspDuoTuner1.java
index 4bd3c2083..4e05307eb 100644
--- a/src/main/java/io/github/dsheirer/source/tuner/sdrplay/rspDuo/ControlRspDuoTuner1.java
+++ b/src/main/java/io/github/dsheirer/source/tuner/sdrplay/rspDuo/ControlRspDuoTuner1.java
@@ -1,6 +1,6 @@
/*
* *****************************************************************************
- * Copyright (C) 2014-2022 Dennis Sheirer
+ * 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
@@ -19,9 +19,8 @@
package io.github.dsheirer.source.tuner.sdrplay.rspDuo;
-import com.github.dsheirer.sdrplay.DeviceDescriptor;
import com.github.dsheirer.sdrplay.SDRPlayException;
-import com.github.dsheirer.sdrplay.SDRplay;
+import com.github.dsheirer.sdrplay.device.RspDuoDevice;
import com.github.dsheirer.sdrplay.device.RspDuoTuner1;
import com.github.dsheirer.sdrplay.device.TunerSelect;
import com.github.dsheirer.sdrplay.parameter.control.ControlParameters;
@@ -40,12 +39,11 @@ public abstract class ControlRspDuoTuner1 extends ControlRspDuo im
/**
* Constructs an instance
*
- * @param sdrplayApi to use
- * @param deviceDescriptor for the device, obtained from the API
+ * @param device to control
*/
- public ControlRspDuoTuner1(SDRplay sdrplayApi, DeviceDescriptor deviceDescriptor)
+ public ControlRspDuoTuner1(RspDuoDevice device)
{
- super(sdrplayApi, deviceDescriptor);
+ super(device);
}
/**
@@ -57,7 +55,7 @@ protected RspDuoTuner1 getTuner() throws SDRPlayException
{
if(hasDevice())
{
- return (RspDuoTuner1)getDevice().getTuner();
+ return (RspDuoTuner1) getDevice().getTuner();
}
throw new SDRPlayException("RSPduo device is not started");
diff --git a/src/main/java/io/github/dsheirer/source/tuner/sdrplay/rspDuo/ControlRspDuoTuner1Master.java b/src/main/java/io/github/dsheirer/source/tuner/sdrplay/rspDuo/ControlRspDuoTuner1Master.java
index eb266f261..641921df0 100644
--- a/src/main/java/io/github/dsheirer/source/tuner/sdrplay/rspDuo/ControlRspDuoTuner1Master.java
+++ b/src/main/java/io/github/dsheirer/source/tuner/sdrplay/rspDuo/ControlRspDuoTuner1Master.java
@@ -1,6 +1,6 @@
/*
* *****************************************************************************
- * Copyright (C) 2014-2022 Dennis Sheirer
+ * 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
@@ -19,16 +19,14 @@
package io.github.dsheirer.source.tuner.sdrplay.rspDuo;
-import com.github.dsheirer.sdrplay.DeviceDescriptor;
import com.github.dsheirer.sdrplay.DeviceSelectionMode;
import com.github.dsheirer.sdrplay.SDRPlayException;
-import com.github.dsheirer.sdrplay.SDRplay;
+import com.github.dsheirer.sdrplay.device.RspDuoDevice;
import io.github.dsheirer.source.tuner.sdrplay.RspSampleRate;
+import java.util.EnumSet;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
-import java.util.EnumSet;
-
/**
* RSPduo operating in dual-tuner mode with tuner 1 configured as master.
*/
@@ -49,20 +47,11 @@ public class ControlRspDuoTuner1Master extends ControlRspDuoTuner1
/**
* Constructs an instance
*
- * @param sdrplayApi to use
- * @param deviceDescriptor for the device, obtained from the API
- */
- public ControlRspDuoTuner1Master(SDRplay sdrplayApi, DeviceDescriptor deviceDescriptor)
- {
- super(sdrplayApi, deviceDescriptor);
- }
-
- /**
- * Assigns the streaming control bridge to this master and registers this master with the bridge.
- * @param bridge to assign
+ * @param device to control
*/
- public void setBridge(MasterSlaveBridge bridge)
+ public ControlRspDuoTuner1Master(RspDuoDevice device, MasterSlaveBridge bridge)
{
+ super(device);
mMasterSlaveBridge = bridge;
}
diff --git a/src/main/java/io/github/dsheirer/source/tuner/sdrplay/rspDuo/ControlRspDuoTuner1Single.java b/src/main/java/io/github/dsheirer/source/tuner/sdrplay/rspDuo/ControlRspDuoTuner1Single.java
index a819e56ff..022707dfc 100644
--- a/src/main/java/io/github/dsheirer/source/tuner/sdrplay/rspDuo/ControlRspDuoTuner1Single.java
+++ b/src/main/java/io/github/dsheirer/source/tuner/sdrplay/rspDuo/ControlRspDuoTuner1Single.java
@@ -1,6 +1,6 @@
/*
* *****************************************************************************
- * Copyright (C) 2014-2022 Dennis Sheirer
+ * 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
@@ -19,12 +19,10 @@
package io.github.dsheirer.source.tuner.sdrplay.rspDuo;
-import com.github.dsheirer.sdrplay.DeviceDescriptor;
import com.github.dsheirer.sdrplay.DeviceSelectionMode;
import com.github.dsheirer.sdrplay.SDRPlayException;
-import com.github.dsheirer.sdrplay.SDRplay;
+import com.github.dsheirer.sdrplay.device.RspDuoDevice;
import io.github.dsheirer.source.tuner.sdrplay.RspSampleRate;
-
import java.util.EnumSet;
/**
@@ -35,12 +33,11 @@ public class ControlRspDuoTuner1Single extends ControlRspDuoTuner1
/**
* Constructs an instance
*
- * @param sdrplayApi to use
- * @param deviceDescriptor for the device, obtained from the API
+ * @param device to control
*/
- public ControlRspDuoTuner1Single(SDRplay sdrplayApi, DeviceDescriptor deviceDescriptor)
+ public ControlRspDuoTuner1Single(RspDuoDevice device)
{
- super(sdrplayApi, deviceDescriptor);
+ super(device);
}
@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 048d64fe9..d054436af 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
@@ -1,6 +1,6 @@
/*
* *****************************************************************************
- * Copyright (C) 2014-2022 Dennis Sheirer
+ * 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
@@ -19,9 +19,8 @@
package io.github.dsheirer.source.tuner.sdrplay.rspDuo;
-import com.github.dsheirer.sdrplay.DeviceDescriptor;
import com.github.dsheirer.sdrplay.SDRPlayException;
-import com.github.dsheirer.sdrplay.SDRplay;
+import com.github.dsheirer.sdrplay.device.RspDuoDevice;
import com.github.dsheirer.sdrplay.device.RspDuoTuner2;
import com.github.dsheirer.sdrplay.device.TunerSelect;
import com.github.dsheirer.sdrplay.parameter.control.ControlParameters;
@@ -39,12 +38,11 @@ public abstract class ControlRspDuoTuner2 extends ControlRspDuo im
/**
* Constructs an instance
*
- * @param sdrplayApi to use
- * @param deviceDescriptor for the device, obtained from the API
+ * @param device for the device, obtained from the API
*/
- public ControlRspDuoTuner2(SDRplay sdrplayApi, DeviceDescriptor deviceDescriptor)
+ public ControlRspDuoTuner2(RspDuoDevice device)
{
- super(sdrplayApi, deviceDescriptor);
+ super(device);
}
/**
@@ -56,7 +54,7 @@ protected RspDuoTuner2 getTuner() throws SDRPlayException
{
if(hasDevice())
{
- return (RspDuoTuner2)getDevice().getTuner();
+ return (RspDuoTuner2) getDevice().getTuner();
}
throw new SDRPlayException("RSPduo device is not started");
diff --git a/src/main/java/io/github/dsheirer/source/tuner/sdrplay/rspDuo/ControlRspDuoTuner2Single.java b/src/main/java/io/github/dsheirer/source/tuner/sdrplay/rspDuo/ControlRspDuoTuner2Single.java
index fb815d0ee..64bf8ccfe 100644
--- a/src/main/java/io/github/dsheirer/source/tuner/sdrplay/rspDuo/ControlRspDuoTuner2Single.java
+++ b/src/main/java/io/github/dsheirer/source/tuner/sdrplay/rspDuo/ControlRspDuoTuner2Single.java
@@ -1,6 +1,6 @@
/*
* *****************************************************************************
- * Copyright (C) 2014-2022 Dennis Sheirer
+ * 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
@@ -19,16 +19,14 @@
package io.github.dsheirer.source.tuner.sdrplay.rspDuo;
-import com.github.dsheirer.sdrplay.DeviceDescriptor;
import com.github.dsheirer.sdrplay.DeviceSelectionMode;
import com.github.dsheirer.sdrplay.SDRPlayException;
-import com.github.dsheirer.sdrplay.SDRplay;
+import com.github.dsheirer.sdrplay.device.RspDuoDevice;
import io.github.dsheirer.source.tuner.sdrplay.RspSampleRate;
+import java.util.EnumSet;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
-import java.util.EnumSet;
-
/**
* Control wrapper for an RSPduo Tuner 2 operating in single-tuner mode.
*/
@@ -39,12 +37,11 @@ public class ControlRspDuoTuner2Single extends ControlRspDuoTuner2
/**
* Constructs an instance
*
- * @param sdrplayApi to use
- * @param deviceDescriptor for the device, obtained from the API
+ * @param device to control
*/
- public ControlRspDuoTuner2Single(SDRplay sdrplayApi, DeviceDescriptor deviceDescriptor)
+ public ControlRspDuoTuner2Single(RspDuoDevice device)
{
- super(sdrplayApi, deviceDescriptor);
+ super(device);
}
@Override
diff --git a/src/main/java/io/github/dsheirer/source/tuner/sdrplay/rspDuo/ControlRspDuoTuner2Slave.java b/src/main/java/io/github/dsheirer/source/tuner/sdrplay/rspDuo/ControlRspDuoTuner2Slave.java
index 20adb64ec..f31cc2c6c 100644
--- a/src/main/java/io/github/dsheirer/source/tuner/sdrplay/rspDuo/ControlRspDuoTuner2Slave.java
+++ b/src/main/java/io/github/dsheirer/source/tuner/sdrplay/rspDuo/ControlRspDuoTuner2Slave.java
@@ -1,6 +1,6 @@
/*
* *****************************************************************************
- * Copyright (C) 2014-2022 Dennis Sheirer
+ * 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
@@ -19,12 +19,10 @@
package io.github.dsheirer.source.tuner.sdrplay.rspDuo;
-import com.github.dsheirer.sdrplay.DeviceDescriptor;
import com.github.dsheirer.sdrplay.DeviceSelectionMode;
import com.github.dsheirer.sdrplay.SDRPlayException;
-import com.github.dsheirer.sdrplay.SDRplay;
+import com.github.dsheirer.sdrplay.device.RspDuoDevice;
import io.github.dsheirer.source.tuner.sdrplay.RspSampleRate;
-
import java.util.EnumSet;
/**
@@ -37,12 +35,12 @@ public class ControlRspDuoTuner2Slave extends ControlRspDuoTuner2
/**
* Constructs an instance
*
- * @param sdrplayApi to use
- * @param deviceDescriptor for the device, obtained from the API
+ * @param device to control
*/
- public ControlRspDuoTuner2Slave(SDRplay sdrplayApi, DeviceDescriptor deviceDescriptor)
+ public ControlRspDuoTuner2Slave(RspDuoDevice device, MasterSlaveBridge bridge)
{
- super(sdrplayApi, deviceDescriptor);
+ super(device);
+ mMasterSlaveBridge = bridge;
}
/**
@@ -61,15 +59,6 @@ public void startStream()
super.startStream();
}
- /**
- * Assigns the streaming control bridge to this slave and registers this slave with the bridge.
- * @param bridge to assign
- */
- public void setBridge(MasterSlaveBridge bridge)
- {
- mMasterSlaveBridge = bridge;
- }
-
@Override
public boolean isSlaveMode()
{
diff --git a/src/main/java/io/github/dsheirer/source/tuner/sdrplay/rspDuo/DiscoveredRspDuoTuner1.java b/src/main/java/io/github/dsheirer/source/tuner/sdrplay/rspDuo/DiscoveredRspDuoTuner1.java
index d4e9bdb87..b817f9ded 100644
--- a/src/main/java/io/github/dsheirer/source/tuner/sdrplay/rspDuo/DiscoveredRspDuoTuner1.java
+++ b/src/main/java/io/github/dsheirer/source/tuner/sdrplay/rspDuo/DiscoveredRspDuoTuner1.java
@@ -1,6 +1,6 @@
/*
* *****************************************************************************
- * Copyright (C) 2014-2022 Dennis Sheirer
+ * 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
@@ -19,26 +19,46 @@
package io.github.dsheirer.source.tuner.sdrplay.rspDuo;
+import com.github.dsheirer.sdrplay.device.DeviceInfo;
import io.github.dsheirer.preference.source.ChannelizerType;
-import io.github.dsheirer.source.SourceException;
+import io.github.dsheirer.source.tuner.TunerFactory;
import io.github.dsheirer.source.tuner.sdrplay.DiscoveredRspTuner;
import io.github.dsheirer.source.tuner.sdrplay.RspTuner;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
/**
* RSPduo Tuner 1 discovered tuner.
+ *
+ * When constructed with a master-slave bridge, this device will be used in master-slave mode. If the bridge is not
+ * provided as construction time, the device will be configured for single-tuner operation.
*/
public class DiscoveredRspDuoTuner1 extends DiscoveredRspTuner
{
+ private static final Logger mLog = LoggerFactory.getLogger(DiscoveredRspTuner.class);
public static final String RSP_DUO_ID_PREFIX = "RSPduo Tuner ";
+ private MasterSlaveBridge mMasterSlaveBridge;
/**
- * Constructs an instance
- * @param controlRspDuoTuner1 for controlling the RSPduo after it's been started
+ * Constructs an instance configured for a single-tuner
+ * @param deviceInfo describing the tuner
* @param channelizerType to use for the tuner once started
*/
- public DiscoveredRspDuoTuner1(IControlRspDuoTuner1 controlRspDuoTuner1, ChannelizerType channelizerType)
+ public DiscoveredRspDuoTuner1(DeviceInfo deviceInfo, ChannelizerType channelizerType)
{
- super(controlRspDuoTuner1, channelizerType);
+ super(deviceInfo, channelizerType);
+ }
+
+ /**
+ * Constructs an instance configured as Master Tuner 1.
+ * @param deviceInfo describing the tuner
+ * @param channelizerType to use for the tuner once started
+ * @param bridge for synchronizing with the slaved tuner 2.
+ */
+ public DiscoveredRspDuoTuner1(DeviceInfo deviceInfo, ChannelizerType channelizerType, MasterSlaveBridge bridge)
+ {
+ super(deviceInfo, channelizerType);
+ mMasterSlaveBridge = bridge;
}
/**
@@ -49,23 +69,48 @@ public void start()
{
if(isAvailable() && !hasTuner())
{
- RspDuoTuner1Controller tunerController = new RspDuoTuner1Controller(getControlRsp(), this);
- mTuner = new RspTuner(tunerController, this, getChannelizerType());
try
{
- mTuner.start();
+ if(mMasterSlaveBridge != null)
+ {
+ mTuner = TunerFactory.getRspDuoTuner(getDeviceInfo(), getChannelizerType(), this, mMasterSlaveBridge);
+
+ if(mTuner instanceof RspTuner rspTuner &&
+ rspTuner.getRspTunerController() instanceof RspDuoTuner1Controller rspDuoTuner1Controller)
+ {
+ mMasterSlaveBridge.setMaster(rspDuoTuner1Controller);
+ }
+ }
+ else
+ {
+ mTuner = TunerFactory.getRspTuner(getDeviceInfo(), getChannelizerType(), this);
+ }
}
- catch(SourceException se)
+ catch(Exception se)
{
- setErrorMessage("Error starting RSPduo Tuner 1 [" + getId() + "]");
+ setErrorMessage("Tuner unavailable [" + getId() + "]");
mTuner = null;
}
+
+ if(hasTuner())
+ {
+ try
+ {
+ mTuner.start();
+ }
+ catch(Exception se)
+ {
+ mLog.error("Error", se);
+ setErrorMessage("Error starting tuner [" + getId() + "]");
+ mTuner = null;
+ }
+ }
}
}
@Override
public String getId()
{
- return RSP_DUO_ID_PREFIX + "1 SER#" + getControlRsp().getDeviceDescriptor().getSerialNumber();
+ return RSP_DUO_ID_PREFIX + "1 SER#" + getDeviceInfo().getSerialNumber();
}
}
diff --git a/src/main/java/io/github/dsheirer/source/tuner/sdrplay/rspDuo/DiscoveredRspDuoTuner2.java b/src/main/java/io/github/dsheirer/source/tuner/sdrplay/rspDuo/DiscoveredRspDuoTuner2.java
index f9809c2d3..24beee645 100644
--- a/src/main/java/io/github/dsheirer/source/tuner/sdrplay/rspDuo/DiscoveredRspDuoTuner2.java
+++ b/src/main/java/io/github/dsheirer/source/tuner/sdrplay/rspDuo/DiscoveredRspDuoTuner2.java
@@ -1,6 +1,6 @@
/*
* *****************************************************************************
- * Copyright (C) 2014-2022 Dennis Sheirer
+ * 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
@@ -19,24 +19,41 @@
package io.github.dsheirer.source.tuner.sdrplay.rspDuo;
+import com.github.dsheirer.sdrplay.device.DeviceInfo;
import io.github.dsheirer.preference.source.ChannelizerType;
-import io.github.dsheirer.source.SourceException;
+import io.github.dsheirer.source.tuner.TunerFactory;
import io.github.dsheirer.source.tuner.sdrplay.DiscoveredRspTuner;
-import io.github.dsheirer.source.tuner.sdrplay.RspTuner;
/**
* RSPduo Tuner 2 discovered tuner.
+ *
+ * When constructed with a master-slave bridge, this device will be used in master-slave mode. If the bridge is not
+ * provided as construction time, the device will be configured for single-tuner operation.
*/
public class DiscoveredRspDuoTuner2 extends DiscoveredRspTuner
{
+ private MasterSlaveBridge mMasterSlaveBridge;
+
+ /**
+ * Constructs an instance configured for a single-tuner
+ * @param deviceInfo describing the tuner
+ * @param channelizerType to use for the tuner once started
+ */
+ public DiscoveredRspDuoTuner2(DeviceInfo deviceInfo, ChannelizerType channelizerType)
+ {
+ super(deviceInfo, channelizerType);
+ }
+
/**
- * Constructs an instance
- * @param controlRspDuoTuner2 for controlling the RSPduo after it's been started
+ * Constructs an instance configured as Slave Tuner 2.
+ * @param deviceInfo describing the tuner
* @param channelizerType to use for the tuner once started
+ * @param bridge for synchronizing with the master tuner 1.
*/
- public DiscoveredRspDuoTuner2(IControlRspDuoTuner2 controlRspDuoTuner2, ChannelizerType channelizerType)
+ public DiscoveredRspDuoTuner2(DeviceInfo deviceInfo, ChannelizerType channelizerType, MasterSlaveBridge bridge)
{
- super(controlRspDuoTuner2, channelizerType);
+ super(deviceInfo, channelizerType);
+ mMasterSlaveBridge = bridge;
}
/**
@@ -47,23 +64,49 @@ public void start()
{
if(isAvailable() && !hasTuner())
{
- RspDuoTuner2Controller tunerController = new RspDuoTuner2Controller(getControlRsp(), this);
- mTuner = new RspTuner(tunerController, this, getChannelizerType());
try
{
- mTuner.start();
+ if(mMasterSlaveBridge != null)
+ {
+ mTuner = TunerFactory.getRspDuoTuner(getDeviceInfo(), getChannelizerType(), this, mMasterSlaveBridge);
+ }
+ else
+ {
+ mTuner = TunerFactory.getRspTuner(getDeviceInfo(), getChannelizerType(), this);
+ }
}
- catch(SourceException se)
+ catch(Exception se)
{
- setErrorMessage("Error starting RSPduo Tuner 2 [" + getId() + "]");
+ setErrorMessage("Tuner unavailable [" + getId() + "]");
mTuner = null;
}
+
+ if(hasTuner())
+ {
+ try
+ {
+ mTuner.start();
+
+ if(mMasterSlaveBridge != null)
+ {
+ if(mTuner.getTunerController() instanceof RspDuoTuner2Controller rspDuoTuner2Controller)
+ {
+ mMasterSlaveBridge.setSlave(rspDuoTuner2Controller);
+ }
+ }
+ }
+ catch(Exception se)
+ {
+ setErrorMessage("Error starting tuner [" + getId() + "]");
+ mTuner = null;
+ }
+ }
}
}
@Override
public String getId()
{
- return DiscoveredRspDuoTuner1.RSP_DUO_ID_PREFIX + "2 SER#" + getControlRsp().getDeviceDescriptor().getSerialNumber();
+ return DiscoveredRspDuoTuner1.RSP_DUO_ID_PREFIX + "2 SER#" + getDeviceInfo().getSerialNumber();
}
}
diff --git a/src/main/java/io/github/dsheirer/source/tuner/sdrplay/rspDuo/MasterSlaveBridge.java b/src/main/java/io/github/dsheirer/source/tuner/sdrplay/rspDuo/MasterSlaveBridge.java
index a94523ad8..b4b21817f 100644
--- a/src/main/java/io/github/dsheirer/source/tuner/sdrplay/rspDuo/MasterSlaveBridge.java
+++ b/src/main/java/io/github/dsheirer/source/tuner/sdrplay/rspDuo/MasterSlaveBridge.java
@@ -1,6 +1,6 @@
/*
* *****************************************************************************
- * Copyright (C) 2014-2022 Dennis Sheirer
+ * 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
@@ -109,6 +109,7 @@ public void stopSlave()
if(mSlave != null)
{
mSlave.stop();
+ mSlave = null;
}
}
diff --git a/src/main/java/io/github/dsheirer/source/tuner/sdrplay/rspDuo/RspDuoTuner2Editor.java b/src/main/java/io/github/dsheirer/source/tuner/sdrplay/rspDuo/RspDuoTuner2Editor.java
index 3fdb9a6dd..5d691727c 100644
--- a/src/main/java/io/github/dsheirer/source/tuner/sdrplay/rspDuo/RspDuoTuner2Editor.java
+++ b/src/main/java/io/github/dsheirer/source/tuner/sdrplay/rspDuo/RspDuoTuner2Editor.java
@@ -1,6 +1,6 @@
/*
* *****************************************************************************
- * Copyright (C) 2014-2022 Dennis Sheirer
+ * 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
@@ -28,6 +28,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 java.util.EnumSet;
import net.miginfocom.swing.MigLayout;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@@ -39,7 +40,6 @@
import javax.swing.JPanel;
import javax.swing.JSeparator;
import javax.swing.SpinnerNumberModel;
-import java.util.EnumSet;
/**
* RSPduo Tuner 2 Editor
@@ -130,7 +130,7 @@ private RspDuoTuner2Controller getTunerController()
*/
private boolean isSlaveMode()
{
- return getDiscoveredRspTuner().getControlRsp() instanceof ControlRspDuoTuner2Slave;
+ return getDiscoveredRspTuner().getDeviceInfo().getDeviceSelectionMode().isSlaveMode();
}
@Override
diff --git a/src/main/java/io/github/dsheirer/source/tuner/sdrplay/rspDx/ControlRspDx.java b/src/main/java/io/github/dsheirer/source/tuner/sdrplay/rspDx/ControlRspDx.java
index 0f0df7d85..8c3c9ffbc 100644
--- a/src/main/java/io/github/dsheirer/source/tuner/sdrplay/rspDx/ControlRspDx.java
+++ b/src/main/java/io/github/dsheirer/source/tuner/sdrplay/rspDx/ControlRspDx.java
@@ -1,6 +1,6 @@
/*
* *****************************************************************************
- * Copyright (C) 2014-2022 Dennis Sheirer
+ * 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
@@ -19,236 +19,28 @@
package io.github.dsheirer.source.tuner.sdrplay.rspDx;
-import com.github.dsheirer.sdrplay.DeviceDescriptor;
-import com.github.dsheirer.sdrplay.DeviceSelectionMode;
import com.github.dsheirer.sdrplay.SDRPlayException;
-import com.github.dsheirer.sdrplay.SDRplay;
-import com.github.dsheirer.sdrplay.UpdateReason;
-import com.github.dsheirer.sdrplay.device.Device;
import com.github.dsheirer.sdrplay.device.RspDxDevice;
-import com.github.dsheirer.sdrplay.device.TunerSelect;
-import com.github.dsheirer.sdrplay.parameter.control.AgcMode;
import com.github.dsheirer.sdrplay.parameter.tuner.HdrModeBandwidth;
-import com.github.dsheirer.sdrplay.parameter.tuner.IfMode;
-import com.github.dsheirer.sdrplay.parameter.tuner.LoMode;
import com.github.dsheirer.sdrplay.parameter.tuner.RspDxAntenna;
import io.github.dsheirer.source.tuner.sdrplay.ControlRsp;
-import io.github.dsheirer.source.tuner.sdrplay.RspSampleRate;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
/**
* Control wrapper for an RSPdx Device
*/
-public class ControlRspDx extends ControlRsp implements IControlRspDx
+public class ControlRspDx extends ControlRsp implements IControlRspDx
{
private Logger mLog = LoggerFactory.getLogger(ControlRspDx.class);
- private RspDxDevice mDevice;
/**
* Constructs an instance
- * @param sdrplayApi to control the device
- * @param deviceDescriptor for the device
+ * @param device for the device
*/
- public ControlRspDx(SDRplay sdrplayApi, DeviceDescriptor deviceDescriptor)
+ public ControlRspDx(RspDxDevice device)
{
- super(sdrplayApi, deviceDescriptor);
- }
-
- /**
- * Indicates if this control has been started and has a non-null device
- */
- private boolean hasDevice()
- {
- return getDevice() != null;
- }
-
- /**
- * Access the device.
- * @return device or null.
- */
- private RspDxDevice getDevice()
- {
- return mDevice;
- }
-
- @Override
- public TunerSelect getTunerSelect()
- {
- return TunerSelect.TUNER_1;
- }
-
- @Override
- public void start() throws SDRPlayException
- {
- Device device = getApi().select(getDeviceDescriptor(), DeviceSelectionMode.SINGLE_TUNER_1);
-
- if(device instanceof RspDxDevice rspDxDevice)
- {
- mDevice = rspDxDevice;
- getDevice().select();
-
- //Enable automatic DC and I/Q correction
- 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);
- getDevice().setIfMode(IfMode.IF_ZERO);
- getDevice().setLoMode(LoMode.AUTO);
- }
- }
-
- @Override
- public void stop() throws SDRPlayException
- {
- if(hasDevice())
- {
- getDevice().release();
- mDevice = null;
- }
- }
-
- @Override
- public void startStream()
- {
- mStreamingLock.lock();
-
- try
- {
- if(hasDevice())
- {
- if(!mStreaming)
- {
- getDevice().initStreamA(getDeviceEventListener(), getStreamListener());
- mStreaming = true;
- }
- }
- else
- {
- mLog.error("Unable to start RSPdx sample stream - device not started");
- }
- }
- catch(SDRPlayException se)
- {
- mLog.error("Unable to initialize/start streaming for RSPdx");
- }
- finally
- {
- mStreamingLock.unlock();
- }
- }
-
- @Override
- public void stopStream()
- {
- mStreamingLock.lock();
-
- try
- {
- if(hasDevice())
- {
- if(mStreaming)
- {
- getDevice().uninitialize();
- mStreaming = false;
- }
- }
- else
- {
- mLog.error("Unable to stop RSPdx sample stream - device not started");
- }
- }
- catch(SDRPlayException se)
- {
- mLog.error("Unable to uninitialize/stop streaming for RSPdx");
- }
- finally
- {
- mStreamingLock.unlock();
- }
- }
-
- /**
- * Sets the sample rate
- * @param sampleRate enumeration value.
- * @throws SDRPlayException
- */
- @Override
- public void setSampleRate(RspSampleRate sampleRate) throws SDRPlayException
- {
- if(hasDevice() && !sampleRate.equals(mSampleRate))
- {
- mSampleRate = sampleRate;
-
- getDevice().getTuner().setBandwidth(sampleRate.getBandwidth());
- getDevice().getCompositeParameters().getDeviceParameters().getSamplingFrequency()
- .setSampleRate(sampleRate.getSampleRate());
- getDevice().update(getTunerSelect(), UpdateReason.DEVICE_SAMPLE_RATE);
- getDevice().getCompositeParameters().getControlAParameters().getDecimation().setWideBandSignal(true);
- getDevice().setDecimation(sampleRate.getDecimation());
- }
- else
- {
- throw new SDRPlayException("Device is not initialized");
- }
- }
-
- /**
- * Sets the gain index
- * @param gain index value (0 - 28)
- * @throws SDRPlayException
- */
- @Override
- public void setGain(int gain) throws SDRPlayException
- {
- validateGain(gain);
-
- if(gain != mGain)
- {
- mGain = gain;
- getDevice().getTuner().setGain(mGain);
- }
- }
-
-
- @Override
- public void acknowledgePowerOverload(TunerSelect tunerSelect) throws SDRPlayException
- {
- if(hasDevice())
- {
- getDevice().acknowledgePowerOverload(tunerSelect);
- }
- else
- {
- throw new SDRPlayException("Device is not initialized");
- }
- }
-
- @Override
- public long getTunedFrequency() throws SDRPlayException
- {
- if(hasDevice())
- {
- return getDevice().getTuner().getFrequency();
- }
- else
- {
- throw new SDRPlayException("Device is not initialized");
- }
- }
-
- @Override
- public void setTunedFrequency(long frequency) throws SDRPlayException
- {
- if(hasDevice())
- {
- getDevice().getTuner().setFrequency(frequency);
- }
- else
- {
- throw new SDRPlayException("Device is not initialized");
- }
+ super(device);
}
@Override
diff --git a/src/main/java/io/github/dsheirer/source/tuner/sdrplay/rspDx/DiscoveredRspDxTuner.java b/src/main/java/io/github/dsheirer/source/tuner/sdrplay/rspDx/DiscoveredRspDxTuner.java
index 76db4cee7..0f8d927db 100644
--- a/src/main/java/io/github/dsheirer/source/tuner/sdrplay/rspDx/DiscoveredRspDxTuner.java
+++ b/src/main/java/io/github/dsheirer/source/tuner/sdrplay/rspDx/DiscoveredRspDxTuner.java
@@ -1,6 +1,6 @@
/*
* *****************************************************************************
- * Copyright (C) 2014-2022 Dennis Sheirer
+ * 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
@@ -19,10 +19,9 @@
package io.github.dsheirer.source.tuner.sdrplay.rspDx;
+import com.github.dsheirer.sdrplay.device.DeviceInfo;
import io.github.dsheirer.preference.source.ChannelizerType;
-import io.github.dsheirer.source.SourceException;
import io.github.dsheirer.source.tuner.sdrplay.DiscoveredRspTuner;
-import io.github.dsheirer.source.tuner.sdrplay.RspTuner;
/**
* RSPdx discovered tuner.
@@ -31,39 +30,11 @@ public class DiscoveredRspDxTuner extends DiscoveredRspTuner
{
/**
* Constructs an instance
- * @param controlRspDx for controlling the RSPdx after it's been started
+ * @param deviceInfo for the tuner
* @param channelizerType to use for the tuner once started
*/
- public DiscoveredRspDxTuner(IControlRspDx controlRspDx, ChannelizerType channelizerType)
+ public DiscoveredRspDxTuner(DeviceInfo deviceInfo, ChannelizerType channelizerType)
{
- super(controlRspDx, channelizerType);
- }
-
- /**
- * Constructs and starts the tuner
- */
- @Override
- public void start()
- {
- if(isAvailable() && !hasTuner())
- {
- RspDxTunerController tunerController = new RspDxTunerController(getControlRsp(), this);
- mTuner = new RspTuner(tunerController, this, getChannelizerType());
- try
- {
- mTuner.start();
- }
- catch(SourceException se)
- {
- setErrorMessage("Error starting RSPdx [" + getId() + "]");
- mTuner = null;
- }
- }
- }
-
- @Override
- public String getId()
- {
- return "RSPdx SER#" + getControlRsp().getDeviceDescriptor().getSerialNumber();
+ super(deviceInfo, channelizerType);
}
}