diff --git a/.gitignore b/.gitignore index e4a1c09b3..0396c7c1c 100644 --- a/.gitignore +++ b/.gitignore @@ -21,9 +21,12 @@ out/ # virtual machine crash logs, see http://www.java.com/en/download/help/error_hotspot.xml hs_err_pid* + ### Gradle template .gradle /build/ +/jsdrplay/build/ +/sdrplay-api/build/ # Ignore Gradle GUI config gradle-app.setting diff --git a/.idea/misc.xml b/.idea/misc.xml index dced427a5..d88165c03 100644 --- a/.idea/misc.xml +++ b/.idea/misc.xml @@ -4,7 +4,7 @@ - + \ No newline at end of file diff --git a/build.gradle b/build.gradle index 7e0df7c2a..46aa85a01 100644 --- a/build.gradle +++ b/build.gradle @@ -1,3 +1,5 @@ +import java.text.SimpleDateFormat + /* * ***************************************************************************** * Copyright (C) 2014-2022 Dennis Sheirer @@ -29,7 +31,13 @@ repositories { } version = '0.6.0-alpha1' -sourceCompatibility = '17' + +//Java 19 is required for this version of the Project Panama preview/incubator feature +java { + toolchain { + languageVersion = JavaLanguageVersion.of(19) + } +} sourceSets { main.java.srcDirs 'src/main' @@ -42,6 +50,9 @@ test { dependencies { + implementation project('sdrplay-api') + implementation project('jsdrplay') + // JUnit Tests testImplementation 'junit:junit:4.13.2' testImplementation 'org.assertj:assertj-core:3.23.1' @@ -91,10 +102,11 @@ dependencies { } /** - * This is needed for the JDK17 vector API ... until it moves out of incubation + * This is needed for the JDK19 panama and vector API ... until it moves out of incubation or preview */ tasks.withType(JavaCompile) { options.compilerArgs.add("--add-modules=jdk.incubator.vector") //Needed while Panama Vector API remains in incubator + options.compilerArgs.add("--enable-preview") //Panama Foreign Function/Memory is preview in JDK 19 } application { @@ -102,7 +114,21 @@ application { applicationDefaultJvmArgs = ['--add-exports=javafx.base/com.sun.javafx.event=ALL-UNNAMED', //Needed for controls-fx.jar '--add-modules=jdk.incubator.vector', //Needed while Panama Vector API remains in incubator - '--add-exports=java.desktop/com.sun.java.swing.plaf.windows=ALL-UNNAMED'] //Windows Swing - jide-oss library + '--add-exports=java.desktop/com.sun.java.swing.plaf.windows=ALL-UNNAMED', //Windows Swing - jide-oss library + '--enable-preview', + '--enable-native-access=ALL-UNNAMED'] //Panama Foreign Function access +} + +//Adds the SDRPlay native API library to the java system path for runtime +run { + OperatingSystem os = org.gradle.nativeplatform.platform.internal.DefaultNativePlatform.currentOperatingSystem; + + if(os.isWindows()) { + systemProperty "java.library.path", "c:\\Program Files\\SDRplay\\API\\x64" + } + else { + systemProperty "java.library.path", "/usr/local/lib" + } } jar { @@ -111,7 +137,7 @@ jar { 'Implementation-Title' : 'sdrtrunk project', 'Implementation-Version' : archiveVersion, 'Created-By' : "Gradle ${gradle.gradleVersion}", - 'Build-Timestamp' : new java.text.SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSSZ").format(new Date()), + 'Build-Timestamp' : new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSSZ").format(new Date()), 'Build-JDK' : "${System.properties['java.version']} (${System.properties['java.vendor']} ${System.properties['java.vm.version']}", 'Build-OS' : "${System.properties['os.name']} (${System.properties['os.arch']} ${System.properties['os.version']}" ) diff --git a/jsdrplay/build.gradle b/jsdrplay/build.gradle new file mode 100644 index 000000000..ef6661e42 --- /dev/null +++ b/jsdrplay/build.gradle @@ -0,0 +1,85 @@ +import org.gradle.nativeplatform.platform.internal.DefaultNativePlatform + +plugins { + id 'java' + id 'maven-publish' +} + +group 'com.github.DSheirer' +version '3.11.0.0' + +repositories { + mavenCentral() + maven { url "https://jitpack.io" } +} + +//Java 19 is required for this version of the Project Panama preview/incubator feature +java { + toolchain { + languageVersion = JavaLanguageVersion.of(19) + } +} + +/** + * This is needed for the JDK19 panama until it moves out of preview + */ +tasks.withType(JavaCompile) { + options.compilerArgs.add("--enable-preview") //Panama Foreign Function/Memory is preview in JDK 19 +} + +var incubatorArguments = ["-Djava.library.path=" + getJavaLibraryPath()] + +tasks.withType(JavaExec) { + jvmArgs += incubatorArguments +} +tasks.withType(Test) { + jvmArgs += incubatorArguments +} + +dependencies { + implementation project(':sdrplay-api') + implementation 'ch.qos.logback:logback-classic:1.4.4' + implementation 'org.apache.commons:commons-lang3:3.12.0' + implementation 'org.slf4j:slf4j-api:2.0.3' + + testImplementation 'com.github.wendykierp:JTransforms:3.1' + testImplementation 'org.junit.jupiter:junit-jupiter-api:5.9.0' + testRuntimeOnly 'org.junit.jupiter:junit-jupiter-engine:5.9.0' +} + +test { + useJUnitPlatform() + + //Exclude all tests by default. Comment out this line to run tests. +// exclude '**/*' +} + +/** + * Determine library path for the current operating system and architecture + */ +static String getJavaLibraryPath() { + OperatingSystem os = DefaultNativePlatform.currentOperatingSystem + + if(os.isLinux() || os.isMacOsX()) { + return "/usr/local/lib" + } + + if(os.isWindows()) { + if(System.getProperty("sun.arch.data.model").contentEquals("64")) { + return "c:\\Program Files\\SDRplay\\API\\x64" + } + else { + return "c:\\Program Files\\SDRplay\\API\\x86" + } + } + + return "" +} + +publishing { + publications { + mavenJava(MavenPublication) { + from components.java + } + } +} \ No newline at end of file diff --git a/jsdrplay/src/main/java/com/github/dsheirer/sdrplay/DeviceSelectionMode.java b/jsdrplay/src/main/java/com/github/dsheirer/sdrplay/DeviceSelectionMode.java new file mode 100644 index 000000000..cdfc76c67 --- /dev/null +++ b/jsdrplay/src/main/java/com/github/dsheirer/sdrplay/DeviceSelectionMode.java @@ -0,0 +1,106 @@ +/* + * ***************************************************************************** + * 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; + +import com.github.dsheirer.sdrplay.device.RspDuoMode; +import com.github.dsheirer.sdrplay.device.TunerSelect; +import java.util.EnumSet; + +/** + * Enumeration of modes that indicate how each SDRplay RSP device can be selected + */ +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), + MASTER_TUNER_1("Master - Tuner 1", RspDuoMode.MASTER, TunerSelect.TUNER_1), + SLAVE_TUNER_2("Slave - Tuner 2", RspDuoMode.SLAVE, TunerSelect.TUNER_2); + + private String mDescription; + private RspDuoMode mRspDuoMode; + private TunerSelect mTunerSelect; + + /** + * Private constructor + * @param description of the mode + * @param rspDuoMode that corresponds to the mode + * @param tunerSelect tuner(s) that correspond to the mode + */ + DeviceSelectionMode(String description, RspDuoMode rspDuoMode, TunerSelect tunerSelect) + { + mDescription = description; + mRspDuoMode = rspDuoMode; + mTunerSelect = tunerSelect; + } + + /** + * Set of all selection modes available for the RSPduo + */ + 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); + + /** + * RSPduo mode associated with the selection mode + */ + public RspDuoMode getRspDuoMode() + { + return mRspDuoMode; + } + + /** + * Indicates if this mode is designated as a master mode. + */ + public boolean isMasterMode() + { + return MASTER_MODES.contains(this); + } + + /** + * Indicates if this mode is designated as a slave mode. + */ + public boolean isSlaveMode() + { + return SLAVE_MODES.contains(this); + } + + /** + * Indicates if this is a single-tuner mode + */ + public boolean isSingleTunerMode() + { + return SINGLE_TUNER_MODES.contains(this); + } + + /** + * Tuner(s) associated with the selection mode + */ + public TunerSelect getTunerSelect() + { + return mTunerSelect; + } + + @Override + public String toString() + { + return mDescription; + } +} diff --git a/jsdrplay/src/main/java/com/github/dsheirer/sdrplay/SDRPlayException.java b/jsdrplay/src/main/java/com/github/dsheirer/sdrplay/SDRPlayException.java new file mode 100644 index 000000000..6e911b6fd --- /dev/null +++ b/jsdrplay/src/main/java/com/github/dsheirer/sdrplay/SDRPlayException.java @@ -0,0 +1,63 @@ +/* + * ***************************************************************************** + * 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; + +/** + * SDRplay checked exception. + */ +public class SDRPlayException extends Exception +{ + private Status mStatus = Status.UNKNOWN; + + /** + * Creates an exception + * @param message for the exception + */ + public SDRPlayException(String message) + { + super(message); + } + + /** + * Creates an operation exception + * @param message for the exception + * @param status of the operation + */ + public SDRPlayException(String message, Status status) + { + super(message + " Status:" + status); + mStatus = status; + } + + /** + * Creates an exception + * @param message for the exception + * @param throwable nested exception + */ + public SDRPlayException(String message, Throwable throwable) + { + super(message, throwable); + } + + public Status getStatus() + { + return mStatus; + } +} diff --git a/jsdrplay/src/main/java/com/github/dsheirer/sdrplay/SDRPlayUpdateException.java b/jsdrplay/src/main/java/com/github/dsheirer/sdrplay/SDRPlayUpdateException.java new file mode 100644 index 000000000..8bbfcc37a --- /dev/null +++ b/jsdrplay/src/main/java/com/github/dsheirer/sdrplay/SDRPlayUpdateException.java @@ -0,0 +1,49 @@ +/* + * ***************************************************************************** + * 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 java.util.ArrayList; +import java.util.List; + +/** + * SDRplay failed update request checked exception. + */ +public class SDRPlayUpdateException extends SDRPlayException +{ + private List mUpdateReasons = new ArrayList<>(); + + /** + * Creates an operation exception + * @param status of the operation + * @param updateReasons that were submitted + */ + public SDRPlayUpdateException(Status status, List updateReasons) + { + super("Unable to update device parameters: " + updateReasons, status); + } + + /** + * List of update reasons that failed. + */ + public List getUpdateReasons() + { + return mUpdateReasons; + } +} diff --git a/jsdrplay/src/main/java/com/github/dsheirer/sdrplay/SDRplay.java b/jsdrplay/src/main/java/com/github/dsheirer/sdrplay/SDRplay.java new file mode 100644 index 000000000..072bf61b2 --- /dev/null +++ b/jsdrplay/src/main/java/com/github/dsheirer/sdrplay/SDRplay.java @@ -0,0 +1,708 @@ +/* + * ***************************************************************************** + * 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; + +import com.github.dsheirer.sdrplay.api.v3_07.sdrplay_api_DeviceT; +import com.github.dsheirer.sdrplay.api.v3_07.sdrplay_api_ErrorInfoT; +import com.github.dsheirer.sdrplay.api.v3_07.sdrplay_api_h; +import com.github.dsheirer.sdrplay.callback.CallbackFunctions; +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.DeviceFactory; +import com.github.dsheirer.sdrplay.device.DeviceInfo; +import com.github.dsheirer.sdrplay.device.DeviceType; +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 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.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. + * + * Note: the jextract auto-generated RuntimeHelper contains a static block that attempts to load the sdrplay_api + * library. This approach fails because the API is installed to a non-default location. Comment out the library + * load code in the RuntimeHelper and we'll directly load the library. + * + * // System.loadLibrary("libsdrplay_api"); + */ +public class SDRplay +{ + public static final String SDRPLAY_API_LIBRARY_NAME = "sdrplay_api"; + public static final String SDRPLAY_API_PATH_LINUX = "/usr/local/lib/libsdrplay_api.so"; + public static final String SDRPLAY_API_PATH_MAC_OS = "/usr/local/lib/libsdrplay_api.dylib"; + public static final String SDRPLAY_API_PATH_WINDOWS = System.getenv("ProgramFiles") + + "\\SDRplay\\API\\" + (System.getProperty("sun.arch.data.model").contentEquals("64") ? "x64" : "x86") + + "\\" + SDRPLAY_API_LIBRARY_NAME; + public static final String JAVA_LIBRARY_PATH_KEY = "java.library.path"; + + private static final Logger mLog = LoggerFactory.getLogger(SDRplay.class); + + /** + * Foreign memory allocation resource scope + */ + private final MemorySession mGlobalMemorySession = MemorySession.global(); + + /** + * Indicates if libsdrplay_api.xx library was found and loaded. + */ + private boolean mSdrplayLibraryLoaded; + + /** + * Indicates if the library is available, meaning that the host system library was loaded AND it supports the + * correct API version + */ + private boolean mAvailable; + + /** + * Map of (reusable) callback functions for each device. Key value is the device handle memory address + */ + private final Map mDeviceCallbackFunctionsMap = new HashMap<>(); + + /** + * Detected version of the API installed on the local system. + */ + private Version mVersion; + + /** + * Controls logging of library load status so that it only gets logged once. Set to false once initial logging complete + */ + private static boolean sLibraryLoadStatusLogging = true; + + /** + * Constructs an instance of the SDRPLay API + */ + public SDRplay() + { + mSdrplayLibraryLoaded = loadLibrary(); + + if(mSdrplayLibraryLoaded) + { + Status openStatus = open(); + if(sLibraryLoadStatusLogging) + { + mLog.info("API library - open status: " + openStatus); + } + mAvailable = openStatus.success() && getVersion().isSupported(); + } + else + { + if(sLibraryLoadStatusLogging) + { + mLog.info("API library was not loaded"); + } + mAvailable = false; + } + + if(isAvailable()) + { + if(sLibraryLoadStatusLogging) + { + mLog.info("API library v" + getVersion() + " - loaded"); + } + } + else + { + if(sLibraryLoadStatusLogging) + { + mLog.info("API library is not available."); + } + } + + sLibraryLoadStatusLogging = false; + } + + /** + * Global Memory Session for this API instance + */ + private MemorySession getGlobalMemorySession() + { + return mGlobalMemorySession; + } + + /** + * Attempts to load the SDRPlay API library from the local system. + * + * @return true if library was loaded successfully. + */ + private boolean loadLibrary() + { + try + { + String libraryPath = getSDRplayLibraryPath(); + 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 API library from default install path. Loading from java system library path", t); + + try + { + System.loadLibrary(SDRPLAY_API_LIBRARY_NAME); + return true; + } + catch(Throwable t2) + { + String name = System.mapLibraryName(SDRPLAY_API_LIBRARY_NAME); + + 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); + } + } + } + + return false; + } + + /** + * List of devices available via the API + * @return list of device infos. + * @throws SDRPlayException if there is an error + */ + 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.createDeviceArray(getVersion(), getGlobalMemorySession()); + + MemorySegment deviceCount = getGlobalMemorySession().allocate(ValueLayout.JAVA_INT, 0); + + Status status = Status.fromValue(sdrplay_api_h.sdrplay_api_GetDevices(devicesArray, deviceCount, + sdrplay_api_h.SDRPLAY_MAX_DEVICES())); + + if(status.success()) + { + int count = deviceCount.get(ValueLayout.JAVA_INT, 0); + deviceStructs.addAll(DeviceFactory.parseDeviceStructs(getVersion(), devicesArray, count)); + } + else + { + mLog.error("Couldn't load RSP devices from API. Status: " + status); + } + + 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 DeviceInfo getDevice(String serialNumber) throws SDRPlayException + { + for(DeviceInfo deviceInfo: getDeviceInfos()) + { + if(deviceInfo.getSerialNumber().equals(serialNumber)) + { + return deviceInfo; + } + } + + return null; + } + + /** + * Obtains the device that matches the device info argument. + * @param deviceInfo to match + * @return non-null device + * @throws SDRPlayException + */ + public Device getDevice(DeviceInfo deviceInfo) throws SDRPlayException + { + Device device = null; + + if(isAvailable()) + { + List deviceStructs = getDeviceStructures(); + + for(IDeviceStruct deviceStruct: deviceStructs) + { + if(deviceInfo.matches(deviceStruct)) + { + device = DeviceFactory.createDevice(this, deviceStruct); + break; + } + } + } + + if(device == null) + { + throw new SDRPlayException("Unable to find RSP device"); + } + + return device; + } + + + /** + * Finds the first device that matches the specified device type. + * + * @param deviceType to find + * @return the specified device type or null. + */ + public DeviceInfo getDeviceInfo(DeviceType deviceType) throws SDRPlayException + { + for(DeviceInfo deviceInfo : getDeviceInfos()) + { + if(deviceInfo.getDeviceType() == deviceType) + { + return deviceInfo; + } + } + + return null; + } + + /** + * Selects the device for exclusive use. This method is invoked by the device instance. + * + * @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(MemorySegment memorySegment) throws SDRPlayException + { + lockDeviceApi(); + Status selectStatus = Status.fromValue(sdrplay_api_h.sdrplay_api_SelectDevice(memorySegment)); + unlockDeviceApi(); + + if(selectStatus.fail()) + { + throw new SDRPlayException("Unable to select the device", selectStatus); + } + } + + /** + * Releases the device from exclusive use. This method is invoked by the device instance. + * + * @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(MemorySegment memorySegment) throws SDRPlayException + { + Status status = Status.fromValue(sdrplay_api_h.sdrplay_api_ReleaseDevice(memorySegment)); + + if(status.fail()) + { + mLog.info("API call to release device failed, however device is effectively released now."); + } + } + + /** + * 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 deviceType to load parameters + * @param deviceHandle to device + * @return constructed device composite paramaters + */ + public CompositeParameters getCompositeParameters(DeviceType deviceType, MemoryAddress deviceHandle) throws SDRPlayException + { + //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)); + + if(status.success()) + { + //Get the memory address from the pointer's memory segment to where the structure is located + MemoryAddress memoryAddress = pointer.get(ValueLayout.ADDRESS, 0); + + //The structure's memory is already allocated ... wrap a memory segment around it + MemorySegment memorySegment = sdrplay_api_DeviceT.ofAddress(memoryAddress, mGlobalMemorySession); + return CompositeParametersFactory.create(deviceType, memorySegment, mGlobalMemorySession); + } + else + { + throw new SDRPlayException("Error retrieving device composite parameters", status); + } + } + + /** + * Initializes a device for use. + * + * @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(MemoryAddress deviceHandle, MemorySegment callbackFunctions) throws SDRPlayException + { + //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)); + + if(!status.success()) + { + throw new SDRPlayException("Error while initializing device", status); + } + } + + /** + * Initializes a device for single-tuner use or for dual-tuner use as stream A + * + * @param device to initialize + * @param deviceHandle to the device + * @param eventListener to receive events for this device + * @param streamListener to receive samples for stream A + * @throws SDRPlayException if the device is not selected of if unable to init the device + */ + public void initA(Device device, MemoryAddress deviceHandle, IDeviceEventListener eventListener, + IStreamListener streamListener) throws SDRPlayException + { + CallbackFunctions callbackFunctions = mDeviceCallbackFunctionsMap.get(deviceHandle); + + if(callbackFunctions == null) + { + callbackFunctions = new CallbackFunctions(getGlobalMemorySession(), eventListener, streamListener, + device.getStreamCallbackListener()); + mDeviceCallbackFunctionsMap.put(deviceHandle, callbackFunctions); + } + else + { + callbackFunctions.setDeviceEventListener(eventListener); + callbackFunctions.setStreamAListener(streamListener); + } + + init(deviceHandle, callbackFunctions.getCallbackFunctionsMemorySegment()); + } + + /** + * Initializes a device for dual-tuner use as stream B + * + * @param device to initialize + * @param deviceHandle to the device + * @param eventListener to receive events for this device + * @param streamListener to receive samples for stream B + * @throws SDRPlayException if the device is not selected of if unable to init the device + */ + public void initB(Device device, MemoryAddress deviceHandle, IDeviceEventListener eventListener, + IStreamListener streamListener) throws SDRPlayException + { + CallbackFunctions callbackFunctions = mDeviceCallbackFunctionsMap.get(deviceHandle); + + if(callbackFunctions == null) + { + callbackFunctions = new CallbackFunctions(getGlobalMemorySession(), eventListener, streamListener, streamListener, + device.getStreamCallbackListener()); + mDeviceCallbackFunctionsMap.put(deviceHandle, callbackFunctions); + } + else + { + callbackFunctions.setDeviceEventListener(eventListener); + callbackFunctions.setStreamAListener(streamListener); + } + + init(deviceHandle, callbackFunctions.getCallbackFunctionsMemorySegment()); + } + + /** + * Un-Initializes a device from use. + * + * @param deviceHandle to the device + * @throws SDRPlayException if error during uninit or if device is not selected + */ + public void uninit(MemoryAddress deviceHandle) throws SDRPlayException + { + Status status = Status.fromValue(sdrplay_api_h.sdrplay_api_Uninit(deviceHandle)); + + if(status.fail() && status != Status.NOT_INITIALIZED) + { + throw new SDRPlayException("Error while un-initializing device", status); + } + } + + /** + * Applies updates made to the device parameters. The device parameter that was updated is specified in the + * update reason. + *

+ * Note: this method is synchronized to prevent multiple threads from attempting to send update requests + * concurrently, which will cause a failed request. + * + * @param device to update + * @param deviceHandle for the device + * @param tunerSelect identifies which tuner to apply the updates + * @param updateReasons identifying what was updated + * @throws SDRPlayException if the device is not selected, or if unable to update the device parameters + */ + public synchronized void update(Device device, MemoryAddress deviceHandle, TunerSelect tunerSelect, + UpdateReason... updateReasons) throws SDRPlayException + { + int reasons = UpdateReason.getReasons(updateReasons); + int extendedReasons = UpdateReason.getExtendedReasons(updateReasons); + + Status status = Status.fromValue(sdrplay_api_h.sdrplay_api_Update(deviceHandle, tunerSelect.getValue(), + reasons, extendedReasons)); + + if(status.fail()) + { + throw new SDRPlayUpdateException(status, Arrays.stream(updateReasons).toList()); + } + } + + /** + * Retrieve error information for the last error for the specified device. + * + * @param deviceSegment for the device + * @return error information + */ + private ErrorInformation getLastError(MemorySegment deviceSegment) + { + MemoryAddress errorAddress = sdrplay_api_h.sdrplay_api_GetLastError(deviceSegment); + MemorySegment errorSegment = sdrplay_api_ErrorInfoT.ofAddress(errorAddress, mGlobalMemorySession); + return new ErrorInformation(errorSegment); + } + + /** + * Sets the debug level logging for the specified device + * + * @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(MemoryAddress deviceHandle, DebugLevel debugLevel) throws SDRPlayException + { + Status status = Status.UNKNOWN; + + if(getVersion() == Version.V3_07) + { + //V3.07 used a debug level argument + status = Status.fromValue(sdrplay_api_h.sdrplay_api_DebugEnable(deviceHandle, debugLevel.getValue())); + } + else if(getVersion().gte(Version.V3_08)) + { + //V3.08+ uses a 0:1 flag to enable debug logging. The method signature didn't change -- still takes an integer + boolean enable = debugLevel != DebugLevel.DISABLE; + status = Status.fromValue(sdrplay_api_h.sdrplay_api_DebugEnable(deviceHandle, Flag.of(enable))); + } + + if(status.fail()) + { + throw new SDRPlayException("Unable to set debug level", status); + } + } + + /** + * 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. + */ + public boolean isAvailable() + { + return mAvailable; + } + + /** + * Opens the API service. MUST be invoked before accessing any of the API functions/methods. + */ + private Status open() + { + return Status.fromValue(sdrplay_api_h.sdrplay_api_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() + { + Status closeStatus; + + try + { + closeStatus = Status.fromValue(sdrplay_api_h.sdrplay_api_Close()); + } + catch(Exception e) + { + closeStatus = Status.FAIL; + mLog.error("Error closing SDRPlay API", e); + } + + mSdrplayLibraryLoaded = false; + mAvailable = false; + return closeStatus; + } + + /** + * Identifies the API version. + * Note: if the library is not found or loaded, or if the API version is not a supported version, this method + * returns UNKNOWN + * + * @return version. + */ + public Version getVersion() + { + if(mVersion == null) + { + if(mSdrplayLibraryLoaded) + { + MemorySegment apiVersion = getGlobalMemorySession().allocate(ValueLayout.JAVA_FLOAT, 0); + Status status = Status.fromValue(sdrplay_api_h.sdrplay_api_ApiVersion(apiVersion)); + if(status.success()) + { + float version = apiVersion.get(ValueLayout.JAVA_FLOAT, 0); + mVersion = Version.fromValue(version); + } + } + + if(mVersion == null) + { + mVersion = Version.UNKNOWN; + } + } + + return mVersion; + } + + /** + * Attempts to lock the API for exclusive use of the current application. Once locked, no other applications + * will be able to use the API. Typically used to lock the API prior to calling sdrplay_api_GetDevices() to + * ensure only one application can select a given device. After completing device selection using + * sdrplay_api_SelectDevice(), sdrplay_api_UnlockDeviceApi() can be used to release the API. May also + * be used prior to calling sdrplay_api_ReleaseDevice() if it is necessary to reselect the same device. + */ + private void lockDeviceApi() throws SDRPlayException + { + if(isAvailable()) + { + Status status = Status.fromValue(sdrplay_api_h.sdrplay_api_LockDeviceApi()); + if(status.fail()) + { + throw new SDRPlayException("Unable to lock Device API for exclusive use", status); + } + } + else + { + throw new SDRPlayException("API is unavailable", Status.API_UNAVAILABLE); + } + } + + /** + * Unlocks the device from exclusive access. + * + * @throws SDRPlayException if unable to unlock the Device API + */ + private void unlockDeviceApi() throws SDRPlayException + { + if(isAvailable()) + { + Status status = Status.fromValue(sdrplay_api_h.sdrplay_api_UnlockDeviceApi()); + + if(status.fail()) + { + throw new SDRPlayException("Unable to unlock Device API", status); + } + } + else + { + throw new SDRPlayException("API is unavailable", Status.API_UNAVAILABLE); + } + } + + /** + * Identifies the java library path for the sdrplay api library at runtime. + */ + public static String getSDRplayLibraryPath() + { + if(SystemUtils.IS_OS_WINDOWS) + { + return SDRPLAY_API_PATH_WINDOWS; + } + else if(SystemUtils.IS_OS_LINUX) + { + return SDRPLAY_API_PATH_LINUX; + } + else if(SystemUtils.IS_OS_MAC_OSX) + { + return SDRPLAY_API_PATH_MAC_OS; + } + + mLog.error("Unrecognized operating system. Cannot identify sdrplay api library path"); + return ""; + } + + public static void main(String[] args) + { + /** + * Note: on windows, add the following environment variable to the IntelliJ launcher: + * -Djava.library.path="C:\Program Files\SDRplay\API\x64" + * + * Alternately, we can add this location to the Windows PATH environment variable and + * Java will look there for the library, without having to specify it as a launcher + * option. This would allow for users that have installed the API to an alternate location. + */ + SDRplay sdrplay = new SDRplay(); + Status status = sdrplay.open(); + mLog.info("Open Status: " + status); + + try + { + for(DeviceInfo deviceInfo: sdrplay.getDeviceInfos()) + { + mLog.info("Found: " + deviceInfo); + } + } + catch(SDRPlayException se) + { + mLog.info("Error", se); + } + + Status closeStatus = sdrplay.close(); + mLog.info("Close Status: " + closeStatus); + } +} diff --git a/jsdrplay/src/main/java/com/github/dsheirer/sdrplay/Status.java b/jsdrplay/src/main/java/com/github/dsheirer/sdrplay/Status.java new file mode 100644 index 000000000..e09b6d13a --- /dev/null +++ b/jsdrplay/src/main/java/com/github/dsheirer/sdrplay/Status.java @@ -0,0 +1,109 @@ +/* + * ***************************************************************************** + * 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.api.v3_07.sdrplay_api_h; + +public enum Status +{ + SUCCESS(sdrplay_api_h.sdrplay_api_Success(), "Success"), + FAIL(sdrplay_api_h.sdrplay_api_Fail(), "Fail"), + INVALID_PARAMETER(sdrplay_api_h.sdrplay_api_InvalidParam(), "Invalid Parameter. Null pointer or invalid operating mode"), + OUT_OF_RANGE(sdrplay_api_h.sdrplay_api_OutOfRange(), "Out of Range. One or more parameters are set incorrectly"), + GAIN_UPDATE_ERROR(sdrplay_api_h.sdrplay_api_GainUpdateError(), "Gain Update Error"), + RF_UPDATE_ERROR(sdrplay_api_h.sdrplay_api_RfUpdateError(), "Frequency Update Error"), + FS_UPDATE_ERROR(sdrplay_api_h.sdrplay_api_FsUpdateError(), "Sample Rate Update Error"), + HARDWARE_ERROR(sdrplay_api_h.sdrplay_api_HwError(), "Hardware Error during tuner initialization"), + ALIASING_ERROR(sdrplay_api_h.sdrplay_api_AliasingError(), "Aliasing Error"), + ALREADY_INITIALIZED(sdrplay_api_h.sdrplay_api_AlreadyInitialised(), "Already Initialized"), + NOT_INITIALIZED(sdrplay_api_h.sdrplay_api_NotInitialised(), "Not Initialized"), + NOT_ENABLED(sdrplay_api_h.sdrplay_api_NotEnabled(), "Not Enabled"), + HARDWARE_VERSION_ERROR(sdrplay_api_h.sdrplay_api_HwVerError(), "Hardware Version Error"), + OUT_OF_MEMORY(sdrplay_api_h.sdrplay_api_OutOfMemError(), "Out Of Memory"), + SERVICE_NOT_RESPONDING(sdrplay_api_h.sdrplay_api_ServiceNotResponding(), "Service Not Responding"), + START_PENDING(sdrplay_api_h.sdrplay_api_StartPending(), "Start Pending"), + STOP_PENDING(sdrplay_api_h.sdrplay_api_StopPending(), "Stop Pending"), + INVALID_MODE(sdrplay_api_h.sdrplay_api_InvalidMode(), "Invalid Mode"), + FAILED_VERIFICATION_1(sdrplay_api_h.sdrplay_api_FailedVerification1(), "Failed Verification 1"), + FAILED_VERIFICATION_2(sdrplay_api_h.sdrplay_api_FailedVerification2(), "Failed Verification 2"), + FAILED_VERIFICATION_3(sdrplay_api_h.sdrplay_api_FailedVerification3(), "Failed Verification 3"), + FAILED_VERIFICATION_4(sdrplay_api_h.sdrplay_api_FailedVerification4(), "Failed Verification 4"), + FAILED_VERIFICATION_5(sdrplay_api_h.sdrplay_api_FailedVerification5(), "Failed Verification 5"), + FAILED_VERIFICATION_6(sdrplay_api_h.sdrplay_api_FailedVerification6(), "Failed Verification 6"), + INVALID_SERVICE_VERSION(sdrplay_api_h.sdrplay_api_InvalidServiceVersion(), "Invalid Service Version"), + + //Custom status codes + API_UNAVAILABLE(-2, "SDRplay API is not installed or it has an unsupported version"), + UNKNOWN(-1, "Unknown"); + + private int mValue; + private String mDescription; + + Status(int value, String description) + { + mValue = value; + mDescription = description; + } + + /** + * Status code value + */ + public int getValue() + { + return mValue; + } + + /** + * Indicates if this is a SUCCESS status. + */ + public boolean success() + { + return this == Status.SUCCESS; + } + + public boolean fail() + { + return this != Status.SUCCESS; + } + + /** + * Lookup the status from a return code + * @param value to lookup + * @return status or UKNOWN if the code is not recognized + */ + public static Status fromValue(int value) + { + for(Status status: Status.values()) + { + if(status.getValue() == value) + { + return status; + } + } + + return UNKNOWN; + } + + @Override + public String toString() + { + return mDescription; + } +} diff --git a/jsdrplay/src/main/java/com/github/dsheirer/sdrplay/UpdateReason.java b/jsdrplay/src/main/java/com/github/dsheirer/sdrplay/UpdateReason.java new file mode 100644 index 000000000..a1ad61749 --- /dev/null +++ b/jsdrplay/src/main/java/com/github/dsheirer/sdrplay/UpdateReason.java @@ -0,0 +1,196 @@ +/* + * ***************************************************************************** + * 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.api.v3_07.sdrplay_api_h; +import java.util.EnumSet; + +/** + * Update reason. + * + * These entries are used to notify the SDRplay API once settings are updated on the device. + */ +public enum UpdateReason +{ + //Master Only mode + DEVICE_SAMPLE_RATE(sdrplay_api_h.sdrplay_api_Update_Dev_Fs(), "Sample Rate"), + DEVICE_PPM(sdrplay_api_h.sdrplay_api_Update_Dev_Ppm(), "PPM"), + DEVICE_SYNC_UPDATE(sdrplay_api_h.sdrplay_api_Update_Dev_SyncUpdate(), "Sync Update"), + DEVICE_RESET_FLAGS(sdrplay_api_h.sdrplay_api_Update_Dev_ResetFlags(), "Reset Flags"), + + RSP1A_BIAS_T_CONTROL(sdrplay_api_h.sdrplay_api_Update_Rsp1a_BiasTControl(), "RSP1A Bias-T Control"), + RSP1A_RF_NOTCH_CONTROL(sdrplay_api_h.sdrplay_api_Update_Rsp1a_RfNotchControl(), "RSP1A RF Notch Control"), + RSP1A_RF_DAB_NOTCH_CONTROL(sdrplay_api_h.sdrplay_api_Update_Rsp1a_RfDabNotchControl(), "RSP1A RF DAB Notch Control"), + + RSP2_BIAS_T_CONTROL(sdrplay_api_h.sdrplay_api_Update_Rsp2_BiasTControl(), "RSP2 Bias-T Control"), + RSP2_AM_PORT_SELECT(sdrplay_api_h.sdrplay_api_Update_Rsp2_AmPortSelect(), "RSP2 AM Port Select"), + RSP2_ANTENNA_CONTROL(sdrplay_api_h.sdrplay_api_Update_Rsp2_AntennaControl(), "RSP2 Antenna Control"), + RSP2_RF_NOTCH_CONTROL(sdrplay_api_h.sdrplay_api_Update_Rsp2_RfNotchControl(), "RSP2 RF Notch Control"), + RSP2_EXT_REF_CONTROL(sdrplay_api_h.sdrplay_api_Update_Rsp2_ExtRefControl(), "RSP2 External Reference Control"), + + RSP_DUO_EXT_REF_CONTROL(sdrplay_api_h.sdrplay_api_Update_RspDuo_ExtRefControl(), "RSPduo External Reference Control"), + + SPARE_1(sdrplay_api_h.sdrplay_api_Update_Master_Spare_1(), "Spare 1"), + SPARE_2(sdrplay_api_h.sdrplay_api_Update_Master_Spare_2(), "Spare 2"), + + //Master and Slave mode + TUNER_GAIN_REDUCTION(sdrplay_api_h.sdrplay_api_Update_Tuner_Gr(), "Tuner Gain Reduction"), + TUNER_GAIN_REDUCTION_LIMITS(sdrplay_api_h.sdrplay_api_Update_Tuner_GrLimits(), "Tuner Gain Reduction Limits"), + TUNER_FREQUENCY_RF(sdrplay_api_h.sdrplay_api_Update_Tuner_Frf(), "Tuner Frequency RF"), + TUNER_BANDWIDTH_TYPE(sdrplay_api_h.sdrplay_api_Update_Tuner_BwType(), "Tuner Bandwidth Type"), + TUNER_IF_TYPE(sdrplay_api_h.sdrplay_api_Update_Tuner_IfType(), "Tuner IF Type"), + TUNER_DC_OFFSET(sdrplay_api_h.sdrplay_api_Update_Tuner_DcOffset(), "Tuner DC Offset"), + TUNER_LO_MODE(sdrplay_api_h.sdrplay_api_Update_Tuner_LoMode(), "Tuner LO Mode"), + + CONTROL_DC_OFFSET_IQ_IMBALANCE(sdrplay_api_h.sdrplay_api_Update_Ctrl_DCoffsetIQimbalance(), "Control DC Offset IQ Imbalance"), + CONTROL_DECIMATION(sdrplay_api_h.sdrplay_api_Update_Ctrl_Decimation(), "Control Decimation"), + CONTROL_AGC(sdrplay_api_h.sdrplay_api_Update_Ctrl_Agc(), "Control AGC"), + CONTROL_ADSB_MODE(sdrplay_api_h.sdrplay_api_Update_Ctrl_AdsbMode(), "Control ADSB Mode"), + CONTROL_OVERLOAD_MESSAGE_ACK(sdrplay_api_h.sdrplay_api_Update_Ctrl_OverloadMsgAck(), "Control Overload Message Ack"), + + RSP_DUO_BIAS_T_CONTROL(sdrplay_api_h.sdrplay_api_Update_RspDuo_BiasTControl(), "RSPduo Bias-T Control"), + RSP_DUO_AM_PORT_SELECT(sdrplay_api_h.sdrplay_api_Update_RspDuo_AmPortSelect(), "RSPduo AM Port Select"), + RSP_DUO_TUNER_1_AM_NOTCH_CONTROL(sdrplay_api_h.sdrplay_api_Update_RspDuo_Tuner1AmNotchControl(), "RSPduo Tuner 1 AM Notch Control"), + RSP_DUO_RF_NOTCH_CONTROL(sdrplay_api_h.sdrplay_api_Update_RspDuo_RfNotchControl(), "RSPduo RF Notch Control"), + RSP_DUO_RF_DAB_NOTCH_CONTROL(sdrplay_api_h.sdrplay_api_Update_RspDuo_RfDabNotchControl(), "RSPduo RF DAB Notch Control"), + + //Extension 1 + EXTENSION_RSP_DX_HDR_ENABLE(sdrplay_api_h.sdrplay_api_Update_RspDx_HdrEnable(), "RSPdx HDR Enable"), + EXTENSION_RSP_DX_BIAS_T_CONTROL(sdrplay_api_h.sdrplay_api_Update_RspDx_BiasTControl(), "RSPdx Bias-T Control"), + EXTENSION_RSP_DX_ANTENNA_CONTROL(sdrplay_api_h.sdrplay_api_Update_RspDx_AntennaControl(), "RSPdx Antenna Control"), + EXTENSION_RSP_DX_RF_NOTCH_CONTROL(sdrplay_api_h.sdrplay_api_Update_RspDx_RfNotchControl(), "RSPdx RF Notch Control"), + EXTENSION_RSP_DX_RF_DAB_NOTCH_CONTROL(sdrplay_api_h.sdrplay_api_Update_RspDx_RfDabNotchControl(), "RSPdx RF DAB Notch Control"), + EXTENSION_RSP_DX_HDR_BANDWIDTH(sdrplay_api_h.sdrplay_api_Update_RspDx_HdrBw(), "RSPdx HDR Bandwidth"), + EXTENSION_NONE(sdrplay_api_h.sdrplay_api_Update_Ext1_None(), "NONE"), + + + NONE(sdrplay_api_h.sdrplay_api_Update_None(), "NONE"); + + private int mValue; + private String mDescription; + + UpdateReason(int value, String description) + { + mValue = value; + mDescription = description; + } + + public static EnumSet EXTENSIONS = EnumSet.range(EXTENSION_RSP_DX_HDR_ENABLE, EXTENSION_NONE); + + + /** + * Many of the update reasons described in this enumeration are submitted asynchronously, since the API is + * non-blocking. However, the device event listener responses are limited to just three events: Frequency, Gain, + * and Sample Rate. This constant describes the three update reasons that correspond to the device events. + */ + public static EnumSet ASYNC_UPDATE_RESPONSES = EnumSet.of(DEVICE_SAMPLE_RATE, TUNER_FREQUENCY_RF, TUNER_GAIN_REDUCTION); + + /** + * Numeric value + */ + public int getValue() + { + return mValue; + } + + /** + * Indicates if this is an extended update reason entry. + */ + public boolean isExtended() + { + return EXTENSIONS.contains(this); + } + + /** + * Indicates if this update reason is one of the limited set of asynchronous update operation response types. + */ + public boolean isAsyncUpdateResponse() + { + return ASYNC_UPDATE_RESPONSES.contains(this); + } + + /** + * Lookup the entry from a return code + * @param value to lookup + * @return entry or UNKNOWN if the code is not recognized + */ + public static UpdateReason fromValue(int value) + { + for(UpdateReason status: UpdateReason.values()) + { + if(status.getValue() == value) + { + return status; + } + } + + return NONE; + } + + /** + * Calculates a combined logical OR value of the non-extended update reasons. Extended reason values will + * be ignored for this calculation. + * + * @param reasons to combine + * @return combined (logical OR) value. + */ + public static int getReasons(UpdateReason ... reasons) + { + int combined = UpdateReason.NONE.getValue(); + + for(UpdateReason reason: reasons) + { + if(!reason.isExtended()) + { + combined += reason.getValue(); + } + } + + return combined; + } + + /** + * Calculates a combined logical OR value of the extended update reasons. Non-extended reason values will + * be ignored for this calculation. + * + * @param reasons to combine + * @return combined (logical OR) value. + */ + public static int getExtendedReasons(UpdateReason ... reasons) + { + int combined = UpdateReason.EXTENSION_NONE.getValue(); + + for(UpdateReason reason: reasons) + { + if(reason.isExtended()) + { + combined += reason.getValue(); + } + } + + return combined; + } + + @Override + public String toString() + { + return mDescription; + } +} diff --git a/jsdrplay/src/main/java/com/github/dsheirer/sdrplay/Version.java b/jsdrplay/src/main/java/com/github/dsheirer/sdrplay/Version.java new file mode 100644 index 000000000..5a2ca8fde --- /dev/null +++ b/jsdrplay/src/main/java/com/github/dsheirer/sdrplay/Version.java @@ -0,0 +1,99 @@ +/* + * ***************************************************************************** + * 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 org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +/** + * SDRPlay API Versions + */ +public enum Version +{ + UNKNOWN(0.0f, false), + V3_07(3.07f, true), + V3_08(3.08f, true), + V3_09(3.09f, true), + V3_10(3.10f, true), + V3_11(3.11f, true); + + private float mValue; + private boolean mSupported; + private static final Logger mLog = LoggerFactory.getLogger(Version.class); + + Version(float value, boolean supported) + { + mValue = value; + mSupported = supported; + } + + /** + * Indicates if the API version is supported by the jsdrplay library + */ + public boolean isSupported() + { + return mSupported; + } + + /** + * Indicates if this version is greater than or equal to the specified version. + * @param version to compare + * @return true if this version is greater than or equal to + */ + public boolean gte(Version version) + { + return this.ordinal() >= version.ordinal(); + } + + /** + * Numeric API version/value + */ + public float getVersion() + { + return mValue; + } + + /** + * Lookup the version from the specified value. + * @param value to lookup + * @return version or UNKNOWN + */ + public static Version fromValue(float value) + { + + for(Version version: values()) + { + if(version.mValue == value) + { + return version; + } + } + + mLog.warn("Unrecognized SDRplay API version [" + value + "]"); + return UNKNOWN; + } + + + @Override + public String toString() + { + return String.valueOf(mValue); + } +} diff --git a/jsdrplay/src/main/java/com/github/dsheirer/sdrplay/async/AsyncFuture.java b/jsdrplay/src/main/java/com/github/dsheirer/sdrplay/async/AsyncFuture.java new file mode 100644 index 000000000..4696149bd --- /dev/null +++ b/jsdrplay/src/main/java/com/github/dsheirer/sdrplay/async/AsyncFuture.java @@ -0,0 +1,227 @@ +/* + * ***************************************************************************** + * 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.async; + +import java.util.concurrent.ExecutionException; +import java.util.concurrent.Future; +import java.util.concurrent.TimeUnit; +import java.util.concurrent.TimeoutException; +import java.util.concurrent.locks.ReentrantLock; + +/** + * Asynchronous operation that implements the Future interface with utility methods for callback on completion, or + * converting to a synchronous (ie blocking) operation. + * @param expected return type upon completion of the operation + */ +public class AsyncFuture implements Future +{ + private R mResult; + private Throwable mError; + private boolean mCancelled; + private boolean mCompleted = false; + private ReentrantLock mLock = new ReentrantLock(); + private IAsyncCallback mCallback; + + /** + * Sets the result and completes this future. + * @param result to apply. + */ + public synchronized void setResult(R result) + { + if(mCompleted) + { + throw new IllegalStateException("Future is already completed."); + } + + mResult = result; + finish(); + } + + /** + * Sets an error resulting from the operation and completes this future. + * @param error produced from the operation + */ + public synchronized void setError(Throwable error) + { + if(mCompleted) + { + throw new IllegalStateException("Future is already completed."); + } + + mError = error; + finish(); + } + + /** + * (Optional) error produced from the operation. + */ + public Throwable getError() + { + return mError; + } + + /** + * Indicates if this future had an error during the operation + */ + public boolean hasError() + { + return mError != null; + } + + /** + * Cleanup task that completes the future and notifies an optional registered callback. + */ + private void finish() + { + mLock.lock(); + + try + { + mCompleted = true; + + if(mCallback != null) + { + mCallback.complete(this); + mCallback = null; + } + } + finally + { + mLock.unlock(); + } + + notifyAll(); + } + + /** + * Signals a desire to cancel this future operation. + * + * Note: it is up to the implementer to monitor this cancel state. + * @param mayInterruptIfRunning not implemented. + * @return true always. + */ + @Override + public boolean cancel(boolean mayInterruptIfRunning) + { + mCancelled = true; + return true; + } + + /** + * Indicates if this future has been cancelled. + */ + @Override + public boolean isCancelled() + { + return mCancelled; + } + + /** + * Indicates if this future has completed. + */ + @Override + public boolean isDone() + { + return mCompleted; + } + + /** + * Blocking call to wait indefinitely for the result of the operation. + * @return result of the operation + * @throws InterruptedException if the calling thread is interrupted while waiting + * @throws ExecutionException if there is an error produced from the operation + */ + @Override + public synchronized R get() throws InterruptedException, ExecutionException + { + while(!mCompleted) + { + wait(); + } + + if(mError != null) + { + throw new ExecutionException(mError); + } + + return mResult; + } + + /** + * Blocking call to synchronously get the result of the operation. + * @param timeout to wait + * @param unit for the timeout + * @return result once completed + * @throws InterruptedException if the calling thread is interrupted while waiting + * @throws ExecutionException if there is an error produced from the operation + * @throws TimeoutException if the timeout is exceeded while waiting. + */ + @Override + public synchronized R get(long timeout, TimeUnit unit) throws InterruptedException, ExecutionException, TimeoutException + { + if(!mCompleted) + { + wait(unit.toMillis(timeout)); + } + + if(!mCompleted) + { + throw new TimeoutException("Get timeout [" + timeout + " " + unit + "] exceeded without completion"); + } + + if(mError != null) + { + throw new ExecutionException(mError); + } + + return mResult; + } + + /** + * Registers the callback to receive the result once the operation completes. If the operation is completed, the + * callback is immediately notified, otherwise the callback will be notified later. + * @param callback to be notified once the operation is completed. + */ + public synchronized void callback(IAsyncCallback callback) + { + if(mCallback != null) + { + throw new IllegalArgumentException("Callback has been registered - only one callback is supported."); + } + + mLock.lock(); + + try + { + if(mCompleted) + { + callback.complete(this); + } + else + { + mCallback = callback; + } + } + finally + { + mLock.unlock(); + } + } +} diff --git a/jsdrplay/src/main/java/com/github/dsheirer/sdrplay/async/AsyncUpdateFuture.java b/jsdrplay/src/main/java/com/github/dsheirer/sdrplay/async/AsyncUpdateFuture.java new file mode 100644 index 000000000..93ee0856d --- /dev/null +++ b/jsdrplay/src/main/java/com/github/dsheirer/sdrplay/async/AsyncUpdateFuture.java @@ -0,0 +1,100 @@ +/* + * ***************************************************************************** + * 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.async; + +import com.github.dsheirer.sdrplay.Status; +import com.github.dsheirer.sdrplay.UpdateReason; +import com.github.dsheirer.sdrplay.device.TunerSelect; + +/** + * Asynchronous future for an SDRplay API update operation. + */ +public class AsyncUpdateFuture extends AsyncFuture +{ + private TunerSelect mTunerSelect; + private UpdateReason mUpdateReason; + private UpdateReason mExpectedResponse; + private boolean mSubmitted; + + /** + * Creates a to-be completed future where a successful update with return success or an unsuccessful update will + * return an exception. + * @param tunerSelect for the tuner to be updated + * @param updateReason of what is to be updated + * @param expectedResponse to be received to indicate the async operation is completed + */ + public AsyncUpdateFuture(TunerSelect tunerSelect, UpdateReason updateReason, UpdateReason expectedResponse) + { + mTunerSelect = tunerSelect; + mUpdateReason = updateReason; + mExpectedResponse = expectedResponse; + } + + /** + * Tuner(s) for the update + */ + public TunerSelect getTunerSelect() + { + return mTunerSelect; + } + + /** + * UpdateReason that is being updated + */ + public UpdateReason getUpdateReason() + { + return mUpdateReason; + } + + /** + * Expected response to this update operation + */ + public UpdateReason getExpectedResponse() + { + return mExpectedResponse; + } + + /** + * Flag to indicate if this update has been submitted and is currently awaiting results. + */ + public boolean isSubmitted() + { + return mSubmitted; + } + + /** + * Sets flag to indicate that this update has been submitted. + */ + public void setSubmitted(boolean submitted) + { + mSubmitted = submitted; + } + + /** + * Indicates if the completed async operation matches this submitted async update future + * @param completedAsyncUpdate to compare + * @return true if there is a match + */ + public boolean matches(CompletedAsyncUpdate completedAsyncUpdate) + { + return getTunerSelect().equals(completedAsyncUpdate.getTunerSelect()) && + getExpectedResponse().equals(completedAsyncUpdate.getUpdateReason()); + } +} diff --git a/jsdrplay/src/main/java/com/github/dsheirer/sdrplay/async/CompletedAsyncUpdate.java b/jsdrplay/src/main/java/com/github/dsheirer/sdrplay/async/CompletedAsyncUpdate.java new file mode 100644 index 000000000..a1e896561 --- /dev/null +++ b/jsdrplay/src/main/java/com/github/dsheirer/sdrplay/async/CompletedAsyncUpdate.java @@ -0,0 +1,57 @@ +/* + * ***************************************************************************** + * 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.async; + +import com.github.dsheirer.sdrplay.UpdateReason; +import com.github.dsheirer.sdrplay.device.TunerSelect; + +/** + * Completed asynchronous update operation + */ +public class CompletedAsyncUpdate +{ + private TunerSelect mTunerSelect; + private UpdateReason mUpdateReason; + + /** + * Creates a completed update. + */ + public CompletedAsyncUpdate(TunerSelect tunerSelect, UpdateReason updateReason) + { + mTunerSelect = tunerSelect; + mUpdateReason = updateReason; + } + + /** + * Tuner(s) for the update + */ + public TunerSelect getTunerSelect() + { + return mTunerSelect; + } + + /** + * UpdateReason that is being updated + */ + public UpdateReason getUpdateReason() + { + return mUpdateReason; + } +} diff --git a/jsdrplay/src/main/java/com/github/dsheirer/sdrplay/async/IAsyncCallback.java b/jsdrplay/src/main/java/com/github/dsheirer/sdrplay/async/IAsyncCallback.java new file mode 100644 index 000000000..bc722eef9 --- /dev/null +++ b/jsdrplay/src/main/java/com/github/dsheirer/sdrplay/async/IAsyncCallback.java @@ -0,0 +1,32 @@ +/* + * ***************************************************************************** + * 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.async; + +/** + * Callback interface to be notified when an async future has completed or has resulted in an error + */ +public interface IAsyncCallback +{ + /** + * Callback method once the future is completed or produces an error. + * @param future that is being monitored + */ + void complete(AsyncFuture future); +} diff --git a/jsdrplay/src/main/java/com/github/dsheirer/sdrplay/callback/CallbackFunctions.java b/jsdrplay/src/main/java/com/github/dsheirer/sdrplay/callback/CallbackFunctions.java new file mode 100644 index 000000000..a3d3b9d35 --- /dev/null +++ b/jsdrplay/src/main/java/com/github/dsheirer/sdrplay/callback/CallbackFunctions.java @@ -0,0 +1,128 @@ +/* + * ***************************************************************************** + * 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.callback; + +import com.github.dsheirer.sdrplay.api.v3_07.sdrplay_api_CallbackFnsT; +import com.github.dsheirer.sdrplay.api.v3_07.sdrplay_api_EventCallback_t; +import com.github.dsheirer.sdrplay.api.v3_07.sdrplay_api_StreamCallback_t; + +import java.lang.foreign.MemorySegment; +import java.lang.foreign.MemorySession; + +/** + * Callback functions (sdrplay_api_CallbackFnsT) factory + */ +public class CallbackFunctions +{ + private DeviceEventAdapter mDeviceEventAdapter; + private StreamCallbackAdapter mStreamACallbackAdapter; + private StreamCallbackAdapter mStreamBCallbackAdapter; + private MemorySegment mCallbackFunctionsMemorySegment; + + /** + * Constructs a callback functions for single-tuner use. + * @param memorySession for native memory allocation + * @param deviceEventListener for device events + * @param streamListener for streaming samples + * @param streamCallbackListener for streaming events + */ + public CallbackFunctions(MemorySession memorySession, IDeviceEventListener deviceEventListener, + IStreamListener streamListener, IStreamCallbackListener streamCallbackListener) + { + //Create the event callback function + mDeviceEventAdapter = new DeviceEventAdapter(memorySession, deviceEventListener); + MemorySegment eventFunction = sdrplay_api_EventCallback_t.allocate(mDeviceEventAdapter, memorySession); + + //Create the stream A callback function + mStreamACallbackAdapter = new StreamCallbackAdapter(memorySession, streamListener, streamCallbackListener); + MemorySegment streamAFunction = sdrplay_api_StreamCallback_t.allocate(mStreamACallbackAdapter, memorySession); + + //Create the callback functions union and populate the callback functions + mCallbackFunctionsMemorySegment = sdrplay_api_CallbackFnsT.allocate(memorySession); + sdrplay_api_CallbackFnsT.EventCbFn$set(mCallbackFunctionsMemorySegment, eventFunction.address()); + sdrplay_api_CallbackFnsT.StreamACbFn$set(mCallbackFunctionsMemorySegment, streamAFunction.address()); + } + + /** + * Constructs a callback functions for dual-tuner use. + * @param memorySession for native memory allocation + * @param deviceEventListener for device events + * @param streamAListener for streaming samples from the master tuner + * @param streamBListener for streaming samples from the slave tuner + * @param streamCallbackListener for streaming events + */ + public CallbackFunctions(MemorySession memorySession, IDeviceEventListener deviceEventListener, + IStreamListener streamAListener, IStreamListener streamBListener, + IStreamCallbackListener streamCallbackListener) + { + //Create the event callback function + mDeviceEventAdapter = new DeviceEventAdapter(memorySession, deviceEventListener); + MemorySegment eventFunction = sdrplay_api_EventCallback_t.allocate(mDeviceEventAdapter, memorySession); + + //Create the stream A callback function + mStreamACallbackAdapter = new StreamCallbackAdapter(memorySession, streamAListener, streamCallbackListener); + MemorySegment streamAFunction = sdrplay_api_StreamCallback_t.allocate(mStreamACallbackAdapter, memorySession); + + //Create the stream B callback function + mStreamBCallbackAdapter = new StreamCallbackAdapter(memorySession, streamBListener, streamCallbackListener); + MemorySegment streamBFunction = sdrplay_api_StreamCallback_t.allocate(mStreamBCallbackAdapter, memorySession); + + //Create the callback functions union and populate the callback functions + mCallbackFunctionsMemorySegment = sdrplay_api_CallbackFnsT.allocate(memorySession); + sdrplay_api_CallbackFnsT.EventCbFn$set(mCallbackFunctionsMemorySegment, eventFunction.address()); + sdrplay_api_CallbackFnsT.StreamACbFn$set(mCallbackFunctionsMemorySegment, streamAFunction.address()); + sdrplay_api_CallbackFnsT.StreamBCbFn$set(mCallbackFunctionsMemorySegment, streamBFunction.address()); + } + + /** + * Foreign memory segment for the callback functions. + */ + public MemorySegment getCallbackFunctionsMemorySegment() + { + return mCallbackFunctionsMemorySegment; + } + + /** + * Updates the device event listener + * @param listener to receive device events + */ + public void setDeviceEventListener(IDeviceEventListener listener) + { + mDeviceEventAdapter.setListener(listener); + } + + /** + * Updates the stream A listener + * @param listener to receive samples for stream A + */ + public void setStreamAListener(IStreamListener listener) + { + mStreamACallbackAdapter.setListener(listener); + } + + /** + * Updates the stream B listener + * @param listener to receive samples for stream B + */ + public void setStreamBListener(IStreamListener listener) + { + mStreamBCallbackAdapter.setListener(listener); + } +} diff --git a/jsdrplay/src/main/java/com/github/dsheirer/sdrplay/callback/DeviceEventAdapter.java b/jsdrplay/src/main/java/com/github/dsheirer/sdrplay/callback/DeviceEventAdapter.java new file mode 100644 index 000000000..8a201d4c3 --- /dev/null +++ b/jsdrplay/src/main/java/com/github/dsheirer/sdrplay/callback/DeviceEventAdapter.java @@ -0,0 +1,112 @@ +/* + * ***************************************************************************** + * 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.callback; + +import com.github.dsheirer.sdrplay.api.v3_07.sdrplay_api_EventCallback_t; +import com.github.dsheirer.sdrplay.api.v3_07.sdrplay_api_EventParamsT; +import com.github.dsheirer.sdrplay.device.TunerSelect; +import com.github.dsheirer.sdrplay.parameter.event.EventParametersFactory; +import com.github.dsheirer.sdrplay.parameter.event.EventType; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import java.lang.foreign.MemoryAddress; +import java.lang.foreign.MemorySegment; +import java.lang.foreign.MemorySession; + +/** + * Adapter for Device Event callbacks. Implements foreign interface and transfers foreign memory event details to + * native Java and invokes the appropriate interface methods for an event listener. + */ +public class DeviceEventAdapter implements sdrplay_api_EventCallback_t +{ + private static final Logger mLog = LoggerFactory.getLogger(DeviceEventAdapter.class); + + private MemorySession mMemorySession; + private IDeviceEventListener mDeviceEventListener; + + /** + * Constructs an instance. + * @param memorySession to use in creating foreign memory segments to access foreign structures. + * @param listener to receive translated device events. + */ + public DeviceEventAdapter(MemorySession memorySession, IDeviceEventListener listener) + { + if(memorySession == null) + { + throw new IllegalArgumentException("Resource scope must be non-null"); + } + + mMemorySession = memorySession; + + setListener(listener); + } + + /** + * Updates the device event listener + * @param listener to receive device events + */ + public void setListener(IDeviceEventListener listener) + { + if(listener == null) + { + throw new IllegalArgumentException("Device event listener must be non-null"); + } + + mDeviceEventListener = listener; + } + + @Override + public void apply(int eventTypeId, int tunerSelectId, MemoryAddress eventParametersPointer, + MemoryAddress callbackContext) + { + MemorySegment memorySegment = sdrplay_api_EventParamsT.ofAddress(eventParametersPointer, mMemorySession); + EventType eventType = EventType.fromValue(eventTypeId); + TunerSelect tunerSelect = TunerSelect.fromValue(tunerSelectId); + + switch(eventType) + { + case GAIN_CHANGE -> { + mDeviceEventListener.processGainChange(tunerSelect, + EventParametersFactory.createGainCallbackParameters(memorySegment)); + } + case POWER_OVERLOAD_CHANGE -> { + mDeviceEventListener.processPowerOverload(tunerSelect, + EventParametersFactory.createPowerOverloadCallbackParameters(memorySegment)); + } + case DEVICE_REMOVED -> { + mDeviceEventListener.processDeviceRemoval(tunerSelect); + } + case RSP_DUO_MODE_CHANGE -> { + mDeviceEventListener.processRspDuoModeChange(tunerSelect, + EventParametersFactory.createRspDuoModeCallbackParameters(memorySegment)); + } + case UNKNOWN -> { + mLog.warn("Unknown device event callback ignored. Please contact the library developer as this may " + + "indicate a change to the SDRPlay API change. Tuner:" + tunerSelect + " Event Type ID:" + + eventTypeId); + mDeviceEventListener.processEvent(eventType, tunerSelect); + } + default -> { + throw new IllegalStateException("DeviceEventAdapter must be updated handle EventType." + eventType); + } + } + } +} diff --git a/jsdrplay/src/main/java/com/github/dsheirer/sdrplay/callback/IDeviceEventListener.java b/jsdrplay/src/main/java/com/github/dsheirer/sdrplay/callback/IDeviceEventListener.java new file mode 100644 index 000000000..0c0d22863 --- /dev/null +++ b/jsdrplay/src/main/java/com/github/dsheirer/sdrplay/callback/IDeviceEventListener.java @@ -0,0 +1,67 @@ +/* + * ***************************************************************************** + * 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.callback; + +import com.github.dsheirer.sdrplay.device.TunerSelect; +import com.github.dsheirer.sdrplay.parameter.event.EventType; +import com.github.dsheirer.sdrplay.parameter.event.GainCallbackParameters; +import com.github.dsheirer.sdrplay.parameter.event.PowerOverloadCallbackParameters; +import com.github.dsheirer.sdrplay.parameter.event.RspDuoModeCallbackParameters; + +/** + * Device event listener. Receives events for the device, impacting one or both (if equipped) tuners on the device. + */ +public interface IDeviceEventListener +{ + /** + * Process a device event + * @param eventType identifies the type of event + * @param tunerSelect identifies which tuner(s) are included in the event (A, B, BOTH, or NEITHER) + */ + void processEvent(EventType eventType, TunerSelect tunerSelect); + + /** + * Process a gain change event + * @param tunerSelect identifies which tuner(s) are included in the event (A, B, BOTH, or NEITHER) + * @param gainCallbackParameters containing event details + */ + void processGainChange(TunerSelect tunerSelect, GainCallbackParameters gainCallbackParameters); + + /** + * Process a power overload event + * @param tunerSelect identifies which tuner(s) are included in the event (A, B, BOTH, or NEITHER) + * @param parameters containing event details + */ + void processPowerOverload(TunerSelect tunerSelect, PowerOverloadCallbackParameters parameters); + + /** + * Process an RSP-Duo mode change event + * @param tunerSelect identifies which tuner(s) are included in the event (A, B, BOTH, or NEITHER) + * @param parameters containing event details + */ + void processRspDuoModeChange(TunerSelect tunerSelect, RspDuoModeCallbackParameters parameters); + + /** + * Process a device removed (ie unplugged) event + * @param tunerSelect identifies which tuner(s) are included in the event (A, B, BOTH, or NEITHER) + */ + void processDeviceRemoval(TunerSelect tunerSelect); + +} diff --git a/jsdrplay/src/main/java/com/github/dsheirer/sdrplay/callback/IStreamCallbackListener.java b/jsdrplay/src/main/java/com/github/dsheirer/sdrplay/callback/IStreamCallbackListener.java new file mode 100644 index 000000000..14610ec57 --- /dev/null +++ b/jsdrplay/src/main/java/com/github/dsheirer/sdrplay/callback/IStreamCallbackListener.java @@ -0,0 +1,32 @@ +/* + * ***************************************************************************** + * 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.callback; + +import com.github.dsheirer.sdrplay.device.TunerSelect; + +public interface IStreamCallbackListener +{ + /** + * Process stream callback parameters and reset value received over the stream callback interface. + * @param parameters to process + * @param reset value + */ + void process(TunerSelect tunerSelect, StreamCallbackParameters parameters, int reset); +} diff --git a/jsdrplay/src/main/java/com/github/dsheirer/sdrplay/callback/IStreamListener.java b/jsdrplay/src/main/java/com/github/dsheirer/sdrplay/callback/IStreamListener.java new file mode 100644 index 000000000..1360a73d3 --- /dev/null +++ b/jsdrplay/src/main/java/com/github/dsheirer/sdrplay/callback/IStreamListener.java @@ -0,0 +1,45 @@ +/* + * ***************************************************************************** + * 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.callback; + +import com.github.dsheirer.sdrplay.device.TunerSelect; + +/** + * Stream Listener interface. + */ +public interface IStreamListener +{ + /** + * Process samples from a single stream of I/Q samples + * @param xi array of Inphase samples + * @param xq array of Quadrature samples + * @param streamCallbackParameters stream callback parameters + * @param reset indicates if a re-initialization has occurred within the API and that local buffering should be reset + */ + void processStream(short[] xi, short[] xq, StreamCallbackParameters streamCallbackParameters, + boolean reset); + + /** + * Indicates which tuner this stream listener is for. Note: this is used to manage asynchronous Updates to ensure + * that submitted updates get correctly mapped and resolved in the Device update manager. + * @return + */ + TunerSelect getTunerSelect(); +} diff --git a/jsdrplay/src/main/java/com/github/dsheirer/sdrplay/callback/StreamCallbackAdapter.java b/jsdrplay/src/main/java/com/github/dsheirer/sdrplay/callback/StreamCallbackAdapter.java new file mode 100644 index 000000000..d21fee3ba --- /dev/null +++ b/jsdrplay/src/main/java/com/github/dsheirer/sdrplay/callback/StreamCallbackAdapter.java @@ -0,0 +1,108 @@ +/* + * ***************************************************************************** + * 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.callback; + +import com.github.dsheirer.sdrplay.api.v3_07.sdrplay_api_StreamCallback_t; +import com.github.dsheirer.sdrplay.api.v3_07.sdrplay_api_StreamCbParamsT; +import com.github.dsheirer.sdrplay.util.Flag; +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; + +/** + * I/Q sample stream callback adapter. Implements the native interface and transfers the native callback data to an + * implementation of the Java IStreamListener interface. + */ +public class StreamCallbackAdapter implements sdrplay_api_StreamCallback_t +{ + private static final Logger mLog = LoggerFactory.getLogger(StreamCallbackAdapter.class); + private MemorySession mMemorySession; + private IStreamListener mStreamListener; + private IStreamCallbackListener mStreamCallbackListener; + + /** + * Constructs an instance of the callback implementation + * @param memorySession for defining new foreign memory segments + * @param streamListener to receive transferred I/Q samples and event details + * @param listener to receive callback parameters + */ + public StreamCallbackAdapter(MemorySession memorySession, IStreamListener streamListener, + IStreamCallbackListener listener) + { + if(memorySession == null) + { + throw new IllegalArgumentException("Resource scope must be non-null"); + } + + mMemorySession = memorySession; + mStreamCallbackListener = listener; + setListener(streamListener); + } + + /** + * Updates the listener for receiving samples + * @param listener to receive stream samples + */ + public void setListener(IStreamListener listener) + { + mStreamListener = listener; + } + + /** + * Receives callback of foreign memory data, transfers it to Java, and passes to the listener. + * @param iSamplesPointer array foreign memory address + * @param qSamplesPointer array foreign memory address + * @param parametersPointer associated with the callback - foreign memory address + * @param sampleCount number of samples in each of the I and Q arrays + * @param reset 0 or 1, translated to a boolean + * @param deviceContext of the device that sourced the samples + */ + @Override + public void apply(MemoryAddress iSamplesPointer, MemoryAddress qSamplesPointer, MemoryAddress parametersPointer, + int sampleCount, int reset, MemoryAddress deviceContext) + { + if(mStreamListener != null || mStreamCallbackListener != null) + { + //Translate the callback parameters pointer to a memory segment and re-construct the parameters as a Java object + StreamCallbackParameters parameters = new StreamCallbackParameters(sdrplay_api_StreamCbParamsT + .ofAddress(parametersPointer, mMemorySession)); + + if(mStreamCallbackListener != null) + { + mStreamCallbackListener.process(mStreamListener.getTunerSelect(), parameters, reset); + } + + if(mStreamListener != null) + { + //Allocate memory segments from I/Q pointers, transfer from native to JVM array, and send to listener + long arrayByteSize = ValueLayout.JAVA_SHORT.byteSize() * sampleCount; + MemorySegment iSamples = MemorySegment.ofAddress(iSamplesPointer, arrayByteSize, mMemorySession); + MemorySegment qSamples = MemorySegment.ofAddress(qSamplesPointer, arrayByteSize, mMemorySession); + short[] i = iSamples.toArray(ValueLayout.JAVA_SHORT); + short[] q = qSamples.toArray(ValueLayout.JAVA_SHORT); + mStreamListener.processStream(i, q, parameters, Flag.evaluate(reset)); + } + } + } +} diff --git a/jsdrplay/src/main/java/com/github/dsheirer/sdrplay/callback/StreamCallbackParameters.java b/jsdrplay/src/main/java/com/github/dsheirer/sdrplay/callback/StreamCallbackParameters.java new file mode 100644 index 000000000..a37952e0f --- /dev/null +++ b/jsdrplay/src/main/java/com/github/dsheirer/sdrplay/callback/StreamCallbackParameters.java @@ -0,0 +1,89 @@ +/* + * ***************************************************************************** + * 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.callback; + +import com.github.dsheirer.sdrplay.api.v3_07.sdrplay_api_StreamCbParamsT; +import com.github.dsheirer.sdrplay.util.Flag; + +import java.lang.foreign.MemorySegment; + +/** + * Stream Callback Parameters structure (sdrplay_api_StreamCbParamsT) + */ +public class StreamCallbackParameters +{ + private int mFirstSampleNumber; + private boolean mGainReductionChanged; + private boolean mRfFrequencyChanged; + private boolean mSampleRateChanged; + private long mNumberSamples; + + /** + * Constructs an instance from the foreign memory segment + */ + public StreamCallbackParameters(MemorySegment memorySegment) + { + mFirstSampleNumber = sdrplay_api_StreamCbParamsT.firstSampleNum$get(memorySegment); + mGainReductionChanged = Flag.evaluate(sdrplay_api_StreamCbParamsT.grChanged$get(memorySegment)); + mRfFrequencyChanged = Flag.evaluate(sdrplay_api_StreamCbParamsT.rfChanged$get(memorySegment)); + mSampleRateChanged = Flag.evaluate(sdrplay_api_StreamCbParamsT.fsChanged$get(memorySegment)); + mNumberSamples = sdrplay_api_StreamCbParamsT.numSamples$get(memorySegment); + } + + /** + * First sample number + */ + public int getFirstSampleNumber() + { + return mFirstSampleNumber; + } + + /** + * Indicates if gain reduction value has changed + */ + public boolean isGainReductionChanged() + { + return mGainReductionChanged; + } + + /** + * Indicates if RF center frequency has changed + */ + public boolean isRfFrequencyChanged() + { + return mRfFrequencyChanged; + } + + /** + * Indicates if sample rate has changed + */ + public boolean isSampleRateChanged() + { + return mSampleRateChanged; + } + + /** + * Number of samples + */ + public long getNumberSamples() + { + return mNumberSamples; + } +} diff --git a/jsdrplay/src/main/java/com/github/dsheirer/sdrplay/device/Decimate.java b/jsdrplay/src/main/java/com/github/dsheirer/sdrplay/device/Decimate.java new file mode 100644 index 000000000..d167f478d --- /dev/null +++ b/jsdrplay/src/main/java/com/github/dsheirer/sdrplay/device/Decimate.java @@ -0,0 +1,84 @@ +/* + * ***************************************************************************** + * 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; + +/** + * Software decimation rates supported by the API for SDRPlay RSP devices + */ +public enum Decimate +{ + X1(1, 16), + X2(2, 16), + X4(4, 17), + X8(8, 17), + X16(16, 18), + X32(32, 20); + + private int mValue; + private int mSampleSize; + + /** + * Constructs an instance + * @param value + * @param sampleSize in bits to represent effective dynamic range. + */ + Decimate(int value, int sampleSize) + { + mValue = value; + mSampleSize = sampleSize; + } + + /** + * Decimation value. + * @return + */ + public int getValue() + { + return mValue; + } + + /** + * Sample size in bits to represent effective dynamic range for the decimation value. + */ + public int getSampleSize() + { + return mSampleSize; + } + + /** + * Indicates if software decimation is enabled. + * @return true for all values except X1. + */ + public boolean isEnabled() + { + return !this.equals(X1); + } + + @Override + public String toString() + { + if(this.equals(X1)) + { + return "None"; + } + + return "x" + getValue(); + } +} 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 new file mode 100644 index 000000000..dfd95f7f8 --- /dev/null +++ b/jsdrplay/src/main/java/com/github/dsheirer/sdrplay/device/Device.java @@ -0,0 +1,696 @@ +/* + * ***************************************************************************** + * 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.SDRPlayException; +import com.github.dsheirer.sdrplay.SDRplay; +import com.github.dsheirer.sdrplay.Status; +import com.github.dsheirer.sdrplay.UpdateReason; +import com.github.dsheirer.sdrplay.async.AsyncUpdateFuture; +import com.github.dsheirer.sdrplay.async.CompletedAsyncUpdate; +import com.github.dsheirer.sdrplay.callback.IDeviceEventListener; +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; +import java.lang.foreign.MemoryAddress; +import java.lang.foreign.MemorySegment; +import java.util.Queue; +import java.util.concurrent.ConcurrentLinkedQueue; +import java.util.concurrent.Executors; +import java.util.concurrent.ScheduledExecutorService; +import java.util.concurrent.TimeUnit; +import java.util.concurrent.locks.ReentrantLock; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +/** + * Abstract device structure (sdrplay_api_DeviceT) + */ +public abstract class Device, R extends RspTuner> +{ + private static final Logger mLog = LoggerFactory.getLogger(Device.class); + + private SDRplay mSDRplay; + private final UpdateRequestManager mUpdateRequestManager = new UpdateRequestManager(); + private final IDeviceStruct mDeviceStruct; + protected boolean mSelected = false; + protected boolean mInitialized = false; + private T mCompositeParameters; + + /** + * Constructs an SDRPlay device from the foreign memory segment + * @param sdrPlay api instance that created this device + * @param deviceStruct to parse or access the fields of the device structure + */ + public Device(SDRplay sdrPlay, IDeviceStruct deviceStruct) + { + mSDRplay = sdrPlay; + mDeviceStruct = deviceStruct; + } + + /** + * Version specific device structure parser + */ + protected IDeviceStruct getDeviceStruct() + { + return mDeviceStruct; + } + + /** + * API that owns this device + */ + protected SDRplay getAPI() + { + return mSDRplay; + } + + /** + * Stream callback listener for parameter change events. + */ + public IStreamCallbackListener getStreamCallbackListener() + { + return mUpdateRequestManager; + } + + /** + * Loads the device parameters for this device. Subsequent calls once the parameters are created are ignored. + * @throws SDRPlayException if the device is not selected or if there is an issue loading the parameters + */ + private void loadDeviceParameters() throws SDRPlayException + { + if(selected()) + { + 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); + } + } + + /** + * Selects this device for exclusive use and loads the device composite parameters. + * @throws SDRPlayException if unable to select the device or if unable to load the composite parameters for use. + */ + public void select() throws SDRPlayException + { + if(!selected()) + { + getAPI().select(getDeviceMemorySegment()); + mSelected = true; + loadDeviceParameters(); + } + } + + /** + * Indicates if this device has been selected via the SDRplay api + */ + protected boolean selected() + { + return mSelected; + } + + /** + * Indicates if the device is valid and ready for use + */ + public boolean isValid() + { + return getDeviceStruct().isValid(); + } + + /** + * Releases this device from exclusive use. + */ + public void release() throws SDRPlayException + { + if(selected()) + { + mSelected = false; + getAPI().release(getDeviceMemorySegment()); + } + } + + /** + * Indicates if this device is initialized for use + */ + public boolean isInitialized() + { + return mInitialized; + } + + /** + * Initializes this device for single-tuner use and starts the tuner providing raw signal samples to the stream + * listener and device events to the event listener. + * + * Note: invoke select() to select this device for exclusive use before invoking this method. If this device has + * previously been initialized, an exception is thrown. Use uninit() to uninitialize this device and stop the + * sample stream and event notifications. + * + * @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 if there is an error + */ + public void initStreamA(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"); + } + + getAPI().initA(Device.this, getDeviceHandle(), eventListener, streamListener); + mInitialized = true; + } + + /** + * Initializes this device for dual-tuner stream B use and starts the tuner providing raw signal samples to the stream + * listener and device events to the event listener. + * + * Note: invoke select() to select this device for exclusive use before invoking this method. If this device has + * previously been initialized, an exception is thrown. Use uninit() to uninitialize this device and stop the + * sample stream and event notifications. + * + * @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 if there is an error + */ + public void initStreamB(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"); + } + + getAPI().initB(Device.this, getDeviceHandle(), eventListener, streamListener); + mInitialized = true; + } + + /** + * Uninitializes this device from use. Note: call is ignored if this device hasn't been initialized + * @throws SDRPlayException if there is an error + */ + public void uninitialize() throws SDRPlayException + { + if(isInitialized()) + { + getAPI().uninit(getDeviceHandle()); + mInitialized = false; + } + else + { + throw new SDRPlayException("Attempt to uninit a device that has not been initialized previously"); + } + } + + /** + * Updates this device after parameter change, only when the device is initialized. If the device is not yet + * initialized, the update request is ignored. + * + * @throws SDRPlayException if unable to apply updates + */ + public void update(TunerSelect tunerSelect, UpdateReason ... updateReasons) throws SDRPlayException + { + if(isInitialized()) + { + submitUpdate(tunerSelect, updateReasons); + } + } + + private String toString(UpdateReason ... updateReasons) + { + StringBuilder sb = new StringBuilder(); + + boolean first = true; + + for(UpdateReason updateReason: updateReasons) + { + if(first) + { + sb.append("["); + } + else + { + sb.append(", "); + } + + sb.append(updateReason.name()); + + first = false; + } + + sb.append("]"); + + return sb.toString(); + } + + /** + * Asynchronous update request. This method should only be used for Frequency, Gain and Sample Rate updates. + * @param tunerSelect tuner being updated + * @param updateReason for the parameter that is being updated + * @param expectedResponse that is one of Gain, Frequency, or Sample Rate. + * @return a future that has already been completed, or if initialized a future that will be completed. + */ + protected AsyncUpdateFuture updateAsync(TunerSelect tunerSelect, UpdateReason updateReason, UpdateReason expectedResponse) + { + if(!expectedResponse.isAsyncUpdateResponse()) + { + throw new IllegalArgumentException("Invalid expected response: " + expectedResponse + + ". Valid values are: " + UpdateReason.ASYNC_UPDATE_RESPONSES); + } + + if(isInitialized()) + { + return mUpdateRequestManager.update(tunerSelect, updateReason, expectedResponse); + } + + //If not initialized, return success. + AsyncUpdateFuture future = new AsyncUpdateFuture(tunerSelect, updateReason, expectedResponse); + future.setResult(Status.SUCCESS); + return future; + } + + /** + * Submits an update request to the API. This method is used/managed by the update request manager. + * @param tunerSelect for the update + * @param updateReasons to apply + * @throws SDRPlayException if there is an issue. + */ + private void submitUpdate(TunerSelect tunerSelect, UpdateReason ... updateReasons) throws SDRPlayException + { + getAPI().update(Device.this, getDeviceHandle(), tunerSelect, updateReasons); + } + + /** + * Acknowledge tuner power overload events + * @param tunerSelect identifying which tuner(s) + * @throws SDRPlayException on error + */ + public void acknowledgePowerOverload(TunerSelect tunerSelect) throws SDRPlayException + { +// 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()) + { + try + { + update(tunerSelect, UpdateReason.CONTROL_OVERLOAD_MESSAGE_ACK); + } + catch(SDRPlayException se) + { + //Ignore the not initialized exception that can happen when shutting down the receiver, otherwise + //rethrow the exception. + if(se.getStatus() != Status.NOT_INITIALIZED) + { + throw se; + } + } + } + } + + /** + * Tuner selection. + * @return tuner select. Defaults to TUNER_1 for all but the RSPduo where it is overridden for tuner 2. + */ + public TunerSelect getTunerSelect() + { + return TunerSelect.TUNER_1; + } + + /** + * Foreign memory segment representing this device. + */ + protected MemorySegment getDeviceMemorySegment() + { + return getDeviceStruct().getDeviceMemorySegment(); + } + + /** + * Handle to this device. + * + * Note: this device must be selected for exclusive use before you can access this handle. + * + * @throws SDRPlayException if this method is accessed before the device has been successfully selected + */ + MemoryAddress getDeviceHandle() throws SDRPlayException + { + if(!selected()) + { + throw new SDRPlayException("This device must be selected for exclusive use before accessing/using the " + + "device handle"); + } + + return getDeviceStruct().getDeviceHandle(); + } + + /** + * Tuner for this device + * @return tuner appropriate for the device type + * @throws SDRPlayException for various reasons include device not selected or API unavailable + */ + public abstract R getTuner() throws SDRPlayException; + + /** + * Composite parameters for this device + */ + public T getCompositeParameters() + { + return mCompositeParameters; + } + + /** + * Indicates if this device has composite parameters + */ + public boolean hasCompositeParameters() + { + return mCompositeParameters != null; + } + + /** + * Indicates if this device is available and has been selected for exclusive use. + */ + public boolean isSelected() + { + return mSelected; + } + + /** + * Device type + */ + public DeviceType getDeviceType() + { + return getDeviceStruct().getDeviceType(); + } + + /** + * Serial number + */ + public String getSerialNumber() + { + return getDeviceStruct().getSerialNumber(); + } + + /** + * Current sample rate + */ + public double getSampleRate() + { + return getCompositeParameters().getDeviceParameters().getSamplingFrequency().getSampleRate(); + } + + public void setIfMode(IfMode ifMode) + { + getCompositeParameters().getTunerAParameters().setIfMode(ifMode); + } + + public void setLoMode(LoMode loMode) + { + getCompositeParameters().getTunerAParameters().setLoMode(loMode); + } + + /** + * Enables or disables wideband signal mode. This should be set according to the IFMode, where IFMode.ZERO is + * wideband and all others are not wideband. + * @param enable + */ + public void setWidebandSignal(boolean enable) throws SDRPlayException + { + getCompositeParameters().getControlAParameters().getDecimation().setWideBandSignal(enable); + + if(isInitialized()) + { + update(getTunerSelect(), UpdateReason.CONTROL_DECIMATION); + } + } + + /** + * Sets the software-based decimation factor for the final sample rate. + * @param decimate value where X1 is no decimation and all others are decimation enabled values. + * @throws SDRPlayException if there is an error while setting decimation + */ + public void setDecimation(Decimate decimate) throws SDRPlayException + { + getCompositeParameters().getControlAParameters().getDecimation().setDecimationFactor(decimate.getValue()); + getCompositeParameters().getControlAParameters().getDecimation().setEnabled(decimate.isEnabled()); + + if(isInitialized()) + { + update(getTunerSelect(), UpdateReason.CONTROL_DECIMATION); + } + } + + @Override + public String toString() + { + StringBuilder sb = new StringBuilder(); + sb.append("SDRPplay Device").append("\n"); + sb.append("\tType: ").append(getDeviceType()).append("\n"); + sb.append("\tSerial Number: ").append(getSerialNumber()).append("\n"); + sb.append("\tSelected: ").append(isSelected()); + if(hasCompositeParameters()) + { + sb.append("\t").append(getCompositeParameters()); + } + + return sb.toString(); + } + + /** + * Thread-safe manager for asynchronous update request queue processing for an initialized RSP device. + * + * Once a device has been initialized, any changes to frequency, gain or sample rate require submitting an update + * request to the device to apply the parameter change(s). However, since the API supports non-blocking operation, + * the operation executes asynchronously. The API supports only a single update request operation + * to be in-progress at a time and any overlapping update requests are met with an unsuccessful status code return + * from the update method. + */ + class UpdateRequestManager implements IStreamCallbackListener + { + private static final long UPDATE_QUEUE_PROCESSING_INTERVAL_MS = 75; + private final ScheduledExecutorService mExecutorService = Executors.newSingleThreadScheduledExecutor(); + private final Queue mUpdateQueue = new ConcurrentLinkedQueue(); + private final Queue mCompletedUpdateQueue = new ConcurrentLinkedQueue(); + private final ReentrantLock mLock = new ReentrantLock(); + + /** + * Submits an update request for the specified tuner and update reason for queued processing. This is a + * non-blocking operation and the update is performed by a thread from the thread pool. + * @param tunerSelect to apply the update + * @param updateReason to update + * @return an asynchronous future to monitor the progress of the update request + */ + public AsyncUpdateFuture update(TunerSelect tunerSelect, UpdateReason updateReason, UpdateReason expectedResponse) + { + AsyncUpdateFuture future = new AsyncUpdateFuture(tunerSelect, updateReason, expectedResponse); + mUpdateQueue.add(future); + processQueuesImmediately(); + return future; + } + + /** + * Schedules a process queues task for immediate execution. Non-blocking. + */ + private void processQueuesImmediately() + { + processQueuesAfterDelay(0); + } + + /** + * Schedules a process queues task after the delay. Non-blocking + * @param delay in milliseconds, or zero for immediate. + */ + private void processQueuesAfterDelay(long delay) + { + mExecutorService.schedule(() -> processQueues(), delay, TimeUnit.MILLISECONDS); + } + + /** + * Processes the pending and completed update operation queues. Submits new update requests one at a time and + * awaits a stream callback notification that the matching update reason has been applied/updated. Ensures + * that only a single update operation is in-progress at any given time. + */ + private synchronized void processQueues() + { + mLock.lock(); + + try + { + if(mUpdateQueue.isEmpty()) + { + //If we have no pending updates, we don't care about any completed update results + mCompletedUpdateQueue.clear(); + } + else + { + boolean processing = true; + + while(processing) + { + processing = false; + + AsyncUpdateFuture futureUpdate = mUpdateQueue.peek(); + + if(futureUpdate != null) + { + if(futureUpdate.isSubmitted()) + { + //Process the completion queue + while(!mCompletedUpdateQueue.isEmpty()) + { + CompletedAsyncUpdate completedUpdate = mCompletedUpdateQueue.poll(); + + if(completedUpdate != null) + { + if(futureUpdate.matches(completedUpdate)) + { + //Clear the remaining completed updates + mCompletedUpdateQueue.clear(); + + //Remove and (successfully) complete the current future + mUpdateQueue.remove(); + futureUpdate.setResult(Status.SUCCESS); + + //Signal to immediately reprocess the queue + processing = true; + + //Break out of the completed update queue processing + break; + } + } + } + } + else + { + //Clear the completed queue and submit the update + mCompletedUpdateQueue.clear(); + + try + { + submitUpdate(futureUpdate.getTunerSelect(), futureUpdate.getUpdateReason()); + futureUpdate.setSubmitted(true); + } + catch(SDRPlayException se) + { + futureUpdate = mUpdateQueue.poll(); + futureUpdate.setError(se); + //Set continuous to true to immediately reprocess the next update + processing = true; + } + } + } + } + } + } + finally + { + mLock.unlock(); + } + + if(!mUpdateQueue.isEmpty()) + { + processQueuesAfterDelay(UPDATE_QUEUE_PROCESSING_INTERVAL_MS); + } + } + + /** + * Receives an update completion event. This is a non-blocking operation since this method will be invoked + * by the stream callback thread, and we don't want to impact the delivery of streaming samples or events. + * + * @param tunerSelect tuner that was updated + * @param updateReason for what was updated + */ + public void completed(TunerSelect tunerSelect, UpdateReason updateReason) + { + mCompletedUpdateQueue.add(new CompletedAsyncUpdate(tunerSelect, updateReason)); + mExecutorService.schedule(this::processQueues, 0, TimeUnit.MILLISECONDS); + } + + /** + * Resets the update queue. + */ + public void reset() + { + mLock.lock(); + + try + { + while(!mUpdateQueue.isEmpty()) + { + AsyncUpdateFuture future = mUpdateQueue.poll(); + future.setResult(Status.UNKNOWN); + } + } + finally + { + mLock.unlock(); + } + } + + /** + * Implements the IStreamCallbackListener interface to receive change notifications from update requests. + * @param parameters to process + * @param reset value with flags + */ + @Override + public void process(TunerSelect tunerSelect, StreamCallbackParameters parameters, int reset) + { + if(parameters.isSampleRateChanged()) + { + completed(tunerSelect, UpdateReason.DEVICE_SAMPLE_RATE); + } + if(parameters.isRfFrequencyChanged()) + { + completed(tunerSelect, UpdateReason.TUNER_FREQUENCY_RF); + } + if(parameters.isGainReductionChanged()) + { + completed(tunerSelect, UpdateReason.TUNER_GAIN_REDUCTION); + } + } + } +} 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 new file mode 100644 index 000000000..1d3cc4cf8 --- /dev/null +++ b/jsdrplay/src/main/java/com/github/dsheirer/sdrplay/device/DeviceFactory.java @@ -0,0 +1,163 @@ +/* + * ***************************************************************************** + * 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.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 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 createDeviceArray(Version version, SegmentAllocator segmentAllocator) + { + if(version.gte(Version.V3_08)) + { + return com.github.dsheirer.sdrplay.api.v3_08.sdrplay_api_DeviceT.allocateArray(sdrplay_api_h.SDRPLAY_MAX_DEVICES(), segmentAllocator); + } + else if(version == Version.V3_07) + { + return sdrplay_api_DeviceT.allocateArray(sdrplay_api_h.SDRPLAY_MAX_DEVICES(), segmentAllocator); + } + + throw new IllegalArgumentException("Unrecognized version: " + version); + } + + /** + * 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 parseDeviceStructs(Version version, MemorySegment devicesArray, int count) throws SDRPlayException + { + 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 -> + deviceStructs.add(DeviceFactory.createDeviceStruct(version, memorySegment))); + } + else if(version == Version.V3_07) + { + devicesArray.elements(sdrplay_api_DeviceT.$LAYOUT()).limit(count).forEach(memorySegment -> + { + deviceStructs.add(DeviceFactory.createDeviceStruct(version, memorySegment)); + }); + } + else + { + throw new SDRPlayException("Unrecognized version: " + version); + } + + return deviceStructs; + } + + /** + * Creates an SDRplay device from the foreign memory Device instance. + * @param sdrPlay for device callback support + * @param deviceMemorySegment instance for the device + * @return correctly typed device + */ + public static Device createDevice(SDRplay sdrPlay, IDeviceStruct deviceStruct) + { + switch(deviceStruct.getDeviceType()) + { + case RSP1 -> { + return new Rsp1Device(sdrPlay, deviceStruct); + } + case RSP1A -> { + return new Rsp1aDevice(sdrPlay, deviceStruct); + } + case RSP2 -> { + return new Rsp2Device(sdrPlay, deviceStruct); + } + case RSPduo -> { + return new RspDuoDevice(sdrPlay, deviceStruct); + } + case RSPdx -> { + return new RspDxDevice(sdrPlay, deviceStruct); + } + default -> { + return new UnknownDevice(sdrPlay, deviceStruct); + } + } + } + + /** + * Creates a device structure parser for the specified API version + * @param version to create + * @param deviceMemorySegment for the device + * @return device structure + */ + private static IDeviceStruct createDeviceStruct(Version version, MemorySegment deviceMemorySegment) + { + if(version == Version.V3_07) + { + return new DeviceStruct_v3_07(deviceMemorySegment); + } + else if(version.gte(Version.V3_08)) + { + return new DeviceStruct_v3_08(deviceMemorySegment); + } + else + { + throw new IllegalArgumentException("Unsupported version: " + version); + } + } +} 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/DeviceStruct_v3_07.java b/jsdrplay/src/main/java/com/github/dsheirer/sdrplay/device/DeviceStruct_v3_07.java new file mode 100644 index 000000000..906f47c63 --- /dev/null +++ b/jsdrplay/src/main/java/com/github/dsheirer/sdrplay/device/DeviceStruct_v3_07.java @@ -0,0 +1,100 @@ +/* + * ***************************************************************************** + * 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.api.v3_07.sdrplay_api_DeviceT; + +import java.lang.foreign.MemoryAddress; +import java.lang.foreign.MemorySegment; + +/** + * sdrplay_api_DeviceT structure parser for API version 3.07 + */ +public class DeviceStruct_v3_07 implements IDeviceStruct +{ + private MemorySegment mDeviceMemorySegment; + private DeviceType mDeviceType; + private String mSerialNumber; + + /** + * Constructs an instance + * @param deviceMemorySegment of foreign memory + */ + public DeviceStruct_v3_07(MemorySegment deviceMemorySegment) + { + mDeviceMemorySegment = deviceMemorySegment; + mDeviceType = DeviceType.fromValue(0xFF & sdrplay_api_DeviceT.hwVer$get(mDeviceMemorySegment)); + MemorySegment serialSegment = sdrplay_api_DeviceT.SerNo$slice(mDeviceMemorySegment); + mSerialNumber = serialSegment.getUtf8String(0); + } + + @Override public MemorySegment getDeviceMemorySegment() + { + return mDeviceMemorySegment; + } + + @Override public String getSerialNumber() + { + return mSerialNumber; + } + + @Override public DeviceType getDeviceType() + { + return mDeviceType; + } + + @Override public TunerSelect getTunerSelect() + { + return TunerSelect.fromValue(sdrplay_api_DeviceT.tuner$get(getDeviceMemorySegment())); + } + + @Override public RspDuoMode getRspDuoMode() + { + return RspDuoMode.fromValue(sdrplay_api_DeviceT.rspDuoMode$get(getDeviceMemorySegment())); + } + + @Override + public void setRspDuoMode(RspDuoMode mode) + { + sdrplay_api_DeviceT.rspDuoMode$set(getDeviceMemorySegment(), mode.getValue()); + } + + @Override public boolean isValid() + { + //Always returns true for version 3.07 + return true; + } + + @Override public double getRspDuoSampleFrequency() + { + return sdrplay_api_DeviceT.rspDuoSampleFreq$get(getDeviceMemorySegment()); + } + + @Override + public void setRspDuoSampleFrequency(double frequency) + { + sdrplay_api_DeviceT.rspDuoSampleFreq$set(getDeviceMemorySegment(), frequency); + } + + @Override public MemoryAddress getDeviceHandle() + { + return sdrplay_api_DeviceT.dev$get(getDeviceMemorySegment()); + } +} diff --git a/jsdrplay/src/main/java/com/github/dsheirer/sdrplay/device/DeviceStruct_v3_08.java b/jsdrplay/src/main/java/com/github/dsheirer/sdrplay/device/DeviceStruct_v3_08.java new file mode 100644 index 000000000..d113e1966 --- /dev/null +++ b/jsdrplay/src/main/java/com/github/dsheirer/sdrplay/device/DeviceStruct_v3_08.java @@ -0,0 +1,100 @@ +/* + * ***************************************************************************** + * 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.api.v3_08.sdrplay_api_DeviceT; + +import java.lang.foreign.MemoryAddress; +import java.lang.foreign.MemorySegment; + +/** + * sdrplay_api_DeviceT structure parser for API version 3.07 + */ +public class DeviceStruct_v3_08 implements IDeviceStruct +{ + private MemorySegment mDeviceMemorySegment; + private DeviceType mDeviceType; + private String mSerialNumber; + + /** + * Constructs an instance + * @param deviceMemorySegment of foreign memory + */ + public DeviceStruct_v3_08(MemorySegment deviceMemorySegment) + { + mDeviceMemorySegment = deviceMemorySegment; + mDeviceType = DeviceType.fromValue(0xFF & sdrplay_api_DeviceT.hwVer$get(mDeviceMemorySegment)); + MemorySegment serialSegment = sdrplay_api_DeviceT.SerNo$slice(mDeviceMemorySegment); + mSerialNumber = serialSegment.getUtf8String(0); + } + + @Override public MemorySegment getDeviceMemorySegment() + { + return mDeviceMemorySegment; + } + + @Override public String getSerialNumber() + { + return mSerialNumber; + } + + @Override public DeviceType getDeviceType() + { + return mDeviceType; + } + + @Override public TunerSelect getTunerSelect() + { + return TunerSelect.fromValue(sdrplay_api_DeviceT.tuner$get(getDeviceMemorySegment())); + } + + @Override public RspDuoMode getRspDuoMode() + { + return RspDuoMode.fromValue(sdrplay_api_DeviceT.rspDuoMode$get(getDeviceMemorySegment())); + } + + @Override + public void setRspDuoMode(RspDuoMode mode) + { + sdrplay_api_DeviceT.rspDuoMode$set(getDeviceMemorySegment(), mode.getValue()); + } + + @Override public boolean isValid() + { + //Always returns true for version 3.07 + return true; + } + + @Override public double getRspDuoSampleFrequency() + { + return sdrplay_api_DeviceT.rspDuoSampleFreq$get(getDeviceMemorySegment()); + } + + @Override + public void setRspDuoSampleFrequency(double frequency) + { + sdrplay_api_DeviceT.rspDuoSampleFreq$set(getDeviceMemorySegment(), frequency); + } + + @Override public MemoryAddress getDeviceHandle() + { + return sdrplay_api_DeviceT.dev$get(getDeviceMemorySegment()); + } +} diff --git a/jsdrplay/src/main/java/com/github/dsheirer/sdrplay/device/DeviceType.java b/jsdrplay/src/main/java/com/github/dsheirer/sdrplay/device/DeviceType.java new file mode 100644 index 000000000..43798f08a --- /dev/null +++ b/jsdrplay/src/main/java/com/github/dsheirer/sdrplay/device/DeviceType.java @@ -0,0 +1,76 @@ +/* + * ***************************************************************************** + * 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.api.v3_07.sdrplay_api_h; + +/** + * RSP Device type + */ +public enum DeviceType +{ + RSP1(sdrplay_api_h.SDRPLAY_RSP1_ID(), "RSP1"), + RSP1A(sdrplay_api_h.SDRPLAY_RSP1A_ID(), "RSP1A"), + RSP2(sdrplay_api_h.SDRPLAY_RSP2_ID(), "RSP2"), + RSPduo(sdrplay_api_h.SDRPLAY_RSPduo_ID(), "RSPduo"), + RSPdx(sdrplay_api_h.SDRPLAY_RSPdx_ID(), "RSPdx"), + UNKNOWN(Integer.MIN_VALUE, "UNKNOWN"); + + private int mValue; + private String mDescription; + + DeviceType(int value, String description) + { + mValue = value; + mDescription = description; + } + + /** + * Numeric value + */ + public int getValue() + { + return mValue; + } + + /** + * Lookup the entry from a return code + * @param value to lookup + * @return entry or UNKNOWN if the code is not recognized + */ + public static DeviceType fromValue(int value) + { + for(DeviceType status: DeviceType.values()) + { + if(status.getValue() == value) + { + return status; + } + } + + return UNKNOWN; + } + + @Override + public String toString() + { + return mDescription; + } +} diff --git a/jsdrplay/src/main/java/com/github/dsheirer/sdrplay/device/IDeviceStruct.java b/jsdrplay/src/main/java/com/github/dsheirer/sdrplay/device/IDeviceStruct.java new file mode 100644 index 000000000..c8d16ec2a --- /dev/null +++ b/jsdrplay/src/main/java/com/github/dsheirer/sdrplay/device/IDeviceStruct.java @@ -0,0 +1,81 @@ +/* + * ***************************************************************************** + * 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 java.lang.foreign.MemoryAddress; +import java.lang.foreign.MemorySegment; + +/** + * Interface for parsing and accessing the fields of the sdrplay_api_DeviceT structure across + * various versions. + */ +public interface IDeviceStruct +{ + /** + * Foreign memory segment for this device structure + */ + MemorySegment getDeviceMemorySegment(); + + /** + * Serial number of the device + */ + String getSerialNumber(); + + /** + * Indicates the device type, or model of RSP + */ + DeviceType getDeviceType(); + + /** + * Indicates single, dual, or master/slave mode for the tuner. + */ + TunerSelect getTunerSelect(); + + /** + * RSPduo mode + */ + RspDuoMode getRspDuoMode(); + + /** + * Sets the RSPduo mode + * @param mode to set + */ + void setRspDuoMode(RspDuoMode mode); + + /** + * Indicates if the device is valid and ready for use (V3.08 and later) + */ + boolean isValid(); + + /** + * Sample frequency/rate for the RSPduo when in master/slave mode + */ + double getRspDuoSampleFrequency(); + + /** + * Sets the sample frequency/rate for the RSPduo when in master (only) mode. + */ + void setRspDuoSampleFrequency(double frequency); + + /** + * Device handle. Note this is only available if the device has been selected. + */ + MemoryAddress getDeviceHandle(); +} diff --git a/jsdrplay/src/main/java/com/github/dsheirer/sdrplay/device/Rsp1Device.java b/jsdrplay/src/main/java/com/github/dsheirer/sdrplay/device/Rsp1Device.java new file mode 100644 index 000000000..07c8940e5 --- /dev/null +++ b/jsdrplay/src/main/java/com/github/dsheirer/sdrplay/device/Rsp1Device.java @@ -0,0 +1,61 @@ +/* + * ***************************************************************************** + * 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.SDRPlayException; +import com.github.dsheirer.sdrplay.SDRplay; +import com.github.dsheirer.sdrplay.parameter.composite.Rsp1CompositeParameters; + +/** + * RSP1 Device + */ +public class Rsp1Device extends Device +{ + private Rsp1Tuner mTuner1; + + /** + * Constructs an SDRPlay RSP1 device from the foreign memory segment + * + * @param sdrPlay api instance that created this device + * @param deviceStruct parser + */ + Rsp1Device(SDRplay sdrPlay, IDeviceStruct deviceStruct) + { + super(sdrPlay, deviceStruct); + } + + @Override + public Rsp1Tuner getTuner() throws SDRPlayException + { + if(!isSelected()) + { + throw new SDRPlayException("Device must be selected before accessing the tuner"); + } + + if(mTuner1 == null) + { + mTuner1 = new Rsp1Tuner(Rsp1Device.this, getAPI(), getTunerSelect(), + getCompositeParameters().getDeviceParameters(), getCompositeParameters().getTunerAParameters(), + getCompositeParameters().getControlAParameters()); + } + + return mTuner1; + } +} diff --git a/jsdrplay/src/main/java/com/github/dsheirer/sdrplay/device/Rsp1Tuner.java b/jsdrplay/src/main/java/com/github/dsheirer/sdrplay/device/Rsp1Tuner.java new file mode 100644 index 000000000..147d3bede --- /dev/null +++ b/jsdrplay/src/main/java/com/github/dsheirer/sdrplay/device/Rsp1Tuner.java @@ -0,0 +1,46 @@ +/* + * ***************************************************************************** + * 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.SDRplay; +import com.github.dsheirer.sdrplay.parameter.control.ControlParameters; +import com.github.dsheirer.sdrplay.parameter.device.Rsp1DeviceParameters; +import com.github.dsheirer.sdrplay.parameter.tuner.Rsp1TunerParameters; + +/** + * RSP1 Tuner + */ +public class Rsp1Tuner extends RspTuner +{ + /** + * Constructs an instance + * @param device parent for this tuner + * @param sdrplay api + * @param tunerSelect to specify which tuner + * @param deviceParameters for this device + * @param tunerParameters for this tuner + * @param controlParameters for this device + */ + public Rsp1Tuner(Device device, SDRplay sdrplay, TunerSelect tunerSelect, Rsp1DeviceParameters deviceParameters, + Rsp1TunerParameters tunerParameters, ControlParameters controlParameters) + { + super(device, sdrplay, tunerSelect, deviceParameters, tunerParameters, controlParameters); + } +} diff --git a/jsdrplay/src/main/java/com/github/dsheirer/sdrplay/device/Rsp1aDevice.java b/jsdrplay/src/main/java/com/github/dsheirer/sdrplay/device/Rsp1aDevice.java new file mode 100644 index 000000000..bce3c4263 --- /dev/null +++ b/jsdrplay/src/main/java/com/github/dsheirer/sdrplay/device/Rsp1aDevice.java @@ -0,0 +1,61 @@ +/* + * ***************************************************************************** + * 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.SDRPlayException; +import com.github.dsheirer.sdrplay.SDRplay; +import com.github.dsheirer.sdrplay.parameter.composite.Rsp1aCompositeParameters; + +/** + * RSP1A Device + */ +public class Rsp1aDevice extends Device +{ + private Rsp1aTuner mTuner1; + + /** + * Constructs an SDRPlay RSP1A device from the foreign memory segment + * + * @param sdrPlay api instance that created this device + * @param deviceStruct parser + */ + Rsp1aDevice(SDRplay sdrPlay, IDeviceStruct deviceStruct) + { + super(sdrPlay, deviceStruct); + } + + @Override + public Rsp1aTuner getTuner() throws SDRPlayException + { + if(!isSelected()) + { + throw new SDRPlayException("Device must be selected before accessing the tuner"); + } + + if(mTuner1 == null) + { + mTuner1 = new Rsp1aTuner(Rsp1aDevice.this, getAPI(), getTunerSelect(), + getCompositeParameters().getDeviceParameters(), getCompositeParameters().getTunerAParameters(), + getCompositeParameters().getControlAParameters()); + } + + return mTuner1; + } +} diff --git a/jsdrplay/src/main/java/com/github/dsheirer/sdrplay/device/Rsp1aTuner.java b/jsdrplay/src/main/java/com/github/dsheirer/sdrplay/device/Rsp1aTuner.java new file mode 100644 index 000000000..db936a0ae --- /dev/null +++ b/jsdrplay/src/main/java/com/github/dsheirer/sdrplay/device/Rsp1aTuner.java @@ -0,0 +1,105 @@ +/* + * ***************************************************************************** + * 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.SDRPlayException; +import com.github.dsheirer.sdrplay.SDRplay; +import com.github.dsheirer.sdrplay.UpdateReason; +import com.github.dsheirer.sdrplay.parameter.control.ControlParameters; +import com.github.dsheirer.sdrplay.parameter.device.Rsp1aDeviceParameters; +import com.github.dsheirer.sdrplay.parameter.tuner.Rsp1aTunerParameters; + +/** + * RSP1A Tuner + */ +public class Rsp1aTuner extends RspTuner +{ + /** + * Constructs an instance + * @param device parent for this tuner + * @param sdrplay api + * @param tunerSelect to specify which tuner + * @param deviceParameters for this device + * @param tunerParameters for this tuner + * @param controlParameters for this device + */ + public Rsp1aTuner(Device device, SDRplay sdrplay, TunerSelect tunerSelect, Rsp1aDeviceParameters deviceParameters, + Rsp1aTunerParameters tunerParameters, ControlParameters controlParameters) + { + super(device, sdrplay, tunerSelect, deviceParameters, tunerParameters, controlParameters); + } + + /** + * Indicates if the RF notch is enabled + */ + public boolean isRfNotch() + { + return getDeviceParameters().isRFNotch(); + } + + /** + * Enables or disables the RF notch + * @param enable setting + * @throws SDRPlayException if there is an error + */ + public void setRfNotch(boolean enable) throws SDRPlayException + { + getDeviceParameters().setRFNotch(enable); + update(UpdateReason.RSP1A_RF_NOTCH_CONTROL); + } + + /** + * Indicates if the RF DAB notch is enabled + */ + public boolean isRfDabNotch() + { + return getDeviceParameters().isRfDabNotch(); + } + + /** + * Enables or disables the RF DAB notch + * @param enable value + * @throws SDRPlayException if there is an error + */ + public void setRfDabNotch(boolean enable) throws SDRPlayException + { + getDeviceParameters().setRfDabNotch(enable); + update(UpdateReason.RSP1A_RF_DAB_NOTCH_CONTROL); + } + + /** + * Indicates if the Bias-T is enabled + */ + public boolean isBiasT() + { + return getTunerParameters().isBiasT(); + } + + /** + * Enables or disables the Bias-T + * @param enable value + * @throws SDRPlayException if there is an error + */ + public void setBiasT(boolean enable) throws SDRPlayException + { + getTunerParameters().setBiasT(enable); + update(UpdateReason.RSP1A_BIAS_T_CONTROL); + } +} diff --git a/jsdrplay/src/main/java/com/github/dsheirer/sdrplay/device/Rsp2Device.java b/jsdrplay/src/main/java/com/github/dsheirer/sdrplay/device/Rsp2Device.java new file mode 100644 index 000000000..eb725046a --- /dev/null +++ b/jsdrplay/src/main/java/com/github/dsheirer/sdrplay/device/Rsp2Device.java @@ -0,0 +1,61 @@ +/* + * ***************************************************************************** + * 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.SDRPlayException; +import com.github.dsheirer.sdrplay.SDRplay; +import com.github.dsheirer.sdrplay.parameter.composite.Rsp2CompositeParameters; + +/** + * RSP2 Device + */ +public class Rsp2Device extends Device +{ + private Rsp2Tuner mTuner1; + + /** + * Constructs an SDRPlay RSP2 device from the foreign memory segment + * + * @param sdrPlay api instance that created this device + * @param deviceStruct parser + */ + Rsp2Device(SDRplay sdrPlay, IDeviceStruct deviceStruct) + { + super(sdrPlay, deviceStruct); + } + + @Override + public Rsp2Tuner getTuner() throws SDRPlayException + { + if(!isSelected()) + { + throw new SDRPlayException("Device must be selected before accessing the tuner"); + } + + if(mTuner1 == null) + { + mTuner1 = new Rsp2Tuner(Rsp2Device.this, getAPI(), getTunerSelect(), + getCompositeParameters().getDeviceParameters(), getCompositeParameters().getTunerAParameters(), + getCompositeParameters().getControlAParameters()); + } + + return mTuner1; + } +} diff --git a/jsdrplay/src/main/java/com/github/dsheirer/sdrplay/device/Rsp2Tuner.java b/jsdrplay/src/main/java/com/github/dsheirer/sdrplay/device/Rsp2Tuner.java new file mode 100644 index 000000000..187191975 --- /dev/null +++ b/jsdrplay/src/main/java/com/github/dsheirer/sdrplay/device/Rsp2Tuner.java @@ -0,0 +1,145 @@ +/* + * ***************************************************************************** + * 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.SDRPlayException; +import com.github.dsheirer.sdrplay.SDRplay; +import com.github.dsheirer.sdrplay.UpdateReason; +import com.github.dsheirer.sdrplay.parameter.control.ControlParameters; +import com.github.dsheirer.sdrplay.parameter.device.Rsp2DeviceParameters; +import com.github.dsheirer.sdrplay.parameter.tuner.Rsp2AmPort; +import com.github.dsheirer.sdrplay.parameter.tuner.Rsp2Antenna; +import com.github.dsheirer.sdrplay.parameter.tuner.Rsp2TunerParameters; + +/** + * RSP2 Tuner + */ +public class Rsp2Tuner extends RspTuner +{ + /** + * Constructs an instance + * @param device parent for this tuner + * @param sdrplay api + * @param tunerSelect to specify which tuner + * @param deviceParameters for this device + * @param tunerParameters for this tuner + * @param controlParameters for this device + */ + public Rsp2Tuner(Device device, SDRplay sdrplay, TunerSelect tunerSelect, Rsp2DeviceParameters deviceParameters, + Rsp2TunerParameters tunerParameters, ControlParameters controlParameters) + { + super(device, sdrplay, tunerSelect, deviceParameters, tunerParameters, controlParameters); + } + + /** + * Indicates if the external reference output is enabled. + */ + public boolean isExternalReferenceOutput() + { + return getDeviceParameters().isExternalReferenceOutput(); + } + + /** + * Enables or disables the external reference output + * @param enable value + * @throws SDRPlayException if there is an error + */ + public void setExternalReferenceOutput(boolean enable) throws SDRPlayException + { + getDeviceParameters().setExternalReferenceOutput(enable); + update(UpdateReason.RSP2_EXT_REF_CONTROL); + } + + /** + * Indicates if the Bias-T is enabled + */ + public boolean isBiasT() + { + return getTunerParameters().isBiasT(); + } + + /** + * Enables or disables the Bias-T + * @param enable value + * @throws SDRPlayException if there is an error + */ + public void setBiasT(boolean enable) throws SDRPlayException + { + getTunerParameters().setBiasT(enable); + update(UpdateReason.RSP2_BIAS_T_CONTROL); + } + + /** + * Indicates if the RF notch is enabled + */ + public boolean isRfNotch() + { + return getTunerParameters().isRfNotch(); + } + + /** + * Enables or disables the RF notch + * @param enable setting + * @throws SDRPlayException if there is an error + */ + public void setRfNotch(boolean enable) throws SDRPlayException + { + getTunerParameters().setRfNotch(enable); + update(UpdateReason.RSP2_RF_NOTCH_CONTROL); + } + + /** + * AM port selection + */ + public Rsp2AmPort getAmPort() + { + return getTunerParameters().getAmPort(); + } + + /** + * Sets the AM port + * @param port to select + * @throws SDRPlayException if there is an error + */ + public void setAmPort(Rsp2AmPort port) throws SDRPlayException + { + getTunerParameters().setAmPort(port); + update(UpdateReason.RSP2_AM_PORT_SELECT); + } + + /** + * Antenna selection + */ + public Rsp2Antenna getAntenna() + { + return getTunerParameters().getAntenna(); + } + + /** + * Sets the antenna + * @param antenna to select + * @throws SDRPlayException if there is an error + */ + public void setAntenna(Rsp2Antenna antenna) throws SDRPlayException + { + getTunerParameters().setAntenna(antenna); + update(UpdateReason.RSP2_ANTENNA_CONTROL); + } +} diff --git a/jsdrplay/src/main/java/com/github/dsheirer/sdrplay/device/RspDuoDevice.java b/jsdrplay/src/main/java/com/github/dsheirer/sdrplay/device/RspDuoDevice.java new file mode 100644 index 000000000..9bb797f76 --- /dev/null +++ b/jsdrplay/src/main/java/com/github/dsheirer/sdrplay/device/RspDuoDevice.java @@ -0,0 +1,212 @@ +/* + * ***************************************************************************** + * 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.SDRPlayException; +import com.github.dsheirer.sdrplay.SDRplay; +import com.github.dsheirer.sdrplay.UpdateReason; +import com.github.dsheirer.sdrplay.api.v3_07.sdrplay_api_DeviceT; +import com.github.dsheirer.sdrplay.parameter.composite.RspDuoCompositeParameters; +import com.github.dsheirer.sdrplay.parameter.tuner.IfMode; +import com.github.dsheirer.sdrplay.parameter.tuner.LoMode; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +/** + * RSPduo Device + */ +public class RspDuoDevice extends Device +{ + private static final Logger mLog = LoggerFactory.getLogger(RspDuoDevice.class); + + private RspDuoTuner mTuner; + + /** + * Constructs an SDRPlay RSPduo device from the foreign memory segment + * + * @param sdrPlay api instance that created this device + * @param deviceStruct parser + */ + RspDuoDevice(SDRplay sdrPlay, IDeviceStruct deviceStruct) + { + super(sdrPlay, deviceStruct); + } + + /** + * Tuner + * @return tuner + * @throws SDRPlayException if there is an error + */ + @Override + public RspDuoTuner getTuner() throws SDRPlayException + { + if(!isSelected()) + { + throw new SDRPlayException("Device must be selected before accessing the tuner"); + } + + if(mTuner == null) + { + if(getTunerSelect().equals(TunerSelect.TUNER_1)) + { + mTuner = new RspDuoTuner1(RspDuoDevice.this, getAPI(), + getCompositeParameters().getDeviceParameters(), getCompositeParameters().getTunerAParameters(), + getCompositeParameters().getControlAParameters()); + } + else + { + mTuner = new RspDuoTuner2(RspDuoDevice.this, getAPI(), + getCompositeParameters().getDeviceParameters(), getCompositeParameters().getTunerBParameters(), + getCompositeParameters().getControlBParameters()); + } + } + + return mTuner; + } + + /** + * Selected tuner(s). + */ + @Override + public TunerSelect getTunerSelect() + { + return TunerSelect.fromValue(sdrplay_api_DeviceT.tuner$get(getDeviceMemorySegment())); + } + + /** + * Sets the selected tuner(s) + */ + public void setTunerSelect(TunerSelect tunerSelect) + { + sdrplay_api_DeviceT.tuner$set(getDeviceMemorySegment(), tunerSelect.getValue()); + } + + /** + * RSPduo mode + */ + public RspDuoMode getRspDuoMode() + { + return getDeviceStruct().getRspDuoMode(); + } + + /** + * Sets RSPduo mode. Note this must be set before selecting the device for use. + * @param mode to set + * @throws SDRPlayException if the device has already been selected + */ + public void setRspDuoMode(RspDuoMode mode) throws SDRPlayException + { + if(isSelected()) + { + throw new SDRPlayException("RSPduo device is already selected. Mode can only be set/changed before the " + + "device is selected for use."); + } + + getDeviceStruct().setRspDuoMode(mode); + } + + /** + * Sample rate when in master/slave mode + */ + public double getRspDuoSampleFrequency() + { + return getDeviceStruct().getRspDuoSampleFrequency(); + } + + /** + * Sets the sample rate when the device is configured for master mode. + * @param frequency + */ + public void setRspDuoSampleFrequency(double frequency) throws SDRPlayException + { + if(!getRspDuoMode().equals(RspDuoMode.MASTER)) + { + throw new SDRPlayException("This method can only be used to set the overall sample rate when the RSPduo " + + "device is configured for master mode."); + } + + getDeviceStruct().setRspDuoSampleFrequency(frequency); + } + + /** + * Sets the decimation factor for the final sample rate. + * @param decimation as an integer multiple of two (e.g. 1, 2, 4, 8) + * @throws SDRPlayException if there is an error while setting decimation + */ + @Override + public void setDecimation(Decimate decimation) throws SDRPlayException + { + if(getTunerSelect() == TunerSelect.TUNER_1) + { + getCompositeParameters().getControlAParameters().getDecimation().setDecimationFactor(decimation.getValue()); + getCompositeParameters().getControlAParameters().getDecimation().setEnabled(decimation.isEnabled()); + update(getTunerSelect(), UpdateReason.CONTROL_DECIMATION); + } + else if(getTunerSelect() == TunerSelect.TUNER_2) + { + getCompositeParameters().getControlBParameters().getDecimation().setDecimationFactor(decimation.getValue()); + getCompositeParameters().getControlBParameters().getDecimation().setEnabled(decimation.isEnabled()); + update(getTunerSelect(), UpdateReason.CONTROL_DECIMATION); + } + else if(getTunerSelect() == TunerSelect.TUNER_BOTH) + { + //Dual-synchronized tuner mode ... let the parent Device class set the value + super.setDecimation(decimation); + } + } + + /** + * Sets the IF mode when tuner 2 is selected in single-tuner mode. + * @param ifMode to set + */ + public void setIfModeTuner2(IfMode ifMode) + { + getCompositeParameters().getTunerBParameters().setIfMode(ifMode); + } + + /** + * Sets the LO mode when tuner 2 is selected in single-tuner mode. + * @param loMode to set + */ + public void setLoModeTuner2(LoMode loMode) + { + getCompositeParameters().getTunerBParameters().setLoMode(loMode); + } + + + @Override + public String toString() + { + StringBuilder sb = new StringBuilder(); + sb.append("SDRPplay Device").append("\n"); + sb.append("\tType: " + getDeviceType()).append("\n"); + sb.append("\tSerial Number: " + getSerialNumber()).append("\n"); + sb.append("\tTuner: " + getTunerSelect()).append("\n"); + sb.append("\tRSP Duo: " + getRspDuoMode()).append("\n"); + sb.append("\tRSP Duo Sample Rate: " + getRspDuoSampleFrequency()).append("\n"); + sb.append("\tSelected: " + isSelected()); + if(hasCompositeParameters()) + { + sb.append("\t").append(getCompositeParameters()); + } + + return sb.toString(); + } +} diff --git a/jsdrplay/src/main/java/com/github/dsheirer/sdrplay/device/RspDuoMode.java b/jsdrplay/src/main/java/com/github/dsheirer/sdrplay/device/RspDuoMode.java new file mode 100644 index 000000000..a95de2ff1 --- /dev/null +++ b/jsdrplay/src/main/java/com/github/dsheirer/sdrplay/device/RspDuoMode.java @@ -0,0 +1,75 @@ +/* + * ***************************************************************************** + * 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.api.v3_07.sdrplay_api_h; + +/** + * RSP-Duo Mode + */ +public enum RspDuoMode +{ + SINGLE_TUNER(sdrplay_api_h.sdrplay_api_RspDuoMode_Single_Tuner(), "SINGLE TUNER"), + DUAL_TUNER(sdrplay_api_h.sdrplay_api_RspDuoMode_Dual_Tuner(), "DUAL TUNER"), + MASTER(sdrplay_api_h.sdrplay_api_RspDuoMode_Master(), "MASTER"), + SLAVE(sdrplay_api_h.sdrplay_api_RspDuoMode_Slave(), "SLAVE"), + UNKNOWN(sdrplay_api_h.sdrplay_api_RspDuoMode_Unknown(), "UNKNOWN"); + + private int mValue; + private String mDescription; + + RspDuoMode(int value, String description) + { + mValue = value; + mDescription = description; + } + + /** + * Numeric value + */ + public int getValue() + { + return mValue; + } + + /** + * Lookup the entry from a return code + * @param value to lookup + * @return entry or UKNOWN if the code is not recognized + */ + public static RspDuoMode fromValue(int value) + { + for(RspDuoMode status: RspDuoMode.values()) + { + if(status.getValue() == value) + { + return status; + } + } + + return UNKNOWN; + } + + @Override + public String toString() + { + return mDescription; + } +} diff --git a/jsdrplay/src/main/java/com/github/dsheirer/sdrplay/device/RspDuoTuner.java b/jsdrplay/src/main/java/com/github/dsheirer/sdrplay/device/RspDuoTuner.java new file mode 100644 index 000000000..5b9594f5f --- /dev/null +++ b/jsdrplay/src/main/java/com/github/dsheirer/sdrplay/device/RspDuoTuner.java @@ -0,0 +1,105 @@ +/* + * ***************************************************************************** + * 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.SDRPlayException; +import com.github.dsheirer.sdrplay.SDRplay; +import com.github.dsheirer.sdrplay.UpdateReason; +import com.github.dsheirer.sdrplay.parameter.control.ControlParameters; +import com.github.dsheirer.sdrplay.parameter.device.RspDuoDeviceParameters; +import com.github.dsheirer.sdrplay.parameter.tuner.RspDuoTunerParameters; + +/** + * RSPduo Tuner + */ +public abstract class RspDuoTuner extends RspTuner +{ + /** + * Constructs an instance + * @param device parent for this tuner + * @param sdrplay api + * @param tunerSelect to specify which tuner + * @param deviceParameters for this device + * @param tunerParameters for this tuner + * @param controlParameters for this device + */ + public RspDuoTuner(Device device, SDRplay sdrplay, TunerSelect tunerSelect, RspDuoDeviceParameters deviceParameters, + RspDuoTunerParameters tunerParameters, ControlParameters controlParameters) + { + super(device, sdrplay, tunerSelect, deviceParameters, tunerParameters, controlParameters); + } + + /** + * Indicates if the RF notch is enabled + */ + public boolean isRFNotch() + { + return getTunerParameters().isRfNotch(); + } + + /** + * Enables or disables the RF notch + * @param enable setting + * @throws SDRPlayException if there is an error + */ + public void setRfNotch(boolean enable) throws SDRPlayException + { + getTunerParameters().setRfNotch(enable); + update(UpdateReason.RSP_DUO_RF_NOTCH_CONTROL); + } + + /** + * Indicates if the RF DAB notch is enabled + */ + public boolean isRfDabNotch() + { + return getTunerParameters().isRfDabNotch(); + } + + /** + * Enables or disables the RF DAB notch + * @param enable value + * @throws SDRPlayException if there is an error + */ + public void setRfDabNotch(boolean enable) throws SDRPlayException + { + getTunerParameters().setRfDabNotch(enable); + update(UpdateReason.RSP_DUO_RF_DAB_NOTCH_CONTROL); + } + + /** + * Indicates if the external reference output is enabled. + */ + public boolean isExternalReferenceOutput() + { + return getDeviceParameters().isExternalReferenceOutput(); + } + + /** + * Enables or disables the external reference output + * @param enable value + * @throws SDRPlayException if there is an error + */ + public void setExternalReferenceOutput(boolean enable) throws SDRPlayException + { + getDeviceParameters().setExternalReferenceOutput(enable); + update(UpdateReason.RSP_DUO_EXT_REF_CONTROL); + } +} diff --git a/jsdrplay/src/main/java/com/github/dsheirer/sdrplay/device/RspDuoTuner1.java b/jsdrplay/src/main/java/com/github/dsheirer/sdrplay/device/RspDuoTuner1.java new file mode 100644 index 000000000..ec7697c23 --- /dev/null +++ b/jsdrplay/src/main/java/com/github/dsheirer/sdrplay/device/RspDuoTuner1.java @@ -0,0 +1,87 @@ +/* + * ***************************************************************************** + * 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.SDRPlayException; +import com.github.dsheirer.sdrplay.SDRplay; +import com.github.dsheirer.sdrplay.UpdateReason; +import com.github.dsheirer.sdrplay.parameter.control.ControlParameters; +import com.github.dsheirer.sdrplay.parameter.device.RspDuoDeviceParameters; +import com.github.dsheirer.sdrplay.parameter.tuner.RspDuoAmPort; +import com.github.dsheirer.sdrplay.parameter.tuner.RspDuoTunerParameters; + +/** + * RSPduo Tuner 1 + */ +public class RspDuoTuner1 extends RspDuoTuner +{ + /** + * Constructs an instance + * + * @param device parent for this tuner + * @param sdrplay api + * @param deviceParameters for this device + * @param tunerParameters for this tuner + * @param controlParameters for this device + */ + public RspDuoTuner1(Device device, SDRplay sdrplay, RspDuoDeviceParameters deviceParameters, + RspDuoTunerParameters tunerParameters, ControlParameters controlParameters) + { + super(device, sdrplay, TunerSelect.TUNER_1, deviceParameters, tunerParameters, controlParameters); + } + + /** + * Indicates which AM port is selected + */ + public RspDuoAmPort getAmPort() + { + return getTunerParameters().getTuner1AmPort(); + } + + /** + * Selects the AM port to use + * @param port to use + * @throws SDRPlayException if there is an error + */ + public void setAmPort(RspDuoAmPort port) throws SDRPlayException + { + getTunerParameters().setTuner1AmPort(port); + update(UpdateReason.RSP_DUO_AM_PORT_SELECT); + } + + /** + * Indicates if the AM notch is enabled + */ + public boolean isAmNotch() + { + return getTunerParameters().isTuner1AmNotch(); + } + + /** + * Enables or disables the AM notch + * @param enable for the notch + * @throws SDRPlayException if there is an error + */ + public void setAmNotch(boolean enable) throws SDRPlayException + { + getTunerParameters().setTuner1AmNotch(enable); + update(UpdateReason.RSP_DUO_TUNER_1_AM_NOTCH_CONTROL); + } +} diff --git a/jsdrplay/src/main/java/com/github/dsheirer/sdrplay/device/RspDuoTuner2.java b/jsdrplay/src/main/java/com/github/dsheirer/sdrplay/device/RspDuoTuner2.java new file mode 100644 index 000000000..eac047bcb --- /dev/null +++ b/jsdrplay/src/main/java/com/github/dsheirer/sdrplay/device/RspDuoTuner2.java @@ -0,0 +1,67 @@ +/* + * ***************************************************************************** + * 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.SDRPlayException; +import com.github.dsheirer.sdrplay.SDRplay; +import com.github.dsheirer.sdrplay.UpdateReason; +import com.github.dsheirer.sdrplay.parameter.control.ControlParameters; +import com.github.dsheirer.sdrplay.parameter.device.RspDuoDeviceParameters; +import com.github.dsheirer.sdrplay.parameter.tuner.RspDuoTunerParameters; + +/** + * RSPduo Tuner 2 + */ +public class RspDuoTuner2 extends RspDuoTuner +{ + /** + * Constructs an instance + * + * @param device parent for this tuner + * @param sdrplay api + * @param deviceParameters for this device + * @param tunerParameters for this tuner + * @param controlParameters for this device + */ + public RspDuoTuner2(Device device, SDRplay sdrplay, RspDuoDeviceParameters deviceParameters, + RspDuoTunerParameters tunerParameters, ControlParameters controlParameters) + { + super(device, sdrplay, TunerSelect.TUNER_2, deviceParameters, tunerParameters, controlParameters); + } + + /** + * Indicates if the Bias-T is enabled + */ + public boolean isBiasT() + { + return getTunerParameters().isBiasT(); + } + + /** + * Enables or disables the Bias-T + * @param enable value + * @throws SDRPlayException if there is an error + */ + public void setBiasT(boolean enable) throws SDRPlayException + { + getTunerParameters().setBiasT(enable); + update(UpdateReason.RSP_DUO_BIAS_T_CONTROL); + } +} diff --git a/jsdrplay/src/main/java/com/github/dsheirer/sdrplay/device/RspDxDevice.java b/jsdrplay/src/main/java/com/github/dsheirer/sdrplay/device/RspDxDevice.java new file mode 100644 index 000000000..4802a82bf --- /dev/null +++ b/jsdrplay/src/main/java/com/github/dsheirer/sdrplay/device/RspDxDevice.java @@ -0,0 +1,62 @@ +/* + * ***************************************************************************** + * 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.SDRPlayException; +import com.github.dsheirer.sdrplay.SDRplay; +import com.github.dsheirer.sdrplay.parameter.composite.RspDxCompositeParameters; + +/** + * RSPdx Device + */ +public class RspDxDevice extends Device +{ + private RspDxTuner mTuner1; + + /** + * Constructs an SDRPlay RSPdx device from the foreign memory segment + * + * @param sdrPlay api instance that created this device + * @param deviceStruct parser + */ + RspDxDevice(SDRplay sdrPlay, IDeviceStruct deviceStruct) + { + super(sdrPlay, deviceStruct); + } + + + @Override + public RspDxTuner getTuner() throws SDRPlayException + { + if(!isSelected()) + { + throw new SDRPlayException("Device must be selected before accessing the tuner"); + } + + if(mTuner1 == null) + { + mTuner1 = new RspDxTuner(RspDxDevice.this, getAPI(), getTunerSelect(), + getCompositeParameters().getDeviceParameters(), getCompositeParameters().getTunerAParameters(), + getCompositeParameters().getControlAParameters()); + } + + return mTuner1; + } +} diff --git a/jsdrplay/src/main/java/com/github/dsheirer/sdrplay/device/RspDxTuner.java b/jsdrplay/src/main/java/com/github/dsheirer/sdrplay/device/RspDxTuner.java new file mode 100644 index 000000000..547d93443 --- /dev/null +++ b/jsdrplay/src/main/java/com/github/dsheirer/sdrplay/device/RspDxTuner.java @@ -0,0 +1,164 @@ +/* + * ***************************************************************************** + * 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.SDRPlayException; +import com.github.dsheirer.sdrplay.SDRplay; +import com.github.dsheirer.sdrplay.UpdateReason; +import com.github.dsheirer.sdrplay.parameter.control.ControlParameters; +import com.github.dsheirer.sdrplay.parameter.device.RspDxDeviceParameters; +import com.github.dsheirer.sdrplay.parameter.tuner.HdrModeBandwidth; +import com.github.dsheirer.sdrplay.parameter.tuner.RspDxAntenna; +import com.github.dsheirer.sdrplay.parameter.tuner.RspDxTunerParameters; + +/** + * RSPdx Tuner + */ +public class RspDxTuner extends RspTuner +{ + /** + * Constructs an instance + * @param device parent for this tuner + * @param sdrplay api + * @param tunerSelect to specify which tuner + * @param deviceParameters for this device + * @param tunerParameters for this tuner + * @param controlParameters for this device + */ + public RspDxTuner(Device device, SDRplay sdrplay, TunerSelect tunerSelect, RspDxDeviceParameters deviceParameters, + RspDxTunerParameters tunerParameters, ControlParameters controlParameters) + { + super(device, sdrplay, tunerSelect, deviceParameters, tunerParameters, controlParameters); + } + + /** + * Indicates if HDR mode is enabled + */ + public boolean isHdrMode() + { + return getDeviceParameters().isHdr(); + } + + /** + * Enables or disables HDR mode + * @param enable mode + * @throws SDRPlayException if there is an error + */ + public void setHdrMode(boolean enable) throws SDRPlayException + { + getDeviceParameters().setHdr(enable); + update(UpdateReason.EXTENSION_RSP_DX_HDR_ENABLE); + } + + /** + * HDR mode bandwidth + */ + public HdrModeBandwidth getHdrModeBandwidth() + { + return getTunerParameters().getHdrModeBandwidth(); + } + + /** + * Sets HDR mode bandwidth + * @param bandwidth to select + * @throws SDRPlayException if there is an error + */ + public void setHdrModeBandwidth(HdrModeBandwidth bandwidth) throws SDRPlayException + { + getTunerParameters().setHdrModeBandwidth(bandwidth); + update(UpdateReason.EXTENSION_RSP_DX_HDR_BANDWIDTH); + } + + /** + * Indicates if the RF notch is enabled + */ + public boolean isRfNotch() + { + return getDeviceParameters().isRfNotch(); + } + + /** + * Enables or disables the RF notch + * @param enable setting + * @throws SDRPlayException if there is an error + */ + public void setRfNotch(boolean enable) throws SDRPlayException + { + getDeviceParameters().setRfNotch(enable); + update(UpdateReason.EXTENSION_RSP_DX_RF_NOTCH_CONTROL); + } + + /** + * Indicates if the RF DAB notch is enabled + */ + public boolean isRfDabNotch() + { + return getDeviceParameters().isRfDabNotch(); + } + + /** + * Enables or disables the RF DAB notch + * @param enable value + * @throws SDRPlayException if there is an error + */ + public void setRfDabNotch(boolean enable) throws SDRPlayException + { + getDeviceParameters().setRfDabNotch(enable); + update(UpdateReason.EXTENSION_RSP_DX_RF_DAB_NOTCH_CONTROL); + } + + /** + * Indicates if the Bias-T is enabled + */ + public boolean isBiasT() + { + return getDeviceParameters().isBiasT(); + } + + /** + * Enables or disables the Bias-T + * @param enable value + * @throws SDRPlayException if there is an error + */ + public void setBiasT(boolean enable) throws SDRPlayException + { + getDeviceParameters().setBiasT(enable); + update(UpdateReason.EXTENSION_RSP_DX_BIAS_T_CONTROL); + } + + /** + * Antenna selection + */ + public RspDxAntenna getAntenna() + { + return getDeviceParameters().getRspDxAntenna(); + } + + /** + * Sets the antenna selection + * @param antenna to select + * @throws SDRPlayException if there is an error + */ + public void setAntenna(RspDxAntenna antenna) throws SDRPlayException + { + getDeviceParameters().setRspDxAntenna(antenna); + update(UpdateReason.EXTENSION_RSP_DX_ANTENNA_CONTROL); + } +} diff --git a/jsdrplay/src/main/java/com/github/dsheirer/sdrplay/device/RspTuner.java b/jsdrplay/src/main/java/com/github/dsheirer/sdrplay/device/RspTuner.java new file mode 100644 index 000000000..5ff90259a --- /dev/null +++ b/jsdrplay/src/main/java/com/github/dsheirer/sdrplay/device/RspTuner.java @@ -0,0 +1,419 @@ +/* + * ***************************************************************************** + * 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.SDRPlayException; +import com.github.dsheirer.sdrplay.SDRplay; +import com.github.dsheirer.sdrplay.UpdateReason; +import com.github.dsheirer.sdrplay.async.AsyncUpdateFuture; +import com.github.dsheirer.sdrplay.parameter.control.AgcMode; +import com.github.dsheirer.sdrplay.parameter.control.ControlParameters; +import com.github.dsheirer.sdrplay.parameter.device.DeviceParameters; +import com.github.dsheirer.sdrplay.parameter.tuner.Bandwidth; +import com.github.dsheirer.sdrplay.parameter.tuner.Gain; +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 com.github.dsheirer.sdrplay.parameter.tuner.TunerParameters; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +/** + * Abstract RSP device tuner + * @param RSP device implementation + */ +public abstract class RspTuner +{ + private static final Logger mLog = LoggerFactory.getLogger(RspTuner.class); + private final SDRplay mSDRplay; + private final Device mDevice; + private final TunerSelect mTunerSelect; + private final D mDeviceParameters; + private final T mTunerParameters; + private final ControlParameters mControlParameters; + + private GainReduction mGainReduction; + + RspTuner(Device device, SDRplay sdrplay, TunerSelect tunerSelect, D deviceParameters, T tunerParameters, + ControlParameters controlParameters) + { + mDevice = device; + mSDRplay = sdrplay; + mTunerSelect = tunerSelect; + mDeviceParameters = deviceParameters; + mTunerParameters = tunerParameters; + mControlParameters = controlParameters; + } + + /** + * SDRplay API + */ + private SDRplay getSDRplay() + { + return mSDRplay; + } + + /** + * Parent device for this tuner + */ + private Device getDevice() + { + return mDevice; + } + + /** + * Selected tuner + */ + public TunerSelect getTunerSelect() + { + return mTunerSelect; + } + + /** + * Device parameters + */ + protected D getDeviceParameters() + { + return mDeviceParameters; + } + + /** + * Tuner parameters for the selected tuner + */ + public T getTunerParameters() + { + return mTunerParameters; + } + + /** + * Control parameters for the selected tuner + */ + protected ControlParameters getControlParameters() + { + return mControlParameters; + } + + /** + * Convenience method for notifying the API that parameters for the device have been updated, when the device is + * initialized. + * + * @param updateReasons indicating what has been updated + * @throws SDRPlayException if there is an error + */ + protected void update(UpdateReason... updateReasons) throws SDRPlayException + { + getDevice().update(getTunerSelect(), updateReasons); + } + + /** + * Convenience method for notifying the device that a parameter for this tuner have been updated. + * + * Note: the asynchronous device event responses are limited to Frequency, Gain and Sample Rate. For example, + * if you update the RSPduo DAB Notch parameter, it will generate a Gain change notification, so we submit + * an async update for the DAB Notch, but anticipate a Gain update response. + * + * @param updateReason indicating what has been updated + * @param expectedResponse that will be received indicating that the async operation is completed. + */ + protected AsyncUpdateFuture updateAsync(UpdateReason updateReason, UpdateReason expectedResponse) + { + return getDevice().updateAsync(getTunerSelect(), updateReason, expectedResponse); + } + + /** + * Current tuner bandwidth + */ + public Bandwidth getBandwidth() + { + return getTunerParameters().getBandwidth(); + } + + /** + * Sets tuner bandwidth + * @param bandwidth to apply + * @throws SDRPlayException if there is an error + */ + public void setBandwidth(Bandwidth bandwidth) throws SDRPlayException + { + getTunerParameters().setBandwidth(bandwidth); + update(UpdateReason.TUNER_BANDWIDTH_TYPE); + } + + /** + * Center frequency for the tuner + */ + public long getFrequency() + { + return (long) getTunerParameters().getRfFrequency().getFrequency(); + } + + /** + * Requests to set the center frequency for the tuner asynchronously. + * + * Note: the API supports the notion of synchronous frequency updates, but in testing I found that you cannot + * submit a second frequency change update request until a previously submitted frequency change update + * operation had completed, otherwise it would generate a fail status. Therefore, this is method is strictly + * an async operation. + * + * @param frequency in Hertz + * @return future that can be monitored for completion of the set frequency operation. + */ + public AsyncUpdateFuture setFrequency(long frequency) + { + try + { + getTunerParameters().getRfFrequency().setFrequency(frequency, false); + updateGainReduction(frequency); + return updateAsync(UpdateReason.TUNER_FREQUENCY_RF, UpdateReason.TUNER_FREQUENCY_RF); + } + catch(SDRPlayException se) + { + AsyncUpdateFuture future = new AsyncUpdateFuture(getTunerSelect(), UpdateReason.TUNER_FREQUENCY_RF, + UpdateReason.TUNER_FREQUENCY_RF); + future.setError(se); + return future; + } + } + + /** + * Gain reduction in use for this device with the current RF frequency + */ + public GainReduction getGainReduction() + { + if(mGainReduction == null) + { + updateGainReduction(getFrequency()); + } + + return mGainReduction; + } + + /** + * Updates the gain reduction, if necessary, for the specified RF frequency + * + * @param frequency value + */ + private void updateGainReduction(long frequency) + { + if(mGainReduction == null || !mGainReduction.isValidFor(frequency)) + { + mGainReduction = GainReduction.lookup(getDevice().getDeviceType(), frequency); + } + } + + /** + * Selects a gain value index from the current gain reduction values + * + * @param index of the gain reduction values to use + */ + public void setGain(int index) throws SDRPlayException + { + getTunerParameters().getGain().setGain(getGainReduction(), index); + update(UpdateReason.TUNER_GAIN_REDUCTION); + } + + /** + * Sets the automatic gain contral (AGC) mode + * + * @param mode to set + * @throws SDRPlayException if there is an error + */ + public void setAGC(AgcMode mode) throws SDRPlayException + { + getControlParameters().getAgc().setAgcMode(mode); + update(UpdateReason.CONTROL_AGC); + } + + /** + * AGC Mode + */ + public AgcMode getAGC() + { + return getControlParameters().getAgc().getAgcMode(); + } + + /** + * Gain for the tuner. + */ + public Gain getGain() + { + return getTunerParameters().getGain(); + } + + /** + * Current gain index value. + * @return current gain index value or -1 if the current gain setting does not match the possible gain reduction options. + */ + public int getGainIndex() + { + int gainDb = getGain().getGainReductionDb(); + return getGainReduction().getGainIndex(gainDb); + } + + /** + * Enables or disables DC correction + * + * @param enable true or false + * @throws SDRPlayException if there is an error + */ + public void setDCCorrection(boolean enable) throws SDRPlayException + { + getControlParameters().getDcOffset().setDC(enable); + update(UpdateReason.CONTROL_DC_OFFSET_IQ_IMBALANCE); + } + + /** + * Enables or disables IQ imbalance correction + * + * @param enable true or false + * @throws SDRPlayException if there is an error + */ + public void setIQCorrection(boolean enable) throws SDRPlayException + { + getControlParameters().getDcOffset().setIQ(enable); + update(UpdateReason.CONTROL_DC_OFFSET_IQ_IMBALANCE); + } + + /** + * Sets or updates the parts per million (ppm) frequency correction + * + * @param ppm value + * @throws SDRPlayException + */ + public AsyncUpdateFuture setPPM(double ppm) throws SDRPlayException + { + getDeviceParameters().setPPM(ppm); + + //Note: async ppm updates effect both frequency and sample rate, so we expect the completion of the + //operation will be first FREQUENCY and then SAMPLE RATE, so we watch for sample rate. + return updateAsync(UpdateReason.DEVICE_PPM, UpdateReason.DEVICE_SAMPLE_RATE); + } + + /** + * Parts per million (PPM) frequency correction value + * + * @return ppm value + */ + public double getPPM() + { + return getDeviceParameters().getPPM(); + } + + /** + * Perform synchronous update + * + * @param sampleNumber value + * @param period value + * @throws SDRPlayException if there is an error + */ + public void setSynchronousUpdate(int sampleNumber, int period) throws SDRPlayException + { + getDeviceParameters().getSynchronousUpdate().set(sampleNumber, period); + update(UpdateReason.DEVICE_SYNC_UPDATE); + } + + /** + * Resets device functions to default + * + * @param frequency to reset + * @param sampleRate to reset + * @param gain to reset + * @throws SDRPlayException if there is an error + */ + public void reset(boolean frequency, boolean sampleRate, boolean gain) throws SDRPlayException + { + getDeviceParameters().getResetFlags().resetGain(gain); + getDeviceParameters().getResetFlags().resetFrequency(frequency); + getDeviceParameters().getResetFlags().resetSampleRate(sampleRate); + update(UpdateReason.DEVICE_RESET_FLAGS); + } + + /** + * Resets the frequency. + * + * @param frequency true to reset + * @throws SDRPlayException if there is an error + */ + public void resetFrequency(boolean frequency) throws SDRPlayException + { + reset(frequency, false, false); + } + + /** + * Resets the sample rate. + * + * @param sampleRate true to reset + * @throws SDRPlayException if there is an error + */ + public void resetSampleRate(boolean sampleRate) throws SDRPlayException + { + reset(false, sampleRate, false); + } + + /** + * Resets the gain (reduction). + * + * @param gain true to reset + * @throws SDRPlayException if there is an error + */ + public void resetGain(boolean gain) throws SDRPlayException + { + reset(false, false, gain); + } + + /** + * IF mode (type) + */ + public IfMode getIfMode() + { + return getTunerParameters().getIfMode(); + } + + /** + * Sets the IF mode (type) + * @param mode to set + * @throws SDRPlayException if there is an error + */ + public void setIfMode(IfMode mode) throws SDRPlayException + { + getTunerParameters().setIfMode(mode); + update(UpdateReason.TUNER_IF_TYPE); + } + + /** + * Local Oscillator (LO) mode + * @return mode + */ + public LoMode getLoMode() + { + return getTunerParameters().getLoMode(); + } + + /** + * Sets the Local Oscillator (LO) mode + * @param mode to set + * @throws SDRPlayException if there is an error + */ + public void setLoMode(LoMode mode) throws SDRPlayException + { + getTunerParameters().setLoMode(mode); + update(UpdateReason.TUNER_LO_MODE); + } +} diff --git a/jsdrplay/src/main/java/com/github/dsheirer/sdrplay/device/TunerSelect.java b/jsdrplay/src/main/java/com/github/dsheirer/sdrplay/device/TunerSelect.java new file mode 100644 index 000000000..78078de3c --- /dev/null +++ b/jsdrplay/src/main/java/com/github/dsheirer/sdrplay/device/TunerSelect.java @@ -0,0 +1,74 @@ +/* + * ***************************************************************************** + * 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.api.v3_07.sdrplay_api_h; + +/** + * Tuner Select + */ +public enum TunerSelect +{ + TUNER_1(sdrplay_api_h.sdrplay_api_Tuner_A(), "TUNER 1"), + TUNER_2(sdrplay_api_h.sdrplay_api_Tuner_B(), "TUNER 2"), + TUNER_BOTH(sdrplay_api_h.sdrplay_api_Tuner_Both(), "TUNER 1 & 2"), + NEITHER(sdrplay_api_h.sdrplay_api_Tuner_Neither(), "NEITHER"); + + private int mValue; + private String mDescription; + + TunerSelect(int value, String description) + { + mValue = value; + mDescription = description; + } + + /** + * Numeric value + */ + public int getValue() + { + return mValue; + } + + /** + * Lookup the entry from a return code + * @param value to lookup + * @return entry or NEITHER if the code is not recognized + */ + public static TunerSelect fromValue(int value) + { + for(TunerSelect status: TunerSelect.values()) + { + if(status.getValue() == value) + { + return status; + } + } + + return NEITHER; + } + + @Override + public String toString() + { + return mDescription; + } +} diff --git a/jsdrplay/src/main/java/com/github/dsheirer/sdrplay/device/UnknownDevice.java b/jsdrplay/src/main/java/com/github/dsheirer/sdrplay/device/UnknownDevice.java new file mode 100644 index 000000000..622cabc3c --- /dev/null +++ b/jsdrplay/src/main/java/com/github/dsheirer/sdrplay/device/UnknownDevice.java @@ -0,0 +1,46 @@ +/* + * ***************************************************************************** + * 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.SDRPlayException; +import com.github.dsheirer.sdrplay.SDRplay; + +/** + * Unknown or Unrecognized SDRplay Device + */ +public class UnknownDevice extends Device +{ + /** + * Constructs an Unknown SDRPlay device from the foreign memory segment + * + * @param sdrPlay api instance that created this device + * @param deviceStruct parser + */ + UnknownDevice(SDRplay sdrPlay, IDeviceStruct deviceStruct) + { + super(sdrPlay, deviceStruct); + } + + @Override + public RspTuner getTuner() throws SDRPlayException + { + throw new SDRPlayException("Unrecognized device type. Cannot construct tuner"); + } +} diff --git a/jsdrplay/src/main/java/com/github/dsheirer/sdrplay/error/DebugLevel.java b/jsdrplay/src/main/java/com/github/dsheirer/sdrplay/error/DebugLevel.java new file mode 100644 index 000000000..44226683a --- /dev/null +++ b/jsdrplay/src/main/java/com/github/dsheirer/sdrplay/error/DebugLevel.java @@ -0,0 +1,76 @@ +/* + * ***************************************************************************** + * 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.error; + +import com.github.dsheirer.sdrplay.api.v3_07.sdrplay_api_h; + +/** + * Debug Level + */ +public enum DebugLevel +{ + DISABLE(sdrplay_api_h.sdrplay_api_DbgLvl_Disable(), "DISABLE"), + VERBOSE(sdrplay_api_h.sdrplay_api_DbgLvl_Verbose(), "VERBOSE"), + WARNING(sdrplay_api_h.sdrplay_api_DbgLvl_Warning(), "WARNING"), + ERROR(sdrplay_api_h.sdrplay_api_DbgLvl_Error(), "ERROR"), + MESSAGE(sdrplay_api_h.sdrplay_api_DbgLvl_Message(), "MESSAGE"), + UNKNOWN(-1, "UNKNOWN"); + + private int mValue; + private String mDescription; + + DebugLevel(int value, String description) + { + mValue = value; + mDescription = description; + } + + /** + * Numeric value + */ + public int getValue() + { + return mValue; + } + + /** + * Lookup the entry from a return code + * @param value to lookup + * @return entry or UNKNOWN if the code is not recognized + */ + public static DebugLevel fromValue(int value) + { + for(DebugLevel status: DebugLevel.values()) + { + if(status.getValue() == value) + { + return status; + } + } + + return UNKNOWN; + } + + @Override + public String toString() + { + return mDescription; + } +} diff --git a/jsdrplay/src/main/java/com/github/dsheirer/sdrplay/error/ErrorInformation.java b/jsdrplay/src/main/java/com/github/dsheirer/sdrplay/error/ErrorInformation.java new file mode 100644 index 000000000..a409ac2d0 --- /dev/null +++ b/jsdrplay/src/main/java/com/github/dsheirer/sdrplay/error/ErrorInformation.java @@ -0,0 +1,78 @@ +/* + * ***************************************************************************** + * 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.error; + +import com.github.dsheirer.sdrplay.api.v3_07.sdrplay_api_ErrorInfoT; + +import java.lang.foreign.MemorySegment; + +/** + * Error Information structure (sdrplay_api_ErrorInfoT) + */ +public class ErrorInformation +{ + private String mFile; + private String mFunction; + private int mLine; + private String mMessage; + + /** + * Constructs an instance from the foreign memory segment + */ + public ErrorInformation(MemorySegment memorySegment) + { + mFile = sdrplay_api_ErrorInfoT.file$slice(memorySegment).getUtf8String(0); + mFunction = sdrplay_api_ErrorInfoT.function$slice(memorySegment).getUtf8String(0); + mLine = sdrplay_api_ErrorInfoT.line$get(memorySegment); + mMessage = sdrplay_api_ErrorInfoT.message$slice(memorySegment).getUtf8String(0); + } + + public String getFile() + { + return mFile; + } + + public String getFunction() + { + return mFunction; + } + + public int getLine() + { + return mLine; + } + + public String getMessage() + { + return mMessage; + } + + @Override + public String toString() + { + StringBuilder sb = new StringBuilder(); + sb.append("Error Information:").append("\n"); + sb.append("\t File: ").append(getFile()).append("\n"); + sb.append("\tFunction: ").append(getFunction()).append("\n"); + sb.append("\t Line: ").append(getLine()).append("\n"); + sb.append("\t Message: ").append(getMessage()).append("\n"); + return sb.toString(); + } +} diff --git a/jsdrplay/src/main/java/com/github/dsheirer/sdrplay/parameter/composite/CompositeParameters.java b/jsdrplay/src/main/java/com/github/dsheirer/sdrplay/parameter/composite/CompositeParameters.java new file mode 100644 index 000000000..3e28a0463 --- /dev/null +++ b/jsdrplay/src/main/java/com/github/dsheirer/sdrplay/parameter/composite/CompositeParameters.java @@ -0,0 +1,109 @@ +/* + * ***************************************************************************** + * 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.parameter.composite; + +import com.github.dsheirer.sdrplay.api.v3_07.sdrplay_api_DevParamsT; +import com.github.dsheirer.sdrplay.api.v3_07.sdrplay_api_DeviceParamsT; +import com.github.dsheirer.sdrplay.api.v3_07.sdrplay_api_RxChannelParamsT; +import com.github.dsheirer.sdrplay.device.DeviceType; +import com.github.dsheirer.sdrplay.parameter.control.ControlParameters; +import com.github.dsheirer.sdrplay.parameter.device.DeviceParameters; +import com.github.dsheirer.sdrplay.parameter.device.DeviceParametersFactory; +import com.github.dsheirer.sdrplay.parameter.tuner.TunerParameters; +import com.github.dsheirer.sdrplay.parameter.tuner.TunerParametersFactory; + +import java.lang.foreign.MemoryAddress; +import java.lang.foreign.MemorySegment; +import java.lang.foreign.MemorySession; + +/** + * Composite Device Parameters structure (sdrplay_api_DeviceParamsT) providing access to the device parameters and + * the tuner 1 parameters. Tuner 2 parameters are only accessible via the RSPduo sub-class implementation. + * + * Note: sub-class implementations will constrain access to the appropriate sub-structures of the DeviceParamsT + * structure for each specific device. + */ +public class CompositeParameters +{ + private D mDeviceParameters; + private T mTunerAParameters; + private ControlParameters mControlAParameters; + + /** + * Constructs an instance from the foreign memory segment + * + * @param deviceType to create + * @param memorySegment for the composite structure in foreign memory + * @param memorySession for allocating additional memory segments for the sub-structures. + */ + public CompositeParameters(DeviceType deviceType, MemorySegment memorySegment, MemorySession memorySession) + { + MemoryAddress parametersMemoryAddress = sdrplay_api_DeviceParamsT.devParams$get(memorySegment); + MemorySegment parametersMemorySegment = sdrplay_api_DevParamsT.ofAddress(parametersMemoryAddress, memorySession); + mDeviceParameters = (D) DeviceParametersFactory.create(deviceType, parametersMemorySegment); + + MemoryAddress memoryAddressRxA = sdrplay_api_DeviceParamsT.rxChannelA$get(memorySegment); + MemorySegment memorySegmentRxA = sdrplay_api_RxChannelParamsT.ofAddress(memoryAddressRxA, memorySession); + mTunerAParameters = (T) TunerParametersFactory.create(deviceType, memorySegmentRxA); + + MemorySegment tunerAControlParametersMemorySegment = sdrplay_api_RxChannelParamsT.ctrlParams$slice(memorySegmentRxA); + mControlAParameters = new ControlParameters(tunerAControlParametersMemorySegment); + } + + /** + * Device parameters + */ + public D getDeviceParameters() + { + return mDeviceParameters; + } + + /** + * Tuner A Parameters. + * + * Note: this is normally mapped to tuner 1. In the RSPduo, this is mapped to Tuner 1 or Tuner 2, according to how + * the user has setup the TunerSelect. + */ + public T getTunerAParameters() + { + return mTunerAParameters; + } + + /** + * Tuner A Control Parameters + * + * Note: this is normally mapped to tuner 1. In the RSPduo, this is mapped to Tuner 1 or Tuner 2, according to how + * the user has setup the TunerSelect. + */ + public ControlParameters getControlAParameters() + { + return mControlAParameters; + } + + @Override + public String toString() + { + StringBuilder sb = new StringBuilder(); + sb.append("Composite Parameters\n"); + sb.append("\tDevice Parameters:\n").append(getDeviceParameters()).append("\n"); + sb.append("\tTuner A Parameters:\n").append(getTunerAParameters()).append("\n"); + return sb.toString(); + } +} diff --git a/jsdrplay/src/main/java/com/github/dsheirer/sdrplay/parameter/composite/CompositeParametersFactory.java b/jsdrplay/src/main/java/com/github/dsheirer/sdrplay/parameter/composite/CompositeParametersFactory.java new file mode 100644 index 000000000..c73b8005d --- /dev/null +++ b/jsdrplay/src/main/java/com/github/dsheirer/sdrplay/parameter/composite/CompositeParametersFactory.java @@ -0,0 +1,62 @@ +/* + * ***************************************************************************** + * 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.parameter.composite; + +import com.github.dsheirer.sdrplay.device.DeviceType; + +import java.lang.foreign.MemorySegment; +import java.lang.foreign.MemorySession; + +/** + * Creates a composite parameters instance for a device type + */ +public class CompositeParametersFactory +{ + /** + * Creates a composite parameters instance for the specified device type + * @param deviceType to create + * @param memorySegment of foreign memory structure for the composite parameters + * @param memorySession to allocate additional memory structures + * @return instance + */ + public static CompositeParameters create(DeviceType deviceType, MemorySegment memorySegment, MemorySession memorySession) + { + switch(deviceType) + { + case RSP1 -> { + return new Rsp1CompositeParameters(memorySegment, memorySession); + } + case RSP1A -> { + return new Rsp1aCompositeParameters(memorySegment, memorySession); + } + case RSP2 -> { + return new Rsp2CompositeParameters(memorySegment, memorySession); + } + case RSPduo -> { + return new RspDuoCompositeParameters(memorySegment, memorySession); + } + case RSPdx -> { + return new RspDxCompositeParameters(memorySegment, memorySession); + } + } + + throw new IllegalArgumentException("Unrecognized device type: " + deviceType); + } +} diff --git a/jsdrplay/src/main/java/com/github/dsheirer/sdrplay/parameter/composite/Rsp1CompositeParameters.java b/jsdrplay/src/main/java/com/github/dsheirer/sdrplay/parameter/composite/Rsp1CompositeParameters.java new file mode 100644 index 000000000..bd19fe4a0 --- /dev/null +++ b/jsdrplay/src/main/java/com/github/dsheirer/sdrplay/parameter/composite/Rsp1CompositeParameters.java @@ -0,0 +1,44 @@ +/* + * ***************************************************************************** + * 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.parameter.composite; + +import com.github.dsheirer.sdrplay.device.DeviceType; +import com.github.dsheirer.sdrplay.parameter.device.Rsp1DeviceParameters; +import com.github.dsheirer.sdrplay.parameter.tuner.Rsp1TunerParameters; + +import java.lang.foreign.MemorySegment; +import java.lang.foreign.MemorySession; + +/** + * RSP1 Composite parameters (device and tuner) + */ +public class Rsp1CompositeParameters extends CompositeParameters +{ + /** + * Constructs an instance from the foreign memory segment + * + * @param memorySegment for the composite structure in foreign memory + * @param memorySession for allocating additional memory segments for the sub-structures. + */ + public Rsp1CompositeParameters(MemorySegment memorySegment, MemorySession memorySession) + { + super(DeviceType.RSP1, memorySegment, memorySession); + } +} diff --git a/jsdrplay/src/main/java/com/github/dsheirer/sdrplay/parameter/composite/Rsp1aCompositeParameters.java b/jsdrplay/src/main/java/com/github/dsheirer/sdrplay/parameter/composite/Rsp1aCompositeParameters.java new file mode 100644 index 000000000..ef031e8e7 --- /dev/null +++ b/jsdrplay/src/main/java/com/github/dsheirer/sdrplay/parameter/composite/Rsp1aCompositeParameters.java @@ -0,0 +1,44 @@ +/* + * ***************************************************************************** + * 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.parameter.composite; + +import com.github.dsheirer.sdrplay.device.DeviceType; +import com.github.dsheirer.sdrplay.parameter.device.Rsp1aDeviceParameters; +import com.github.dsheirer.sdrplay.parameter.tuner.Rsp1aTunerParameters; + +import java.lang.foreign.MemorySegment; +import java.lang.foreign.MemorySession; + +/** + * RSP1A Composite parameters (device and tuner) + */ +public class Rsp1aCompositeParameters extends CompositeParameters +{ + /** + * Constructs an instance from the foreign memory segment + * + * @param memorySegment for the composite structure in foreign memory + * @param memorySession for allocating additional memory segments for the sub-structures. + */ + public Rsp1aCompositeParameters(MemorySegment memorySegment, MemorySession memorySession) + { + super(DeviceType.RSP1A, memorySegment, memorySession); + } +} diff --git a/jsdrplay/src/main/java/com/github/dsheirer/sdrplay/parameter/composite/Rsp2CompositeParameters.java b/jsdrplay/src/main/java/com/github/dsheirer/sdrplay/parameter/composite/Rsp2CompositeParameters.java new file mode 100644 index 000000000..e09116452 --- /dev/null +++ b/jsdrplay/src/main/java/com/github/dsheirer/sdrplay/parameter/composite/Rsp2CompositeParameters.java @@ -0,0 +1,44 @@ +/* + * ***************************************************************************** + * 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.parameter.composite; + +import com.github.dsheirer.sdrplay.device.DeviceType; +import com.github.dsheirer.sdrplay.parameter.device.Rsp2DeviceParameters; +import com.github.dsheirer.sdrplay.parameter.tuner.Rsp2TunerParameters; + +import java.lang.foreign.MemorySegment; +import java.lang.foreign.MemorySession; + +/** + * RSP2 Composite parameters (device and tuner) + */ +public class Rsp2CompositeParameters extends CompositeParameters +{ + /** + * Constructs an instance from the foreign memory segment + * + * @param memorySegment for the composite structure in foreign memory + * @param memorySession for allocating additional memory segments for the sub-structures. + */ + public Rsp2CompositeParameters(MemorySegment memorySegment, MemorySession memorySession) + { + super(DeviceType.RSP2, memorySegment, memorySession); + } +} diff --git a/jsdrplay/src/main/java/com/github/dsheirer/sdrplay/parameter/composite/RspDuoCompositeParameters.java b/jsdrplay/src/main/java/com/github/dsheirer/sdrplay/parameter/composite/RspDuoCompositeParameters.java new file mode 100644 index 000000000..764c3245c --- /dev/null +++ b/jsdrplay/src/main/java/com/github/dsheirer/sdrplay/parameter/composite/RspDuoCompositeParameters.java @@ -0,0 +1,86 @@ +/* + * ***************************************************************************** + * 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.parameter.composite; + +import com.github.dsheirer.sdrplay.api.v3_07.sdrplay_api_DeviceParamsT; +import com.github.dsheirer.sdrplay.api.v3_07.sdrplay_api_RxChannelParamsT; +import com.github.dsheirer.sdrplay.device.DeviceType; +import com.github.dsheirer.sdrplay.parameter.control.ControlParameters; +import com.github.dsheirer.sdrplay.parameter.device.RspDuoDeviceParameters; +import com.github.dsheirer.sdrplay.parameter.tuner.RspDuoTunerParameters; +import com.github.dsheirer.sdrplay.parameter.tuner.TunerParametersFactory; + +import java.lang.foreign.MemoryAddress; +import java.lang.foreign.MemorySegment; +import java.lang.foreign.MemorySession; + +/** + * RSPduo Composite parameters (device and two tuners) + */ +public class RspDuoCompositeParameters extends CompositeParameters +{ + private RspDuoTunerParameters mTunerBParameters; + private ControlParameters mControlBParameters; + + /** + * Constructs an instance from the foreign memory segment + * + * @param memorySegment for the composite structure in foreign memory + * @param memorySession for allocating additional memory segments for the sub-structures. + */ + public RspDuoCompositeParameters(MemorySegment memorySegment, MemorySession memorySession) + { + super(DeviceType.RSPduo, memorySegment, memorySession); + + MemoryAddress memoryAddressRxB = sdrplay_api_DeviceParamsT.rxChannelB$get(memorySegment); + MemorySegment memorySegmentRxB = sdrplay_api_RxChannelParamsT.ofAddress(memoryAddressRxB, memorySession); + mTunerBParameters = (RspDuoTunerParameters) TunerParametersFactory.create(DeviceType.RSPduo, memorySegmentRxB); + + MemorySegment tunerBControlParametersMemorySegment = sdrplay_api_RxChannelParamsT.ctrlParams$slice(memorySegmentRxB); + mControlBParameters = new ControlParameters(tunerBControlParametersMemorySegment); + } + + /** + * Tuner B Tuner Parameters + */ + public RspDuoTunerParameters getTunerBParameters() + { + return mTunerBParameters; + } + + /** + * Tuner B Control Parameters + */ + public ControlParameters getControlBParameters() + { + return mControlBParameters; + } + + @Override + public String toString() + { + StringBuilder sb = new StringBuilder(); + sb.append("Device Composite Parameters\n"); + sb.append("\tDevice Parameters:\n").append(getDeviceParameters()).append("\n"); + sb.append("\tTuner Channel A:\n").append(getTunerAParameters()).append("\n"); + sb.append("\tTuner Channel B:\n").append(getTunerBParameters()).append("\n"); + return sb.toString(); + } +} diff --git a/jsdrplay/src/main/java/com/github/dsheirer/sdrplay/parameter/composite/RspDxCompositeParameters.java b/jsdrplay/src/main/java/com/github/dsheirer/sdrplay/parameter/composite/RspDxCompositeParameters.java new file mode 100644 index 000000000..711e612ac --- /dev/null +++ b/jsdrplay/src/main/java/com/github/dsheirer/sdrplay/parameter/composite/RspDxCompositeParameters.java @@ -0,0 +1,44 @@ +/* + * ***************************************************************************** + * 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.parameter.composite; + +import com.github.dsheirer.sdrplay.device.DeviceType; +import com.github.dsheirer.sdrplay.parameter.device.RspDxDeviceParameters; +import com.github.dsheirer.sdrplay.parameter.tuner.RspDxTunerParameters; + +import java.lang.foreign.MemorySegment; +import java.lang.foreign.MemorySession; + +/** + * RSPdx Composite parameters (device and receiver) + */ +public class RspDxCompositeParameters extends CompositeParameters +{ + /** + * Constructs an instance from the foreign memory segment + * + * @param memorySegment for the composite structure in foreign memory + * @param memorySession for allocating additional memory segments for the sub-structures. + */ + public RspDxCompositeParameters(MemorySegment memorySegment, MemorySession memorySession) + { + super(DeviceType.RSPdx, memorySegment, memorySession); + } +} diff --git a/jsdrplay/src/main/java/com/github/dsheirer/sdrplay/parameter/control/AdsbMode.java b/jsdrplay/src/main/java/com/github/dsheirer/sdrplay/parameter/control/AdsbMode.java new file mode 100644 index 000000000..96f616aad --- /dev/null +++ b/jsdrplay/src/main/java/com/github/dsheirer/sdrplay/parameter/control/AdsbMode.java @@ -0,0 +1,74 @@ +/* + * ***************************************************************************** + * 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.parameter.control; + +import com.github.dsheirer.sdrplay.api.v3_07.sdrplay_api_h; + +/** + * ADSB Mode (for ADS-B decoding applications) + */ +public enum AdsbMode +{ + NO_DECIMATION_LOWPASS(sdrplay_api_h.sdrplay_api_ADSB_NO_DECIMATION_LOWPASS(), "No Decimation-Lowpass"), + NO_DECIMATION_BANDPASS_2_MHZ(sdrplay_api_h.sdrplay_api_ADSB_NO_DECIMATION_BANDPASS_2MHZ(), "No Decimation-Bandpass 2 MHz"), + NO_DECIMATION_BANDPASS_3_MHZ(sdrplay_api_h.sdrplay_api_ADSB_NO_DECIMATION_BANDPASS_3MHZ(), "No Decimation-Bandpass 3 MHz"), + DECIMATION(sdrplay_api_h.sdrplay_api_ADSB_DECIMATION(), "Decimation"); + + private int mValue; + private String mDescription; + + AdsbMode(int value, String description) + { + mValue = value; + mDescription = description; + } + + /** + * Numeric value + */ + public int getValue() + { + return mValue; + } + + /** + * Lookup the entry from a return code + * @param value to lookup + * @return entry or DECIMATION if the code is not recognized + */ + public static AdsbMode fromValue(int value) + { + for(AdsbMode status: AdsbMode.values()) + { + if(status.getValue() == value) + { + return status; + } + } + + return DECIMATION; + } + + @Override + public String toString() + { + return mDescription; + } +} diff --git a/jsdrplay/src/main/java/com/github/dsheirer/sdrplay/parameter/control/Agc.java b/jsdrplay/src/main/java/com/github/dsheirer/sdrplay/parameter/control/Agc.java new file mode 100644 index 000000000..e88b579f6 --- /dev/null +++ b/jsdrplay/src/main/java/com/github/dsheirer/sdrplay/parameter/control/Agc.java @@ -0,0 +1,154 @@ +/* + * ***************************************************************************** + * 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.parameter.control; + +import com.github.dsheirer.sdrplay.api.v3_07.sdrplay_api_AgcT; +import com.github.dsheirer.sdrplay.util.Flag; + +import java.lang.foreign.MemorySegment; + +/** + * AGC structure (sdrplay_api_AgcT) + */ +public class Agc +{ + private MemorySegment mMemorySegment; + + /** + * Constructs an instance from the foreign memory segment + */ + public Agc(MemorySegment memorySegment) + { + mMemorySegment = memorySegment; + } + + /** + * Foreign memory segment for this structure + */ + private MemorySegment getMemorySegment() + { + return mMemorySegment; + } + + /** + * AGC Control (mode) + */ + public AgcMode getAgcMode() + { + return AgcMode.fromValue(sdrplay_api_AgcT.enable$get(getMemorySegment())); + } + + /** + * Sets AGC Control (mode) + */ + public void setAgcMode(AgcMode mode) + { + sdrplay_api_AgcT.enable$set(getMemorySegment(), mode.getValue()); + } + + /** + * Set point dBfs + */ + public int getSetPointDbfs() + { + return sdrplay_api_AgcT.setPoint_dBfs$get(getMemorySegment()); + } + + /** + * Sets the set point dBfs + */ + public void setSetPointDbfs(int setPointDbfs) + { + sdrplay_api_AgcT.setPoint_dBfs$set(getMemorySegment(), setPointDbfs); + } + + /** + * Attack rate in milliseconds + */ + public int getAttackMs() + { + return sdrplay_api_AgcT.attack_ms$get(getMemorySegment()); + } + + /** + * Sets the attack rate in milliseconds + */ + public void setAttackMs(int attackMs) + { + sdrplay_api_AgcT.attack_ms$set(getMemorySegment(), (short)attackMs); + } + + /** + * Decay rate in milliseconds + */ + public int getDecayMs() + { + return sdrplay_api_AgcT.decay_ms$get(getMemorySegment()); + } + + /** + * Sets the decay rate in milliseconds + */ + public void setDecayMs(int decayMs) + { + sdrplay_api_AgcT.decay_ms$set(getMemorySegment(), (short)decayMs); + } + + /** + * Decay delay rate in milliseconds + */ + public int getDecayDelayMs() + { + return sdrplay_api_AgcT.decay_delay_ms$get(getMemorySegment()); + } + + /** + * Sets the decay delay rate in milliseconds + */ + public void setDecayDelayMs(int decayDelayMs) + { + sdrplay_api_AgcT.decay_delay_ms$set(getMemorySegment(), (short)decayDelayMs); + } + + /** + * Decay threshold in dB + */ + public int getDecayThresholdDb() + { + return sdrplay_api_AgcT.decay_threshold_dB$get(getMemorySegment()); + } + + /** + * Sets the decay threshold in dB + */ + public void setDecayThresholdDb(int decayThresholdDb) + { + sdrplay_api_AgcT.decay_threshold_dB$set(getMemorySegment(), (short)decayThresholdDb); + } + + /** + * Sets the changes to be applied as a synchronous update + */ + public void setSynchronousUpdate(boolean syncUpdate) + { + //Note: this is supposed to be an integer value ... does it represent a boolean (0 or 1) or something else?? + sdrplay_api_AgcT.syncUpdate$set(getMemorySegment(), Flag.of(syncUpdate)); + } +} diff --git a/jsdrplay/src/main/java/com/github/dsheirer/sdrplay/parameter/control/AgcMode.java b/jsdrplay/src/main/java/com/github/dsheirer/sdrplay/parameter/control/AgcMode.java new file mode 100644 index 000000000..ce8cecf41 --- /dev/null +++ b/jsdrplay/src/main/java/com/github/dsheirer/sdrplay/parameter/control/AgcMode.java @@ -0,0 +1,75 @@ +/* + * ***************************************************************************** + * 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.parameter.control; + +import com.github.dsheirer.sdrplay.api.v3_07.sdrplay_api_h; + +/** + * Automatic Gain Control (AGC) Control (mode) + */ +public enum AgcMode +{ + DISABLE(sdrplay_api_h.sdrplay_api_AGC_DISABLE(), "DISABLE"), + AGC_100_HZ(sdrplay_api_h.sdrplay_api_AGC_100HZ(), "100 Hz"), + AGC_50_HZ(sdrplay_api_h.sdrplay_api_AGC_50HZ(), "50 Hz"), + AGC_5_HZ(sdrplay_api_h.sdrplay_api_AGC_5HZ(), "5 Hz"), + ENABLE(sdrplay_api_h.sdrplay_api_AGC_CTRL_EN(), "ENABLE"); + + private int mValue; + private String mDescription; + + AgcMode(int value, String description) + { + mValue = value; + mDescription = description; + } + + /** + * Numeric value + */ + public int getValue() + { + return mValue; + } + + /** + * Lookup the entry from a return code + * @param value to lookup + * @return entry or DISABLE if the code is not recognized + */ + public static AgcMode fromValue(int value) + { + for(AgcMode status: AgcMode.values()) + { + if(status.getValue() == value) + { + return status; + } + } + + return DISABLE; + } + + @Override + public String toString() + { + return mDescription; + } +} diff --git a/jsdrplay/src/main/java/com/github/dsheirer/sdrplay/parameter/control/ControlParameters.java b/jsdrplay/src/main/java/com/github/dsheirer/sdrplay/parameter/control/ControlParameters.java new file mode 100644 index 000000000..cbca315b6 --- /dev/null +++ b/jsdrplay/src/main/java/com/github/dsheirer/sdrplay/parameter/control/ControlParameters.java @@ -0,0 +1,94 @@ +/* + * ***************************************************************************** + * 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.parameter.control; + +import com.github.dsheirer.sdrplay.api.v3_07.sdrplay_api_ControlParamsT; + +import java.lang.foreign.MemorySegment; + +/** + * Control Parameters structure (sdrplay_api_ControlParamsT) + */ +public class ControlParameters +{ + private MemorySegment mMemorySegment; + private DcOffset mDcOffset; + private Decimation mDecimation; + private Agc mAgc; + + /** + * Creates an instance from the foreign memory segment + */ + public ControlParameters(MemorySegment memorySegment) + { + mMemorySegment = memorySegment; + mDcOffset = new DcOffset(sdrplay_api_ControlParamsT.dcOffset$slice(memorySegment)); + mDecimation = new Decimation(sdrplay_api_ControlParamsT.decimation$slice(memorySegment)); + mAgc = new Agc(sdrplay_api_ControlParamsT.agc$slice(memorySegment)); + } + + /** + * Foreign memory segment for this structure + */ + private MemorySegment getMemorySegment() + { + return mMemorySegment; + } + + /** + * DC offset settings for DC and IQ correction + */ + public DcOffset getDcOffset() + { + return mDcOffset; + } + + /** + * Decimation settings + */ + public Decimation getDecimation() + { + return mDecimation; + } + + /** + * Automatic Gain Control (AGC) settings + */ + public Agc getAgc() + { + return mAgc; + } + + /** + * Current ADSB mode + */ + public AdsbMode getAdsbMode() + { + return AdsbMode.fromValue(sdrplay_api_ControlParamsT.adsbMode$get(getMemorySegment())); + } + + /** + * Sets ADSB mode + */ + public void setAdsbMode(AdsbMode mode) + { + sdrplay_api_ControlParamsT.adsbMode$set(getMemorySegment(), mode.getValue()); + } +} diff --git a/jsdrplay/src/main/java/com/github/dsheirer/sdrplay/parameter/control/DcOffset.java b/jsdrplay/src/main/java/com/github/dsheirer/sdrplay/parameter/control/DcOffset.java new file mode 100644 index 000000000..e95783dbc --- /dev/null +++ b/jsdrplay/src/main/java/com/github/dsheirer/sdrplay/parameter/control/DcOffset.java @@ -0,0 +1,81 @@ +/* + * ***************************************************************************** + * 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.parameter.control; + +import com.github.dsheirer.sdrplay.api.v3_07.sdrplay_api_DcOffsetT; +import com.github.dsheirer.sdrplay.util.Flag; + +import java.lang.foreign.MemorySegment; + +/** + * DC Offset structure (sdrplay_api_DCOffsetT) + */ +public class DcOffset +{ + private MemorySegment mMemorySegment; + + /** + * Constructs an instance from the foreign memory segment + */ + public DcOffset(MemorySegment memorySegment) + { + mMemorySegment = memorySegment; + } + + /** + * Foreign memory segment for this structure + */ + private MemorySegment getMemorySegment() + { + return mMemorySegment; + } + + /** + * Indicates if DC correction is enabled. + */ + public boolean isDC() + { + return Flag.evaluate(sdrplay_api_DcOffsetT.DCenable$get(getMemorySegment())); + } + + /** + * Enable or disable DC correction + */ + public void setDC(boolean enable) + { + sdrplay_api_DcOffsetT.DCenable$set(getMemorySegment(), Flag.of(enable)); + } + + /** + * Indicates if IQ correction is enabled + */ + public boolean isIQ() + { + return Flag.evaluate(sdrplay_api_DcOffsetT.IQenable$get(getMemorySegment())); + } + + /** + * Enable or disable IQ correction + */ + public void setIQ(boolean enable) + { + sdrplay_api_DcOffsetT.IQenable$set(getMemorySegment(), Flag.of(enable)); + } +} diff --git a/jsdrplay/src/main/java/com/github/dsheirer/sdrplay/parameter/control/Decimation.java b/jsdrplay/src/main/java/com/github/dsheirer/sdrplay/parameter/control/Decimation.java new file mode 100644 index 000000000..13849ed3a --- /dev/null +++ b/jsdrplay/src/main/java/com/github/dsheirer/sdrplay/parameter/control/Decimation.java @@ -0,0 +1,97 @@ +/* + * ***************************************************************************** + * 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.parameter.control; + +import com.github.dsheirer.sdrplay.api.v3_07.sdrplay_api_DecimationT; +import com.github.dsheirer.sdrplay.util.Flag; + +import java.lang.foreign.MemorySegment; + +/** + * Decimation structure (sdrplay_api_DecimationT) + */ +public class Decimation +{ + private MemorySegment mMemorySegment; + + /** + * Constructs an instance from the foreign memory segment + */ + public Decimation(MemorySegment memorySegment) + { + mMemorySegment = memorySegment; + } + + /** + * Foreign memory segment for this structure + */ + public MemorySegment getMemorySegment() + { + return mMemorySegment; + } + + /** + * Indicates if decimation is enabled + */ + public boolean isEnabled() + { + return Flag.evaluate(sdrplay_api_DecimationT.enable$get(getMemorySegment())); + } + + /** + * Enable or disable decimation + */ + public void setEnabled(boolean enable) + { + sdrplay_api_DecimationT.enable$set(getMemorySegment(), Flag.of(enable)); + } + + /** + * Decimation factor + */ + public int getDecimationFactor() + { + return sdrplay_api_DecimationT.decimationFactor$get(getMemorySegment()); + } + + /** + * Sets the decimation factor + */ + public void setDecimationFactor(int decimationFactor) + { + sdrplay_api_DecimationT.decimationFactor$set(getMemorySegment(), (byte)decimationFactor); + } + + /** + * Indicates if the wideband signal setting is enabled + */ + public boolean isWideBandSignal() + { + return Flag.evaluate(sdrplay_api_DecimationT.wideBandSignal$get(getMemorySegment())); + } + + /** + * Enables or disables the wideband signal setting + */ + public void setWideBandSignal(boolean enable) + { + sdrplay_api_DecimationT.wideBandSignal$set(getMemorySegment(), Flag.of(enable)); + } +} diff --git a/jsdrplay/src/main/java/com/github/dsheirer/sdrplay/parameter/device/DeviceParameters.java b/jsdrplay/src/main/java/com/github/dsheirer/sdrplay/parameter/device/DeviceParameters.java new file mode 100644 index 000000000..68960bbe4 --- /dev/null +++ b/jsdrplay/src/main/java/com/github/dsheirer/sdrplay/parameter/device/DeviceParameters.java @@ -0,0 +1,132 @@ +/* + * ***************************************************************************** + * 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.parameter.device; + +import com.github.dsheirer.sdrplay.api.v3_07.sdrplay_api_DevParamsT; + +import java.lang.foreign.MemorySegment; + +/** + * Device Parameters structure (sdrplay_api_DevParamsT) + */ +public abstract class DeviceParameters +{ + private MemorySegment mMemorySegment; + private SamplingFrequency mSamplingFrequency; + private SynchronousUpdate mSynchronousUpdate; + private ResetFlags mResetFlags; + + public DeviceParameters(MemorySegment memorySegment) + { + mMemorySegment = memorySegment; + mSamplingFrequency = new SamplingFrequency(sdrplay_api_DevParamsT.fsFreq$slice(memorySegment)); + mSynchronousUpdate = new SynchronousUpdate(sdrplay_api_DevParamsT.syncUpdate$slice(memorySegment)); + mResetFlags = new ResetFlags(sdrplay_api_DevParamsT.resetFlags$slice(memorySegment)); + } + + /** + * Foreign memory segment for this device parameters instance + */ + protected MemorySegment getMemorySegment() + { + return mMemorySegment; + } + + /** + * Parts Per Million (ppm) center frequency correction value. + * @return ppm + */ + public double getPPM() + { + return sdrplay_api_DevParamsT.ppm$get(getMemorySegment()); + } + + /** + * Sets the parts per million (ppm) center frequency correction value + * @param ppm parts per million + */ + public void setPPM(double ppm) + { + sdrplay_api_DevParamsT.ppm$set(getMemorySegment(), ppm); + } + + /** + * Sampling frequency structure. + */ + public SamplingFrequency getSamplingFrequency() + { + return mSamplingFrequency; + } + + /** + * Synchronous update structure + */ + public SynchronousUpdate getSynchronousUpdate() + { + return mSynchronousUpdate; + } + + /** + * Reset request flags + */ + public ResetFlags getResetFlags() + { + return mResetFlags; + } + + /** + * USB Transfer mode currently used by the device + */ + public TransferMode getTransferMode() + { + return TransferMode.fromValue(sdrplay_api_DevParamsT.mode$get(getMemorySegment())); + } + + /** + * Sets the USB transfer mode used by the device + */ + public void setTransferMode(TransferMode transferMode) + { + if(transferMode != TransferMode.UNKNOWN) + { + sdrplay_api_DevParamsT.mode$set(getMemorySegment(), transferMode.getValue()); + } + } + + public long getSamplesPerPacket() + { + return sdrplay_api_DevParamsT.samplesPerPkt$get(getMemorySegment()); + } + + @Override + public String toString() + { + StringBuilder sb = new StringBuilder(); + sb.append("\tDevice Parameters").append("\n"); + sb.append("\t\tPPM: ").append(getPPM()).append("\n"); + sb.append("\t\tSample Rate: ").append(getSamplingFrequency()).append("\n"); + sb.append("\t\tSamples Per Packet: ").append(getSamplesPerPacket()).append("\n"); + sb.append("\t\tSync Update: ").append(getSynchronousUpdate()).append("\n"); + sb.append("\t\tReset Flags: ").append(getResetFlags()).append("\n"); + sb.append("\t\tTransfer Mode: ").append(getTransferMode()).append("\n"); + + return sb.toString(); + } +} diff --git a/jsdrplay/src/main/java/com/github/dsheirer/sdrplay/parameter/device/DeviceParametersFactory.java b/jsdrplay/src/main/java/com/github/dsheirer/sdrplay/parameter/device/DeviceParametersFactory.java new file mode 100644 index 000000000..af528ba22 --- /dev/null +++ b/jsdrplay/src/main/java/com/github/dsheirer/sdrplay/parameter/device/DeviceParametersFactory.java @@ -0,0 +1,60 @@ +/* + * ***************************************************************************** + * 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.parameter.device; + +import com.github.dsheirer.sdrplay.device.DeviceType; + +import java.lang.foreign.MemorySegment; + +/** + * Creates device parameters instance from a foreign memory segment + */ +public class DeviceParametersFactory +{ + /** + * Create a device parameters instance + * @param deviceType for the device + * @param memorySegment of foreign memory representing the device type + * @return instance + */ + public static DeviceParameters create(DeviceType deviceType, MemorySegment memorySegment) + { + switch(deviceType) + { + case RSP1 -> { + return new Rsp1DeviceParameters(memorySegment); + } + case RSP1A -> { + return new Rsp1aDeviceParameters(memorySegment); + } + case RSP2 -> { + return new Rsp2DeviceParameters(memorySegment); + } + case RSPduo -> { + return new RspDuoDeviceParameters(memorySegment); + } + case RSPdx -> { + return new RspDxDeviceParameters(memorySegment); + } + } + + throw new IllegalArgumentException("Unrecognized Device Type: " + deviceType); + } +} diff --git a/jsdrplay/src/main/java/com/github/dsheirer/sdrplay/parameter/device/ResetFlags.java b/jsdrplay/src/main/java/com/github/dsheirer/sdrplay/parameter/device/ResetFlags.java new file mode 100644 index 000000000..494a575b1 --- /dev/null +++ b/jsdrplay/src/main/java/com/github/dsheirer/sdrplay/parameter/device/ResetFlags.java @@ -0,0 +1,74 @@ +/* + * ***************************************************************************** + * 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.parameter.device; + +import com.github.dsheirer.sdrplay.api.v3_07.sdrplay_api_ResetFlagsT; +import com.github.dsheirer.sdrplay.util.Flag; + +import java.lang.foreign.MemorySegment; + +/** + * Reset Flags structure + */ +public class ResetFlags +{ + private MemorySegment mMemorySegment; + + /** + * Constructs an instance from a foreign memory segment and transfers the structure fields into this instance. + * @param memorySegment pointer + */ + public ResetFlags(MemorySegment memorySegment) + { + mMemorySegment = memorySegment; + } + + /** + * Foreign memory segment + */ + private MemorySegment getMemorySegment() + { + return mMemorySegment; + } + + /** + * Request a reset of the gain reduction + */ + public void resetGain(boolean reset) + { + sdrplay_api_ResetFlagsT.resetGainUpdate$set(getMemorySegment(), reset ? Flag.TRUE : Flag.FALSE); + } + + /** + * Request a reset of the center frequency value + */ + public void resetFrequency(boolean reset) + { + sdrplay_api_ResetFlagsT.resetRfUpdate$set(getMemorySegment(), reset ? Flag.TRUE : Flag.FALSE); + } + + /** + * Request a reset of the sample rate value. + */ + public void resetSampleRate(boolean reset) + { + sdrplay_api_ResetFlagsT.resetFsUpdate$set(getMemorySegment(), reset ? Flag.TRUE : Flag.FALSE); + } +} diff --git a/jsdrplay/src/main/java/com/github/dsheirer/sdrplay/parameter/device/Rsp1DeviceParameters.java b/jsdrplay/src/main/java/com/github/dsheirer/sdrplay/parameter/device/Rsp1DeviceParameters.java new file mode 100644 index 000000000..7fbb06989 --- /dev/null +++ b/jsdrplay/src/main/java/com/github/dsheirer/sdrplay/parameter/device/Rsp1DeviceParameters.java @@ -0,0 +1,37 @@ +/* + * ***************************************************************************** + * 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.parameter.device; + +import java.lang.foreign.MemorySegment; + +/** + * RSP-1 Device Parameters structure + */ +public class Rsp1DeviceParameters extends DeviceParameters +{ + /** + * Constructs an instance + * @param memorySegment for this structure + */ + public Rsp1DeviceParameters(MemorySegment memorySegment) + { + super(memorySegment); + } +} diff --git a/jsdrplay/src/main/java/com/github/dsheirer/sdrplay/parameter/device/Rsp1aDeviceParameters.java b/jsdrplay/src/main/java/com/github/dsheirer/sdrplay/parameter/device/Rsp1aDeviceParameters.java new file mode 100644 index 000000000..d89f3ce9a --- /dev/null +++ b/jsdrplay/src/main/java/com/github/dsheirer/sdrplay/parameter/device/Rsp1aDeviceParameters.java @@ -0,0 +1,84 @@ +/* + * ***************************************************************************** + * 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.parameter.device; + +import com.github.dsheirer.sdrplay.api.v3_07.sdrplay_api_DevParamsT; +import com.github.dsheirer.sdrplay.api.v3_07.sdrplay_api_Rsp1aParamsT; +import com.github.dsheirer.sdrplay.util.Flag; + +import java.lang.foreign.MemorySegment; + +/** + * RSP-1A Device Parameters structure + */ +public class Rsp1aDeviceParameters extends DeviceParameters +{ + private MemorySegment mRsp1AMemorySegment; + + /** + * Constructs an instance + * @param memorySegment for this structure + */ + public Rsp1aDeviceParameters(MemorySegment memorySegment) + { + super(memorySegment); + mRsp1AMemorySegment = sdrplay_api_DevParamsT.rsp1aParams$slice(memorySegment); + } + + /** + * Foreign memory segment representing this structure + */ + private MemorySegment getRsp1AMemorySegment() + { + return mRsp1AMemorySegment; + } + + /** + * Indicates if RF notch is enabled. + */ + public boolean isRFNotch() + { + return Flag.evaluate(sdrplay_api_Rsp1aParamsT.rfNotchEnable$get(getRsp1AMemorySegment())); + } + + /** + * Enables or disables the RF notch. + */ + public void setRFNotch(boolean enable) + { + sdrplay_api_Rsp1aParamsT.rfNotchEnable$set(getRsp1AMemorySegment(), Flag.of(enable)); + } + + /** + * Indicates if DAB RF notch is enabled + */ + public boolean isRfDabNotch() + { + return Flag.evaluate(sdrplay_api_Rsp1aParamsT.rfDabNotchEnable$get(getRsp1AMemorySegment())); + } + + /** + * Enables or disables the DAB RF notch + */ + public void setRfDabNotch(boolean enable) + { + sdrplay_api_Rsp1aParamsT.rfDabNotchEnable$set(getRsp1AMemorySegment(), Flag.of(enable)); + } +} diff --git a/jsdrplay/src/main/java/com/github/dsheirer/sdrplay/parameter/device/Rsp2DeviceParameters.java b/jsdrplay/src/main/java/com/github/dsheirer/sdrplay/parameter/device/Rsp2DeviceParameters.java new file mode 100644 index 000000000..7e24ee5d6 --- /dev/null +++ b/jsdrplay/src/main/java/com/github/dsheirer/sdrplay/parameter/device/Rsp2DeviceParameters.java @@ -0,0 +1,68 @@ +/* + * ***************************************************************************** + * 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.parameter.device; + +import com.github.dsheirer.sdrplay.api.v3_07.sdrplay_api_DevParamsT; +import com.github.dsheirer.sdrplay.api.v3_07.sdrplay_api_Rsp2ParamsT; +import com.github.dsheirer.sdrplay.util.Flag; + +import java.lang.foreign.MemorySegment; + +/** + * RSP-2 Device Parameters structure + */ +public class Rsp2DeviceParameters extends DeviceParameters +{ + private MemorySegment mRsp2MemorySegment; + + /** + * Constructs an instance + * @param memorySegment for this structure + */ + public Rsp2DeviceParameters(MemorySegment memorySegment) + { + super(memorySegment); + mRsp2MemorySegment = sdrplay_api_DevParamsT.rsp2Params$slice(memorySegment); + } + + /** + * Foreign memory segment representing this structure + */ + private MemorySegment getRsp2MemorySegment() + { + return mRsp2MemorySegment; + } + + /** + * Indicates if the external reference output is enabled + */ + public boolean isExternalReferenceOutput() + { + return Flag.evaluate(sdrplay_api_Rsp2ParamsT.extRefOutputEn$get(getRsp2MemorySegment())); + } + + /** + * Enables or disables the external reference output + */ + public void setExternalReferenceOutput(boolean enable) + { + sdrplay_api_Rsp2ParamsT.extRefOutputEn$set(getRsp2MemorySegment(), Flag.of(enable)); + } +} diff --git a/jsdrplay/src/main/java/com/github/dsheirer/sdrplay/parameter/device/RspDuoDeviceParameters.java b/jsdrplay/src/main/java/com/github/dsheirer/sdrplay/parameter/device/RspDuoDeviceParameters.java new file mode 100644 index 000000000..b141ddf62 --- /dev/null +++ b/jsdrplay/src/main/java/com/github/dsheirer/sdrplay/parameter/device/RspDuoDeviceParameters.java @@ -0,0 +1,68 @@ +/* + * ***************************************************************************** + * 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.parameter.device; + +import com.github.dsheirer.sdrplay.api.v3_07.sdrplay_api_DevParamsT; +import com.github.dsheirer.sdrplay.api.v3_07.sdrplay_api_RspDuoParamsT; +import com.github.dsheirer.sdrplay.util.Flag; + +import java.lang.foreign.MemorySegment; + +/** + * RSPduo Device Parameters structure + */ +public class RspDuoDeviceParameters extends DeviceParameters +{ + private MemorySegment mRspDuoMemorySegment; + + /** + * Constructs an instance + * @param memorySegment for this structure + */ + public RspDuoDeviceParameters(MemorySegment memorySegment) + { + super(memorySegment); + mRspDuoMemorySegment = sdrplay_api_DevParamsT.rspDuoParams$slice(memorySegment); + } + + /** + * Foreign memory segment representing this structure + */ + private MemorySegment getRspDuoMemorySegment() + { + return mRspDuoMemorySegment; + } + + /** + * Indicates if the external reference output is enabled + */ + public boolean isExternalReferenceOutput() + { + return Flag.evaluate(sdrplay_api_RspDuoParamsT.extRefOutputEn$get(getRspDuoMemorySegment())); + } + + /** + * Enables or disables the external reference output + */ + public void setExternalReferenceOutput(boolean enable) + { + sdrplay_api_RspDuoParamsT.extRefOutputEn$set(getRspDuoMemorySegment(), Flag.of(enable)); + } +} diff --git a/jsdrplay/src/main/java/com/github/dsheirer/sdrplay/parameter/device/RspDxDeviceParameters.java b/jsdrplay/src/main/java/com/github/dsheirer/sdrplay/parameter/device/RspDxDeviceParameters.java new file mode 100644 index 000000000..6a2989fc8 --- /dev/null +++ b/jsdrplay/src/main/java/com/github/dsheirer/sdrplay/parameter/device/RspDxDeviceParameters.java @@ -0,0 +1,132 @@ +/* + * ***************************************************************************** + * 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.parameter.device; + +import com.github.dsheirer.sdrplay.api.v3_07.sdrplay_api_DevParamsT; +import com.github.dsheirer.sdrplay.api.v3_07.sdrplay_api_RspDxParamsT; +import com.github.dsheirer.sdrplay.parameter.tuner.RspDxAntenna; +import com.github.dsheirer.sdrplay.util.Flag; + +import java.lang.foreign.MemorySegment; + +/** + * RSP-DX Device Parameters structure + */ +public class RspDxDeviceParameters extends DeviceParameters +{ + private MemorySegment mRspDxMemorySegment; + + /** + * Constructs an instance from the foreign memory segment. + */ + public RspDxDeviceParameters(MemorySegment memorySegment) + { + super(memorySegment); + mRspDxMemorySegment = sdrplay_api_DevParamsT.rspDxParams$slice(memorySegment); + } + + /** + * Foreign memory segment for this structure + */ + private MemorySegment getRspDxMemorySegment() + { + return mRspDxMemorySegment; + } + + /** + * Indicates if High Dynamic Range (HDR) is enabled + */ + public boolean isHdr() + { + return Flag.evaluate(sdrplay_api_RspDxParamsT.hdrEnable$get(getRspDxMemorySegment())); + } + + /** + * Enables or disables High Dynamic Range (HDR) + */ + public void setHdr(boolean enable) + { + sdrplay_api_RspDxParamsT.hdrEnable$set(getRspDxMemorySegment(), Flag.of(enable)); + } + + /** + * Indicates if Bias-T is enabled + */ + public boolean isBiasT() + { + return Flag.evaluate(sdrplay_api_RspDxParamsT.biasTEnable$get(getRspDxMemorySegment())); + } + + /** + * Enables or disables Bias-T + */ + public void setBiasT(boolean enable) + { + sdrplay_api_RspDxParamsT.biasTEnable$set(getRspDxMemorySegment(), Flag.of(enable)); + } + + /** + * RSPdx Antenna Setting + */ + public RspDxAntenna getRspDxAntenna() + { + return RspDxAntenna.fromValue(sdrplay_api_RspDxParamsT.antennaSel$get(getRspDxMemorySegment())); + } + + /** + * Selects the RSPdx Antenna + */ + public void setRspDxAntenna(RspDxAntenna rspDxAntenna) + { + sdrplay_api_RspDxParamsT.antennaSel$set(getRspDxMemorySegment(), rspDxAntenna.getValue()); + } + + /** + * Indicates if RF notch is enabled + */ + public boolean isRfNotch() + { + return Flag.evaluate(sdrplay_api_RspDxParamsT.rfNotchEnable$get(getRspDxMemorySegment())); + } + + /** + * Enables or disables RF notch + */ + public void setRfNotch(boolean enable) + { + sdrplay_api_RspDxParamsT.rfNotchEnable$set(getRspDxMemorySegment(), Flag.of(enable)); + } + + /** + * Indicates if the RF DAB notch is enabled + */ + public boolean isRfDabNotch() + { + return Flag.evaluate(sdrplay_api_RspDxParamsT.rfDabNotchEnable$get(getRspDxMemorySegment())); + } + + /** + * Enables or disables the RF DAB notch + */ + public void setRfDabNotch(boolean enable) + { + sdrplay_api_RspDxParamsT.rfDabNotchEnable$set(getRspDxMemorySegment(), Flag.of(enable)); + } +} diff --git a/jsdrplay/src/main/java/com/github/dsheirer/sdrplay/parameter/device/SamplingFrequency.java b/jsdrplay/src/main/java/com/github/dsheirer/sdrplay/parameter/device/SamplingFrequency.java new file mode 100644 index 000000000..d8c2a33a7 --- /dev/null +++ b/jsdrplay/src/main/java/com/github/dsheirer/sdrplay/parameter/device/SamplingFrequency.java @@ -0,0 +1,87 @@ +/* + * ***************************************************************************** + * 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.parameter.device; + +import com.github.dsheirer.sdrplay.api.v3_07.sdrplay_api_FsFreqT; +import com.github.dsheirer.sdrplay.util.Flag; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import java.lang.foreign.MemorySegment; + +/** + * Sample Rate structure + */ +public class SamplingFrequency +{ + private Logger mLog = LoggerFactory.getLogger(SamplingFrequency.class); + private MemorySegment mMemorySegment; + + /** + * Constructs an instance from a foreign memory segment and transfers the structure fields into this instance. + * @param memorySegment pointer + */ + public SamplingFrequency(MemorySegment memorySegment) + { + mMemorySegment = memorySegment; + } + + private MemorySegment getMemorySegment() + { + return mMemorySegment; + } + + /** + * Sample rate frequency + * @return frequency in Hertz + */ + public double getSampleRate() + { + return sdrplay_api_FsFreqT.fsHz$get(getMemorySegment()); + } + + /** + * Applies the requested sample rate to the device parameters + * @param sampleRate requested rate + * @param synchronousUpdate request + * @param recalibrate request + */ + public void setSampleRate(double sampleRate, boolean synchronousUpdate, boolean recalibrate) + { + sdrplay_api_FsFreqT.fsHz$set(getMemorySegment(), sampleRate); + sdrplay_api_FsFreqT.syncUpdate$set(getMemorySegment(), synchronousUpdate ? Flag.TRUE : Flag.FALSE); + sdrplay_api_FsFreqT.reCal$set(getMemorySegment(), recalibrate ? Flag.TRUE : Flag.FALSE); + } + + /** + * Applies the requested sample rate to the device parameters with synchronous update and recalibrate set to false. + * @param sampleRate requested rate + */ + public void setSampleRate(double sampleRate) + { + setSampleRate(sampleRate, false, false); + } + + @Override + public String toString() + { + return "Sample Rate:" + getSampleRate(); + } +} diff --git a/jsdrplay/src/main/java/com/github/dsheirer/sdrplay/parameter/device/SynchronousUpdate.java b/jsdrplay/src/main/java/com/github/dsheirer/sdrplay/parameter/device/SynchronousUpdate.java new file mode 100644 index 000000000..93b7c9b2c --- /dev/null +++ b/jsdrplay/src/main/java/com/github/dsheirer/sdrplay/parameter/device/SynchronousUpdate.java @@ -0,0 +1,57 @@ +/* + * ***************************************************************************** + * 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.parameter.device; + +import com.github.dsheirer.sdrplay.api.v3_07.sdrplay_api_SyncUpdateT; + +import java.lang.foreign.MemorySegment; + +/** + * Sync Update structure + */ +public class SynchronousUpdate +{ + private MemorySegment mMemorySegment; + + /** + * Constructs an instance from a foreign memory segment + * @param memorySegment pointer + */ + public SynchronousUpdate(MemorySegment memorySegment) + { + mMemorySegment = memorySegment; + } + + private MemorySegment getMemorySegment() + { + return mMemorySegment; + } + + /** + * Sets the sample number and period to apply to both tuners for a synchronous update. + * @param sampleNumber value + * @param period value + */ + public void set(int sampleNumber, int period) + { + sdrplay_api_SyncUpdateT.sampleNum$set(getMemorySegment(), sampleNumber); + sdrplay_api_SyncUpdateT.period$set(getMemorySegment(), period); + } +} diff --git a/jsdrplay/src/main/java/com/github/dsheirer/sdrplay/parameter/device/TransferMode.java b/jsdrplay/src/main/java/com/github/dsheirer/sdrplay/parameter/device/TransferMode.java new file mode 100644 index 000000000..207396a96 --- /dev/null +++ b/jsdrplay/src/main/java/com/github/dsheirer/sdrplay/parameter/device/TransferMode.java @@ -0,0 +1,73 @@ +/* + * ***************************************************************************** + * 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.parameter.device; + +import com.github.dsheirer.sdrplay.api.v3_07.sdrplay_api_h; + +/** + * USB Transfer Mode + */ +public enum TransferMode +{ + ISOCHRONOUS(sdrplay_api_h.sdrplay_api_ISOCH(), "ISOCHRONOUS"), + BULK(sdrplay_api_h.sdrplay_api_BULK(), "BULK"), + UNKNOWN(-1, "UNKNOWN"); + + private int mValue; + private String mDescription; + + TransferMode(int value, String description) + { + mValue = value; + mDescription = description; + } + + /** + * Numeric value + */ + public int getValue() + { + return mValue; + } + + /** + * Lookup the entry from a return code + * @param value to lookup + * @return entry or UNKNOWN if the code is not recognized + */ + public static TransferMode fromValue(int value) + { + for(TransferMode status: TransferMode.values()) + { + if(status.getValue() == value) + { + return status; + } + } + + return UNKNOWN; + } + + @Override + public String toString() + { + return mDescription; + } +} diff --git a/jsdrplay/src/main/java/com/github/dsheirer/sdrplay/parameter/event/EventParametersFactory.java b/jsdrplay/src/main/java/com/github/dsheirer/sdrplay/parameter/event/EventParametersFactory.java new file mode 100644 index 000000000..28477b828 --- /dev/null +++ b/jsdrplay/src/main/java/com/github/dsheirer/sdrplay/parameter/event/EventParametersFactory.java @@ -0,0 +1,58 @@ +/* + * ***************************************************************************** + * 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.parameter.event; + +import com.github.dsheirer.sdrplay.api.v3_07.sdrplay_api_EventParamsT; + +import java.lang.foreign.MemorySegment; + +/** + * Event Parameters structure (sdrplay_api_EventParamsT) + */ +public class EventParametersFactory +{ + private GainCallbackParameters mGainCallbackParameters; + private PowerOverloadCallbackParameters mPowerOverloadCallbackParameters; + private RspDuoModeCallbackParameters mRspDuoModeCallbackParameters; + + /** + * Gain event callback parameters + */ + public static GainCallbackParameters createGainCallbackParameters(MemorySegment memorySegment) + { + return new GainCallbackParameters(sdrplay_api_EventParamsT.gainParams$slice(memorySegment)); + } + + /** + * Power overload event callback parameters + */ + public static PowerOverloadCallbackParameters createPowerOverloadCallbackParameters(MemorySegment memorySegment) + { + return new PowerOverloadCallbackParameters(sdrplay_api_EventParamsT.powerOverloadParams$slice(memorySegment)); + } + + /** + * RSPduo mode event callback parameters + */ + public static RspDuoModeCallbackParameters createRspDuoModeCallbackParameters(MemorySegment memorySegment) + { + return new RspDuoModeCallbackParameters(sdrplay_api_EventParamsT.rspDuoModeParams$slice(memorySegment)); + } +} diff --git a/jsdrplay/src/main/java/com/github/dsheirer/sdrplay/parameter/event/EventType.java b/jsdrplay/src/main/java/com/github/dsheirer/sdrplay/parameter/event/EventType.java new file mode 100644 index 000000000..3dd6eacc3 --- /dev/null +++ b/jsdrplay/src/main/java/com/github/dsheirer/sdrplay/parameter/event/EventType.java @@ -0,0 +1,75 @@ +/* + * ***************************************************************************** + * 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.parameter.event; + +import com.github.dsheirer.sdrplay.api.v3_07.sdrplay_api_h; + +/** + * (Callback) Event Type (sdrplay_api_EventT) + */ +public enum EventType +{ + GAIN_CHANGE(sdrplay_api_h.sdrplay_api_GainChange(), "GAIN CHANGE"), + POWER_OVERLOAD_CHANGE(sdrplay_api_h.sdrplay_api_PowerOverloadChange(), "POWER OVERLOAD CHANGE"), + DEVICE_REMOVED(sdrplay_api_h.sdrplay_api_DeviceRemoved(), "DEVICE REMOVED"), + RSP_DUO_MODE_CHANGE(sdrplay_api_h.sdrplay_api_RspDuoModeChange(), "RSP-DUO MODE CHANGE"), + UNKNOWN(-1, "UNKNOWN"); + + private int mValue; + private String mDescription; + + EventType(int value, String description) + { + mValue = value; + mDescription = description; + } + + /** + * Numeric value + */ + public int getValue() + { + return mValue; + } + + /** + * Lookup the entry from a return code + * @param value to lookup + * @return entry or UNKNOWN if the code is not recognized + */ + public static EventType fromValue(int value) + { + for(EventType status: EventType.values()) + { + if(status.getValue() == value) + { + return status; + } + } + + return UNKNOWN; + } + + @Override + public String toString() + { + return mDescription; + } +} diff --git a/jsdrplay/src/main/java/com/github/dsheirer/sdrplay/parameter/event/GainCallbackParameters.java b/jsdrplay/src/main/java/com/github/dsheirer/sdrplay/parameter/event/GainCallbackParameters.java new file mode 100644 index 000000000..878dc0935 --- /dev/null +++ b/jsdrplay/src/main/java/com/github/dsheirer/sdrplay/parameter/event/GainCallbackParameters.java @@ -0,0 +1,81 @@ +/* + * ***************************************************************************** + * 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.parameter.event; + +import com.github.dsheirer.sdrplay.api.v3_07.sdrplay_api_GainCbParamT; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import java.lang.foreign.MemorySegment; + +/** + * Gain Callback Parameters structure (sdrplay_api_GainCbParamT) + */ +public class GainCallbackParameters +{ + private static final Logger mLog = LoggerFactory.getLogger(GainCallbackParameters.class); + private int mGainReductionDb; + private int mLnaGainReductionDb; + private double mCurrentGain; + + /** + * Constructs an instance from the foreign memory segment + */ + public GainCallbackParameters(MemorySegment memorySegment) + { + mGainReductionDb = sdrplay_api_GainCbParamT.gRdB$get(memorySegment); + mLnaGainReductionDb = sdrplay_api_GainCbParamT.lnaGRdB$get(memorySegment); + mCurrentGain = sdrplay_api_GainCbParamT.currGain$get(memorySegment); + } + + /** + * Current gain reduction value + */ + public int getGainReductionDb() + { + return mGainReductionDb; + } + + /** + * Current LNA state setting + */ + public int getLnaGainReductionDb() + { + return mLnaGainReductionDb; + } + + /** + * Current gain value + */ + public double getCurrentGain() + { + return mCurrentGain; + } + + @Override + public String toString() + { + StringBuilder sb = new StringBuilder(); + sb.append("GR:").append(getGainReductionDb()); + sb.append(" LNA:").append(getLnaGainReductionDb()); + sb.append(" CURRENT GAIN:").append(getCurrentGain()); + return sb.toString(); + } +} diff --git a/jsdrplay/src/main/java/com/github/dsheirer/sdrplay/parameter/event/PowerOverloadCallbackParameters.java b/jsdrplay/src/main/java/com/github/dsheirer/sdrplay/parameter/event/PowerOverloadCallbackParameters.java new file mode 100644 index 000000000..5c506fe4f --- /dev/null +++ b/jsdrplay/src/main/java/com/github/dsheirer/sdrplay/parameter/event/PowerOverloadCallbackParameters.java @@ -0,0 +1,49 @@ +/* + * ***************************************************************************** + * 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.parameter.event; + +import com.github.dsheirer.sdrplay.api.v3_07.sdrplay_api_PowerOverloadCbParamT; + +import java.lang.foreign.MemorySegment; + +/** + * Power Overload Callback Parameters (sdrplay_api_PowerOverloadCbParamT) + */ +public class PowerOverloadCallbackParameters +{ + private PowerOverloadEventType mPowerOverloadEventType; + + /** + * Constructs an instance from the foreign memory segment + */ + public PowerOverloadCallbackParameters(MemorySegment memorySegment) + { + mPowerOverloadEventType = PowerOverloadEventType + .fromValue(sdrplay_api_PowerOverloadCbParamT.powerOverloadChangeType$get(memorySegment)); + } + + /** + * Event type + */ + public PowerOverloadEventType getPowerOverloadEvent() + { + return mPowerOverloadEventType; + } +} diff --git a/jsdrplay/src/main/java/com/github/dsheirer/sdrplay/parameter/event/PowerOverloadEventType.java b/jsdrplay/src/main/java/com/github/dsheirer/sdrplay/parameter/event/PowerOverloadEventType.java new file mode 100644 index 000000000..b6862c22c --- /dev/null +++ b/jsdrplay/src/main/java/com/github/dsheirer/sdrplay/parameter/event/PowerOverloadEventType.java @@ -0,0 +1,73 @@ +/* + * ***************************************************************************** + * 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.parameter.event; + +import com.github.dsheirer.sdrplay.api.v3_07.sdrplay_api_h; + +/** + * Power Overload Callback Event type + */ +public enum PowerOverloadEventType +{ + OVERLOAD_DETECTED(sdrplay_api_h.sdrplay_api_Overload_Detected(), "OVERLOAD DETECTED"), + OVERLOAD_CORRECTED(sdrplay_api_h.sdrplay_api_Overload_Corrected(), "OVERLOAD CORRECTED"), + UNKNOWN(-1, "UNKNOWN"); + + private int mValue; + private String mDescription; + + PowerOverloadEventType(int value, String description) + { + mValue = value; + mDescription = description; + } + + /** + * Numeric value + */ + public int getValue() + { + return mValue; + } + + /** + * Lookup the entry from a return code + * @param value to lookup + * @return entry or UNKNOWN if the code is not recognized + */ + public static PowerOverloadEventType fromValue(int value) + { + for(PowerOverloadEventType status: PowerOverloadEventType.values()) + { + if(status.getValue() == value) + { + return status; + } + } + + return UNKNOWN; + } + + @Override + public String toString() + { + return mDescription; + } +} diff --git a/jsdrplay/src/main/java/com/github/dsheirer/sdrplay/parameter/event/RspDuoModeCallbackParameters.java b/jsdrplay/src/main/java/com/github/dsheirer/sdrplay/parameter/event/RspDuoModeCallbackParameters.java new file mode 100644 index 000000000..0b7565739 --- /dev/null +++ b/jsdrplay/src/main/java/com/github/dsheirer/sdrplay/parameter/event/RspDuoModeCallbackParameters.java @@ -0,0 +1,48 @@ +/* + * ***************************************************************************** + * 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.parameter.event; + +import com.github.dsheirer.sdrplay.api.v3_07.sdrplay_api_RspDuoModeCbParamT; + +import java.lang.foreign.MemorySegment; + +/** + * RSP-Duo Mode Callback Parameters (sdrplay_api_RspDuoModeCbParamT) + */ +public class RspDuoModeCallbackParameters +{ + private RspDuoModeEventType mRspDuoModeEventType; + + /** + * Constructs an instance from the foreign memory segment + */ + public RspDuoModeCallbackParameters(MemorySegment memorySegment) + { + mRspDuoModeEventType = RspDuoModeEventType.fromValue(sdrplay_api_RspDuoModeCbParamT.modeChangeType$get(memorySegment)); + } + + /** + * Event type + */ + public RspDuoModeEventType getRspDuoModeEvent() + { + return mRspDuoModeEventType; + } +} diff --git a/jsdrplay/src/main/java/com/github/dsheirer/sdrplay/parameter/event/RspDuoModeEventType.java b/jsdrplay/src/main/java/com/github/dsheirer/sdrplay/parameter/event/RspDuoModeEventType.java new file mode 100644 index 000000000..57eec76a0 --- /dev/null +++ b/jsdrplay/src/main/java/com/github/dsheirer/sdrplay/parameter/event/RspDuoModeEventType.java @@ -0,0 +1,78 @@ +/* + * ***************************************************************************** + * 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.parameter.event; + +import com.github.dsheirer.sdrplay.api.v3_07.sdrplay_api_h; + +/** + * RSP-Duo Mode Callback Event type + */ +public enum RspDuoModeEventType +{ + MASTER_INITIALIZED(sdrplay_api_h.sdrplay_api_MasterInitialised(), "MASTER INITIALIZED"), + SLAVE_ATTACHED(sdrplay_api_h.sdrplay_api_SlaveAttached(), "SLAVE ATTACHED"), + SLAVE_DETACHED(sdrplay_api_h.sdrplay_api_SlaveDetached(), "SLAVE DETACHED"), + SLAVE_INITIALIZED(sdrplay_api_h.sdrplay_api_SlaveInitialised(), "SLAVE INITIALIZED"), + SLAVE_UNINITIALIZED(sdrplay_api_h.sdrplay_api_SlaveUninitialised(), "SLAVE UNINITIALIZED"), + MASTER_DLL_DISAPPEARED(sdrplay_api_h.sdrplay_api_MasterDllDisappeared(), "MASTER DLL DISAPPEARED"), + SLAVE_DLL_DISAPPEARED(sdrplay_api_h.sdrplay_api_SlaveDllDisappeared(), "SLAVE DLL DISAPPEARED"), + UNKNOWN(-1, "UNKNOWN"); + + private int mValue; + private String mDescription; + + RspDuoModeEventType(int value, String description) + { + mValue = value; + mDescription = description; + } + + /** + * Numeric value + */ + public int getValue() + { + return mValue; + } + + /** + * Lookup the entry from a return code + * @param value to lookup + * @return entry or UNKNOWN if the code is not recognized + */ + public static RspDuoModeEventType fromValue(int value) + { + for(RspDuoModeEventType status: RspDuoModeEventType.values()) + { + if(status.getValue() == value) + { + return status; + } + } + + return UNKNOWN; + } + + @Override + public String toString() + { + return mDescription; + } +} diff --git a/jsdrplay/src/main/java/com/github/dsheirer/sdrplay/parameter/tuner/Bandwidth.java b/jsdrplay/src/main/java/com/github/dsheirer/sdrplay/parameter/tuner/Bandwidth.java new file mode 100644 index 000000000..2bbef028e --- /dev/null +++ b/jsdrplay/src/main/java/com/github/dsheirer/sdrplay/parameter/tuner/Bandwidth.java @@ -0,0 +1,89 @@ +/* + * ***************************************************************************** + * 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.parameter.tuner; + +import com.github.dsheirer.sdrplay.api.v3_07.sdrplay_api_h; + +/** + * Bandwidth + */ +public enum Bandwidth +{ + BW_0_200(sdrplay_api_h.sdrplay_api_BW_0_200(), 200_000, "0.200 MHz"), + BW_0_300(sdrplay_api_h.sdrplay_api_BW_0_300(), 300_000, "0.300 MHz"), + BW_0_600(sdrplay_api_h.sdrplay_api_BW_0_600(), 600_000, "0.600 MHz"), + BW_1_536(sdrplay_api_h.sdrplay_api_BW_1_536(), 1_536_000, "1.536 MHz"), + BW_5_000(sdrplay_api_h.sdrplay_api_BW_5_000(), 5_000_000, "5.000 MHz"), + BW_6_000(sdrplay_api_h.sdrplay_api_BW_6_000(), 6_000_000, "6.000 MHz"), + BW_7_000(sdrplay_api_h.sdrplay_api_BW_7_000(), 7_000_000, "7.000 MHz"), + BW_8_000(sdrplay_api_h.sdrplay_api_BW_8_000(), 8_000_000, "8.000 MHz"), + UNDEFINED(sdrplay_api_h.sdrplay_api_BW_Undefined(), 0, "UNDEFINED"); + + private int mValue; + private long mBandwidth; + private String mDescription; + + Bandwidth(int value, long bandwidth, String description) + { + mValue = value; + mBandwidth = bandwidth; + mDescription = description; + } + + /** + * Numeric value + */ + public int getValue() + { + return mValue; + } + + /** + * Bandwidth (Hz) + */ + public long getBandwidth() + { + return mBandwidth; + } + + /** + * Lookup the entry from a return code + * @param value to lookup + * @return entry or UNDEFINED if the code is not recognized + */ + public static Bandwidth fromValue(int value) + { + for(Bandwidth status: Bandwidth.values()) + { + if(status.getValue() == value) + { + return status; + } + } + + return UNDEFINED; + } + + @Override + public String toString() + { + return mDescription; + } +} diff --git a/jsdrplay/src/main/java/com/github/dsheirer/sdrplay/parameter/tuner/DcOffsetTuner.java b/jsdrplay/src/main/java/com/github/dsheirer/sdrplay/parameter/tuner/DcOffsetTuner.java new file mode 100644 index 000000000..46161bb8d --- /dev/null +++ b/jsdrplay/src/main/java/com/github/dsheirer/sdrplay/parameter/tuner/DcOffsetTuner.java @@ -0,0 +1,102 @@ +/* + * ***************************************************************************** + * 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.parameter.tuner; + +import com.github.dsheirer.sdrplay.api.v3_07.sdrplay_api_DcOffsetTunerT; +import com.github.dsheirer.sdrplay.util.Flag; + +import java.lang.foreign.MemorySegment; + +/** + * DC Offset Tuner structure (sdrplay_api_DcOffsetTunerT) + */ +public class DcOffsetTuner +{ + private MemorySegment mMemorySegment; + + /** + * Constructs an instance from the foreign memory segment + */ + public DcOffsetTuner(MemorySegment memorySegment) + { + mMemorySegment = memorySegment; + } + + /** + * Foreign memory segment for this structure + */ + private MemorySegment getMemorySegment() + { + return mMemorySegment; + } + + /** + * DC calibration mode. + * @return + */ + public int getDcCal() + { + return sdrplay_api_DcOffsetTunerT.dcCal$get(getMemorySegment()); + } + + public void setDcCal(int dcCal) + { + sdrplay_api_DcOffsetTunerT.dcCal$set(getMemorySegment(), (byte)dcCal); + } + + public boolean isSpeedUp() + { + return Flag.evaluate(sdrplay_api_DcOffsetTunerT.speedUp$get(getMemorySegment())); + } + + public void setSpeedUp(boolean speedUp) + { + sdrplay_api_DcOffsetTunerT.speedUp$set(getMemorySegment(), Flag.of(speedUp)); + } + + public int getTrackTime() + { + return sdrplay_api_DcOffsetTunerT.trackTime$get(getMemorySegment()); + } + + public void setTrackTime(int trackTime) + { + sdrplay_api_DcOffsetTunerT.trackTime$set(getMemorySegment(), trackTime); + } + + public int getRefreshRateTime() + { + return sdrplay_api_DcOffsetTunerT.refreshRateTime$get(getMemorySegment()); + } + + public void setRefreshRateTime(int refreshRateTime) + { + sdrplay_api_DcOffsetTunerT.refreshRateTime$set(getMemorySegment(), refreshRateTime); + } + + @Override + public String toString() + { + StringBuilder sb = new StringBuilder(); + sb.append("DC Cal:").append(getDcCal()).append(" Speed Up:").append(isSpeedUp()); + sb.append(" Track Time:").append(getTrackTime()).append(" Refresh Rate Time:").append(getRefreshRateTime()); + return sb.toString(); + } +} diff --git a/jsdrplay/src/main/java/com/github/dsheirer/sdrplay/parameter/tuner/FrequencyBand.java b/jsdrplay/src/main/java/com/github/dsheirer/sdrplay/parameter/tuner/FrequencyBand.java new file mode 100644 index 000000000..a8a7edf20 --- /dev/null +++ b/jsdrplay/src/main/java/com/github/dsheirer/sdrplay/parameter/tuner/FrequencyBand.java @@ -0,0 +1,104 @@ +/* + * ***************************************************************************** + * 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.parameter.tuner; + +import java.util.EnumSet; + +/** + * RSP Frequency Bands + */ +public enum FrequencyBand +{ + BAND_0_12(1_000, 12_000_000, "0.001-12 MHz"), + BAND_12_60(12_000_000, 60_000_000, "12-60 MHz"), + BAND_60_250(60_000_000, 250_000_000, "60-250 MHz"), + BAND_250_420(250_000_000, 420_000_000, "250-420 MHz"), + BAND_420_1000(420_000_000, 1_000_000_000, "420-1000 MHz"), + BAND_1000_2000(1_000_000_000, 2_000_000_000, "1000-2000 MHz"), + UNKNOWN(-1, 0,"UNKNOWN"); + + private long mMinimum; + private long mMaximum; + private String mDescription; + + FrequencyBand(long min, long max, String description) + { + mMinimum = min; + mMaximum = max; + mDescription = description; + } + + /** + * Valid frequency bands + */ + public static EnumSet VALID_FREQUENCY_BANDS = EnumSet.range(BAND_0_12, BAND_1000_2000); + + /** + * Minimum frequency + * @return frequency in Hertz + */ + public long getMinimum() + { + return mMinimum; + } + + /** + * Maximum frequency + * @return frequency in Hertz + */ + public long getMaximum() + { + return mMaximum; + } + + /** + * Lookup the entry from a return code + * @param frequency to lookup + * @return entry or UNKNOWN if the code is not recognized + */ + public static FrequencyBand fromValue(long frequency) + { + for(FrequencyBand band: FrequencyBand.values()) + { + if(band.contains(frequency)) + { + return band; + } + } + + return UNKNOWN; + } + + /** + * Indicates if this frequency band entry contains the specified frequency + * @param frequency to check + * @return true if this entry contains the frequency + */ + public boolean contains(long frequency) + { + return getMinimum() <= frequency && frequency < getMaximum(); + } + + @Override + public String toString() + { + return mDescription; + } +} diff --git a/jsdrplay/src/main/java/com/github/dsheirer/sdrplay/parameter/tuner/Gain.java b/jsdrplay/src/main/java/com/github/dsheirer/sdrplay/parameter/tuner/Gain.java new file mode 100644 index 000000000..187329361 --- /dev/null +++ b/jsdrplay/src/main/java/com/github/dsheirer/sdrplay/parameter/tuner/Gain.java @@ -0,0 +1,143 @@ +/* + * ***************************************************************************** + * 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.parameter.tuner; + +import com.github.dsheirer.sdrplay.api.v3_07.sdrplay_api_GainT; +import com.github.dsheirer.sdrplay.util.Flag; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import java.lang.foreign.MemorySegment; + +/** + * Gain structure (sdrplay_api_GainT) + */ +public class Gain +{ + private static final Logger mLog = LoggerFactory.getLogger(Gain.class); + + private MemorySegment mMemorySegment; + private GainValues mGainValues; + + /** + * Constructs an instance from the foreign memory segment + */ + public Gain(MemorySegment memorySegment) + { + mMemorySegment = memorySegment; + mGainValues = new GainValues(sdrplay_api_GainT.gainVals$slice(memorySegment)); + } + + /** + * Foreign memory segment for this structure + */ + private MemorySegment getMemorySegment() + { + return mMemorySegment; + } + + /** + * Sets the LNA state and gain reduction from the set of gain reduction values using the specified index + * @param gainReduction for the current frequency band + * @param index into the gain values to use for LNA state and gain reduction + */ + public void setGain(GainReduction gainReduction, int index) + { + setLNA(gainReduction.getLnaState(index)); + setGainReductionDb(gainReduction.getGainReduction(index)); + } + + /** + * Current gain reduction + * @return gain dB + */ + public int getGainReductionDb() + { + return sdrplay_api_GainT.gRdB$get(getMemorySegment()); + } + + /** + * Sets the gain reduction value + * @param gainReductionDb + */ + public void setGainReductionDb(int gainReductionDb) + { + sdrplay_api_GainT.gRdB$set(getMemorySegment(), gainReductionDb); + } + + /** + * Low Noise Amplifier (LNA) state/value + */ + public int getLNA() + { + return sdrplay_api_GainT.LNAstate$get(getMemorySegment()); + } + + /** + * Sets the Low Noise Amplifier (LNA) state + */ + public void setLNA(int lna) + { + sdrplay_api_GainT.LNAstate$set(getMemorySegment(), (byte)lna); + } + + /** + * Specifies if LNA and gain reduction changes should be applied synchronously + */ + public void setSynchronousUpdate(boolean syncUpdate) + { + sdrplay_api_GainT.syncUpdate$set(getMemorySegment(), Flag.of(syncUpdate)); + } + + /** + * Minimum gain reduction mode + */ + public MinimumGainReductionMode getMinimumGainReductionMode() + { + return MinimumGainReductionMode.fromValue(sdrplay_api_GainT.minGr$get(getMemorySegment())); + } + + /** + * Sets the minimum gain reduction mode + */ + public void setMinimumGainReductionMode(MinimumGainReductionMode minimumGainReductionMode) + { + sdrplay_api_GainT.minGr$set(getMemorySegment(), minimumGainReductionMode.getValue()); + } + + /** + * Gain values structure + */ + public GainValues getGainValues() + { + return mGainValues; + } + + @Override + public String toString() + { + StringBuilder sb = new StringBuilder(); + sb.append("Reduction:").append(getGainReductionDb()).append("dB"); + sb.append(" LNA:").append(getLNA()); + sb.append(" Min Gain Reduction Mode:").append(getMinimumGainReductionMode()); + sb.append(" Gain Values:").append(getGainValues()); + return sb.toString(); + } +} diff --git a/jsdrplay/src/main/java/com/github/dsheirer/sdrplay/parameter/tuner/GainReduction.java b/jsdrplay/src/main/java/com/github/dsheirer/sdrplay/parameter/tuner/GainReduction.java new file mode 100644 index 000000000..62cb0ee4e --- /dev/null +++ b/jsdrplay/src/main/java/com/github/dsheirer/sdrplay/parameter/tuner/GainReduction.java @@ -0,0 +1,354 @@ +/* + * ***************************************************************************** + * 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.parameter.tuner; + +import com.github.dsheirer.sdrplay.device.DeviceType; +import java.util.EnumSet; + +/** + * RSP Gain Reduction values and LNA states for each RSP model. + * + * Use lookup() as convenience method to find a gain reduction entry for a device type and frequency band. + * + * Reference: SDRplay API Specification, Gain Reduction Tables + * and https://github.com/SDRplay/RSPTCPServer/blob/master/rsp_tcp.c + */ +public enum GainReduction +{ + RSP1_BAND_0_12(FrequencyBand.BAND_0_12, + new int[]{ 3, 3, 3, 3, 3, 3, 3, 1, 1, 1, 1, 1, 1, 2, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, + new int[]{ 59,56,53,50,47,44,41,58,55,52,49,46,43,45,42,58,55,52,49,46,43,41,38,35,32,29,26,23,20 }), + RSP1_BAND_12_60(FrequencyBand.BAND_12_60, + new int[]{ 3, 3, 3, 3, 3, 3, 3, 1, 1, 1, 1, 1, 1, 2, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, + new int[]{ 59,56,53,50,47,44,41,58,55,52,49,46,43,45,42,58,55,52,49,46,43,41,38,35,32,29,26,23,20 }), + RSP1_BAND_60_250(FrequencyBand.BAND_60_250, + new int[]{ 3, 3, 3, 3, 3, 3, 3, 1, 1, 1, 1, 1, 1, 2, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, + new int[]{ 59,56,53,50,47,44,41,58,55,52,49,46,43,45,42,58,55,52,49,46,43,41,38,35,32,29,26,23,20 }), + RSP1_BAND_250_420(FrequencyBand.BAND_250_420, + new int[]{ 3, 3, 3, 3, 3, 3, 3, 1, 1, 1, 1, 1, 1, 2, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, + new int[]{ 59,56,53,50,47,44,41,58,55,52,49,46,43,45,42,58,55,52,49,46,43,41,38,35,32,29,26,23,20 }), + RSP1_BAND_420_1000(FrequencyBand.BAND_420_1000, + new int[]{ 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 2, 2, 2, 1, 1, 1, 1, 1, 0, 0, 0, 0 }, + new int[]{ 59,57,54,52,50,47,45,43,40,38,36,33,31,29,27,24,22,27,24,22,32,29,27,25,22,27,25,22,20 }), + RSP1_BAND_1000_2000(FrequencyBand.BAND_1000_2000, + new int[]{ 3, 3, 3, 3, 3, 3, 3, 3, 3, 2, 2, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, + new int[]{ 59,57,55,52,50,48,46,43,41,44,42,53,51,49,47,44,42,45,43,40,38,36,34,31,29,27,25,22,20 }), + + RSP1A_BAND_0_12(FrequencyBand.BAND_0_12, + new int[]{ 6, 6, 6, 6, 6, 6, 5, 5, 5, 5, 5, 4, 4, 3, 3, 3, 3, 3, 2, 2, 1, 0, 0, 0, 0, 0, 0, 0, 0 }, + new int[]{ 59,55,52,48,45,41,57,53,49,46,42,44,40,56,52,48,45,41,44,40,43,45,41,38,34,31,27,24,20 }), + RSP1A_BAND_12_60(FrequencyBand.BAND_12_60, + new int[]{ 9, 9, 9, 9, 9, 9, 8, 7, 7, 7, 7, 7, 6, 6, 5, 5, 4, 3, 2, 2, 1, 0, 0, 0, 0, 0, 0, 0, 0 }, + new int[]{ 59,55,52,48,45,41,42,58,54,51,47,43,46,42,44,41,43,42,44,40,43,45,42,38,34,31,27,24,20 }), + RSP1A_BAND_60_250(FrequencyBand.BAND_60_250, + new int[]{ 9, 9, 9, 9, 9, 9, 8, 7, 7, 7, 7, 7, 6, 6, 5, 5, 4, 3, 2, 2, 1, 0, 0, 0, 0, 0, 0, 0, 0 }, + new int[]{ 59,55,52,48,45,41,42,58,54,51,47,43,46,42,44,41,43,42,44,40,43,45,42,38,34,31,27,24,20 }), + RSP1A_BAND_250_420(FrequencyBand.BAND_250_420, + new int[]{ 9, 9, 9, 9, 9, 9, 8, 7, 7, 7, 7, 7, 6, 6, 5, 5, 4, 3, 2, 2, 1, 0, 0, 0, 0, 0, 0, 0, 0 }, + new int[]{ 59,55,52,48,45,41,42,58,54,51,47,43,46,42,44,41,43,42,44,40,43,45,42,38,34,31,27,24,20 }), + RSP1A_BAND_420_1000(FrequencyBand.BAND_420_1000, + new int[]{ 9, 9, 9, 9, 9, 9, 8, 8, 8, 8, 8, 7, 6, 6, 5, 5, 4, 4, 2, 2, 1, 0, 0, 0, 0, 0, 0, 0, 0 }, + new int[]{ 59,55,52,48,44,41,56,52,49,45,41,44,46,42,45,41,44,40,44,40,42,46,42,38,35,31,27,24,20 }), + RSP1A_BAND_1000_2000(FrequencyBand.BAND_1000_2000, + new int[]{ 8, 8, 8, 8, 8, 8, 7, 7, 7, 7, 7, 6, 5, 5, 4, 4, 3, 2, 2, 2, 1, 0, 0, 0, 0, 0, 0, 0, 0 }, + new int[]{ 59,55,52,48,45,41,56,53,49,46,42,43,46,42,44,41,43,48,44,40,43,45,42,38,34,31,27,24,20 }), + + RSP2_BAND_0_12(FrequencyBand.BAND_0_12, + new int[]{ 8, 8, 8, 8, 8, 8, 7, 7, 7, 7, 7, 6, 5, 5, 4, 4, 4, 2, 2, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, + new int[]{ 59,55,52,48,44,41,56,52,49,45,41,44,45,41,48,44,40,45,42,43,49,46,42,38,35,31,27,24,20 }), + RSP2_BAND_12_60(FrequencyBand.BAND_12_60, + new int[]{ 8, 8, 8, 8, 8, 8, 7, 7, 7, 7, 7, 6, 5, 5, 4, 4, 4, 2, 2, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, + new int[]{ 59,55,52,48,44,41,56,52,49,45,41,44,45,41,48,44,40,45,42,43,49,46,42,38,35,31,27,24,20 }), + RSP2_BAND_60_250(FrequencyBand.BAND_60_250, + new int[]{ 8, 8, 8, 8, 8, 8, 7, 7, 7, 7, 7, 6, 5, 5, 4, 4, 4, 2, 2, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, + new int[]{ 59,55,52,48,44,41,56,52,49,45,41,44,45,41,48,44,40,45,42,43,49,46,42,38,35,31,27,24,20 }), + RSP2_BAND_250_420(FrequencyBand.BAND_250_420, + new int[]{ 8, 8, 8, 8, 8, 8, 7, 7, 7, 7, 7, 6, 5, 5, 4, 4, 4, 2, 2, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, + new int[]{ 59,55,52,48,44,41,56,52,49,45,41,44,45,41,48,44,40,45,42,43,49,46,42,38,35,31,27,24,20 }), + RSP2_BAND_420_1000(FrequencyBand.BAND_420_1000, + new int[]{ 5, 5, 5, 5, 5, 5, 5, 4, 4, 4, 4, 4, 4, 4, 3, 3, 2, 2, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, + new int[]{ 59,56,53,50,48,45,42,58,55,52,49,47,44,41,43,40,44,41,42,46,43,40,37,34,31,29,26,23,20 }), + RSP2_BAND_1000_2000(FrequencyBand.BAND_1000_2000, + new int[]{ 4, 4, 4, 4, 4, 4, 4, 4, 3, 3, 3, 3, 3, 3, 3, 2, 2, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, + new int[]{ 59,56,54,51,48,45,43,40,56,54,51,48,45,43,40,43,41,44,41,44,42,39,36,34,31,28,25,23,20 }), + + RSP_DUO_BAND_0_12(FrequencyBand.BAND_0_12, + new int[]{ 6, 6, 6, 6, 6, 6, 5, 5, 5, 5, 5, 4, 4, 3, 3, 3, 3, 3, 2, 2, 1, 0, 0, 0, 0, 0, 0, 0, 0 }, + new int[]{ 59,55,52,48,45,41,57,53,49,46,42,44,40,56,52,48,45,41,44,40,43,45,41,38,34,31,27,24,20 }), + RSP_DUO_BAND_12_60(FrequencyBand.BAND_12_60, + new int[]{ 9, 9, 9, 9, 9, 9, 8, 7, 7, 7, 7, 7, 6, 6, 5, 5, 4, 3, 2, 2, 1, 0, 0, 0, 0, 0, 0, 0, 0 }, + new int[]{ 59,55,52,48,45,41,42,58,54,51,47,43,46,42,44,41,43,42,44,40,43,45,42,38,34,31,27,24,20 }), + RSP_DUO_BAND_60_250(FrequencyBand.BAND_60_250, + new int[]{ 9, 9, 9, 9, 9, 9, 8, 7, 7, 7, 7, 7, 6, 6, 5, 5, 4, 3, 2, 2, 1, 0, 0, 0, 0, 0, 0, 0, 0 }, + new int[]{ 59,55,52,48,45,41,42,58,54,51,47,43,46,42,44,41,43,42,44,40,43,45,42,38,34,31,27,24,20 }), + RSP_DUO_BAND_250_420(FrequencyBand.BAND_250_420, + new int[]{ 9, 9, 9, 9, 9, 9, 8, 7, 7, 7, 7, 7, 6, 6, 5, 5, 4, 3, 2, 2, 1, 0, 0, 0, 0, 0, 0, 0, 0 }, + new int[]{ 59,55,52,48,45,41,42,58,54,51,47,43,46,42,44,41,43,42,44,40,43,45,42,38,34,31,27,24,20 }), + RSP_DUO_BAND_420_1000(FrequencyBand.BAND_420_1000, + new int[]{ 9, 9, 9, 9, 9, 9, 8, 8, 8, 8, 8, 7, 6, 6, 5, 5, 4, 4, 2, 2, 1, 0, 0, 0, 0, 0, 0, 0, 0 }, + new int[]{ 59,55,52,48,44,41,56,52,49,45,41,44,46,42,45,41,44,40,44,40,42,46,42,38,35,31,27,24,20 }), + RSP_DUO_BAND_1000_2000(FrequencyBand.BAND_1000_2000, + new int[]{ 8, 8, 8, 8, 8, 8, 7, 7, 7, 7, 7, 6, 5, 5, 4, 4, 3, 2, 2, 2, 1, 0, 0, 0, 0, 0, 0, 0, 0 }, + new int[]{ 59,55,52,48,45,41,56,53,49,46,42,43,46,42,44,41,43,48,44,40,43,45,42,38,34,31,27,24,20 }), + + RSP_DX_BAND_0_12(FrequencyBand.BAND_0_12, + new int[]{ 18,18,18,18,18,18,17,16,14,13,12,11,10, 9, 7, 6, 5, 5, 5, 3, 2, 1, 0, 0, 0, 0, 0, 0, 0 }, + new int[]{ 59,55,52,48,45,41,41,40,43,42,42,41,41,40,42,42,47,44,40,43,42,42,41,38,34,31,27,24,20 }), + RSP_DX_BAND_12_60(FrequencyBand.BAND_12_60, + new int[]{ 26,26,26,26,26,25,23,22,20,19,17,16,14,13,11,10, 8, 7, 5, 5, 5, 3, 2, 0, 0, 0, 0, 0, 0 }, + new int[]{ 59,55,50,46,41,40,42,40,42,40,42,41,42,41,43,41,43,41,49,45,40,42,40,42,38,33,29,24,20 }), + RSP_DX_BAND_60_250(FrequencyBand.BAND_60_250, + new int[]{ 26,26,26,26,26,25,23,22,20,19,17,16,14,13,11,10, 8, 7, 5, 5, 5, 3, 2, 0, 0, 0, 0, 0, 0 }, + new int[]{ 59,55,50,46,41,40,42,40,42,40,42,41,42,41,43,41,43,41,49,45,40,42,40,42,38,33,29,24,20 }), + RSP_DX_BAND_250_420(FrequencyBand.BAND_250_420, + new int[]{ 27,27,27,27,27,26,24,23,21,20,18,17,15,14,12,11, 9, 8, 6, 6, 5, 3, 2, 0, 0, 0, 0, 0, 0 }, + new int[]{ 59,55,50,46,41,40,42,40,42,40,42,41,42,41,43,41,43,41,46,42,40,42,40,42,38,33,29,24,20 }), + RSP_DX_BAND_420_1000(FrequencyBand.BAND_420_1000, + new int[]{ 20,20,20,20,20,20,18,17,16,14,13,12,11, 9, 8, 7, 7, 5, 4, 3, 2, 0, 0, 0, 0, 0, 0, 0, 0 }, + new int[]{ 59,55,51,48,44,40,42,42,41,43,42,41,41,43,42,44,40,43,42,41,40,46,43,39,35,31,28,24,20 }), + RSP_DX_BAND_1000_2000(FrequencyBand.BAND_1000_2000, + new int[]{ 18,18,18,18,18,18,16,15,14,13,11,10, 9, 8, 7, 6, 6, 6, 5, 3, 2, 1, 0, 0, 0, 0, 0, 0, 0 }, + new int[]{ 59,55,52,48,44,40,43,42,41,41,43,42,41,41,40,48,45,41,40,42,42,41,42,39,35,31,27,24,20 }), + + //HiZ Port - RSP2 and RSPduo + RSP_2_AND_DUO_HIZ_BAND_0_12(FrequencyBand.BAND_0_12, + new int[]{ 4, 4, 4, 4, 4, 4, 4, 4, 3, 3, 3, 3, 3, 3, 3, 2, 2, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, + new int[]{ 59,56,54,51,48,45,43,40,56,54,51,48,45,43,40,43,41,44,41,44,42,39,36,34,31,28,25,23,20 }), + RSP_2_AND_DUO_HIZ_BAND_12_60(FrequencyBand.BAND_12_60, + new int[]{ 4, 4, 4, 4, 4, 4, 4, 4, 3, 3, 3, 3, 3, 3, 3, 2, 2, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, + new int[]{ 59,56,54,51,48,45,43,40,56,54,51,48,45,43,40,43,41,44,41,44,42,39,36,34,31,28,25,23,20 }), + + //RSPdx HDR Mode + RSP_DX_HDR_BAND_0_2(FrequencyBand.BAND_0_12, + new int[]{ 18,18,18,18,18,18,17,16,14,13,12,11,10, 9, 7, 6, 5, 5, 5, 3, 2, 1, 0, 0, 0, 0, 0, 0, 0 }, + new int[]{ 59,55,52,48,45,41,41,40,43,42,42,41,41,40,42,42,47,44,40,43,42,42,41,38,34,31,27,24,20 }), + + UNKNOWN(FrequencyBand.UNKNOWN, new int[]{}, new int[]{}); + + private FrequencyBand mFrequencyBand; + private int[] mLnaStates; + private int[] mGainReductions; + + GainReduction(FrequencyBand frequencyBand, int[] lnaStates, int[] gainReductions) + { + mFrequencyBand = frequencyBand; + mLnaStates = lnaStates; + mGainReductions = gainReductions; + } + + /** + * Identifies the index of the gain reduction value from the array of possible gain reduction values. + * @param gainReductionValue to lookup index + * @return matching index or -1 if a matching index is not found. + */ + public int getGainIndex(int gainReductionValue) + { + for(int x = 0; x < mGainReductions.length; x++) + { + if(mGainReductions[x] == gainReductionValue) + { + return x; + } + } + + return -1; + } + + /** + * Minimum index for gain values + */ + public static int MIN_GAIN_INDEX = 0; + + /** + * Maximum index for gain values + */ + public static int MAX_GAIN_INDEX = 28; + + /** + * Number of discrete gain steps available for each entry + */ + public static int GAIN_STEPS_AVAILABLE = 29; + + /** + * RSP1 Gain Reduction Tables + */ + public static EnumSet RSP_1_GAINS = EnumSet.range(RSP1_BAND_0_12, RSP1_BAND_1000_2000); + + /** + * RSP1A Gain Reduction Tables + */ + public static EnumSet RSP_1A_GAINS = EnumSet.range(RSP1A_BAND_0_12, RSP1A_BAND_1000_2000); + + /** + * RSP2 Gain Reduction Tables + */ + public static EnumSet RSP_2_GAINS = EnumSet.range(RSP2_BAND_0_12, RSP2_BAND_1000_2000); + + /** + * RSPduo Gain Reduction Tables + */ + public static EnumSet RSP_DUO_GAINS = EnumSet.range(RSP_DUO_BAND_0_12, RSP_DUO_BAND_1000_2000); + + /** + * RSPdx Gain Reduction Tables + */ + public static EnumSet RSP_DX_GAINS = EnumSet.range(RSP_DX_BAND_0_12, RSP_DX_BAND_1000_2000); + + /** + * RSPdx HDR Mode Gain Reduction Tables + */ + public static EnumSet RSP_DX_HDR_GAINS = EnumSet.of(RSP_DX_HDR_BAND_0_2); + + /** + * RSP2 and RSPduo HiZ Port Gain Reduction Tables + */ + public static EnumSet RSP_HIZ_GAINS = EnumSet.range(RSP_2_AND_DUO_HIZ_BAND_0_12, RSP_2_AND_DUO_HIZ_BAND_12_60); + + /** + * Lookup the gain reduction entry for a device that matches the frequency band. + * + * Note: directly use the RSP_DX_HDR_GAINS and RSP_HIZ_GAINS enumeration sets to match for HDR or HIZ modes. + * + * @param deviceType to lookup + * @param frequencyBand to match + * @return entry or UNKNOWN + */ + public static GainReduction lookup(DeviceType deviceType, FrequencyBand frequencyBand) + { + switch(deviceType) + { + case RSP1 -> { + return fromBand(frequencyBand, RSP_1_GAINS); + } + case RSP1A -> { + return fromBand(frequencyBand, RSP_1A_GAINS); + } + case RSP2 -> { + return fromBand(frequencyBand, RSP_2_GAINS); + } + case RSPduo -> { + return fromBand(frequencyBand, RSP_DUO_GAINS); + } + case RSPdx -> { + return fromBand(frequencyBand, RSP_DX_GAINS); + } + } + + return UNKNOWN; + } + + /** + * Lookup the gain reduction entry for a device that matches the specified frequency + * @param deviceType to lookup + * @param frequency to map to a frequency band + * @return gain reduction entry or UNKNOWN + */ + public static GainReduction lookup(DeviceType deviceType, long frequency) + { + FrequencyBand band = FrequencyBand.fromValue(frequency); + return lookup(deviceType, band); + } + + /** + * Look up the gain reduction value that matches the frequency band from the set of gain reduction values. + * @param frequencyBand to lookup + * @param values to choose from + * @return matching entry or UNKNOWN + */ + private static GainReduction fromBand(FrequencyBand frequencyBand, EnumSet values) + { + for(GainReduction gainReduction: values) + { + if(gainReduction.getFrequencyBand() == frequencyBand) + { + return gainReduction; + } + } + + return UNKNOWN; + } + + /** + * Frequency band for the range of LNA state and gain reduction values. + */ + public FrequencyBand getFrequencyBand() + { + return mFrequencyBand; + } + + /** + * Array of LNA states + */ + private int[] getLnaStates() + { + return mLnaStates; + } + + /** + * Array of gain reduction values + */ + private int[] getGainReductions() + { + return mGainReductions; + } + + /** + * LNA state value for the specified gain index + * @param index for the gain (0 - 29) + * @return lna state + */ + public int getLnaState(int index) + { + if(MIN_GAIN_INDEX <= index && index <= MAX_GAIN_INDEX) + { + return getLnaStates()[index]; + } + + throw new IllegalArgumentException("Unrecognized gain index [" + index + "] - valid range: " + + MIN_GAIN_INDEX + " <> " + MAX_GAIN_INDEX); + } + + /** + * Gain reduction value for the specified gain index + * @param index for the gain (0 - 29) + * @return gain reduction value (dB) + */ + public int getGainReduction(int index) + { + if(MIN_GAIN_INDEX <= index && index <= MAX_GAIN_INDEX) + { + return getGainReductions()[index]; + } + + throw new IllegalArgumentException("Unrecognized gain index [" + index + "] - valid range: " + + MIN_GAIN_INDEX + " <> " + MAX_GAIN_INDEX); + } + + /** + * Indicates if this gain reduction entry is valid for the specified frequency by checking the frequency band + * of this entry and testing for containment. + * @param frequency to check + * @return true if the frequency is contained in the frequency band for this entry. + */ + public boolean isValidFor(long frequency) + { + return getFrequencyBand().contains(frequency); + } +} diff --git a/jsdrplay/src/main/java/com/github/dsheirer/sdrplay/parameter/tuner/GainValues.java b/jsdrplay/src/main/java/com/github/dsheirer/sdrplay/parameter/tuner/GainValues.java new file mode 100644 index 000000000..6e2a617c0 --- /dev/null +++ b/jsdrplay/src/main/java/com/github/dsheirer/sdrplay/parameter/tuner/GainValues.java @@ -0,0 +1,74 @@ +/* + * ***************************************************************************** + * 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.parameter.tuner; + +import com.github.dsheirer.sdrplay.api.v3_07.sdrplay_api_GainValuesT; + +import java.lang.foreign.MemorySegment; + +/** + * Gain Values structure (sdrplay_api_GainValuesT) + * + * Note: these are output parameters, so there are no setter methods. + */ +public class GainValues +{ + private MemorySegment mMemorySegment; + + /** + * Constructs an instance from the foreign memory segment + */ + public GainValues(MemorySegment memorySegment) + { + mMemorySegment = memorySegment; + } + + /** + * Foreign memory segment for this structure + */ + private MemorySegment getMemorySegment() + { + return mMemorySegment; + } + + + public float getCurrent() + { + return sdrplay_api_GainValuesT.curr$get(getMemorySegment()); + } + + public float getMax() + { + return sdrplay_api_GainValuesT.max$get(getMemorySegment()); + } + + public float getMin() + { + return sdrplay_api_GainValuesT.min$get(getMemorySegment()); + } + + @Override + public String toString() + { + StringBuilder sb = new StringBuilder(); + sb.append("Current:").append(getCurrent()).append(" Max:").append(getMax()).append(" Min:").append(getMin()); + return sb.toString(); + } +} diff --git a/jsdrplay/src/main/java/com/github/dsheirer/sdrplay/parameter/tuner/HdrModeBandwidth.java b/jsdrplay/src/main/java/com/github/dsheirer/sdrplay/parameter/tuner/HdrModeBandwidth.java new file mode 100644 index 000000000..5990e50a6 --- /dev/null +++ b/jsdrplay/src/main/java/com/github/dsheirer/sdrplay/parameter/tuner/HdrModeBandwidth.java @@ -0,0 +1,85 @@ +/* + * ***************************************************************************** + * 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.parameter.tuner; + +import com.github.dsheirer.sdrplay.api.v3_07.sdrplay_api_h; + +/** + * RSPdx High Dynamic Range (HDR) Mode Bandwidth + */ +public enum HdrModeBandwidth +{ + BANDWIDTH_0_200(sdrplay_api_h.sdrplay_api_RspDx_HDRMODE_BW_0_200(), 200_000, ".2 MHz"), + BANDWIDTH_0_500(sdrplay_api_h.sdrplay_api_RspDx_HDRMODE_BW_0_500(), 500_000, ".5 MHz"), + BANDWIDTH_1_200(sdrplay_api_h.sdrplay_api_RspDx_HDRMODE_BW_1_200(), 1_200_000, "1.2 MHz"), + BANDWIDTH_1_700(sdrplay_api_h.sdrplay_api_RspDx_HDRMODE_BW_1_700(), 1_700_000, "1.7 MHz"), + UNKNOWN(-1, 0, "UNKNOWN"); + + private int mValue; + private long mBandwidth; + private String mDescription; + + HdrModeBandwidth(int value, long bandwidth, String description) + { + mValue = value; + mBandwidth = bandwidth; + mDescription = description; + } + + /** + * Numeric value + */ + public int getValue() + { + return mValue; + } + + /** + * Bandwidth in Hertz + */ + public long getBandwidth() + { + return mBandwidth; + } + + /** + * Lookup the entry from a return code + * @param value to lookup + * @return entry or UKNOWN if the code is not recognized + */ + public static HdrModeBandwidth fromValue(int value) + { + for(HdrModeBandwidth status: HdrModeBandwidth.values()) + { + if(status.getValue() == value) + { + return status; + } + } + + return UNKNOWN; + } + + @Override + public String toString() + { + return mDescription; + } +} diff --git a/jsdrplay/src/main/java/com/github/dsheirer/sdrplay/parameter/tuner/IfMode.java b/jsdrplay/src/main/java/com/github/dsheirer/sdrplay/parameter/tuner/IfMode.java new file mode 100644 index 000000000..43b125016 --- /dev/null +++ b/jsdrplay/src/main/java/com/github/dsheirer/sdrplay/parameter/tuner/IfMode.java @@ -0,0 +1,83 @@ +/* + * ***************************************************************************** + * 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.parameter.tuner; + +import com.github.dsheirer.sdrplay.api.v3_07.sdrplay_api_h; + +/** + * Intermediate Frequency (IF) Mode / Frequency + */ +public enum IfMode +{ + IF_ZERO(sdrplay_api_h.sdrplay_api_IF_Zero(), "ZIF 0.000 MHz"), + IF_450(sdrplay_api_h.sdrplay_api_IF_0_450(), "0.450 MHz"), + IF_1620(sdrplay_api_h.sdrplay_api_IF_1_620(), "1.620 MHz"), + IF_2048(sdrplay_api_h.sdrplay_api_IF_2_048(), "2.048 MHz"), + UNDEFINED(sdrplay_api_h.sdrplay_api_IF_Undefined(), "UNDEFINED"); + + private int mValue; + private String mDescription; + + IfMode(int value, String description) + { + mValue = value; + mDescription = description; + } + + /** + * Indicates the wideband enable decimation setting to use for this IF value. + */ + public boolean isWidebandSignal() + { + return this.equals(IF_ZERO); + } + + /** + * Numeric value + */ + public int getValue() + { + return mValue; + } + + /** + * Lookup the entry from a return code + * @param value to lookup + * @return entry or UNKNOWN if the code is not recognized + */ + public static IfMode fromValue(int value) + { + for(IfMode status: IfMode.values()) + { + if(status.getValue() == value) + { + return status; + } + } + + return UNDEFINED; + } + + @Override + public String toString() + { + return mDescription; + } +} diff --git a/jsdrplay/src/main/java/com/github/dsheirer/sdrplay/parameter/tuner/LoMode.java b/jsdrplay/src/main/java/com/github/dsheirer/sdrplay/parameter/tuner/LoMode.java new file mode 100644 index 000000000..dd09bacfd --- /dev/null +++ b/jsdrplay/src/main/java/com/github/dsheirer/sdrplay/parameter/tuner/LoMode.java @@ -0,0 +1,75 @@ +/* + * ***************************************************************************** + * 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.parameter.tuner; + +import com.github.dsheirer.sdrplay.api.v3_07.sdrplay_api_h; + +/** + * Local Oscillator Mode + */ +public enum LoMode +{ + AUTO(sdrplay_api_h.sdrplay_api_LO_Auto(), "AUTO"), + MHZ_120(sdrplay_api_h.sdrplay_api_LO_120MHz(), "120 MHz"), + MHZ_144(sdrplay_api_h.sdrplay_api_LO_144MHz(), "144 MHz"), + MHZ_168(sdrplay_api_h.sdrplay_api_LO_168MHz(), "168 MHz"), + UNDEFINED(sdrplay_api_h.sdrplay_api_LO_Undefined(), "UNDEFINED"); + + private int mValue; + private String mDescription; + + LoMode(int value, String description) + { + mValue = value; + mDescription = description; + } + + /** + * Numeric value + */ + public int getValue() + { + return mValue; + } + + /** + * Lookup the entry from a return code + * @param value to lookup + * @return entry or UNKNOWN if the code is not recognized + */ + public static LoMode fromValue(int value) + { + for(LoMode status: LoMode.values()) + { + if(status.getValue() == value) + { + return status; + } + } + + return UNDEFINED; + } + + @Override + public String toString() + { + return mDescription; + } +} diff --git a/jsdrplay/src/main/java/com/github/dsheirer/sdrplay/parameter/tuner/MinimumGainReductionMode.java b/jsdrplay/src/main/java/com/github/dsheirer/sdrplay/parameter/tuner/MinimumGainReductionMode.java new file mode 100644 index 000000000..26c9b53c6 --- /dev/null +++ b/jsdrplay/src/main/java/com/github/dsheirer/sdrplay/parameter/tuner/MinimumGainReductionMode.java @@ -0,0 +1,73 @@ +/* + * ***************************************************************************** + * 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.parameter.tuner; + +import com.github.dsheirer.sdrplay.api.v3_07.sdrplay_api_h; + +/** + * Minimum Gain Reduction (mode) + */ +public enum MinimumGainReductionMode +{ + EXTENDED(sdrplay_api_h.sdrplay_api_EXTENDED_MIN_GR(), "EXTENDED"), + NORMAL(sdrplay_api_h.sdrplay_api_NORMAL_MIN_GR(), "NORMAL"), + UNKNOWN(-1, "UNKNOWN"); + + private int mValue; + private String mDescription; + + MinimumGainReductionMode(int value, String description) + { + mValue = value; + mDescription = description; + } + + /** + * Numeric value + */ + public int getValue() + { + return mValue; + } + + /** + * Lookup the entry from a return code + * @param value to lookup + * @return entry or UNKNOWN if the code is not recognized + */ + public static MinimumGainReductionMode fromValue(int value) + { + for(MinimumGainReductionMode status: MinimumGainReductionMode.values()) + { + if(status.getValue() == value) + { + return status; + } + } + + return UNKNOWN; + } + + @Override + public String toString() + { + return mDescription; + } +} diff --git a/jsdrplay/src/main/java/com/github/dsheirer/sdrplay/parameter/tuner/RfFrequency.java b/jsdrplay/src/main/java/com/github/dsheirer/sdrplay/parameter/tuner/RfFrequency.java new file mode 100644 index 000000000..7fc08a854 --- /dev/null +++ b/jsdrplay/src/main/java/com/github/dsheirer/sdrplay/parameter/tuner/RfFrequency.java @@ -0,0 +1,95 @@ +/* + * ***************************************************************************** + * 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.parameter.tuner; + +import com.github.dsheirer.sdrplay.SDRPlayException; +import com.github.dsheirer.sdrplay.api.v3_07.sdrplay_api_RfFreqT; +import com.github.dsheirer.sdrplay.util.Flag; + +import java.lang.foreign.MemorySegment; + +/** + * RF Frequency structure (sdrplay_api_RfFreqT) + */ +public class RfFrequency +{ + private static final double MINIMUM_FREQUENCY = 1_200; + private static final double MAXIMUM_FREQUENCY = 2_000_000_000; + private MemorySegment mMemorySegment; + + /** + * Constructs an instance from the foreign memory segment + * @param memorySegment representing the structure + */ + public RfFrequency(MemorySegment memorySegment) + { + mMemorySegment = memorySegment; + } + + private MemorySegment getMemorySegment() + { + return mMemorySegment; + } + + /** + * RF Frequency + * @return frequency in Hertz + */ + public double getFrequency() + { + return sdrplay_api_RfFreqT.rfHz$get(getMemorySegment()); + } + + /** + * Sets the RF frequency + * @param frequency (0 < frequency <= 2,000,000,000 Hz) + * @param synchronousUpdate to set the frequency as a synchronous update + * @throws SDRPlayException for an invalid frequency (ie out of valid range) + */ + public void setFrequency(double frequency, boolean synchronousUpdate) throws SDRPlayException + { + if(MINIMUM_FREQUENCY < frequency && frequency <= MAXIMUM_FREQUENCY) + { + sdrplay_api_RfFreqT.rfHz$set(getMemorySegment(), frequency); + sdrplay_api_RfFreqT.syncUpdate$set(getMemorySegment(), Flag.of(synchronousUpdate)); + } + else + { + throw new SDRPlayException("Invalid frequency: " + frequency + " - valid range: " + + MINIMUM_FREQUENCY + "-" + MAXIMUM_FREQUENCY); + } + } + + /** + * Sets the RF frequency as a synchronous update + */ + public void setFrequency(double frequency) throws SDRPlayException + { + setFrequency(frequency, true); + } + + @Override + public String toString() + { + StringBuilder sb = new StringBuilder(); + sb.append("Frequency:").append(getFrequency()); + return sb.toString(); + } +} diff --git a/jsdrplay/src/main/java/com/github/dsheirer/sdrplay/parameter/tuner/Rsp1TunerParameters.java b/jsdrplay/src/main/java/com/github/dsheirer/sdrplay/parameter/tuner/Rsp1TunerParameters.java new file mode 100644 index 000000000..6b1dfd114 --- /dev/null +++ b/jsdrplay/src/main/java/com/github/dsheirer/sdrplay/parameter/tuner/Rsp1TunerParameters.java @@ -0,0 +1,38 @@ +/* + * ***************************************************************************** + * 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.parameter.tuner; + +import java.lang.foreign.MemorySegment; + +/** + * RSP1 Tuner Parameters structure + * + * Note: the RSP1 doesn't have any additional settings beyond the basic tuner parameters + */ +public class Rsp1TunerParameters extends TunerParameters +{ + /** + * Constructs an instance from the foreign memory segment. + */ + public Rsp1TunerParameters(MemorySegment tunerParametersMemorySegment) + { + super(tunerParametersMemorySegment); + } +} diff --git a/jsdrplay/src/main/java/com/github/dsheirer/sdrplay/parameter/tuner/Rsp1aTunerParameters.java b/jsdrplay/src/main/java/com/github/dsheirer/sdrplay/parameter/tuner/Rsp1aTunerParameters.java new file mode 100644 index 000000000..459e7c7e5 --- /dev/null +++ b/jsdrplay/src/main/java/com/github/dsheirer/sdrplay/parameter/tuner/Rsp1aTunerParameters.java @@ -0,0 +1,66 @@ +/* + * ***************************************************************************** + * 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.parameter.tuner; + +import com.github.dsheirer.sdrplay.api.v3_07.sdrplay_api_Rsp1aTunerParamsT; +import com.github.dsheirer.sdrplay.util.Flag; + +import java.lang.foreign.MemorySegment; + +/** + * RSP-1A Tuner Parameters structure + */ +public class Rsp1aTunerParameters extends TunerParameters +{ + private MemorySegment mRsp1aMemorySegment; + + /** + * Constructs an instance from the foreign memory segment. + */ + public Rsp1aTunerParameters(MemorySegment tunerParametersMemorySegment, MemorySegment rsp1aMemorySegment) + { + super(tunerParametersMemorySegment); + mRsp1aMemorySegment = rsp1aMemorySegment; + } + + /** + * Foreign memory segment for this structure + */ + private MemorySegment getRsp1aMemorySegment() + { + return mRsp1aMemorySegment; + } + + /** + * Indicates if the Bias-T is enabled + */ + public boolean isBiasT() + { + return Flag.evaluate(sdrplay_api_Rsp1aTunerParamsT.biasTEnable$get(getRsp1aMemorySegment())); + } + + /** + * Enable or disable the Bias-T + */ + public void setBiasT(boolean enable) + { + sdrplay_api_Rsp1aTunerParamsT.biasTEnable$set(getRsp1aMemorySegment(), Flag.of(enable)); + } +} diff --git a/jsdrplay/src/main/java/com/github/dsheirer/sdrplay/parameter/tuner/Rsp2AmPort.java b/jsdrplay/src/main/java/com/github/dsheirer/sdrplay/parameter/tuner/Rsp2AmPort.java new file mode 100644 index 000000000..a0914a738 --- /dev/null +++ b/jsdrplay/src/main/java/com/github/dsheirer/sdrplay/parameter/tuner/Rsp2AmPort.java @@ -0,0 +1,72 @@ +/* + * ***************************************************************************** + * 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.parameter.tuner; + +import com.github.dsheirer.sdrplay.api.v3_07.sdrplay_api_h; + +/** + * RSP-2 AM Port + */ +public enum Rsp2AmPort +{ + PORT_1_HIGH_Z(sdrplay_api_h.sdrplay_api_Rsp2_AMPORT_1(), "HIGH-Z"), + PORT_2_SMA(sdrplay_api_h.sdrplay_api_Rsp2_AMPORT_2(), "SMA"); + + private int mValue; + private String mDescription; + + Rsp2AmPort(int value, String description) + { + mValue = value; + mDescription = description; + } + + /** + * Numeric value + */ + public int getValue() + { + return mValue; + } + + /** + * Lookup the entry from a return code + * @param value to lookup + * @return entry or PORT 2 if the code is not recognized + */ + public static Rsp2AmPort fromValue(int value) + { + for(Rsp2AmPort status: Rsp2AmPort.values()) + { + if(status.getValue() == value) + { + return status; + } + } + + return PORT_2_SMA; + } + + @Override + public String toString() + { + return mDescription; + } +} diff --git a/jsdrplay/src/main/java/com/github/dsheirer/sdrplay/parameter/tuner/Rsp2Antenna.java b/jsdrplay/src/main/java/com/github/dsheirer/sdrplay/parameter/tuner/Rsp2Antenna.java new file mode 100644 index 000000000..2e35f8824 --- /dev/null +++ b/jsdrplay/src/main/java/com/github/dsheirer/sdrplay/parameter/tuner/Rsp2Antenna.java @@ -0,0 +1,72 @@ +/* + * ***************************************************************************** + * 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.parameter.tuner; + +import com.github.dsheirer.sdrplay.api.v3_07.sdrplay_api_h; + +/** + * RSP-2 Antenna + */ +public enum Rsp2Antenna +{ + ANTENNA_A(sdrplay_api_h.sdrplay_api_Rsp2_ANTENNA_A(), "ANT A"), + ANTENNA_B(sdrplay_api_h.sdrplay_api_Rsp2_ANTENNA_B(), "ANT B"); + + private int mValue; + private String mDescription; + + Rsp2Antenna(int value, String description) + { + mValue = value; + mDescription = description; + } + + /** + * Numeric value + */ + public int getValue() + { + return mValue; + } + + /** + * Lookup the entry from a return code + * @param value to lookup + * @return entry or ANTENNA A if the code is not recognized + */ + public static Rsp2Antenna fromValue(int value) + { + for(Rsp2Antenna status: Rsp2Antenna.values()) + { + if(status.getValue() == value) + { + return status; + } + } + + return ANTENNA_A; + } + + @Override + public String toString() + { + return mDescription; + } +} diff --git a/jsdrplay/src/main/java/com/github/dsheirer/sdrplay/parameter/tuner/Rsp2AntennaSelection.java b/jsdrplay/src/main/java/com/github/dsheirer/sdrplay/parameter/tuner/Rsp2AntennaSelection.java new file mode 100644 index 000000000..a246d9078 --- /dev/null +++ b/jsdrplay/src/main/java/com/github/dsheirer/sdrplay/parameter/tuner/Rsp2AntennaSelection.java @@ -0,0 +1,65 @@ +/* + * ***************************************************************************** + * 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.parameter.tuner; + +/** + * RSP-2 Antenna + */ +public enum Rsp2AntennaSelection +{ + ANT_A(Rsp2Antenna.ANTENNA_A, Rsp2AmPort.PORT_2_SMA,"ANT A"), + ANT_B(Rsp2Antenna.ANTENNA_B, Rsp2AmPort.PORT_2_SMA, "ANT B"), + HIGH_Z(Rsp2Antenna.ANTENNA_B, Rsp2AmPort.PORT_1_HIGH_Z, "HIGH Z"); + + private Rsp2Antenna mAntenna; + private Rsp2AmPort mAmPort; + private String mDescription; + + Rsp2AntennaSelection(Rsp2Antenna antenna, Rsp2AmPort amPort, String description) + { + mAntenna = antenna; + mAmPort = amPort; + mDescription = description; + } + + /** + * Antenna setting for the selection. + * @return antenna + */ + public Rsp2Antenna getAntenna() + { + return mAntenna; + } + + /** + * AM Port for the selection + * @return am port + */ + public Rsp2AmPort getAmPort() + { + return mAmPort; + } + + @Override + public String toString() + { + return mDescription; + } +} diff --git a/jsdrplay/src/main/java/com/github/dsheirer/sdrplay/parameter/tuner/Rsp2TunerParameters.java b/jsdrplay/src/main/java/com/github/dsheirer/sdrplay/parameter/tuner/Rsp2TunerParameters.java new file mode 100644 index 000000000..252155cca --- /dev/null +++ b/jsdrplay/src/main/java/com/github/dsheirer/sdrplay/parameter/tuner/Rsp2TunerParameters.java @@ -0,0 +1,111 @@ +/* + * ***************************************************************************** + * 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.parameter.tuner; + +import com.github.dsheirer.sdrplay.api.v3_07.sdrplay_api_Rsp2TunerParamsT; +import com.github.dsheirer.sdrplay.util.Flag; + +import java.lang.foreign.MemorySegment; + +/** + * RSP2 Tuner Parameters structure + */ +public class Rsp2TunerParameters extends TunerParameters +{ + private MemorySegment mRsp2MemorySegment; + + public Rsp2TunerParameters(MemorySegment tunerParametersMemorySegment, MemorySegment rsp2MemorySegment) + { + super(tunerParametersMemorySegment); + mRsp2MemorySegment = rsp2MemorySegment; + } + + /** + * Foreign memory segment for this structure + */ + private MemorySegment getRsp2MemorySegment() + { + return mRsp2MemorySegment; + } + + /** + * Indicates if the Bias-T is enabled + */ + public boolean isBiasT() + { + return Flag.evaluate(sdrplay_api_Rsp2TunerParamsT.biasTEnable$get(getRsp2MemorySegment())); + } + + /** + * Enables or disables the Bias-T + */ + public void setBiasT(boolean enable) + { + sdrplay_api_Rsp2TunerParamsT.biasTEnable$set(getRsp2MemorySegment(), Flag.of(enable)); + } + + /** + * Current AM port setting + */ + public Rsp2AmPort getAmPort() + { + return Rsp2AmPort.fromValue(sdrplay_api_Rsp2TunerParamsT.amPortSel$get(getRsp2MemorySegment())); + } + + /** + * Sets the AM port to use + */ + public void setAmPort(Rsp2AmPort amPort) + { + sdrplay_api_Rsp2TunerParamsT.amPortSel$set(getRsp2MemorySegment(), amPort.getValue()); + } + + /** + * Antenna setting + */ + public Rsp2Antenna getAntenna() + { + return Rsp2Antenna.fromValue(sdrplay_api_Rsp2TunerParamsT.antennaSel$get(getRsp2MemorySegment())); + } + + /** + * Sets the antenna + */ + public void setAntenna(Rsp2Antenna rsp2Antenna) + { + sdrplay_api_Rsp2TunerParamsT.antennaSel$set(getRsp2MemorySegment(), rsp2Antenna.getValue()); + } + + /** + * Indicates if the RF notch is enabled + */ + public boolean isRfNotch() + { + return Flag.evaluate(sdrplay_api_Rsp2TunerParamsT.rfNotchEnable$get(getRsp2MemorySegment())); + } + + /** + * Enables or disables the RF notch + */ + public void setRfNotch(boolean enable) + { + sdrplay_api_Rsp2TunerParamsT.rfNotchEnable$set(getRsp2MemorySegment(), Flag.of(enable)); + } +} diff --git a/jsdrplay/src/main/java/com/github/dsheirer/sdrplay/parameter/tuner/RspDuoAmPort.java b/jsdrplay/src/main/java/com/github/dsheirer/sdrplay/parameter/tuner/RspDuoAmPort.java new file mode 100644 index 000000000..6debfa34c --- /dev/null +++ b/jsdrplay/src/main/java/com/github/dsheirer/sdrplay/parameter/tuner/RspDuoAmPort.java @@ -0,0 +1,72 @@ +/* + * ***************************************************************************** + * 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.parameter.tuner; + +import com.github.dsheirer.sdrplay.api.v3_07.sdrplay_api_h; + +/** + * RSP-Duo AM Port + */ +public enum RspDuoAmPort +{ + PORT_1(sdrplay_api_h.sdrplay_api_RspDuo_AMPORT_1(), "HIGH Z"), + PORT_2(sdrplay_api_h.sdrplay_api_RspDuo_AMPORT_2(), "50\u2126 SMA"); + + private int mValue; + private String mDescription; + + RspDuoAmPort(int value, String description) + { + mValue = value; + mDescription = description; + } + + /** + * Numeric value + */ + public int getValue() + { + return mValue; + } + + /** + * Lookup the entry from a return code + * @param value to lookup + * @return entry or PORT_2 if the code is not recognized + */ + public static RspDuoAmPort fromValue(int value) + { + for(RspDuoAmPort status: RspDuoAmPort.values()) + { + if(status.getValue() == value) + { + return status; + } + } + + return PORT_2; + } + + @Override + public String toString() + { + return mDescription; + } +} diff --git a/jsdrplay/src/main/java/com/github/dsheirer/sdrplay/parameter/tuner/RspDuoTunerParameters.java b/jsdrplay/src/main/java/com/github/dsheirer/sdrplay/parameter/tuner/RspDuoTunerParameters.java new file mode 100644 index 000000000..18f31818a --- /dev/null +++ b/jsdrplay/src/main/java/com/github/dsheirer/sdrplay/parameter/tuner/RspDuoTunerParameters.java @@ -0,0 +1,132 @@ +/* + * ***************************************************************************** + * 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.parameter.tuner; + +import com.github.dsheirer.sdrplay.api.v3_07.sdrplay_api_RspDuoTunerParamsT; +import com.github.dsheirer.sdrplay.util.Flag; + +import java.lang.foreign.MemorySegment; + +/** + * RSPduo Tuner Parameters structure + */ +public class RspDuoTunerParameters extends TunerParameters +{ + private MemorySegment mRspDuoMemorySegment; + + /** + * Constructs an instance from the foreign memory segment + * @param tunerParametersMemorySegment of foreign memory structure + * @param rspDuoMemorySegment of foreign memory structure + */ + RspDuoTunerParameters(MemorySegment tunerParametersMemorySegment, MemorySegment rspDuoMemorySegment) + { + super(tunerParametersMemorySegment); + mRspDuoMemorySegment = rspDuoMemorySegment; + } + + /** + * Foreign memory segment for this structure + */ + private MemorySegment getRspDuoMemorySegment() + { + return mRspDuoMemorySegment; + } + + /** + * Indicates if the Bias-T is enabled + */ + public boolean isBiasT() + { + return Flag.evaluate(sdrplay_api_RspDuoTunerParamsT.biasTEnable$get(getRspDuoMemorySegment())); + } + + /** + * Enables or disables the Bias-T + */ + public void setBiasT(boolean enable) + { + sdrplay_api_RspDuoTunerParamsT.biasTEnable$set(getRspDuoMemorySegment(), Flag.of(enable)); + } + + /** + * Tuner 1 AM port setting + */ + public RspDuoAmPort getTuner1AmPort() + { + return RspDuoAmPort.fromValue(sdrplay_api_RspDuoTunerParamsT.tuner1AmPortSel$get(getRspDuoMemorySegment())); + } + + /** + * Set Tuner 1 AM port setting + */ + public void setTuner1AmPort(RspDuoAmPort amPort) + { + sdrplay_api_RspDuoTunerParamsT.tuner1AmPortSel$set(getRspDuoMemorySegment(), amPort.getValue()); + } + + /** + * Indicates if Tuner 1 AM notch is enabled + */ + public boolean isTuner1AmNotch() + { + return Flag.evaluate(sdrplay_api_RspDuoTunerParamsT.tuner1AmNotchEnable$get(getRspDuoMemorySegment())); + } + + /** + * Enables or disables the Tuner 1 AM notch + */ + public void setTuner1AmNotch(boolean enable) + { + sdrplay_api_RspDuoTunerParamsT.tuner1AmNotchEnable$set(getRspDuoMemorySegment(), Flag.of(enable)); + } + + /** + * Indicates if the RF notch is enabled + */ + public boolean isRfNotch() + { + return Flag.evaluate(sdrplay_api_RspDuoTunerParamsT.rfNotchEnable$get(getRspDuoMemorySegment())); + } + + /** + * Enables or disables the RF notch + */ + public void setRfNotch(boolean enable) + { + sdrplay_api_RspDuoTunerParamsT.rfNotchEnable$set(getRspDuoMemorySegment(), Flag.of(enable)); + } + + /** + * Indicates if the RF DAB notch is enabled + */ + public boolean isRfDabNotch() + { + return Flag.evaluate(sdrplay_api_RspDuoTunerParamsT.rfDabNotchEnable$get(getRspDuoMemorySegment())); + } + + /** + * Enables or disables the RF DAB notch + */ + public void setRfDabNotch(boolean enable) + { + sdrplay_api_RspDuoTunerParamsT.rfDabNotchEnable$set(getRspDuoMemorySegment(), Flag.of(enable)); + } +} diff --git a/jsdrplay/src/main/java/com/github/dsheirer/sdrplay/parameter/tuner/RspDxAntenna.java b/jsdrplay/src/main/java/com/github/dsheirer/sdrplay/parameter/tuner/RspDxAntenna.java new file mode 100644 index 000000000..bcdd433e0 --- /dev/null +++ b/jsdrplay/src/main/java/com/github/dsheirer/sdrplay/parameter/tuner/RspDxAntenna.java @@ -0,0 +1,73 @@ +/* + * ***************************************************************************** + * 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.parameter.tuner; + +import com.github.dsheirer.sdrplay.api.v3_07.sdrplay_api_h; + +/** + * RSP-Dx Antenna + */ +public enum RspDxAntenna +{ + ANTENNA_A(sdrplay_api_h.sdrplay_api_RspDx_ANTENNA_A(), "ANT A (1 kHz to 2 GHz)"), + ANTENNA_B(sdrplay_api_h.sdrplay_api_RspDx_ANTENNA_B(), "ANT B (1 kHz to 2 GHz)"), + ANTENNA_C(sdrplay_api_h.sdrplay_api_RspDx_ANTENNA_C(), "ANT C (1 kHz to 200 MHz)"); + + private int mValue; + private String mDescription; + + RspDxAntenna(int value, String description) + { + mValue = value; + mDescription = description; + } + + /** + * Numeric value + */ + public int getValue() + { + return mValue; + } + + /** + * Lookup the entry from a return code + * @param value to lookup + * @return entry or ANTENNA A if the code is not recognized + */ + public static RspDxAntenna fromValue(int value) + { + for(RspDxAntenna status: RspDxAntenna.values()) + { + if(status.getValue() == value) + { + return status; + } + } + + return ANTENNA_A; + } + + @Override + public String toString() + { + return mDescription; + } +} diff --git a/jsdrplay/src/main/java/com/github/dsheirer/sdrplay/parameter/tuner/RspDxTunerParameters.java b/jsdrplay/src/main/java/com/github/dsheirer/sdrplay/parameter/tuner/RspDxTunerParameters.java new file mode 100644 index 000000000..f02931c52 --- /dev/null +++ b/jsdrplay/src/main/java/com/github/dsheirer/sdrplay/parameter/tuner/RspDxTunerParameters.java @@ -0,0 +1,65 @@ +/* + * ***************************************************************************** + * 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.parameter.tuner; + +import com.github.dsheirer.sdrplay.api.v3_07.sdrplay_api_RspDxTunerParamsT; + +import java.lang.foreign.MemorySegment; + +/** + * RSP-Dx Tuner Parameters structure + */ +public class RspDxTunerParameters extends TunerParameters +{ + private MemorySegment mRspDxMemorySegment; + + /** + * Constructs an instance from the foreign memory segment. + */ + public RspDxTunerParameters(MemorySegment tunerParametersMemorySegment, MemorySegment rspDxMemorySegment) + { + super(tunerParametersMemorySegment); + mRspDxMemorySegment = rspDxMemorySegment; + } + + /** + * Foreign memory segment for this structure + */ + private MemorySegment getRspDxMemorySegment() + { + return mRspDxMemorySegment; + } + + /** + * Current bandwidth setting for High Dynamic Range (HDR) mode + */ + public HdrModeBandwidth getHdrModeBandwidth() + { + return HdrModeBandwidth.fromValue(sdrplay_api_RspDxTunerParamsT.hdrBw$get(getRspDxMemorySegment())); + } + + /** + * Sets bandwidth for High Dynamic Range (HDR) mode + */ + public void setHdrModeBandwidth(HdrModeBandwidth bandwidth) + { + sdrplay_api_RspDxTunerParamsT.hdrBw$set(getRspDxMemorySegment(), bandwidth.getValue()); + } +} diff --git a/jsdrplay/src/main/java/com/github/dsheirer/sdrplay/parameter/tuner/TunerParameters.java b/jsdrplay/src/main/java/com/github/dsheirer/sdrplay/parameter/tuner/TunerParameters.java new file mode 100644 index 000000000..006f77a07 --- /dev/null +++ b/jsdrplay/src/main/java/com/github/dsheirer/sdrplay/parameter/tuner/TunerParameters.java @@ -0,0 +1,140 @@ +/* + * ***************************************************************************** + * 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.parameter.tuner; + +import com.github.dsheirer.sdrplay.api.v3_07.sdrplay_api_TunerParamsT; + +import java.lang.foreign.MemorySegment; + +/** + * Tuner Parameters structure (sdrplay_api_TunerParamsT) + */ +public abstract class TunerParameters +{ + private MemorySegment mMemorySegment; + private RfFrequency mRfFrequency; + private Gain mGain; + private DcOffsetTuner mDcOffsetTuner; + + /** + * Constructs an instance from the foreign memory segment + */ + public TunerParameters(MemorySegment memorySegment) + { + mMemorySegment = memorySegment; + mRfFrequency = new RfFrequency(sdrplay_api_TunerParamsT.rfFreq$slice(memorySegment)); + mGain = new Gain(sdrplay_api_TunerParamsT.gain$slice(memorySegment)); + mDcOffsetTuner = new DcOffsetTuner(sdrplay_api_TunerParamsT.dcOffsetTuner$slice(memorySegment)); + } + + /** + * Foreign memory segment for this tuner parameters structure + */ + private MemorySegment getMemorySegment() + { + return mMemorySegment; + } + + /** + * IF bandwidth + */ + public Bandwidth getBandwidth() + { + return Bandwidth.fromValue(sdrplay_api_TunerParamsT.bwType$get(getMemorySegment())); + } + + /** + * Sets the IF bandwidth + */ + public void setBandwidth(Bandwidth bandwidth) + { + sdrplay_api_TunerParamsT.bwType$set(getMemorySegment(), bandwidth.getValue()); + } + + /** + * IF mode + */ + public IfMode getIfMode() + { + return IfMode.fromValue(sdrplay_api_TunerParamsT.ifType$get(getMemorySegment())); + } + + /** + * Sets IF mode + */ + public void setIfMode(IfMode ifMode) + { + sdrplay_api_TunerParamsT.ifType$set(getMemorySegment(), ifMode.getValue()); + } + + /** + * LO mode + */ + public LoMode getLoMode() + { + return LoMode.fromValue(sdrplay_api_TunerParamsT.loMode$get(getMemorySegment())); + } + + /** + * Sets LO mode + */ + public void setLoMode(LoMode loMode) + { + sdrplay_api_TunerParamsT.loMode$set(getMemorySegment(), loMode.getValue()); + } + + /** + * Gain settings structure + */ + public Gain getGain() + { + return mGain; + } + + /** + * RF frequency structure + */ + public RfFrequency getRfFrequency() + { + return mRfFrequency; + } + + /** + * DC offset tuner structure + */ + public DcOffsetTuner getDcOffsetTuner() + { + return mDcOffsetTuner; + } + + @Override + public String toString() + { + StringBuilder sb = new StringBuilder(); + sb.append("Tuner Parameters\n"); + sb.append("\tBandwidth: ").append(getBandwidth()).append("\n"); + sb.append("\tIF Mode: ").append(getIfMode()).append("\n"); + sb.append("\tLO Mode: ").append(getLoMode()).append("\n"); + sb.append("\tGain: ").append(getGain()).append("\n"); + sb.append("\tRF Frequency: ").append(getRfFrequency()).append("\n"); + sb.append("\tDC Offset Tuner: ").append(getDcOffsetTuner()).append("\n"); + return sb.toString(); + } +} diff --git a/jsdrplay/src/main/java/com/github/dsheirer/sdrplay/parameter/tuner/TunerParametersFactory.java b/jsdrplay/src/main/java/com/github/dsheirer/sdrplay/parameter/tuner/TunerParametersFactory.java new file mode 100644 index 000000000..ab46b5b24 --- /dev/null +++ b/jsdrplay/src/main/java/com/github/dsheirer/sdrplay/parameter/tuner/TunerParametersFactory.java @@ -0,0 +1,66 @@ +/* + * ***************************************************************************** + * 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.parameter.tuner; + +import com.github.dsheirer.sdrplay.api.v3_07.sdrplay_api_RxChannelParamsT; +import com.github.dsheirer.sdrplay.device.DeviceType; + +import java.lang.foreign.MemorySegment; + +/** + * Factory for creating tuner parameters structures + */ +public class TunerParametersFactory +{ + /** + * Creats a tuner parameters instance for the specified device type + * @param deviceType to create + * @param memorySegment for the sdrplay_api_RxChannelParamsT structure + * @return tuner parameters + */ + public static TunerParameters create(DeviceType deviceType, MemorySegment memorySegment) + { + MemorySegment tunerParametersMemorySegment = sdrplay_api_RxChannelParamsT.tunerParams$slice(memorySegment); + + switch(deviceType) + { + case RSP1 -> { + return new Rsp1TunerParameters(tunerParametersMemorySegment); + } + case RSP1A -> { + MemorySegment rsp1AMemorySegment = sdrplay_api_RxChannelParamsT.rsp1aTunerParams$slice(memorySegment); + return new Rsp1aTunerParameters(memorySegment, rsp1AMemorySegment); + } + case RSP2 -> { + MemorySegment rsp2MemorySegment = sdrplay_api_RxChannelParamsT.rsp2TunerParams$slice(memorySegment); + return new Rsp2TunerParameters(memorySegment, rsp2MemorySegment); + } + case RSPduo -> { + MemorySegment rspDuoMemorySegment = sdrplay_api_RxChannelParamsT.rspDuoTunerParams$slice(memorySegment); + return new RspDuoTunerParameters(memorySegment, rspDuoMemorySegment); + } + case RSPdx -> { + MemorySegment rspDxMemorySegment = sdrplay_api_RxChannelParamsT.rspDxTunerParams$slice(memorySegment); + return new RspDxTunerParameters(memorySegment, rspDxMemorySegment); + } + default -> throw new IllegalArgumentException("Unrecognized device type: " + deviceType); + } + } +} diff --git a/jsdrplay/src/main/java/com/github/dsheirer/sdrplay/util/Flag.java b/jsdrplay/src/main/java/com/github/dsheirer/sdrplay/util/Flag.java new file mode 100644 index 000000000..ff4ead27b --- /dev/null +++ b/jsdrplay/src/main/java/com/github/dsheirer/sdrplay/util/Flag.java @@ -0,0 +1,59 @@ +/* + * ***************************************************************************** + * 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.util; + +/** + * Utility for integer and byte values representing true/false flags. + */ +public class Flag +{ + public static final byte TRUE = 0x01; + public static final byte FALSE = 0x00; + + /** + * Evaluates the boolean value false (0x00) or true + * @param value to evaluate + * @return true of the value is non-zero + */ + public static boolean evaluate(byte value) + { + return value != FALSE; + } + + /** + * Evaluates the boolean value false (0) or true + * @param value to evaluate + * @return true of the value is non-zero + */ + public static boolean evaluate(int value) + { + return value != 0; + } + + /** + * Returns a byte value representing the boolean value. + * @param value to lookup + * @return byte flag value + */ + public static byte of(boolean value) + { + return value ? TRUE : FALSE; + } +} diff --git a/jsdrplay/src/main/java/com/github/dsheirer/sdrplay/util/Retry.java b/jsdrplay/src/main/java/com/github/dsheirer/sdrplay/util/Retry.java new file mode 100644 index 000000000..cc0812122 --- /dev/null +++ b/jsdrplay/src/main/java/com/github/dsheirer/sdrplay/util/Retry.java @@ -0,0 +1,91 @@ +/* + * ***************************************************************************** + * 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.util; + +import com.github.dsheirer.sdrplay.SDRPlayException; + +/** + * Utility for retrying SDRplay API operations with thread sleep delay + * + * Note: the SDRplay API is non-blocking and therefore non-deterministic because it will return a Fail status code + * if it can't execute the requested operation at that time. Your only recourse is to repeatedly attempt an + * operation until you get a successful status return code. + */ +public class Retry +{ + /** + * Attempts to execute the runnable up to a maximum of 5 attempts, sleeping the thread by 20 millis each time. + * @param r to execute + */ + public static void quietly(Retryable r) + { + quietly(5, 20, r); + } + + /** + * Attempts to execute the runnable up to a maximum of (attempts), sleeping the thread by (pause) millis each time. + * @param attempts number of tries + * @param pause in milliseconds between each attempt + * @param r to execute + */ + public static void quietly(int attempts, long pause, Retryable r) + { + int attempt = 0; + + boolean success = false; + + while(attempt < attempts && !success) + { + attempt++; + + try + { + r.run(); + success = true; + } + catch(SDRPlayException e) + { + //Quietly ... no logging + } + + if(!success) + { + try + { + Thread.sleep(pause); + } + catch(Exception e) + { + //Do nothing + } + } + } + } + + /** + * Functional interface that encapsulates an SDRplay API operation that can throw an SDRplay exception and that + * can be attempted multiple times until successful. + */ + @FunctionalInterface + public interface Retryable + { + void run() throws SDRPlayException; + } +} diff --git a/jsdrplay/src/main/java/module-info.java b/jsdrplay/src/main/java/module-info.java new file mode 100644 index 000000000..61e6fb795 --- /dev/null +++ b/jsdrplay/src/main/java/module-info.java @@ -0,0 +1,18 @@ +module io.github.dsheirer.sdrplay { + exports com.github.dsheirer.sdrplay; + exports com.github.dsheirer.sdrplay.device; + exports com.github.dsheirer.sdrplay.callback; + exports com.github.dsheirer.sdrplay.parameter.composite; + exports com.github.dsheirer.sdrplay.parameter.device; + exports com.github.dsheirer.sdrplay.parameter.tuner; + exports com.github.dsheirer.sdrplay.parameter.control; + exports com.github.dsheirer.sdrplay.error; + exports com.github.dsheirer.sdrplay.parameter.event; + exports com.github.dsheirer.sdrplay.util; + exports com.github.dsheirer.sdrplay.async; + + requires ch.qos.logback.classic; + requires org.apache.commons.lang3; + requires org.slf4j; + requires sdrplay.api; +} \ No newline at end of file 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 new file mode 100644 index 000000000..e2309ca79 --- /dev/null +++ b/jsdrplay/src/test/java/io/github/dsherer/sdrplay/test/RspDeviceTest.java @@ -0,0 +1,135 @@ +/* + * ***************************************************************************** + * Copyright (C) 2014-2023 Dennis Sheirer + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see + * **************************************************************************** + */ + +package io.github.dsherer.sdrplay.test; + +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; +import org.junit.jupiter.api.Test; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +/** + * Unit testing for an RSP1A device + */ +public class RspDeviceTest +{ + public static final Logger mLog = LoggerFactory.getLogger(RspDeviceTest.class); + + @Test + @DisplayName("List available RSP devices") + public void listDevices() + { + SDRplay api = new SDRplay(); + + try + { + for(DeviceInfo deviceInfo: api.getDeviceInfos()) + { + mLog.info(deviceInfo.toString()); + } + + api.close(); + } + catch(Exception se) + { + mLog.error("Error closing API", se); + } + } + + /** + * Tests an RSP1A. + */ + @Test + @DisplayName("Test an RSP1A device") + public void testRSP1A() + { + testDevice(DeviceType.RSP1A, DeviceSelectionMode.SINGLE_TUNER_1); + } + + /** + * Tests an RSP1. + */ + @Test + @DisplayName("Test an RSP1 device") + public void testRSP1() + { + testDevice(DeviceType.RSP1, DeviceSelectionMode.SINGLE_TUNER_1); + } + + /** + * Tests the RSPduo with the specified device selection mode + * @param deviceSelectionMode + */ + private void testDevice(DeviceType deviceType, DeviceSelectionMode deviceSelectionMode) + { + SDRplay api = new SDRplay(); + mLog.info("Version: " + api.getVersion()); + try + { + 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("Selected: " + device.getClass()); + + mLog.info("Setting Sample Rate"); +// device.setSampleRate(SampleRate.RATE_0_250); + + 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.logSpectrum1(); + + device.release(); + mLog.info("Released"); + } + catch(SDRPlayException se) + { + mLog.error("Error testing device", se); + } + + try + { + api.close(); + } + catch(Exception se) + { + mLog.error("Error closing api"); + } + } + +} 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 new file mode 100644 index 000000000..eeb1dca1d --- /dev/null +++ b/jsdrplay/src/test/java/io/github/dsherer/sdrplay/test/RspDuoTest.java @@ -0,0 +1,144 @@ +/* + * ***************************************************************************** + * Copyright (C) 2014-2023 Dennis Sheirer + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see + * **************************************************************************** + */ + +package io.github.dsherer.sdrplay.test; + +import org.junit.jupiter.api.TestInstance; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +/** + * Unit testing for an RSPduo device + */ +@TestInstance(TestInstance.Lifecycle.PER_METHOD) +public class RspDuoTest +{ + private static Logger mLog = LoggerFactory.getLogger(RspDuoTest.class); + +// /** +// * 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/jsdrplay/src/test/java/io/github/dsherer/sdrplay/test/SDRplayTest.java b/jsdrplay/src/test/java/io/github/dsherer/sdrplay/test/SDRplayTest.java new file mode 100644 index 000000000..159a40d44 --- /dev/null +++ b/jsdrplay/src/test/java/io/github/dsherer/sdrplay/test/SDRplayTest.java @@ -0,0 +1,69 @@ +/* + * ***************************************************************************** + * 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 io.github.dsherer.sdrplay.test; + +import com.github.dsheirer.sdrplay.SDRplay; +import com.github.dsheirer.sdrplay.parameter.tuner.GainReduction; +import org.junit.jupiter.api.DisplayName; +import org.junit.jupiter.api.Test; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import static org.junit.jupiter.api.Assertions.assertTrue; + +public class SDRplayTest +{ + public static Logger mlog = LoggerFactory.getLogger(SDRplayTest.class); + + public SDRplayTest() + { + } + + @Test + public void loadLibrary() + { + mlog.info("Loading SDRplay API"); + SDRplay sdrplay = new SDRplay(); + assertTrue(sdrplay.isAvailable(), "Library is not available"); + } + + @Test + @DisplayName("Ensure each Gain Reduction entry has the specified number of gain indices") + void testGainReductionIndices() + { + for(GainReduction gainReduction: GainReduction.values()) + { + if(gainReduction != GainReduction.UNKNOWN) + { + for(int x = GainReduction.MIN_GAIN_INDEX; x <= GainReduction.MAX_GAIN_INDEX; x++) + { + int grValue = gainReduction.getGainReduction(x); + assertTrue(0 <= grValue, "Gain reduction value greater than 0"); + assertTrue(59 >= grValue, "Gain reduction value less than 60"); + + int lnaValue = gainReduction.getLnaState(x); + assertTrue(0 <= lnaValue, "LNA value greater than 0"); + assertTrue(27 >= lnaValue, "LNA value less than 60"); + } + } + } + } + +} diff --git a/jsdrplay/src/test/java/io/github/dsherer/sdrplay/test/Window.java b/jsdrplay/src/test/java/io/github/dsherer/sdrplay/test/Window.java new file mode 100644 index 000000000..2a34d22d6 --- /dev/null +++ b/jsdrplay/src/test/java/io/github/dsherer/sdrplay/test/Window.java @@ -0,0 +1,498 @@ +/* + * ***************************************************************************** + * 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 io.github.dsherer.sdrplay.test; + +import java.util.Arrays; +import org.apache.commons.math3.util.FastMath; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +/** + * Window factory and corresponding utility methods. + */ +public class Window +{ + private final static Logger mLog = LoggerFactory.getLogger(Window.class); + + private static final double TWO_PI = FastMath.PI * 2.0d; + private static final double FOUR_PI = FastMath.PI * 4.0d; + private static final double SIX_PI = FastMath.PI * 6.0d; + private static final double EIGHT_PI = FastMath.PI * 8.0d; + + /** + * Creates a window of the specified type and length. + * + * @param type of window + * @param length of window + * @return window of the specified type and length + */ + public static double[] getWindow(WindowType type, int length) + { + switch(type) + { + case BLACKMAN: + return getBlackman(length); + case BLACKMAN_HARRIS_4: + return getBlackmanHarris4(length); + case BLACKMAN_HARRIS_7: + return getBlackmanHarris7(length); + case BLACKMAN_NUTALL: + return getBlackmanNutall(length); + case COSINE: + return getCosine(length); + case FLAT_TOP: + return getFlatTop(length); + case HAMMING: + return getHamming(length); + case HANN: + return getHann(length); + case KAISER: + throw new IllegalArgumentException("Kaiser Window cannot be created via this method. Use the getKaiser() method instead."); + case NUTALL: + return getNutall(length); + case NONE: + default: + return getRectangular(length); + } + } + + /** + * Creates an all-pass or rectangular window. + * + * @param length of the window + * @return rectangular window + */ + public static double[] getRectangular(int length) + { + double[] coefficients = new double[length]; + + Arrays.fill(coefficients, 1.0d); + + return coefficients; + } + + /** + * Creates a cosine window of the specified length. + * + * @param length of the window + * @return cosine window + */ + public static double[] getCosine(int length) + { + double[] coefficients = new double[length]; + + if(length % 2 == 0) //Even length + { + int half = (int)((length - 1) / 2); + + for(int x = -half; x < length / 2 + 1; x++) + { + coefficients[x + half] = FastMath.cos( + ((double)x * FastMath.PI) / ((double)length + 1.0d)); + } + } + else //Odd length + { + int half = (int)length / 2; + + for(int x = -half; x < half + 1; x++) + { + coefficients[x + half] = FastMath.cos( + ((double)x * FastMath.PI) / ((double)length + 1.0d)); + } + } + + return coefficients; + } + + /** + * Creates a 3-term Blackman window. + * + * @param length of the window + * @return Blackman window + */ + public static double[] getBlackman(int length) + { + double[] coefficients = new double[length]; + + double denominator = length - 1; + + double a0 = 0.426590713672; + double a1 = 0.496560619089; + double a2 = 0.0768486672399; + + for(int x = 0; x < length; x++) + { + coefficients[x] = a0 - + (a1 * FastMath.cos((TWO_PI * (double)x) / denominator)) + + (a2 * FastMath.cos((FOUR_PI * (double)x) / denominator)); + } + + return coefficients; + } + + /** + * Creates a 4-term Nutall window + * + * @param length of the window + * @return Nutall window + */ + public static double[] getNutall(int length) + { + double[] coefficients = new double[length]; + + double denominator = length - 1; + double a0 = 0.355768; + double a1 = 0.487396; + double a2 = 0.144232; + double a3 = 0.012604; + + for(int x = 0; x < length; x++) + { + coefficients[x] = a0 - + (a1 * FastMath.cos(TWO_PI * (double)x / denominator)) + + (a2 * FastMath.cos(FOUR_PI * (double)x / denominator)) - + (a3 * FastMath.cos(SIX_PI * (double)x / denominator)); + } + + return coefficients; + } + + /** + * Creates a 4-term Blackman-Nutall window + * + * @param length of the window + * @return Blackman-Nutall window + */ + public static double[] getBlackmanNutall(int length) + { + double[] coefficients = new double[length]; + + double denominator = length - 1; + double a0 = 0.3635819; + double a1 = 0.4891775; + double a2 = 0.1365995; + double a3 = 0.0106411; + + for(int x = 0; x < length; x++) + { + coefficients[x] = a0 - + (a1 * FastMath.cos(TWO_PI * (double)x / denominator)) + + (a2 * FastMath.cos(FOUR_PI * (double)x / denominator)) - + (a3 * FastMath.cos(SIX_PI * (double)x / denominator)); + } + + return coefficients; + } + + /** + * Creates a 4-term Blackman-Harris window + * + * @param length of the window + * @return Blackman-Harris window + */ + public static double[] getBlackmanHarris4(int length) + { + double[] coefficients = new double[length]; + + double denominator = length - 1; + double a0 = 0.35875; + double a1 = 0.48829; + double a2 = 0.14128; + double a3 = 0.01168; + + for(int x = 0; x < length; x++) + { + coefficients[x] = a0 - + (a1 * FastMath.cos(TWO_PI * (double)x / denominator)) + + (a2 * FastMath.cos(FOUR_PI * (double)x / denominator)) - + (a3 * FastMath.cos(SIX_PI * (double)x / denominator)); + } + + return coefficients; + } + + /** + * Creates a 7-term Blackman-Harris window + * + * @param length of the window + * @return Blackman-Harris window + */ + public static double[] getBlackmanHarris7(int length) + { + double[] coefficients = new double[length]; + + double denominator = length - 1; + + double a0 = 0.27105140069342; + double a1 = 0.43329793923448; + double a2 = 0.21812299954311; + double a3 = 0.06592544638803; + double a4 = 0.01081174209837; + double a5 = 0.00077658482522; + double a6 = 0.00001388721735; + + + for(int x = 0; x < length; x++) + { + double w = TWO_PI * (double)x / denominator; + + coefficients[x] = a0 - + (a1 * FastMath.cos(w)) + + (a2 * FastMath.cos(2.0 * w)) - + (a3 * FastMath.cos(3.0 * w)) + + (a4 * FastMath.cos(4.0 * w)) - + (a5 * FastMath.cos(5.0 * w)) + + (a6 * FastMath.cos(6.0 * w)); + } + + return coefficients; + } + + /** + * Creates a Hamming window + * + * @param length of the window + * @return Hamming window + */ + public static double[] getHamming(int length) + { + double[] coefficients = new double[length]; + + for(int x = 0; x < length; x++) + { + coefficients[x] = 0.54 - (0.46 * FastMath.cos((TWO_PI * x) / (length - 1))); + } + + return coefficients; + } + + /** + * Creates a Hann window + * + * @param length of the window + * @return Hann window + */ + public static double[] getHann(int length) + { + double[] coefficients = new double[length]; + + for(int x = 0; x < length; x++) + { + coefficients[x] = 0.5 - (0.5 * FastMath.cos(TWO_PI * (double)x / (length - 1))); + } + + return coefficients; + } + + /** + * Creates a 4-term Blackman-Harris window + * + * @param length of the window + * @return Blackman-Harris window + */ + public static double[] getFlatTop(int length) + { + double[] coefficients = new double[length]; + + double denominator = length - 1; + + double a0 = 0.215578948; + double a1 = 0.41663158; + double a2 = 0.277263158; + double a3 = 0.083578947; + double a4 = 0.006947368; + + for(int x = 0; x < length; x++) + { + coefficients[x] = a0 - + (a1 * FastMath.cos(TWO_PI * (double)x / denominator)) + + (a2 * FastMath.cos(FOUR_PI * (double)x / denominator)) - + (a3 * FastMath.cos(SIX_PI * (double)x / denominator)) + + (a4 * FastMath.cos(EIGHT_PI * (double)x / denominator)); + } + + return coefficients; + } + + /** + * Calculates the beta (roll-off factor) for a Kaiser window based on the specified attenuation. + * + * @param attenuation in decibels + * @return beta value in the range of 0.0 to 1.0 + */ + public static double getKaiserBeta(double attenuation) + { + if(attenuation > 50.0) + { + return 0.1102 * (attenuation - 8.7); + } + else if(attenuation >= 21.0) + { + return (0.5842 * FastMath.pow(attenuation - 21.0, 0.4)) + (0.07886 * (attenuation - 21.0)); + } + else + { + return 0.0; + } + } + + /** + * Creates a Kaiser window. + * + * @param length of the window + * @param attenuation desired + * @return window + */ + public static double[] getKaiser(int length, double attenuation) + { + double[] coefficients = new double[length]; + + double beta = getKaiserBeta(attenuation); + + double betaBesselZerothOrder = getBesselZerothOrder(beta); + + double temp; + + for(int x = 0; x < coefficients.length; x++) + { + temp = beta * FastMath.sqrt(1.0 - FastMath.pow(2.0 * x / (length - 1) - 1.0, 2)); + coefficients[x] = getBesselZerothOrder(temp) / betaBesselZerothOrder; + } + + return coefficients; + } + + + /** + * Zeroth order modified Bessel function. + * + * @param x Value. + * @return Return value. + */ + public final static double getBesselZerothOrder(final double x) + { + double f = 1; + final double x2 = x * x * 0.25; + double xc = x2; + double v = 1 + x2; + for (int i = 2; i < 100; i++) + { + f *= i; + xc *= x2; + final double a = xc / (f * f); + v += a; + if (a < 1e-20) break; + } + + return v; + } + + /** + * Apply the window against an array of float-type samples + */ + public static float[] apply(double[] coefficients, float[] samples) + { + for(int x = 0; x < coefficients.length; x++) + { + samples[x] = (float)(samples[x] * coefficients[x]); + } + + return samples; + } + + /** + * Apply the window type against the float array of samples + * + * @param type of window to use + * @param samples to be windowed + * @return windowed samples + */ + public static float[] apply(WindowType type, float[] samples) + { + double[] coefficients = getWindow(type, samples.length); + + return apply(coefficients, samples); + } + + /** + * Apply the window against an array of double-type samples + */ + public static double[] apply(double[] coefficients, double[] samples) + { + for(int x = 0; x < coefficients.length; x++) + { + samples[x] = samples[x] * coefficients[x]; + } + + return samples; + } + + /** + * Apply the window type against the double array of samples + * + * @param type of window to use + * @param samples to be windowed + * @return windowed samples + */ + public static double[] apply(WindowType type, double[] samples) + { + double[] coefficients = getWindow(type, samples.length); + + return apply(coefficients, samples); + } + + /** + * Window types + */ + public enum WindowType + { + BLACKMAN("Blackman"), + BLACKMAN_HARRIS_4("Blackman-Harris 4"), + BLACKMAN_HARRIS_7("Blackman-Harris 7"), + BLACKMAN_NUTALL("Blackman-Nutall"), + COSINE("Cosine"), + FLAT_TOP("Flat Top"), + HAMMING("Hamming"), + HANN("Hann"), + KAISER("Kaiser"), + NUTALL("Nutall"), + NONE("None"); + + private String mLabel; + + WindowType(String label) + { + mLabel = label; + } + + public String toString() + { + return mLabel; + } + } + + public static void main(String[] args) + { + double[] kaiser = getKaiser(16, 80.0); + + mLog.debug("Window:" + Arrays.toString(kaiser)); + } +} diff --git a/jsdrplay/src/test/java/io/github/dsherer/sdrplay/test/listener/ISampleCountListener.java b/jsdrplay/src/test/java/io/github/dsherer/sdrplay/test/listener/ISampleCountListener.java new file mode 100644 index 000000000..a9ec32ad9 --- /dev/null +++ b/jsdrplay/src/test/java/io/github/dsherer/sdrplay/test/listener/ISampleCountListener.java @@ -0,0 +1,31 @@ +/* + * ***************************************************************************** + * 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 io.github.dsherer.sdrplay.test.listener; + +/** + * Listener interface to be notified of cumulative/increasing sample count + */ +public interface ISampleCountListener +{ + /** + * Notification of the current sample count + */ + void sampleCount(long sampleCount); +} diff --git a/jsdrplay/src/test/java/io/github/dsherer/sdrplay/test/listener/LoggingDeviceEventListener.java b/jsdrplay/src/test/java/io/github/dsherer/sdrplay/test/listener/LoggingDeviceEventListener.java new file mode 100644 index 000000000..b5be7757d --- /dev/null +++ b/jsdrplay/src/test/java/io/github/dsherer/sdrplay/test/listener/LoggingDeviceEventListener.java @@ -0,0 +1,90 @@ +/* + * ***************************************************************************** + * 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 io.github.dsherer.sdrplay.test.listener; + +import com.github.dsheirer.sdrplay.SDRPlayException; +import com.github.dsheirer.sdrplay.callback.IDeviceEventListener; +import com.github.dsheirer.sdrplay.device.Device; +import com.github.dsheirer.sdrplay.device.TunerSelect; +import com.github.dsheirer.sdrplay.parameter.event.EventType; +import com.github.dsheirer.sdrplay.parameter.event.GainCallbackParameters; +import com.github.dsheirer.sdrplay.parameter.event.PowerOverloadCallbackParameters; +import com.github.dsheirer.sdrplay.parameter.event.RspDuoModeCallbackParameters; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +/** + * Logging device event listener for debug or testing. + */ +public class LoggingDeviceEventListener implements IDeviceEventListener +{ + private static final Logger mLog = LoggerFactory.getLogger(LoggingDeviceEventListener.class); + private String mLabel; + private Device mDevice; + + /** + * Constructs an instance + * @param label prefix for logging. + */ + public LoggingDeviceEventListener(String label, Device device) + { + mLabel = label; + mDevice = device; + } + + @Override + public void processEvent(EventType eventType, TunerSelect tunerSelect) + { + mLog.info(mLabel + " - Unrecognized Event: " + eventType + " Tuner:" + tunerSelect); + } + + @Override + public void processGainChange(TunerSelect tunerSelect, GainCallbackParameters gainCallbackParameters) + { + mLog.info(mLabel + " - Gain Change - Tuner: " + tunerSelect + " " + gainCallbackParameters.toString()); + } + + @Override + public void processPowerOverload(TunerSelect tunerSelect, PowerOverloadCallbackParameters parameters) + { + mLog.info(mLabel + " - Power Overload - Tuner: " + tunerSelect + " - acknowledging"); + + try + { + mDevice.acknowledgePowerOverload(tunerSelect); + } + catch(SDRPlayException se) + { + mLog.error("Unable to acknowledge power overload for tuner(s): " + tunerSelect + ": " + se.getLocalizedMessage()); + } + } + + @Override + public void processRspDuoModeChange(TunerSelect tunerSelect, RspDuoModeCallbackParameters parameters) + { + mLog.info(mLabel + " - RSPduo Mode Change - Tuner: " + tunerSelect + " Event:" + parameters.getRspDuoModeEvent()); + } + + @Override + public void processDeviceRemoval(TunerSelect tunerSelect) + { + mLog.info(mLabel + " - Device Removed"); + } +} diff --git a/jsdrplay/src/test/java/io/github/dsherer/sdrplay/test/listener/LoggingStreamConsumer.java b/jsdrplay/src/test/java/io/github/dsherer/sdrplay/test/listener/LoggingStreamConsumer.java new file mode 100644 index 000000000..203edfd96 --- /dev/null +++ b/jsdrplay/src/test/java/io/github/dsherer/sdrplay/test/listener/LoggingStreamConsumer.java @@ -0,0 +1,123 @@ +/* + * ***************************************************************************** + * 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 io.github.dsherer.sdrplay.test.listener; + +import com.github.dsheirer.sdrplay.SDRPlayException; +import com.github.dsheirer.sdrplay.callback.IDeviceEventListener; +import com.github.dsheirer.sdrplay.device.Device; +import com.github.dsheirer.sdrplay.device.TunerSelect; +import java.util.concurrent.CountDownLatch; +import java.util.concurrent.Executors; +import java.util.concurrent.ScheduledExecutorService; +import java.util.concurrent.TimeUnit; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +/** + * Streaming samples consumer that can initialize a device, process streaming data for 5 seconds, and un-initialize + * the device. + */ +public class LoggingStreamConsumer +{ + private static final Logger mLog = LoggerFactory.getLogger(LoggingStreamConsumer.class); + private Device mDevice; + private LoggingStreamListener mStreamAListener; + private LoggingStreamListener mStreamBListener; + private IDeviceEventListener mDeviceEventListener; + + public LoggingStreamConsumer(Device device, TunerSelect tunerA, TunerSelect tunerB) + { + mDevice = device; + mDeviceEventListener = new LoggingDeviceEventListener(device.getDeviceType().toString(), device); + mStreamAListener = new LoggingStreamListener("Stream A", tunerA); + mStreamBListener = new LoggingStreamListener("Stream B", tunerB); + } + + public LoggingStreamConsumer(Device device) + { + this(device, TunerSelect.TUNER_1, TunerSelect.TUNER_2); + } + + /** + * Initializes the device, consumes samples for the specified period and then uninitializes the device. + * @param durationSeconds duration of the test in seconds. + * @throws SDRPlayException + */ + public void process(int durationSeconds) throws SDRPlayException + { + mLog.info("Initializing device ..."); + mDevice.initStreamA(mDeviceEventListener, mStreamAListener); + + final long startTimestamp = System.currentTimeMillis(); + + CountDownLatch latch = new CountDownLatch(1); + + ScheduledExecutorService executorService = Executors.newScheduledThreadPool(1); + executorService.schedule(new Runnable() + { + @Override + public void run() + { + try + { + mLog.info("Un-initializing the device"); + mDevice.uninitialize(); + + mStreamAListener.logSampleRate(System.currentTimeMillis() - startTimestamp); + mStreamBListener.logSampleRate(System.currentTimeMillis() - startTimestamp); + + mLog.info("releasing device"); + mDevice.release(); + } + catch(SDRPlayException se) + { + mLog.error("Error releasing RSPduo device", se); + } + + latch.countDown(); + } + }, durationSeconds, TimeUnit.SECONDS); + + try + { + latch.await(durationSeconds + 10, TimeUnit.SECONDS); + } + catch(InterruptedException e) + { + e.printStackTrace(); + } + } + + /** + * Logs the spectral (FFT) data captured from stream A. + */ + public void logSpectrumA() + { + mStreamAListener.logSpectrum(); + } + + /** + * Logs the spectral (FFT) data captured from stream B. + */ + public void logSpectrumB() + { + mStreamBListener.logSpectrum(); + } +} diff --git a/jsdrplay/src/test/java/io/github/dsherer/sdrplay/test/listener/LoggingStreamListener.java b/jsdrplay/src/test/java/io/github/dsherer/sdrplay/test/listener/LoggingStreamListener.java new file mode 100644 index 000000000..6aa69195f --- /dev/null +++ b/jsdrplay/src/test/java/io/github/dsherer/sdrplay/test/listener/LoggingStreamListener.java @@ -0,0 +1,203 @@ +/* + * ***************************************************************************** + * 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 io.github.dsherer.sdrplay.test.listener; + +import com.github.dsheirer.sdrplay.callback.IStreamListener; +import com.github.dsheirer.sdrplay.callback.StreamCallbackParameters; +import com.github.dsheirer.sdrplay.device.TunerSelect; +import io.github.dsherer.sdrplay.test.Window; +import java.text.DecimalFormat; +import java.text.NumberFormat; +import java.util.ArrayList; +import java.util.List; +import org.apache.commons.math3.util.FastMath; +import org.jtransforms.fft.FloatFFT_1D; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +/** + * Simple stream listener for debug/testing. Provides logging + */ +public class LoggingStreamListener implements IStreamListener +{ + private static final Logger mLog = LoggerFactory.getLogger(LoggingStreamListener.class); + private final String mLabel; + private final TunerSelect mTunerSelect; + private long mSampleCount = 0; + private static final int FFT_SIZE = 8192; + private short[] mISamples = new short[FFT_SIZE]; + private short[] mQSamples = new short[FFT_SIZE]; + private ISampleCountListener mSampleCountListener; + + /** + * Constructs an instance. + * @param label to use as a prefix for logging + * @param tunerSelect to indicate which tuner is producing the samples. + */ + public LoggingStreamListener(String label, TunerSelect tunerSelect) + { + mLabel = label; + mTunerSelect = tunerSelect; + } + + @Override + public TunerSelect getTunerSelect() + { + return mTunerSelect; + } + + /** + * Registers the listener to be notified of the cumulative sample count received by this stream listener. + */ + public void setSampleCountListener(ISampleCountListener listener) + { + mSampleCountListener = listener; + } + + public short[] getISamples() + { + return mISamples; + } + + public short[] getQSamples() + { + return mQSamples; + } + + /** + * Resets the sample counter and the log emission interval counter + */ + public void reset() + { + mSampleCount = 0; + } + + /** + * Calculates the estimated sample rate using the sample count and the provided elapsed milliseconds value. + * @param elapsedMilliseconds value + */ + public void logSampleRate(long elapsedMilliseconds) + { + DecimalFormat df = new DecimalFormat("0.000"); + + mLog.info(mLabel + " - " + NumberFormat.getNumberInstance().format(mSampleCount) + + " samples captured in " + df.format(elapsedMilliseconds / 1E3d) + + " secs. Approximate Sample Rate:" + + df.format(mSampleCount / (elapsedMilliseconds / 1E3d) / 1E6d) + " MHz"); + } + + /** + * Sample count + */ + public long getSampleCount() + { + return mSampleCount; + } + + @Override + public void processStream(short[] xi, short[] xq, StreamCallbackParameters parameters, + boolean reset) + { + //Retain latest set of samples for post run FFT + System.arraycopy(mISamples, xi.length, mISamples, 0, mISamples.length - xi.length); + System.arraycopy(xi, 0, mISamples, mISamples.length - xi.length, xi.length); + System.arraycopy(mQSamples, xq.length, mQSamples, 0, mQSamples.length - xq.length); + System.arraycopy(xq, 0, mQSamples, mQSamples.length - xq.length, xq.length); + + if(reset || parameters.isGainReductionChanged() || parameters.isRfFrequencyChanged() || parameters.isSampleRateChanged()) + { + List changes = new ArrayList<>(); + if(reset) + { + changes.add("TUNER RESET"); + } + if(parameters.isGainReductionChanged()) + { + changes.add("GAIN REDUCTION"); + } + if(parameters.isRfFrequencyChanged()) + { + changes.add("RF CENTER FREQUENCY"); + } + if(parameters.isSampleRateChanged()) + { + changes.add("SAMPLE RATE"); + } + + mLog.info(mLabel + " - Parameters Changed " + changes); + } + + mSampleCount += parameters.getNumberSamples(); + + if(mSampleCountListener != null) + { + mSampleCountListener.sampleCount(mSampleCount); + } + } + + public void logSpectrum() + { + if(mISamples != null && mQSamples != null) + { + float multiplier = 1.0f / Short.MAX_VALUE; + + float[] samples = new float[FFT_SIZE * 2]; + + for(int x = 0; x < FFT_SIZE; x ++) + { + samples[x * 2] = mISamples[x] * multiplier; + samples[x * 2 + 1] = mQSamples[x] * multiplier; + } + + Window.apply(Window.WindowType.BLACKMAN, samples); + + FloatFFT_1D fft = new FloatFFT_1D(FFT_SIZE); + fft.complexForward(samples); + + double[] db = new double[FFT_SIZE]; + + //dB scaling factor for 14-bit sample size + double scalor = -20.0 * Math.log10(1.0 / Math.pow(2.0, 13)); + + for(int x = 0; x < FFT_SIZE; x++) + { + double magnitude = Math.pow(samples[x * 2], 2.0) + Math.pow(samples[x * 2 + 1], 2.0); + db[x] = ((10.0 * FastMath.log10(magnitude) / FFT_SIZE) * scalor * 100) - 72; + } + + double[] db_arranged = new double[FFT_SIZE]; + System.arraycopy(db, 0, db_arranged, FFT_SIZE / 2, FFT_SIZE / 2); + System.arraycopy(db, FFT_SIZE / 2, db_arranged, 0, FFT_SIZE / 2); + + StringBuilder sb = new StringBuilder(); + sb.append("\n\n=========================================== " + mLabel + + " FFT Spectrum ===========================================================\n\n"); + for(int x = 0; x < db_arranged.length; x++) + { + sb.append(db_arranged[x]).append("\n"); + } + mLog.info(mLabel + " - Calculated Spectrum (FFT): " + sb); + } + else + { + mLog.info(mLabel + " either I or Q samples were null ... no fft for you today"); + } + } +} diff --git a/jsdrplay/src/test/java/io/github/dsherer/sdrplay/test/listener/SampleCountLogger.java b/jsdrplay/src/test/java/io/github/dsherer/sdrplay/test/listener/SampleCountLogger.java new file mode 100644 index 000000000..2faa26ce1 --- /dev/null +++ b/jsdrplay/src/test/java/io/github/dsherer/sdrplay/test/listener/SampleCountLogger.java @@ -0,0 +1,49 @@ +/* + * ***************************************************************************** + * 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 io.github.dsherer.sdrplay.test.listener; + +/** + * Logs the cumulative/running sample count + */ +public class SampleCountLogger implements ISampleCountListener +{ + private final String mLabel; + private final int mSampleLogInterval; + + public SampleCountLogger(String label, int sampleLoggingInterval) + { + mLabel = label; + mSampleLogInterval = sampleLoggingInterval; + } + + @Override + public void sampleCount(long sampleCount) + { + +// mEmitSampleLogCount++; +// +// if(mEmitSampleLogCount % mSampleLogInterval == 0) +// { +// mEmitSampleLogCount = 0; +// mLog.info(mLabel + " - Samples Received: " + mSampleCount); +// } + + } +} diff --git a/sdrplay-api/api/README.txt b/sdrplay-api/api/README.txt new file mode 100644 index 000000000..ff2036b1b --- /dev/null +++ b/sdrplay-api/api/README.txt @@ -0,0 +1,36 @@ +Auto-generating Java code from SDRPlay API using jextract. + +Note: the api headers in the 3.11 folder are equivalent to the 3.08 headers. The only +difference from the 3.07 headers is the addition of the boolean 'valid' flag to DeviceT structure. + +1. Download JDK19 compatible build of jextract JDK: https://jdk.java.net/jextract/ +2. If generating on windows platform, modify the sdrplay_api.h to remove the windows + pieces of the file. Specifically: +2a. Comment out these lines but leave the *HANDLE typedef: + +//#if defined(_M_X64) || defined(_M_IX86) || defined(_M_ARM64) +//#include "windows.h" +//#elif defined (__GNUC__) +typedef void *HANDLE; +//#endif + +//#ifndef _SDRPLAY_DLL_QUALIFIER +//#if !defined(STATIC_LIB) && (defined(_M_X64) || defined(_M_IX86) || defined(_M_ARM64)) +//#define _SDRPLAY_DLL_QUALIFIER __declspec(dllimport) +//#elif defined(STATIC_LIB) || defined(__GNUC__) +//#define _SDRPLAY_DLL_QUALIFIER +//#endif +//#endif // _SDRPLAY_DLL_QUALIFIER + +2b. Remove the '_SDRPLAY_DLL_QUALIFIER' from in front of the method declarations + +2c. Change the 3.11 version string to 3.08 either in the header file, or in the generated java class + +3. Open command prompt to the root source code where the generated files should be placed: +..\SDRtrunk\sdrplay-api\src\main\java + +4. Generate the code: +c:\Users\Denny\Downloads\jdk-19-ea2-panama\bin\jextract "C:\Users\Denny\git\sdrtrunk\sdrplay-api\api\v3_11\sdrplay_api.h" -l libsdrplay_api --source + +5. Do this for all versions of the API. + diff --git a/sdrplay-api/api/v3_07/sdrplay_api.h b/sdrplay-api/api/v3_07/sdrplay_api.h new file mode 100644 index 000000000..321b8a511 --- /dev/null +++ b/sdrplay-api/api/v3_07/sdrplay_api.h @@ -0,0 +1,229 @@ +#ifndef SDRPLAY_API_H +#define SDRPLAY_API_H + +#include "sdrplay_api_dev.h" +#include "sdrplay_api_rx_channel.h" +#include "sdrplay_api_callback.h" + +//#if defined(_M_X64) || defined(_M_IX86) +//#include "windows.h" +//#elif defined (__GNUC__) +typedef void *HANDLE; +//#endif + +//#ifndef _SDRPLAY_DLL_QUALIFIER +//#if !defined(STATIC_LIB) && (defined(_M_X64) || defined(_M_IX86)) +//#define _SDRPLAY_DLL_QUALIFIER __declspec(dllimport) +//#elif defined(STATIC_LIB) || defined(__GNUC__) +//#define _SDRPLAY_DLL_QUALIFIER +//#endif +//#endif // _SDRPLAY_DLL_QUALIFIER + +// Application code should check that it is compiled against the same API version +// sdrplay_api_ApiVersion() returns the API version +#define SDRPLAY_API_VERSION (float)(3.07) + +// API Constants +#define SDRPLAY_MAX_DEVICES (16) +#define SDRPLAY_MAX_TUNERS_PER_DEVICE (2) + +#define SDRPLAY_MAX_SER_NO_LEN (64) +#define SDRPLAY_MAX_ROOT_NM_LEN (32) + +#define SDRPLAY_RSP1_ID (1) +#define SDRPLAY_RSP1A_ID (255) +#define SDRPLAY_RSP2_ID (2) +#define SDRPLAY_RSPduo_ID (3) +#define SDRPLAY_RSPdx_ID (4) + +// Enum types +typedef enum +{ + sdrplay_api_Success = 0, + sdrplay_api_Fail = 1, + sdrplay_api_InvalidParam = 2, + sdrplay_api_OutOfRange = 3, + sdrplay_api_GainUpdateError = 4, + sdrplay_api_RfUpdateError = 5, + sdrplay_api_FsUpdateError = 6, + sdrplay_api_HwError = 7, + sdrplay_api_AliasingError = 8, + sdrplay_api_AlreadyInitialised = 9, + sdrplay_api_NotInitialised = 10, + sdrplay_api_NotEnabled = 11, + sdrplay_api_HwVerError = 12, + sdrplay_api_OutOfMemError = 13, + sdrplay_api_ServiceNotResponding = 14, + sdrplay_api_StartPending = 15, + sdrplay_api_StopPending = 16, + sdrplay_api_InvalidMode = 17, + sdrplay_api_FailedVerification1 = 18, + sdrplay_api_FailedVerification2 = 19, + sdrplay_api_FailedVerification3 = 20, + sdrplay_api_FailedVerification4 = 21, + sdrplay_api_FailedVerification5 = 22, + sdrplay_api_FailedVerification6 = 23, + sdrplay_api_InvalidServiceVersion = 24 +} sdrplay_api_ErrT; + +typedef enum +{ + sdrplay_api_Update_None = 0x00000000, + + // Reasons for master only mode + sdrplay_api_Update_Dev_Fs = 0x00000001, + sdrplay_api_Update_Dev_Ppm = 0x00000002, + sdrplay_api_Update_Dev_SyncUpdate = 0x00000004, + sdrplay_api_Update_Dev_ResetFlags = 0x00000008, + + sdrplay_api_Update_Rsp1a_BiasTControl = 0x00000010, + sdrplay_api_Update_Rsp1a_RfNotchControl = 0x00000020, + sdrplay_api_Update_Rsp1a_RfDabNotchControl = 0x00000040, + + sdrplay_api_Update_Rsp2_BiasTControl = 0x00000080, + sdrplay_api_Update_Rsp2_AmPortSelect = 0x00000100, + sdrplay_api_Update_Rsp2_AntennaControl = 0x00000200, + sdrplay_api_Update_Rsp2_RfNotchControl = 0x00000400, + sdrplay_api_Update_Rsp2_ExtRefControl = 0x00000800, + + sdrplay_api_Update_RspDuo_ExtRefControl = 0x00001000, + + sdrplay_api_Update_Master_Spare_1 = 0x00002000, + sdrplay_api_Update_Master_Spare_2 = 0x00004000, + + // Reasons for master and slave mode + // Note: sdrplay_api_Update_Tuner_Gr MUST be the first value defined in this section! + sdrplay_api_Update_Tuner_Gr = 0x00008000, + sdrplay_api_Update_Tuner_GrLimits = 0x00010000, + sdrplay_api_Update_Tuner_Frf = 0x00020000, + sdrplay_api_Update_Tuner_BwType = 0x00040000, + sdrplay_api_Update_Tuner_IfType = 0x00080000, + sdrplay_api_Update_Tuner_DcOffset = 0x00100000, + sdrplay_api_Update_Tuner_LoMode = 0x00200000, + + sdrplay_api_Update_Ctrl_DCoffsetIQimbalance = 0x00400000, + sdrplay_api_Update_Ctrl_Decimation = 0x00800000, + sdrplay_api_Update_Ctrl_Agc = 0x01000000, + sdrplay_api_Update_Ctrl_AdsbMode = 0x02000000, + sdrplay_api_Update_Ctrl_OverloadMsgAck = 0x04000000, + + sdrplay_api_Update_RspDuo_BiasTControl = 0x08000000, + sdrplay_api_Update_RspDuo_AmPortSelect = 0x10000000, + sdrplay_api_Update_RspDuo_Tuner1AmNotchControl = 0x20000000, + sdrplay_api_Update_RspDuo_RfNotchControl = 0x40000000, + sdrplay_api_Update_RspDuo_RfDabNotchControl = 0x80000000, +} sdrplay_api_ReasonForUpdateT; + +typedef enum +{ + sdrplay_api_Update_Ext1_None = 0x00000000, + + // Reasons for master only mode + sdrplay_api_Update_RspDx_HdrEnable = 0x00000001, + sdrplay_api_Update_RspDx_BiasTControl = 0x00000002, + sdrplay_api_Update_RspDx_AntennaControl = 0x00000004, + sdrplay_api_Update_RspDx_RfNotchControl = 0x00000008, + sdrplay_api_Update_RspDx_RfDabNotchControl = 0x00000010, + sdrplay_api_Update_RspDx_HdrBw = 0x00000020, + + // Reasons for master and slave mode +} sdrplay_api_ReasonForUpdateExtension1T; + +typedef enum +{ + sdrplay_api_DbgLvl_Disable = 0, + sdrplay_api_DbgLvl_Verbose = 1, + sdrplay_api_DbgLvl_Warning = 2, + sdrplay_api_DbgLvl_Error = 3, + sdrplay_api_DbgLvl_Message = 4, +} sdrplay_api_DbgLvl_t; + +// Device structure +typedef struct +{ + char SerNo[SDRPLAY_MAX_SER_NO_LEN]; + unsigned char hwVer; + sdrplay_api_TunerSelectT tuner; + sdrplay_api_RspDuoModeT rspDuoMode; + double rspDuoSampleFreq; + HANDLE dev; +} sdrplay_api_DeviceT; + +// Device parameter structure +typedef struct +{ + sdrplay_api_DevParamsT *devParams; + sdrplay_api_RxChannelParamsT *rxChannelA; + sdrplay_api_RxChannelParamsT *rxChannelB; +} sdrplay_api_DeviceParamsT; + +// Extended error message structure +typedef struct +{ + char file[256]; + char function[256]; + int line; + char message[1024]; +} sdrplay_api_ErrorInfoT; + +// Comman API function types +typedef sdrplay_api_ErrT (*sdrplay_api_Open_t)(void); +typedef sdrplay_api_ErrT (*sdrplay_api_Close_t)(void); +typedef sdrplay_api_ErrT (*sdrplay_api_ApiVersion_t)(float *apiVer); +typedef sdrplay_api_ErrT (*sdrplay_api_LockDeviceApi_t)(void); +typedef sdrplay_api_ErrT (*sdrplay_api_UnlockDeviceApi_t)(void); +typedef sdrplay_api_ErrT (*sdrplay_api_GetDevices_t)(sdrplay_api_DeviceT *devices, unsigned int *numDevs, unsigned int maxDevs); +typedef sdrplay_api_ErrT (*sdrplay_api_SelectDevice_t)(sdrplay_api_DeviceT *device); +typedef sdrplay_api_ErrT (*sdrplay_api_ReleaseDevice_t)(sdrplay_api_DeviceT *device); +typedef const char* (*sdrplay_api_GetErrorString_t)(sdrplay_api_ErrT err); +typedef sdrplay_api_ErrorInfoT* (*sdrplay_api_GetLastError_t)(sdrplay_api_DeviceT *device); +typedef sdrplay_api_ErrT (*sdrplay_api_DisableHeartbeat_t)(void); + +// Device API function types +typedef sdrplay_api_ErrT (*sdrplay_api_DebugEnable_t)(HANDLE dev, sdrplay_api_DbgLvl_t dbgLvl); +typedef sdrplay_api_ErrT (*sdrplay_api_GetDeviceParams_t)(HANDLE dev, sdrplay_api_DeviceParamsT **deviceParams); +typedef sdrplay_api_ErrT (*sdrplay_api_Init_t)(HANDLE dev, sdrplay_api_CallbackFnsT *callbackFns, void *cbContext); +typedef sdrplay_api_ErrT (*sdrplay_api_Uninit_t)(HANDLE dev); +typedef sdrplay_api_ErrT (*sdrplay_api_Update_t)(HANDLE dev, sdrplay_api_TunerSelectT tuner, sdrplay_api_ReasonForUpdateT reasonForUpdate, sdrplay_api_ReasonForUpdateExtension1T reasonForUpdateExt1); +typedef sdrplay_api_ErrT (*sdrplay_api_SwapRspDuoActiveTuner_t)(HANDLE dev, sdrplay_api_TunerSelectT *tuner, sdrplay_api_RspDuo_AmPortSelectT tuner1AmPortSel); +typedef sdrplay_api_ErrT (*sdrplay_api_SwapRspDuoDualTunerModeSampleRate_t)(double *currentSampleRate); +typedef sdrplay_api_ErrT (*sdrplay_api_SwapRspDuoMode_t)(sdrplay_api_DeviceT *currDevice, sdrplay_api_DeviceParamsT **deviceParams, + sdrplay_api_RspDuoModeT rspDuoMode, double sampleRate, sdrplay_api_TunerSelectT tuner, + sdrplay_api_Bw_MHzT bwType, sdrplay_api_If_kHzT ifType, sdrplay_api_RspDuo_AmPortSelectT tuner1AmPortSel); + +// API function definitions +#ifdef __cplusplus +extern "C" +{ +#endif + + // Comman API function definitions + sdrplay_api_ErrT sdrplay_api_Open(void); + sdrplay_api_ErrT sdrplay_api_Close(void); + sdrplay_api_ErrT sdrplay_api_ApiVersion(float *apiVer); + sdrplay_api_ErrT sdrplay_api_LockDeviceApi(void); + sdrplay_api_ErrT sdrplay_api_UnlockDeviceApi(void); + sdrplay_api_ErrT sdrplay_api_GetDevices(sdrplay_api_DeviceT *devices, unsigned int *numDevs, unsigned int maxDevs); + sdrplay_api_ErrT sdrplay_api_SelectDevice(sdrplay_api_DeviceT *device); + sdrplay_api_ErrT sdrplay_api_ReleaseDevice(sdrplay_api_DeviceT *device); + const char* sdrplay_api_GetErrorString(sdrplay_api_ErrT err); + sdrplay_api_ErrorInfoT* sdrplay_api_GetLastError(sdrplay_api_DeviceT *device); + sdrplay_api_ErrT sdrplay_api_DisableHeartbeat(void); // Must be called before sdrplay_api_SelectDevice() + + // Device API function definitions + sdrplay_api_ErrT sdrplay_api_DebugEnable(HANDLE dev, sdrplay_api_DbgLvl_t enable); + sdrplay_api_ErrT sdrplay_api_GetDeviceParams(HANDLE dev, sdrplay_api_DeviceParamsT **deviceParams); + sdrplay_api_ErrT sdrplay_api_Init(HANDLE dev, sdrplay_api_CallbackFnsT *callbackFns, void *cbContext); + sdrplay_api_ErrT sdrplay_api_Uninit(HANDLE dev); + sdrplay_api_ErrT sdrplay_api_Update(HANDLE dev, sdrplay_api_TunerSelectT tuner, sdrplay_api_ReasonForUpdateT reasonForUpdate, sdrplay_api_ReasonForUpdateExtension1T reasonForUpdateExt1); + sdrplay_api_ErrT sdrplay_api_SwapRspDuoActiveTuner(HANDLE dev, sdrplay_api_TunerSelectT *currentTuner, sdrplay_api_RspDuo_AmPortSelectT tuner1AmPortSel); + sdrplay_api_ErrT sdrplay_api_SwapRspDuoDualTunerModeSampleRate(HANDLE dev, double *currentSampleRate); + sdrplay_api_ErrT sdrplay_api_SwapRspDuoMode(sdrplay_api_DeviceT *currDevice, sdrplay_api_DeviceParamsT **deviceParams, + sdrplay_api_RspDuoModeT rspDuoMode, double sampleRate, sdrplay_api_TunerSelectT tuner, + sdrplay_api_Bw_MHzT bwType, sdrplay_api_If_kHzT ifType, sdrplay_api_RspDuo_AmPortSelectT tuner1AmPortSel); + +#ifdef __cplusplus +} +#endif + +#endif //SDRPLAY_API_H diff --git a/sdrplay-api/api/v3_07/sdrplay_api_callback.h b/sdrplay-api/api/v3_07/sdrplay_api_callback.h new file mode 100644 index 000000000..88d560490 --- /dev/null +++ b/sdrplay-api/api/v3_07/sdrplay_api_callback.h @@ -0,0 +1,78 @@ +#ifndef SDRPLAY_API_CALLBACK_H +#define SDRPLAY_API_CALLBACK_H + +// Event callback enums +typedef enum +{ + sdrplay_api_Overload_Detected = 0, + sdrplay_api_Overload_Corrected = 1, +} sdrplay_api_PowerOverloadCbEventIdT; + +typedef enum +{ + sdrplay_api_MasterInitialised = 0, + sdrplay_api_SlaveAttached = 1, + sdrplay_api_SlaveDetached = 2, + sdrplay_api_SlaveInitialised = 3, + sdrplay_api_SlaveUninitialised = 4, + sdrplay_api_MasterDllDisappeared = 5, + sdrplay_api_SlaveDllDisappeared = 6, +} sdrplay_api_RspDuoModeCbEventIdT; + +typedef enum +{ + sdrplay_api_GainChange = 0, + sdrplay_api_PowerOverloadChange = 1, + sdrplay_api_DeviceRemoved = 2, + sdrplay_api_RspDuoModeChange = 3, +} sdrplay_api_EventT; + +// Event callback parameter structs +typedef struct +{ + unsigned int gRdB; + unsigned int lnaGRdB; + double currGain; +} sdrplay_api_GainCbParamT; + +typedef struct +{ + sdrplay_api_PowerOverloadCbEventIdT powerOverloadChangeType; +} sdrplay_api_PowerOverloadCbParamT; + +typedef struct +{ + sdrplay_api_RspDuoModeCbEventIdT modeChangeType; +} sdrplay_api_RspDuoModeCbParamT; + +// Event parameters overlay +typedef union +{ + sdrplay_api_GainCbParamT gainParams; + sdrplay_api_PowerOverloadCbParamT powerOverloadParams; + sdrplay_api_RspDuoModeCbParamT rspDuoModeParams; +} sdrplay_api_EventParamsT; + +// Stream callback parameter structs +typedef struct +{ + unsigned int firstSampleNum; + int grChanged; + int rfChanged; + int fsChanged; + unsigned int numSamples; +} sdrplay_api_StreamCbParamsT; + +// Callback function prototypes +typedef void (*sdrplay_api_StreamCallback_t)(short *xi, short *xq, sdrplay_api_StreamCbParamsT *params, unsigned int numSamples, unsigned int reset, void *cbContext); +typedef void (*sdrplay_api_EventCallback_t)(sdrplay_api_EventT eventId, sdrplay_api_TunerSelectT tuner, sdrplay_api_EventParamsT *params, void *cbContext); + +// Callback function struct +typedef struct +{ + sdrplay_api_StreamCallback_t StreamACbFn; + sdrplay_api_StreamCallback_t StreamBCbFn; + sdrplay_api_EventCallback_t EventCbFn; +} sdrplay_api_CallbackFnsT; + +#endif //SDRPLAY_API_CALLBACK_H diff --git a/sdrplay-api/api/v3_07/sdrplay_api_control.h b/sdrplay-api/api/v3_07/sdrplay_api_control.h new file mode 100644 index 000000000..5a52a1046 --- /dev/null +++ b/sdrplay-api/api/v3_07/sdrplay_api_control.h @@ -0,0 +1,55 @@ +#ifndef SDRPLAY_API_CONTROL_H +#define SDRPLAY_API_CONTROL_H + +// Control parameter enums +typedef enum +{ + sdrplay_api_AGC_DISABLE = 0, + sdrplay_api_AGC_100HZ = 1, + sdrplay_api_AGC_50HZ = 2, + sdrplay_api_AGC_5HZ = 3, + sdrplay_api_AGC_CTRL_EN = 4 +} sdrplay_api_AgcControlT; + +typedef enum +{ + sdrplay_api_ADSB_DECIMATION = 0, + sdrplay_api_ADSB_NO_DECIMATION_LOWPASS = 1, + sdrplay_api_ADSB_NO_DECIMATION_BANDPASS_2MHZ = 2, + sdrplay_api_ADSB_NO_DECIMATION_BANDPASS_3MHZ = 3 +} sdrplay_api_AdsbModeT; + +// Control parameter structs +typedef struct +{ + unsigned char DCenable; // default: 1 + unsigned char IQenable; // default: 1 +} sdrplay_api_DcOffsetT; + +typedef struct +{ + unsigned char enable; // default: 0 + unsigned char decimationFactor; // default: 1 + unsigned char wideBandSignal; // default: 0 +} sdrplay_api_DecimationT; + +typedef struct +{ + sdrplay_api_AgcControlT enable; // default: sdrplay_api_AGC_50HZ + int setPoint_dBfs; // default: -60 + unsigned short attack_ms; // default: 0 + unsigned short decay_ms; // default: 0 + unsigned short decay_delay_ms; // default: 0 + unsigned short decay_threshold_dB; // default: 0 + int syncUpdate; // default: 0 +} sdrplay_api_AgcT; + +typedef struct +{ + sdrplay_api_DcOffsetT dcOffset; + sdrplay_api_DecimationT decimation; + sdrplay_api_AgcT agc; + sdrplay_api_AdsbModeT adsbMode; //default: sdrplay_api_ADSB_DECIMATION +} sdrplay_api_ControlParamsT; + +#endif //SDRPLAY_API_CONTROL_H diff --git a/sdrplay-api/api/v3_07/sdrplay_api_dev.h b/sdrplay-api/api/v3_07/sdrplay_api_dev.h new file mode 100644 index 000000000..5ac99ae25 --- /dev/null +++ b/sdrplay-api/api/v3_07/sdrplay_api_dev.h @@ -0,0 +1,51 @@ +#ifndef SDRPLAY_API_DEV_H +#define SDRPLAY_API_DEV_H + +#include "sdrplay_api_rsp1a.h" +#include "sdrplay_api_rsp2.h" +#include "sdrplay_api_rspDuo.h" +#include "sdrplay_api_rspDx.h" + +// Dev parameter enums +typedef enum +{ + sdrplay_api_ISOCH = 0, + sdrplay_api_BULK = 1 +} sdrplay_api_TransferModeT; + +// Dev parameter structs +typedef struct +{ + double fsHz; // default: 2000000.0 + unsigned char syncUpdate; // default: 0 + unsigned char reCal; // default: 0 +} sdrplay_api_FsFreqT; + +typedef struct +{ + unsigned int sampleNum; // default: 0 + unsigned int period; // default: 0 +} sdrplay_api_SyncUpdateT; + +typedef struct +{ + unsigned char resetGainUpdate; // default: 0 + unsigned char resetRfUpdate; // default: 0 + unsigned char resetFsUpdate; // default: 0 +} sdrplay_api_ResetFlagsT; + +typedef struct +{ + double ppm; // default: 0.0 + sdrplay_api_FsFreqT fsFreq; + sdrplay_api_SyncUpdateT syncUpdate; + sdrplay_api_ResetFlagsT resetFlags; + sdrplay_api_TransferModeT mode; // default: sdrplay_api_ISOCH + unsigned int samplesPerPkt; // default: 0 (output param) + sdrplay_api_Rsp1aParamsT rsp1aParams; + sdrplay_api_Rsp2ParamsT rsp2Params; + sdrplay_api_RspDuoParamsT rspDuoParams; + sdrplay_api_RspDxParamsT rspDxParams; +} sdrplay_api_DevParamsT; + +#endif //SDRPLAY_API_DEV_H diff --git a/sdrplay-api/api/v3_07/sdrplay_api_rsp1a.h b/sdrplay-api/api/v3_07/sdrplay_api_rsp1a.h new file mode 100644 index 000000000..3affbcc3e --- /dev/null +++ b/sdrplay-api/api/v3_07/sdrplay_api_rsp1a.h @@ -0,0 +1,22 @@ +#ifndef SDRPLAY_API_RSP1A_H +#define SDRPLAY_API_RSP1A_H + +#define RSPIA_NUM_LNA_STATES 10 +#define RSPIA_NUM_LNA_STATES_AM 7 +#define RSPIA_NUM_LNA_STATES_LBAND 9 + +// RSP1A parameter enums + +// RSP1A parameter structs +typedef struct +{ + unsigned char rfNotchEnable; // default: 0 + unsigned char rfDabNotchEnable; // default: 0 +} sdrplay_api_Rsp1aParamsT; + +typedef struct +{ + unsigned char biasTEnable; // default: 0 +} sdrplay_api_Rsp1aTunerParamsT; + +#endif //SDRPLAY_API_RSP1A_H diff --git a/sdrplay-api/api/v3_07/sdrplay_api_rsp2.h b/sdrplay-api/api/v3_07/sdrplay_api_rsp2.h new file mode 100644 index 000000000..930d3e956 --- /dev/null +++ b/sdrplay-api/api/v3_07/sdrplay_api_rsp2.h @@ -0,0 +1,35 @@ +#ifndef SDRPLAY_API_RSP2_H +#define SDRPLAY_API_RSP2_H + +#define RSPII_NUM_LNA_STATES 9 +#define RSPII_NUM_LNA_STATES_AMPORT 5 +#define RSPII_NUM_LNA_STATES_420MHZ 6 + +// RSP2 parameter enums +typedef enum +{ + sdrplay_api_Rsp2_ANTENNA_A = 5, + sdrplay_api_Rsp2_ANTENNA_B = 6, +} sdrplay_api_Rsp2_AntennaSelectT; + +typedef enum +{ + sdrplay_api_Rsp2_AMPORT_1 = 1, + sdrplay_api_Rsp2_AMPORT_2 = 0, +} sdrplay_api_Rsp2_AmPortSelectT; + +// RSP2 parameter structs +typedef struct +{ + unsigned char extRefOutputEn; // default: 0 +} sdrplay_api_Rsp2ParamsT; + +typedef struct +{ + unsigned char biasTEnable; // default: 0 + sdrplay_api_Rsp2_AmPortSelectT amPortSel; // default: sdrplay_api_Rsp2_AMPORT_2 + sdrplay_api_Rsp2_AntennaSelectT antennaSel; // default: sdrplay_api_Rsp2_ANTENNA_A + unsigned char rfNotchEnable; // default: 0 +} sdrplay_api_Rsp2TunerParamsT; + +#endif //SDRPLAY_API_RSP2_H diff --git a/sdrplay-api/api/v3_07/sdrplay_api_rspDuo.h b/sdrplay-api/api/v3_07/sdrplay_api_rspDuo.h new file mode 100644 index 000000000..3c4566350 --- /dev/null +++ b/sdrplay-api/api/v3_07/sdrplay_api_rspDuo.h @@ -0,0 +1,40 @@ +#ifndef SDRPLAY_API_RSPduo_H +#define SDRPLAY_API_RSPduo_H + +#define RSPDUO_NUM_LNA_STATES 10 +#define RSPDUO_NUM_LNA_STATES_AMPORT 5 +#define RSPDUO_NUM_LNA_STATES_AM 7 +#define RSPDUO_NUM_LNA_STATES_LBAND 9 + +// RSPduo parameter enums +typedef enum +{ + sdrplay_api_RspDuoMode_Unknown = 0, + sdrplay_api_RspDuoMode_Single_Tuner = 1, + sdrplay_api_RspDuoMode_Dual_Tuner = 2, + sdrplay_api_RspDuoMode_Master = 4, + sdrplay_api_RspDuoMode_Slave = 8, +} sdrplay_api_RspDuoModeT; + +typedef enum +{ + sdrplay_api_RspDuo_AMPORT_1 = 1, + sdrplay_api_RspDuo_AMPORT_2 = 0, +} sdrplay_api_RspDuo_AmPortSelectT; + +// RSPduo parameter structs +typedef struct +{ + int extRefOutputEn; // default: 0 +} sdrplay_api_RspDuoParamsT; + +typedef struct +{ + unsigned char biasTEnable; // default: 0 + sdrplay_api_RspDuo_AmPortSelectT tuner1AmPortSel; // default: sdrplay_api_RspDuo_AMPORT_2 + unsigned char tuner1AmNotchEnable; // default: 0 + unsigned char rfNotchEnable; // default: 0 + unsigned char rfDabNotchEnable; // default: 0 +} sdrplay_api_RspDuoTunerParamsT; + +#endif //SDRPLAY_API_RSPduo_H diff --git a/sdrplay-api/api/v3_07/sdrplay_api_rspDx.h b/sdrplay-api/api/v3_07/sdrplay_api_rspDx.h new file mode 100644 index 000000000..14cad9dc0 --- /dev/null +++ b/sdrplay-api/api/v3_07/sdrplay_api_rspDx.h @@ -0,0 +1,45 @@ +#ifndef SDRPLAY_API_RSPDX_H +#define SDRPLAY_API_RSPDX_H + +#include "sdrplay_api_tuner.h" + +#define RSPDX_NUM_LNA_STATES 28 // Number of LNA states in all bands (except where defined differently below) +#define RSPDX_NUM_LNA_STATES_AMPORT2_0_12 19 // Number of LNA states when using AM Port 2 between 0 and 12MHz +#define RSPDX_NUM_LNA_STATES_AMPORT2_12_60 20 // Number of LNA states when using AM Port 2 between 12 and 60MHz +#define RSPDX_NUM_LNA_STATES_VHF_BAND3 27 // Number of LNA states in VHF and Band3 +#define RSPDX_NUM_LNA_STATES_420MHZ 21 // Number of LNA states in 420MHz band +#define RSPDX_NUM_LNA_STATES_LBAND 19 // Number of LNA states in L-band +#define RSPDX_NUM_LNA_STATES_DX 26 // Number of LNA states in DX path + +// RSPdx parameter enums +typedef enum +{ + sdrplay_api_RspDx_ANTENNA_A = 0, + sdrplay_api_RspDx_ANTENNA_B = 1, + sdrplay_api_RspDx_ANTENNA_C = 2, +} sdrplay_api_RspDx_AntennaSelectT; + +typedef enum +{ + sdrplay_api_RspDx_HDRMODE_BW_0_200 = 0, + sdrplay_api_RspDx_HDRMODE_BW_0_500 = 1, + sdrplay_api_RspDx_HDRMODE_BW_1_200 = 2, + sdrplay_api_RspDx_HDRMODE_BW_1_700 = 3, +} sdrplay_api_RspDx_HdrModeBwT; + +// RSPdx parameter structs +typedef struct +{ + unsigned char hdrEnable; // default: 0 + unsigned char biasTEnable; // default: 0 + sdrplay_api_RspDx_AntennaSelectT antennaSel; // default: sdrplay_api_RspDx_ANTENNA_A + unsigned char rfNotchEnable; // default: 0 + unsigned char rfDabNotchEnable; // default: 0 +} sdrplay_api_RspDxParamsT; + +typedef struct +{ + sdrplay_api_RspDx_HdrModeBwT hdrBw; // default: sdrplay_api_RspDx_HDRMODE_BW_1_700 +} sdrplay_api_RspDxTunerParamsT; + +#endif //SDRPLAY_API_RSPDX_H diff --git a/sdrplay-api/api/v3_07/sdrplay_api_rx_channel.h b/sdrplay-api/api/v3_07/sdrplay_api_rx_channel.h new file mode 100644 index 000000000..010080402 --- /dev/null +++ b/sdrplay-api/api/v3_07/sdrplay_api_rx_channel.h @@ -0,0 +1,21 @@ +#ifndef SDRPLAY_API_RX_CHANNEL_H +#define SDRPLAY_API_RX_CHANNEL_H + +#include "sdrplay_api_tuner.h" +#include "sdrplay_api_control.h" +#include "sdrplay_api_rsp1a.h" +#include "sdrplay_api_rsp2.h" +#include "sdrplay_api_rspDuo.h" +#include "sdrplay_api_rspDx.h" + +typedef struct +{ + sdrplay_api_TunerParamsT tunerParams; + sdrplay_api_ControlParamsT ctrlParams; + sdrplay_api_Rsp1aTunerParamsT rsp1aTunerParams; + sdrplay_api_Rsp2TunerParamsT rsp2TunerParams; + sdrplay_api_RspDuoTunerParamsT rspDuoTunerParams; + sdrplay_api_RspDxTunerParamsT rspDxTunerParams; +} sdrplay_api_RxChannelParamsT; + +#endif //SDRPLAY_API_RX_CHANNEL_H diff --git a/sdrplay-api/api/v3_07/sdrplay_api_tuner.h b/sdrplay-api/api/v3_07/sdrplay_api_tuner.h new file mode 100644 index 000000000..a5c446d61 --- /dev/null +++ b/sdrplay-api/api/v3_07/sdrplay_api_tuner.h @@ -0,0 +1,93 @@ +#ifndef SDRPLAY_API_TUNER_H +#define SDRPLAY_API_TUNER_H + +#define MAX_BB_GR (59) + +// Tuner parameter enums +typedef enum +{ + sdrplay_api_BW_Undefined = 0, + sdrplay_api_BW_0_200 = 200, + sdrplay_api_BW_0_300 = 300, + sdrplay_api_BW_0_600 = 600, + sdrplay_api_BW_1_536 = 1536, + sdrplay_api_BW_5_000 = 5000, + sdrplay_api_BW_6_000 = 6000, + sdrplay_api_BW_7_000 = 7000, + sdrplay_api_BW_8_000 = 8000 +} sdrplay_api_Bw_MHzT; + +typedef enum +{ + sdrplay_api_IF_Undefined = -1, + sdrplay_api_IF_Zero = 0, + sdrplay_api_IF_0_450 = 450, + sdrplay_api_IF_1_620 = 1620, + sdrplay_api_IF_2_048 = 2048 +} sdrplay_api_If_kHzT; + +typedef enum +{ + sdrplay_api_LO_Undefined = 0, + sdrplay_api_LO_Auto = 1, + sdrplay_api_LO_120MHz = 2, + sdrplay_api_LO_144MHz = 3, + sdrplay_api_LO_168MHz = 4 +} sdrplay_api_LoModeT; + +typedef enum +{ + sdrplay_api_EXTENDED_MIN_GR = 0, + sdrplay_api_NORMAL_MIN_GR = 20 +} sdrplay_api_MinGainReductionT; + +typedef enum +{ + sdrplay_api_Tuner_Neither = 0, + sdrplay_api_Tuner_A = 1, + sdrplay_api_Tuner_B = 2, + sdrplay_api_Tuner_Both = 3, +} sdrplay_api_TunerSelectT; + +// Tuner parameter structs +typedef struct +{ + float curr; + float max; + float min; +} sdrplay_api_GainValuesT; + +typedef struct +{ + int gRdB; // default: 50 + unsigned char LNAstate; // default: 0 + unsigned char syncUpdate; // default: 0 + sdrplay_api_MinGainReductionT minGr; // default: sdrplay_api_NORMAL_MIN_GR + sdrplay_api_GainValuesT gainVals; // output parameter +} sdrplay_api_GainT; + +typedef struct +{ + double rfHz; // default: 200000000.0 + unsigned char syncUpdate; // default: 0 +} sdrplay_api_RfFreqT; + +typedef struct +{ + unsigned char dcCal; // default: 3 (Periodic mode) + unsigned char speedUp; // default: 0 (No speedup) + int trackTime; // default: 1 (=> time in uSec = (72 * 3 * trackTime) / 24e6 = 9uSec) + int refreshRateTime; // default: 2048 (=> time in uSec = (72 * 3 * refreshRateTime) / 24e6 = 18432uSec) +} sdrplay_api_DcOffsetTunerT; + +typedef struct +{ + sdrplay_api_Bw_MHzT bwType; // default: sdrplay_api_BW_0_200 + sdrplay_api_If_kHzT ifType; // default: sdrplay_api_IF_Zero + sdrplay_api_LoModeT loMode; // default: sdrplay_api_LO_Auto + sdrplay_api_GainT gain; + sdrplay_api_RfFreqT rfFreq; + sdrplay_api_DcOffsetTunerT dcOffsetTuner; +} sdrplay_api_TunerParamsT; + +#endif //SDRPLAY_API_TUNER_H diff --git a/sdrplay-api/api/v3_11/sdrplay_api.h b/sdrplay-api/api/v3_11/sdrplay_api.h new file mode 100644 index 000000000..f3400d88a --- /dev/null +++ b/sdrplay-api/api/v3_11/sdrplay_api.h @@ -0,0 +1,230 @@ +#ifndef SDRPLAY_API_H +#define SDRPLAY_API_H + +#include "sdrplay_api_dev.h" +#include "sdrplay_api_rx_channel.h" +#include "sdrplay_api_callback.h" + +//#if defined(_M_X64) || defined(_M_IX86) || defined(_M_ARM64) +//#include "windows.h" +//#elif defined (__GNUC__) +typedef void *HANDLE; +//#endif + +//#ifndef _SDRPLAY_DLL_QUALIFIER +//#if !defined(STATIC_LIB) && (defined(_M_X64) || defined(_M_IX86) || defined(_M_ARM64)) +//#define _SDRPLAY_DLL_QUALIFIER __declspec(dllimport) +//#elif defined(STATIC_LIB) || defined(__GNUC__) +//#define _SDRPLAY_DLL_QUALIFIER +//#endif +//#endif // _SDRPLAY_DLL_QUALIFIER + +// Application code should check that it is compiled against the same API version +// sdrplay_api_ApiVersion() returns the API version +#define SDRPLAY_API_VERSION (float)(3.11) + +// API Constants +#define SDRPLAY_MAX_DEVICES (16) +#define SDRPLAY_MAX_TUNERS_PER_DEVICE (2) + +#define SDRPLAY_MAX_SER_NO_LEN (64) +#define SDRPLAY_MAX_ROOT_NM_LEN (32) + +#define SDRPLAY_RSP1_ID (1) +#define SDRPLAY_RSP1A_ID (255) +#define SDRPLAY_RSP2_ID (2) +#define SDRPLAY_RSPduo_ID (3) +#define SDRPLAY_RSPdx_ID (4) + +// Enum types +typedef enum +{ + sdrplay_api_Success = 0, + sdrplay_api_Fail = 1, + sdrplay_api_InvalidParam = 2, + sdrplay_api_OutOfRange = 3, + sdrplay_api_GainUpdateError = 4, + sdrplay_api_RfUpdateError = 5, + sdrplay_api_FsUpdateError = 6, + sdrplay_api_HwError = 7, + sdrplay_api_AliasingError = 8, + sdrplay_api_AlreadyInitialised = 9, + sdrplay_api_NotInitialised = 10, + sdrplay_api_NotEnabled = 11, + sdrplay_api_HwVerError = 12, + sdrplay_api_OutOfMemError = 13, + sdrplay_api_ServiceNotResponding = 14, + sdrplay_api_StartPending = 15, + sdrplay_api_StopPending = 16, + sdrplay_api_InvalidMode = 17, + sdrplay_api_FailedVerification1 = 18, + sdrplay_api_FailedVerification2 = 19, + sdrplay_api_FailedVerification3 = 20, + sdrplay_api_FailedVerification4 = 21, + sdrplay_api_FailedVerification5 = 22, + sdrplay_api_FailedVerification6 = 23, + sdrplay_api_InvalidServiceVersion = 24 +} sdrplay_api_ErrT; + +typedef enum +{ + sdrplay_api_Update_None = 0x00000000, + + // Reasons for master only mode + sdrplay_api_Update_Dev_Fs = 0x00000001, + sdrplay_api_Update_Dev_Ppm = 0x00000002, + sdrplay_api_Update_Dev_SyncUpdate = 0x00000004, + sdrplay_api_Update_Dev_ResetFlags = 0x00000008, + + sdrplay_api_Update_Rsp1a_BiasTControl = 0x00000010, + sdrplay_api_Update_Rsp1a_RfNotchControl = 0x00000020, + sdrplay_api_Update_Rsp1a_RfDabNotchControl = 0x00000040, + + sdrplay_api_Update_Rsp2_BiasTControl = 0x00000080, + sdrplay_api_Update_Rsp2_AmPortSelect = 0x00000100, + sdrplay_api_Update_Rsp2_AntennaControl = 0x00000200, + sdrplay_api_Update_Rsp2_RfNotchControl = 0x00000400, + sdrplay_api_Update_Rsp2_ExtRefControl = 0x00000800, + + sdrplay_api_Update_RspDuo_ExtRefControl = 0x00001000, + + sdrplay_api_Update_Master_Spare_1 = 0x00002000, + sdrplay_api_Update_Master_Spare_2 = 0x00004000, + + // Reasons for master and slave mode + // Note: sdrplay_api_Update_Tuner_Gr MUST be the first value defined in this section! + sdrplay_api_Update_Tuner_Gr = 0x00008000, + sdrplay_api_Update_Tuner_GrLimits = 0x00010000, + sdrplay_api_Update_Tuner_Frf = 0x00020000, + sdrplay_api_Update_Tuner_BwType = 0x00040000, + sdrplay_api_Update_Tuner_IfType = 0x00080000, + sdrplay_api_Update_Tuner_DcOffset = 0x00100000, + sdrplay_api_Update_Tuner_LoMode = 0x00200000, + + sdrplay_api_Update_Ctrl_DCoffsetIQimbalance = 0x00400000, + sdrplay_api_Update_Ctrl_Decimation = 0x00800000, + sdrplay_api_Update_Ctrl_Agc = 0x01000000, + sdrplay_api_Update_Ctrl_AdsbMode = 0x02000000, + sdrplay_api_Update_Ctrl_OverloadMsgAck = 0x04000000, + + sdrplay_api_Update_RspDuo_BiasTControl = 0x08000000, + sdrplay_api_Update_RspDuo_AmPortSelect = 0x10000000, + sdrplay_api_Update_RspDuo_Tuner1AmNotchControl = 0x20000000, + sdrplay_api_Update_RspDuo_RfNotchControl = 0x40000000, + sdrplay_api_Update_RspDuo_RfDabNotchControl = 0x80000000, +} sdrplay_api_ReasonForUpdateT; + +typedef enum +{ + sdrplay_api_Update_Ext1_None = 0x00000000, + + // Reasons for master only mode + sdrplay_api_Update_RspDx_HdrEnable = 0x00000001, + sdrplay_api_Update_RspDx_BiasTControl = 0x00000002, + sdrplay_api_Update_RspDx_AntennaControl = 0x00000004, + sdrplay_api_Update_RspDx_RfNotchControl = 0x00000008, + sdrplay_api_Update_RspDx_RfDabNotchControl = 0x00000010, + sdrplay_api_Update_RspDx_HdrBw = 0x00000020, + + // Reasons for master and slave mode +} sdrplay_api_ReasonForUpdateExtension1T; + +typedef enum +{ + sdrplay_api_DbgLvl_Disable = 0, + sdrplay_api_DbgLvl_Verbose = 1, + sdrplay_api_DbgLvl_Warning = 2, + sdrplay_api_DbgLvl_Error = 3, + sdrplay_api_DbgLvl_Message = 4, +} sdrplay_api_DbgLvl_t; + +// Device structure +typedef struct +{ + char SerNo[SDRPLAY_MAX_SER_NO_LEN]; + unsigned char hwVer; + sdrplay_api_TunerSelectT tuner; + sdrplay_api_RspDuoModeT rspDuoMode; + unsigned char valid; + double rspDuoSampleFreq; + HANDLE dev; +} sdrplay_api_DeviceT; + +// Device parameter structure +typedef struct +{ + sdrplay_api_DevParamsT *devParams; + sdrplay_api_RxChannelParamsT *rxChannelA; + sdrplay_api_RxChannelParamsT *rxChannelB; +} sdrplay_api_DeviceParamsT; + +// Extended error message structure +typedef struct +{ + char file[256]; + char function[256]; + int line; + char message[1024]; +} sdrplay_api_ErrorInfoT; + +// Comman API function types +typedef sdrplay_api_ErrT (*sdrplay_api_Open_t)(void); +typedef sdrplay_api_ErrT (*sdrplay_api_Close_t)(void); +typedef sdrplay_api_ErrT (*sdrplay_api_ApiVersion_t)(float *apiVer); +typedef sdrplay_api_ErrT (*sdrplay_api_LockDeviceApi_t)(void); +typedef sdrplay_api_ErrT (*sdrplay_api_UnlockDeviceApi_t)(void); +typedef sdrplay_api_ErrT (*sdrplay_api_GetDevices_t)(sdrplay_api_DeviceT *devices, unsigned int *numDevs, unsigned int maxDevs); +typedef sdrplay_api_ErrT (*sdrplay_api_SelectDevice_t)(sdrplay_api_DeviceT *device); +typedef sdrplay_api_ErrT (*sdrplay_api_ReleaseDevice_t)(sdrplay_api_DeviceT *device); +typedef const char* (*sdrplay_api_GetErrorString_t)(sdrplay_api_ErrT err); +typedef sdrplay_api_ErrorInfoT* (*sdrplay_api_GetLastError_t)(sdrplay_api_DeviceT *device); +typedef sdrplay_api_ErrT (*sdrplay_api_DisableHeartbeat_t)(void); + +// Device API function types +typedef sdrplay_api_ErrT (*sdrplay_api_DebugEnable_t)(HANDLE dev, sdrplay_api_DbgLvl_t dbgLvl); +typedef sdrplay_api_ErrT (*sdrplay_api_GetDeviceParams_t)(HANDLE dev, sdrplay_api_DeviceParamsT **deviceParams); +typedef sdrplay_api_ErrT (*sdrplay_api_Init_t)(HANDLE dev, sdrplay_api_CallbackFnsT *callbackFns, void *cbContext); +typedef sdrplay_api_ErrT (*sdrplay_api_Uninit_t)(HANDLE dev); +typedef sdrplay_api_ErrT (*sdrplay_api_Update_t)(HANDLE dev, sdrplay_api_TunerSelectT tuner, sdrplay_api_ReasonForUpdateT reasonForUpdate, sdrplay_api_ReasonForUpdateExtension1T reasonForUpdateExt1); +typedef sdrplay_api_ErrT (*sdrplay_api_SwapRspDuoActiveTuner_t)(HANDLE dev, sdrplay_api_TunerSelectT *tuner, sdrplay_api_RspDuo_AmPortSelectT tuner1AmPortSel); +typedef sdrplay_api_ErrT (*sdrplay_api_SwapRspDuoDualTunerModeSampleRate_t)(double *currentSampleRate, double newSampleRate); +typedef sdrplay_api_ErrT (*sdrplay_api_SwapRspDuoMode_t)(sdrplay_api_DeviceT *currDevice, sdrplay_api_DeviceParamsT **deviceParams, + sdrplay_api_RspDuoModeT rspDuoMode, double sampleRate, sdrplay_api_TunerSelectT tuner, + sdrplay_api_Bw_MHzT bwType, sdrplay_api_If_kHzT ifType, sdrplay_api_RspDuo_AmPortSelectT tuner1AmPortSel); + +// API function definitions +#ifdef __cplusplus +extern "C" +{ +#endif + + // Comman API function definitions + sdrplay_api_ErrT sdrplay_api_Open(void); + sdrplay_api_ErrT sdrplay_api_Close(void); + sdrplay_api_ErrT sdrplay_api_ApiVersion(float *apiVer); + sdrplay_api_ErrT sdrplay_api_LockDeviceApi(void); + sdrplay_api_ErrT sdrplay_api_UnlockDeviceApi(void); + sdrplay_api_ErrT sdrplay_api_GetDevices(sdrplay_api_DeviceT *devices, unsigned int *numDevs, unsigned int maxDevs); + sdrplay_api_ErrT sdrplay_api_SelectDevice(sdrplay_api_DeviceT *device); + sdrplay_api_ErrT sdrplay_api_ReleaseDevice(sdrplay_api_DeviceT *device); + const char* sdrplay_api_GetErrorString(sdrplay_api_ErrT err); + sdrplay_api_ErrorInfoT* sdrplay_api_GetLastError(sdrplay_api_DeviceT *device); + sdrplay_api_ErrT sdrplay_api_DisableHeartbeat(void); // Must be called before sdrplay_api_SelectDevice() + + // Device API function definitions + sdrplay_api_ErrT sdrplay_api_DebugEnable(HANDLE dev, sdrplay_api_DbgLvl_t enable); + sdrplay_api_ErrT sdrplay_api_GetDeviceParams(HANDLE dev, sdrplay_api_DeviceParamsT **deviceParams); + sdrplay_api_ErrT sdrplay_api_Init(HANDLE dev, sdrplay_api_CallbackFnsT *callbackFns, void *cbContext); + sdrplay_api_ErrT sdrplay_api_Uninit(HANDLE dev); + sdrplay_api_ErrT sdrplay_api_Update(HANDLE dev, sdrplay_api_TunerSelectT tuner, sdrplay_api_ReasonForUpdateT reasonForUpdate, sdrplay_api_ReasonForUpdateExtension1T reasonForUpdateExt1); + sdrplay_api_ErrT sdrplay_api_SwapRspDuoActiveTuner(HANDLE dev, sdrplay_api_TunerSelectT *currentTuner, sdrplay_api_RspDuo_AmPortSelectT tuner1AmPortSel); + sdrplay_api_ErrT sdrplay_api_SwapRspDuoDualTunerModeSampleRate(HANDLE dev, double *currentSampleRate, double newSampleRate); + sdrplay_api_ErrT sdrplay_api_SwapRspDuoMode(sdrplay_api_DeviceT *currDevice, sdrplay_api_DeviceParamsT **deviceParams, + sdrplay_api_RspDuoModeT rspDuoMode, double sampleRate, sdrplay_api_TunerSelectT tuner, + sdrplay_api_Bw_MHzT bwType, sdrplay_api_If_kHzT ifType, sdrplay_api_RspDuo_AmPortSelectT tuner1AmPortSel); + +#ifdef __cplusplus +} +#endif + +#endif //SDRPLAY_API_H diff --git a/sdrplay-api/api/v3_11/sdrplay_api_callback.h b/sdrplay-api/api/v3_11/sdrplay_api_callback.h new file mode 100644 index 000000000..0da80502a --- /dev/null +++ b/sdrplay-api/api/v3_11/sdrplay_api_callback.h @@ -0,0 +1,79 @@ +#ifndef SDRPLAY_API_CALLBACK_H +#define SDRPLAY_API_CALLBACK_H + +// Event callback enums +typedef enum +{ + sdrplay_api_Overload_Detected = 0, + sdrplay_api_Overload_Corrected = 1, +} sdrplay_api_PowerOverloadCbEventIdT; + +typedef enum +{ + sdrplay_api_MasterInitialised = 0, + sdrplay_api_SlaveAttached = 1, + sdrplay_api_SlaveDetached = 2, + sdrplay_api_SlaveInitialised = 3, + sdrplay_api_SlaveUninitialised = 4, + sdrplay_api_MasterDllDisappeared = 5, + sdrplay_api_SlaveDllDisappeared = 6, +} sdrplay_api_RspDuoModeCbEventIdT; + +typedef enum +{ + sdrplay_api_GainChange = 0, + sdrplay_api_PowerOverloadChange = 1, + sdrplay_api_DeviceRemoved = 2, + sdrplay_api_RspDuoModeChange = 3, + sdrplay_api_DeviceFailure = 4, +} sdrplay_api_EventT; + +// Event callback parameter structs +typedef struct +{ + unsigned int gRdB; + unsigned int lnaGRdB; + double currGain; +} sdrplay_api_GainCbParamT; + +typedef struct +{ + sdrplay_api_PowerOverloadCbEventIdT powerOverloadChangeType; +} sdrplay_api_PowerOverloadCbParamT; + +typedef struct +{ + sdrplay_api_RspDuoModeCbEventIdT modeChangeType; +} sdrplay_api_RspDuoModeCbParamT; + +// Event parameters overlay +typedef union +{ + sdrplay_api_GainCbParamT gainParams; + sdrplay_api_PowerOverloadCbParamT powerOverloadParams; + sdrplay_api_RspDuoModeCbParamT rspDuoModeParams; +} sdrplay_api_EventParamsT; + +// Stream callback parameter structs +typedef struct +{ + unsigned int firstSampleNum; + int grChanged; + int rfChanged; + int fsChanged; + unsigned int numSamples; +} sdrplay_api_StreamCbParamsT; + +// Callback function prototypes +typedef void (*sdrplay_api_StreamCallback_t)(short *xi, short *xq, sdrplay_api_StreamCbParamsT *params, unsigned int numSamples, unsigned int reset, void *cbContext); +typedef void (*sdrplay_api_EventCallback_t)(sdrplay_api_EventT eventId, sdrplay_api_TunerSelectT tuner, sdrplay_api_EventParamsT *params, void *cbContext); + +// Callback function struct +typedef struct +{ + sdrplay_api_StreamCallback_t StreamACbFn; + sdrplay_api_StreamCallback_t StreamBCbFn; + sdrplay_api_EventCallback_t EventCbFn; +} sdrplay_api_CallbackFnsT; + +#endif //SDRPLAY_API_CALLBACK_H diff --git a/sdrplay-api/api/v3_11/sdrplay_api_control.h b/sdrplay-api/api/v3_11/sdrplay_api_control.h new file mode 100644 index 000000000..5a52a1046 --- /dev/null +++ b/sdrplay-api/api/v3_11/sdrplay_api_control.h @@ -0,0 +1,55 @@ +#ifndef SDRPLAY_API_CONTROL_H +#define SDRPLAY_API_CONTROL_H + +// Control parameter enums +typedef enum +{ + sdrplay_api_AGC_DISABLE = 0, + sdrplay_api_AGC_100HZ = 1, + sdrplay_api_AGC_50HZ = 2, + sdrplay_api_AGC_5HZ = 3, + sdrplay_api_AGC_CTRL_EN = 4 +} sdrplay_api_AgcControlT; + +typedef enum +{ + sdrplay_api_ADSB_DECIMATION = 0, + sdrplay_api_ADSB_NO_DECIMATION_LOWPASS = 1, + sdrplay_api_ADSB_NO_DECIMATION_BANDPASS_2MHZ = 2, + sdrplay_api_ADSB_NO_DECIMATION_BANDPASS_3MHZ = 3 +} sdrplay_api_AdsbModeT; + +// Control parameter structs +typedef struct +{ + unsigned char DCenable; // default: 1 + unsigned char IQenable; // default: 1 +} sdrplay_api_DcOffsetT; + +typedef struct +{ + unsigned char enable; // default: 0 + unsigned char decimationFactor; // default: 1 + unsigned char wideBandSignal; // default: 0 +} sdrplay_api_DecimationT; + +typedef struct +{ + sdrplay_api_AgcControlT enable; // default: sdrplay_api_AGC_50HZ + int setPoint_dBfs; // default: -60 + unsigned short attack_ms; // default: 0 + unsigned short decay_ms; // default: 0 + unsigned short decay_delay_ms; // default: 0 + unsigned short decay_threshold_dB; // default: 0 + int syncUpdate; // default: 0 +} sdrplay_api_AgcT; + +typedef struct +{ + sdrplay_api_DcOffsetT dcOffset; + sdrplay_api_DecimationT decimation; + sdrplay_api_AgcT agc; + sdrplay_api_AdsbModeT adsbMode; //default: sdrplay_api_ADSB_DECIMATION +} sdrplay_api_ControlParamsT; + +#endif //SDRPLAY_API_CONTROL_H diff --git a/sdrplay-api/api/v3_11/sdrplay_api_dev.h b/sdrplay-api/api/v3_11/sdrplay_api_dev.h new file mode 100644 index 000000000..5ac99ae25 --- /dev/null +++ b/sdrplay-api/api/v3_11/sdrplay_api_dev.h @@ -0,0 +1,51 @@ +#ifndef SDRPLAY_API_DEV_H +#define SDRPLAY_API_DEV_H + +#include "sdrplay_api_rsp1a.h" +#include "sdrplay_api_rsp2.h" +#include "sdrplay_api_rspDuo.h" +#include "sdrplay_api_rspDx.h" + +// Dev parameter enums +typedef enum +{ + sdrplay_api_ISOCH = 0, + sdrplay_api_BULK = 1 +} sdrplay_api_TransferModeT; + +// Dev parameter structs +typedef struct +{ + double fsHz; // default: 2000000.0 + unsigned char syncUpdate; // default: 0 + unsigned char reCal; // default: 0 +} sdrplay_api_FsFreqT; + +typedef struct +{ + unsigned int sampleNum; // default: 0 + unsigned int period; // default: 0 +} sdrplay_api_SyncUpdateT; + +typedef struct +{ + unsigned char resetGainUpdate; // default: 0 + unsigned char resetRfUpdate; // default: 0 + unsigned char resetFsUpdate; // default: 0 +} sdrplay_api_ResetFlagsT; + +typedef struct +{ + double ppm; // default: 0.0 + sdrplay_api_FsFreqT fsFreq; + sdrplay_api_SyncUpdateT syncUpdate; + sdrplay_api_ResetFlagsT resetFlags; + sdrplay_api_TransferModeT mode; // default: sdrplay_api_ISOCH + unsigned int samplesPerPkt; // default: 0 (output param) + sdrplay_api_Rsp1aParamsT rsp1aParams; + sdrplay_api_Rsp2ParamsT rsp2Params; + sdrplay_api_RspDuoParamsT rspDuoParams; + sdrplay_api_RspDxParamsT rspDxParams; +} sdrplay_api_DevParamsT; + +#endif //SDRPLAY_API_DEV_H diff --git a/sdrplay-api/api/v3_11/sdrplay_api_rsp1a.h b/sdrplay-api/api/v3_11/sdrplay_api_rsp1a.h new file mode 100644 index 000000000..3affbcc3e --- /dev/null +++ b/sdrplay-api/api/v3_11/sdrplay_api_rsp1a.h @@ -0,0 +1,22 @@ +#ifndef SDRPLAY_API_RSP1A_H +#define SDRPLAY_API_RSP1A_H + +#define RSPIA_NUM_LNA_STATES 10 +#define RSPIA_NUM_LNA_STATES_AM 7 +#define RSPIA_NUM_LNA_STATES_LBAND 9 + +// RSP1A parameter enums + +// RSP1A parameter structs +typedef struct +{ + unsigned char rfNotchEnable; // default: 0 + unsigned char rfDabNotchEnable; // default: 0 +} sdrplay_api_Rsp1aParamsT; + +typedef struct +{ + unsigned char biasTEnable; // default: 0 +} sdrplay_api_Rsp1aTunerParamsT; + +#endif //SDRPLAY_API_RSP1A_H diff --git a/sdrplay-api/api/v3_11/sdrplay_api_rsp2.h b/sdrplay-api/api/v3_11/sdrplay_api_rsp2.h new file mode 100644 index 000000000..930d3e956 --- /dev/null +++ b/sdrplay-api/api/v3_11/sdrplay_api_rsp2.h @@ -0,0 +1,35 @@ +#ifndef SDRPLAY_API_RSP2_H +#define SDRPLAY_API_RSP2_H + +#define RSPII_NUM_LNA_STATES 9 +#define RSPII_NUM_LNA_STATES_AMPORT 5 +#define RSPII_NUM_LNA_STATES_420MHZ 6 + +// RSP2 parameter enums +typedef enum +{ + sdrplay_api_Rsp2_ANTENNA_A = 5, + sdrplay_api_Rsp2_ANTENNA_B = 6, +} sdrplay_api_Rsp2_AntennaSelectT; + +typedef enum +{ + sdrplay_api_Rsp2_AMPORT_1 = 1, + sdrplay_api_Rsp2_AMPORT_2 = 0, +} sdrplay_api_Rsp2_AmPortSelectT; + +// RSP2 parameter structs +typedef struct +{ + unsigned char extRefOutputEn; // default: 0 +} sdrplay_api_Rsp2ParamsT; + +typedef struct +{ + unsigned char biasTEnable; // default: 0 + sdrplay_api_Rsp2_AmPortSelectT amPortSel; // default: sdrplay_api_Rsp2_AMPORT_2 + sdrplay_api_Rsp2_AntennaSelectT antennaSel; // default: sdrplay_api_Rsp2_ANTENNA_A + unsigned char rfNotchEnable; // default: 0 +} sdrplay_api_Rsp2TunerParamsT; + +#endif //SDRPLAY_API_RSP2_H diff --git a/sdrplay-api/api/v3_11/sdrplay_api_rspDuo.h b/sdrplay-api/api/v3_11/sdrplay_api_rspDuo.h new file mode 100644 index 000000000..3c4566350 --- /dev/null +++ b/sdrplay-api/api/v3_11/sdrplay_api_rspDuo.h @@ -0,0 +1,40 @@ +#ifndef SDRPLAY_API_RSPduo_H +#define SDRPLAY_API_RSPduo_H + +#define RSPDUO_NUM_LNA_STATES 10 +#define RSPDUO_NUM_LNA_STATES_AMPORT 5 +#define RSPDUO_NUM_LNA_STATES_AM 7 +#define RSPDUO_NUM_LNA_STATES_LBAND 9 + +// RSPduo parameter enums +typedef enum +{ + sdrplay_api_RspDuoMode_Unknown = 0, + sdrplay_api_RspDuoMode_Single_Tuner = 1, + sdrplay_api_RspDuoMode_Dual_Tuner = 2, + sdrplay_api_RspDuoMode_Master = 4, + sdrplay_api_RspDuoMode_Slave = 8, +} sdrplay_api_RspDuoModeT; + +typedef enum +{ + sdrplay_api_RspDuo_AMPORT_1 = 1, + sdrplay_api_RspDuo_AMPORT_2 = 0, +} sdrplay_api_RspDuo_AmPortSelectT; + +// RSPduo parameter structs +typedef struct +{ + int extRefOutputEn; // default: 0 +} sdrplay_api_RspDuoParamsT; + +typedef struct +{ + unsigned char biasTEnable; // default: 0 + sdrplay_api_RspDuo_AmPortSelectT tuner1AmPortSel; // default: sdrplay_api_RspDuo_AMPORT_2 + unsigned char tuner1AmNotchEnable; // default: 0 + unsigned char rfNotchEnable; // default: 0 + unsigned char rfDabNotchEnable; // default: 0 +} sdrplay_api_RspDuoTunerParamsT; + +#endif //SDRPLAY_API_RSPduo_H diff --git a/sdrplay-api/api/v3_11/sdrplay_api_rspDx.h b/sdrplay-api/api/v3_11/sdrplay_api_rspDx.h new file mode 100644 index 000000000..0528de96c --- /dev/null +++ b/sdrplay-api/api/v3_11/sdrplay_api_rspDx.h @@ -0,0 +1,46 @@ +#ifndef SDRPLAY_API_RSPDX_H +#define SDRPLAY_API_RSPDX_H + +#include "sdrplay_api_tuner.h" + +#define RSPDX_NUM_LNA_STATES 28 // Number of LNA states in all bands (except where defined differently below) +#define RSPDX_NUM_LNA_STATES_AMPORT2_0_12 19 // Number of LNA states when using AM Port 2 between 0 and 12MHz +#define RSPDX_NUM_LNA_STATES_AMPORT2_12_50 20 // Number of LNA states when using AM Port 2 between 12 and 50MHz +#define RSPDX_NUM_LNA_STATES_AMPORT2_50_60 25 // Number of LNA states when using AM Port 2 between 50 and 60MHz +#define RSPDX_NUM_LNA_STATES_VHF_BAND3 27 // Number of LNA states in VHF and Band3 +#define RSPDX_NUM_LNA_STATES_420MHZ 21 // Number of LNA states in 420MHz band +#define RSPDX_NUM_LNA_STATES_LBAND 19 // Number of LNA states in L-band +#define RSPDX_NUM_LNA_STATES_DX 22 // Number of LNA states in DX path + +// RSPdx parameter enums +typedef enum +{ + sdrplay_api_RspDx_ANTENNA_A = 0, + sdrplay_api_RspDx_ANTENNA_B = 1, + sdrplay_api_RspDx_ANTENNA_C = 2, +} sdrplay_api_RspDx_AntennaSelectT; + +typedef enum +{ + sdrplay_api_RspDx_HDRMODE_BW_0_200 = 0, + sdrplay_api_RspDx_HDRMODE_BW_0_500 = 1, + sdrplay_api_RspDx_HDRMODE_BW_1_200 = 2, + sdrplay_api_RspDx_HDRMODE_BW_1_700 = 3, +} sdrplay_api_RspDx_HdrModeBwT; + +// RSPdx parameter structs +typedef struct +{ + unsigned char hdrEnable; // default: 0 + unsigned char biasTEnable; // default: 0 + sdrplay_api_RspDx_AntennaSelectT antennaSel; // default: sdrplay_api_RspDx_ANTENNA_A + unsigned char rfNotchEnable; // default: 0 + unsigned char rfDabNotchEnable; // default: 0 +} sdrplay_api_RspDxParamsT; + +typedef struct +{ + sdrplay_api_RspDx_HdrModeBwT hdrBw; // default: sdrplay_api_RspDx_HDRMODE_BW_1_700 +} sdrplay_api_RspDxTunerParamsT; + +#endif //SDRPLAY_API_RSPDX_H diff --git a/sdrplay-api/api/v3_11/sdrplay_api_rx_channel.h b/sdrplay-api/api/v3_11/sdrplay_api_rx_channel.h new file mode 100644 index 000000000..010080402 --- /dev/null +++ b/sdrplay-api/api/v3_11/sdrplay_api_rx_channel.h @@ -0,0 +1,21 @@ +#ifndef SDRPLAY_API_RX_CHANNEL_H +#define SDRPLAY_API_RX_CHANNEL_H + +#include "sdrplay_api_tuner.h" +#include "sdrplay_api_control.h" +#include "sdrplay_api_rsp1a.h" +#include "sdrplay_api_rsp2.h" +#include "sdrplay_api_rspDuo.h" +#include "sdrplay_api_rspDx.h" + +typedef struct +{ + sdrplay_api_TunerParamsT tunerParams; + sdrplay_api_ControlParamsT ctrlParams; + sdrplay_api_Rsp1aTunerParamsT rsp1aTunerParams; + sdrplay_api_Rsp2TunerParamsT rsp2TunerParams; + sdrplay_api_RspDuoTunerParamsT rspDuoTunerParams; + sdrplay_api_RspDxTunerParamsT rspDxTunerParams; +} sdrplay_api_RxChannelParamsT; + +#endif //SDRPLAY_API_RX_CHANNEL_H diff --git a/sdrplay-api/api/v3_11/sdrplay_api_tuner.h b/sdrplay-api/api/v3_11/sdrplay_api_tuner.h new file mode 100644 index 000000000..a5c446d61 --- /dev/null +++ b/sdrplay-api/api/v3_11/sdrplay_api_tuner.h @@ -0,0 +1,93 @@ +#ifndef SDRPLAY_API_TUNER_H +#define SDRPLAY_API_TUNER_H + +#define MAX_BB_GR (59) + +// Tuner parameter enums +typedef enum +{ + sdrplay_api_BW_Undefined = 0, + sdrplay_api_BW_0_200 = 200, + sdrplay_api_BW_0_300 = 300, + sdrplay_api_BW_0_600 = 600, + sdrplay_api_BW_1_536 = 1536, + sdrplay_api_BW_5_000 = 5000, + sdrplay_api_BW_6_000 = 6000, + sdrplay_api_BW_7_000 = 7000, + sdrplay_api_BW_8_000 = 8000 +} sdrplay_api_Bw_MHzT; + +typedef enum +{ + sdrplay_api_IF_Undefined = -1, + sdrplay_api_IF_Zero = 0, + sdrplay_api_IF_0_450 = 450, + sdrplay_api_IF_1_620 = 1620, + sdrplay_api_IF_2_048 = 2048 +} sdrplay_api_If_kHzT; + +typedef enum +{ + sdrplay_api_LO_Undefined = 0, + sdrplay_api_LO_Auto = 1, + sdrplay_api_LO_120MHz = 2, + sdrplay_api_LO_144MHz = 3, + sdrplay_api_LO_168MHz = 4 +} sdrplay_api_LoModeT; + +typedef enum +{ + sdrplay_api_EXTENDED_MIN_GR = 0, + sdrplay_api_NORMAL_MIN_GR = 20 +} sdrplay_api_MinGainReductionT; + +typedef enum +{ + sdrplay_api_Tuner_Neither = 0, + sdrplay_api_Tuner_A = 1, + sdrplay_api_Tuner_B = 2, + sdrplay_api_Tuner_Both = 3, +} sdrplay_api_TunerSelectT; + +// Tuner parameter structs +typedef struct +{ + float curr; + float max; + float min; +} sdrplay_api_GainValuesT; + +typedef struct +{ + int gRdB; // default: 50 + unsigned char LNAstate; // default: 0 + unsigned char syncUpdate; // default: 0 + sdrplay_api_MinGainReductionT minGr; // default: sdrplay_api_NORMAL_MIN_GR + sdrplay_api_GainValuesT gainVals; // output parameter +} sdrplay_api_GainT; + +typedef struct +{ + double rfHz; // default: 200000000.0 + unsigned char syncUpdate; // default: 0 +} sdrplay_api_RfFreqT; + +typedef struct +{ + unsigned char dcCal; // default: 3 (Periodic mode) + unsigned char speedUp; // default: 0 (No speedup) + int trackTime; // default: 1 (=> time in uSec = (72 * 3 * trackTime) / 24e6 = 9uSec) + int refreshRateTime; // default: 2048 (=> time in uSec = (72 * 3 * refreshRateTime) / 24e6 = 18432uSec) +} sdrplay_api_DcOffsetTunerT; + +typedef struct +{ + sdrplay_api_Bw_MHzT bwType; // default: sdrplay_api_BW_0_200 + sdrplay_api_If_kHzT ifType; // default: sdrplay_api_IF_Zero + sdrplay_api_LoModeT loMode; // default: sdrplay_api_LO_Auto + sdrplay_api_GainT gain; + sdrplay_api_RfFreqT rfFreq; + sdrplay_api_DcOffsetTunerT dcOffsetTuner; +} sdrplay_api_TunerParamsT; + +#endif //SDRPLAY_API_TUNER_H diff --git a/sdrplay-api/build.gradle b/sdrplay-api/build.gradle new file mode 100644 index 000000000..8a542e169 --- /dev/null +++ b/sdrplay-api/build.gradle @@ -0,0 +1,47 @@ +plugins { + id 'java' + id 'maven-publish' +} + +group 'com.github.DSheirer' +version '3.11.0.0' + +repositories { + mavenCentral() + maven { url "https://jitpack.io" } +} + +//Java 19 is required for this version of the Project Panama preview/incubator feature +java { + toolchain { + languageVersion = JavaLanguageVersion.of(19) + } +} + +dependencies { + implementation 'org.slf4j:slf4j-api:1.7.32' + testImplementation 'org.junit.jupiter:junit-jupiter-api:5.8.1' + testRuntimeOnly 'org.junit.jupiter:junit-jupiter-engine:5.8.1' +} + +/** + * This is needed for the JDK19 panama until it moves out of preview + */ +tasks.withType(JavaCompile) { + options.compilerArgs.add("--enable-preview") //Panama Foreign Function/Memory is preview in JDK 19 +} + + +test { + //Exclude all tests by default + exclude '**/*' + useJUnitPlatform() +} + +publishing { + publications { + mavenJava(MavenPublication) { + from components.java + } + } +} \ No newline at end of file diff --git a/sdrplay-api/src/main/java/com/github/dsheirer/sdrplay/api/v3_07/Constants$root.java b/sdrplay-api/src/main/java/com/github/dsheirer/sdrplay/api/v3_07/Constants$root.java new file mode 100644 index 000000000..898f4a81c --- /dev/null +++ b/sdrplay-api/src/main/java/com/github/dsheirer/sdrplay/api/v3_07/Constants$root.java @@ -0,0 +1,34 @@ +// Generated by jextract + +package com.github.dsheirer.sdrplay.api.v3_07; + +import static java.lang.foreign.ValueLayout.ADDRESS; +import static java.lang.foreign.ValueLayout.JAVA_BOOLEAN; +import static java.lang.foreign.ValueLayout.JAVA_BYTE; +import static java.lang.foreign.ValueLayout.JAVA_DOUBLE; +import static java.lang.foreign.ValueLayout.JAVA_FLOAT; +import static java.lang.foreign.ValueLayout.JAVA_INT; +import static java.lang.foreign.ValueLayout.JAVA_LONG; +import static java.lang.foreign.ValueLayout.JAVA_SHORT; +import static java.lang.foreign.ValueLayout.OfAddress; +import static java.lang.foreign.ValueLayout.OfBoolean; +import static java.lang.foreign.ValueLayout.OfByte; +import static java.lang.foreign.ValueLayout.OfDouble; +import static java.lang.foreign.ValueLayout.OfFloat; +import static java.lang.foreign.ValueLayout.OfInt; +import static java.lang.foreign.ValueLayout.OfLong; +import static java.lang.foreign.ValueLayout.OfShort; +public class Constants$root { + + static final OfBoolean C_BOOL$LAYOUT = JAVA_BOOLEAN; + static final OfByte C_CHAR$LAYOUT = JAVA_BYTE; + static final OfShort C_SHORT$LAYOUT = JAVA_SHORT.withBitAlignment(16); + static final OfInt C_INT$LAYOUT = JAVA_INT.withBitAlignment(32); + static final OfInt C_LONG$LAYOUT = JAVA_INT.withBitAlignment(32); + static final OfLong C_LONG_LONG$LAYOUT = JAVA_LONG.withBitAlignment(64); + static final OfFloat C_FLOAT$LAYOUT = JAVA_FLOAT.withBitAlignment(32); + static final OfDouble C_DOUBLE$LAYOUT = JAVA_DOUBLE.withBitAlignment(64); + static final OfAddress C_POINTER$LAYOUT = ADDRESS.withBitAlignment(64); +} + + diff --git a/sdrplay-api/src/main/java/com/github/dsheirer/sdrplay/api/v3_07/RuntimeHelper.java b/sdrplay-api/src/main/java/com/github/dsheirer/sdrplay/api/v3_07/RuntimeHelper.java new file mode 100644 index 000000000..28385ba41 --- /dev/null +++ b/sdrplay-api/src/main/java/com/github/dsheirer/sdrplay/api/v3_07/RuntimeHelper.java @@ -0,0 +1,228 @@ +package com.github.dsheirer.sdrplay.api.v3_07; +// Generated by jextract + +import java.lang.foreign.Addressable; +import java.lang.foreign.FunctionDescriptor; +import java.lang.foreign.GroupLayout; +import java.lang.foreign.Linker; +import java.lang.foreign.MemoryAddress; +import java.lang.foreign.MemoryLayout; +import java.lang.foreign.MemorySegment; +import java.lang.foreign.MemorySession; +import java.lang.foreign.SegmentAllocator; +import java.lang.foreign.SymbolLookup; +import java.lang.foreign.ValueLayout; +import java.lang.invoke.MethodHandle; +import java.lang.invoke.MethodHandles; +import java.lang.invoke.MethodType; + +import static java.lang.foreign.ValueLayout.ADDRESS; +import static java.lang.foreign.ValueLayout.JAVA_DOUBLE; +import static java.lang.foreign.ValueLayout.JAVA_LONG; + +final class RuntimeHelper { + + private RuntimeHelper() {} + private final static Linker LINKER = Linker.nativeLinker(); + private final static ClassLoader LOADER = RuntimeHelper.class.getClassLoader(); + private final static MethodHandles.Lookup MH_LOOKUP = MethodHandles.lookup(); + private final static SymbolLookup SYMBOL_LOOKUP; + + final static SegmentAllocator CONSTANT_ALLOCATOR = + (size, align) -> MemorySegment.allocateNative(size, align, MemorySession.openImplicit()); + + static { +// System.loadLibrary("libsdrplay_api"); + SymbolLookup loaderLookup = SymbolLookup.loaderLookup(); + SYMBOL_LOOKUP = name -> loaderLookup.lookup(name).or(() -> LINKER.defaultLookup().lookup(name)); + } + + static T requireNonNull(T obj, String symbolName) { + if (obj == null) { + throw new UnsatisfiedLinkError("unresolved symbol: " + symbolName); + } + return obj; + } + + private final static SegmentAllocator THROWING_ALLOCATOR = (x, y) -> { throw new AssertionError("should not reach here"); }; + + static final MemorySegment lookupGlobalVariable(String name, MemoryLayout layout) { + return SYMBOL_LOOKUP.lookup(name).map(symbol -> MemorySegment.ofAddress(symbol.address(), layout.byteSize(), MemorySession.openShared())).orElse(null); + } + + static final MethodHandle downcallHandle(String name, FunctionDescriptor fdesc) { + return SYMBOL_LOOKUP.lookup(name). + map(addr -> LINKER.downcallHandle(addr, fdesc)). + orElse(null); + } + + static final MethodHandle downcallHandle(FunctionDescriptor fdesc) { + return LINKER.downcallHandle(fdesc); + } + + static final MethodHandle downcallHandleVariadic(String name, FunctionDescriptor fdesc) { + return SYMBOL_LOOKUP.lookup(name). + map(addr -> VarargsInvoker.make(addr, fdesc)). + orElse(null); + } + + static final MemorySegment upcallStub(Class fi, Z z, FunctionDescriptor fdesc, MemorySession session) { + try { + MethodHandle handle = MH_LOOKUP.findVirtual(fi, "apply", Linker.upcallType(fdesc)); + handle = handle.bindTo(z); + return LINKER.upcallStub(handle, fdesc, session); + } catch (Throwable ex) { + throw new AssertionError(ex); + } + } + + static MemorySegment asArray(MemoryAddress addr, MemoryLayout layout, int numElements, MemorySession session) { + return MemorySegment.ofAddress(addr, numElements * layout.byteSize(), session); + } + + // Internals only below this point + + private static class VarargsInvoker { + private static final MethodHandle INVOKE_MH; + private final MemorySegment symbol; + private final FunctionDescriptor function; + + private VarargsInvoker(MemorySegment symbol, FunctionDescriptor function) { + this.symbol = symbol; + this.function = function; + } + + static { + try { + INVOKE_MH = MethodHandles.lookup().findVirtual(VarargsInvoker.class, "invoke", MethodType.methodType(Object.class, SegmentAllocator.class, Object[].class)); + } catch (ReflectiveOperationException e) { + throw new RuntimeException(e); + } + } + + static MethodHandle make(MemorySegment symbol, FunctionDescriptor function) { + VarargsInvoker invoker = new VarargsInvoker(symbol, function); + MethodHandle handle = INVOKE_MH.bindTo(invoker).asCollector(Object[].class, function.argumentLayouts().size() + 1); + MethodType mtype = MethodType.methodType(function.returnLayout().isPresent() ? carrier(function.returnLayout().get(), true) : void.class); + for (MemoryLayout layout : function.argumentLayouts()) { + mtype = mtype.appendParameterTypes(carrier(layout, false)); + } + mtype = mtype.appendParameterTypes(Object[].class); + if (mtype.returnType().equals(MemorySegment.class)) { + mtype = mtype.insertParameterTypes(0, SegmentAllocator.class); + } else { + handle = MethodHandles.insertArguments(handle, 0, THROWING_ALLOCATOR); + } + return handle.asType(mtype); + } + + static Class carrier(MemoryLayout layout, boolean ret) { + if (layout instanceof ValueLayout valueLayout) { + return (ret || valueLayout.carrier() != MemoryAddress.class) ? + valueLayout.carrier() : Addressable.class; + } else if (layout instanceof GroupLayout) { + return MemorySegment.class; + } else { + throw new AssertionError("Cannot get here!"); + } + } + + private Object invoke(SegmentAllocator allocator, Object[] args) throws Throwable { + // one trailing Object[] + int nNamedArgs = function.argumentLayouts().size(); + assert(args.length == nNamedArgs + 1); + // The last argument is the array of vararg collector + Object[] unnamedArgs = (Object[]) args[args.length - 1]; + + int argsCount = nNamedArgs + unnamedArgs.length; + Class[] argTypes = new Class[argsCount]; + MemoryLayout[] argLayouts = new MemoryLayout[nNamedArgs + unnamedArgs.length]; + + int pos = 0; + for (pos = 0; pos < nNamedArgs; pos++) { + argLayouts[pos] = function.argumentLayouts().get(pos); + } + + assert pos == nNamedArgs; + for (Object o: unnamedArgs) { + argLayouts[pos] = variadicLayout(normalize(o.getClass())); + pos++; + } + assert pos == argsCount; + + FunctionDescriptor f = (function.returnLayout().isEmpty()) ? + FunctionDescriptor.ofVoid(argLayouts) : + FunctionDescriptor.of(function.returnLayout().get(), argLayouts); + MethodHandle mh = LINKER.downcallHandle(symbol, f); + if (mh.type().returnType() == MemorySegment.class) { + mh = mh.bindTo(allocator); + } + // flatten argument list so that it can be passed to an asSpreader MH + Object[] allArgs = new Object[nNamedArgs + unnamedArgs.length]; + System.arraycopy(args, 0, allArgs, 0, nNamedArgs); + System.arraycopy(unnamedArgs, 0, allArgs, nNamedArgs, unnamedArgs.length); + + return mh.asSpreader(Object[].class, argsCount).invoke(allArgs); + } + + private static Class unboxIfNeeded(Class clazz) { + if (clazz == Boolean.class) { + return boolean.class; + } else if (clazz == Void.class) { + return void.class; + } else if (clazz == Byte.class) { + return byte.class; + } else if (clazz == Character.class) { + return char.class; + } else if (clazz == Short.class) { + return short.class; + } else if (clazz == Integer.class) { + return int.class; + } else if (clazz == Long.class) { + return long.class; + } else if (clazz == Float.class) { + return float.class; + } else if (clazz == Double.class) { + return double.class; + } else { + return clazz; + } + } + + private Class promote(Class c) { + if (c == byte.class || c == char.class || c == short.class || c == int.class) { + return long.class; + } else if (c == float.class) { + return double.class; + } else { + return c; + } + } + + private Class normalize(Class c) { + c = unboxIfNeeded(c); + if (c.isPrimitive()) { + return promote(c); + } + if (MemoryAddress.class.isAssignableFrom(c)) { + return MemoryAddress.class; + } + if (MemorySegment.class.isAssignableFrom(c)) { + return MemorySegment.class; + } + throw new IllegalArgumentException("Invalid type for ABI: " + c.getTypeName()); + } + + private MemoryLayout variadicLayout(Class c) { + if (c == long.class) { + return JAVA_LONG; + } else if (c == double.class) { + return JAVA_DOUBLE; + } else if (MemoryAddress.class.isAssignableFrom(c)) { + return ADDRESS; + } else { + throw new IllegalArgumentException("Unhandled variadic argument class: " + c); + } + } + } +} diff --git a/sdrplay-api/src/main/java/com/github/dsheirer/sdrplay/api/v3_07/constants$0.java b/sdrplay-api/src/main/java/com/github/dsheirer/sdrplay/api/v3_07/constants$0.java new file mode 100644 index 000000000..d28b2b571 --- /dev/null +++ b/sdrplay-api/src/main/java/com/github/dsheirer/sdrplay/api/v3_07/constants$0.java @@ -0,0 +1,35 @@ +// Generated by jextract + +package com.github.dsheirer.sdrplay.api.v3_07; + +import java.lang.foreign.FunctionDescriptor; +import java.lang.invoke.MethodHandle; +class constants$0 { + + static final FunctionDescriptor sdrplay_api_StreamCallback_t$FUNC = FunctionDescriptor.ofVoid( + Constants$root.C_POINTER$LAYOUT, + Constants$root.C_POINTER$LAYOUT, + Constants$root.C_POINTER$LAYOUT, + Constants$root.C_LONG$LAYOUT, + Constants$root.C_LONG$LAYOUT, + Constants$root.C_POINTER$LAYOUT + ); + static final MethodHandle sdrplay_api_StreamCallback_t$MH = RuntimeHelper.downcallHandle( + constants$0.sdrplay_api_StreamCallback_t$FUNC + ); + static final FunctionDescriptor sdrplay_api_EventCallback_t$FUNC = FunctionDescriptor.ofVoid( + Constants$root.C_LONG$LAYOUT, + Constants$root.C_LONG$LAYOUT, + Constants$root.C_POINTER$LAYOUT, + Constants$root.C_POINTER$LAYOUT + ); + static final MethodHandle sdrplay_api_EventCallback_t$MH = RuntimeHelper.downcallHandle( + constants$0.sdrplay_api_EventCallback_t$FUNC + ); + static final FunctionDescriptor sdrplay_api_Open_t$FUNC = FunctionDescriptor.of(Constants$root.C_LONG$LAYOUT); + static final MethodHandle sdrplay_api_Open_t$MH = RuntimeHelper.downcallHandle( + constants$0.sdrplay_api_Open_t$FUNC + ); +} + + diff --git a/sdrplay-api/src/main/java/com/github/dsheirer/sdrplay/api/v3_07/constants$1.java b/sdrplay-api/src/main/java/com/github/dsheirer/sdrplay/api/v3_07/constants$1.java new file mode 100644 index 000000000..daf28fe8d --- /dev/null +++ b/sdrplay-api/src/main/java/com/github/dsheirer/sdrplay/api/v3_07/constants$1.java @@ -0,0 +1,25 @@ +// Generated by jextract + +package com.github.dsheirer.sdrplay.api.v3_07; + +import java.lang.foreign.FunctionDescriptor; +import java.lang.invoke.MethodHandle; +class constants$1 { + + static final FunctionDescriptor sdrplay_api_Close_t$FUNC = FunctionDescriptor.of(Constants$root.C_LONG$LAYOUT); + static final MethodHandle sdrplay_api_Close_t$MH = RuntimeHelper.downcallHandle( + constants$1.sdrplay_api_Close_t$FUNC + ); + static final FunctionDescriptor sdrplay_api_ApiVersion_t$FUNC = FunctionDescriptor.of(Constants$root.C_LONG$LAYOUT, + Constants$root.C_POINTER$LAYOUT + ); + static final MethodHandle sdrplay_api_ApiVersion_t$MH = RuntimeHelper.downcallHandle( + constants$1.sdrplay_api_ApiVersion_t$FUNC + ); + static final FunctionDescriptor sdrplay_api_LockDeviceApi_t$FUNC = FunctionDescriptor.of(Constants$root.C_LONG$LAYOUT); + static final MethodHandle sdrplay_api_LockDeviceApi_t$MH = RuntimeHelper.downcallHandle( + constants$1.sdrplay_api_LockDeviceApi_t$FUNC + ); +} + + diff --git a/sdrplay-api/src/main/java/com/github/dsheirer/sdrplay/api/v3_07/constants$10.java b/sdrplay-api/src/main/java/com/github/dsheirer/sdrplay/api/v3_07/constants$10.java new file mode 100644 index 000000000..71c755949 --- /dev/null +++ b/sdrplay-api/src/main/java/com/github/dsheirer/sdrplay/api/v3_07/constants$10.java @@ -0,0 +1,25 @@ +// Generated by jextract + +package com.github.dsheirer.sdrplay.api.v3_07; + +import java.lang.foreign.FunctionDescriptor; +import java.lang.invoke.MethodHandle; +class constants$10 { + + static final FunctionDescriptor sdrplay_api_SwapRspDuoMode$FUNC = FunctionDescriptor.of(Constants$root.C_LONG$LAYOUT, + Constants$root.C_POINTER$LAYOUT, + Constants$root.C_POINTER$LAYOUT, + Constants$root.C_LONG$LAYOUT, + Constants$root.C_DOUBLE$LAYOUT, + Constants$root.C_LONG$LAYOUT, + Constants$root.C_LONG$LAYOUT, + Constants$root.C_LONG$LAYOUT, + Constants$root.C_LONG$LAYOUT + ); + static final MethodHandle sdrplay_api_SwapRspDuoMode$MH = RuntimeHelper.downcallHandle( + "sdrplay_api_SwapRspDuoMode", + constants$10.sdrplay_api_SwapRspDuoMode$FUNC + ); +} + + diff --git a/sdrplay-api/src/main/java/com/github/dsheirer/sdrplay/api/v3_07/constants$2.java b/sdrplay-api/src/main/java/com/github/dsheirer/sdrplay/api/v3_07/constants$2.java new file mode 100644 index 000000000..90db15b83 --- /dev/null +++ b/sdrplay-api/src/main/java/com/github/dsheirer/sdrplay/api/v3_07/constants$2.java @@ -0,0 +1,29 @@ +// Generated by jextract + +package com.github.dsheirer.sdrplay.api.v3_07; + +import java.lang.foreign.FunctionDescriptor; +import java.lang.invoke.MethodHandle; +class constants$2 { + + static final FunctionDescriptor sdrplay_api_UnlockDeviceApi_t$FUNC = FunctionDescriptor.of(Constants$root.C_LONG$LAYOUT); + static final MethodHandle sdrplay_api_UnlockDeviceApi_t$MH = RuntimeHelper.downcallHandle( + constants$2.sdrplay_api_UnlockDeviceApi_t$FUNC + ); + static final FunctionDescriptor sdrplay_api_GetDevices_t$FUNC = FunctionDescriptor.of(Constants$root.C_LONG$LAYOUT, + Constants$root.C_POINTER$LAYOUT, + Constants$root.C_POINTER$LAYOUT, + Constants$root.C_LONG$LAYOUT + ); + static final MethodHandle sdrplay_api_GetDevices_t$MH = RuntimeHelper.downcallHandle( + constants$2.sdrplay_api_GetDevices_t$FUNC + ); + static final FunctionDescriptor sdrplay_api_SelectDevice_t$FUNC = FunctionDescriptor.of(Constants$root.C_LONG$LAYOUT, + Constants$root.C_POINTER$LAYOUT + ); + static final MethodHandle sdrplay_api_SelectDevice_t$MH = RuntimeHelper.downcallHandle( + constants$2.sdrplay_api_SelectDevice_t$FUNC + ); +} + + diff --git a/sdrplay-api/src/main/java/com/github/dsheirer/sdrplay/api/v3_07/constants$3.java b/sdrplay-api/src/main/java/com/github/dsheirer/sdrplay/api/v3_07/constants$3.java new file mode 100644 index 000000000..6e98cf9fb --- /dev/null +++ b/sdrplay-api/src/main/java/com/github/dsheirer/sdrplay/api/v3_07/constants$3.java @@ -0,0 +1,29 @@ +// Generated by jextract + +package com.github.dsheirer.sdrplay.api.v3_07; + +import java.lang.foreign.FunctionDescriptor; +import java.lang.invoke.MethodHandle; +class constants$3 { + + static final FunctionDescriptor sdrplay_api_ReleaseDevice_t$FUNC = FunctionDescriptor.of(Constants$root.C_LONG$LAYOUT, + Constants$root.C_POINTER$LAYOUT + ); + static final MethodHandle sdrplay_api_ReleaseDevice_t$MH = RuntimeHelper.downcallHandle( + constants$3.sdrplay_api_ReleaseDevice_t$FUNC + ); + static final FunctionDescriptor sdrplay_api_GetErrorString_t$FUNC = FunctionDescriptor.of(Constants$root.C_POINTER$LAYOUT, + Constants$root.C_LONG$LAYOUT + ); + static final MethodHandle sdrplay_api_GetErrorString_t$MH = RuntimeHelper.downcallHandle( + constants$3.sdrplay_api_GetErrorString_t$FUNC + ); + static final FunctionDescriptor sdrplay_api_GetLastError_t$FUNC = FunctionDescriptor.of(Constants$root.C_POINTER$LAYOUT, + Constants$root.C_POINTER$LAYOUT + ); + static final MethodHandle sdrplay_api_GetLastError_t$MH = RuntimeHelper.downcallHandle( + constants$3.sdrplay_api_GetLastError_t$FUNC + ); +} + + diff --git a/sdrplay-api/src/main/java/com/github/dsheirer/sdrplay/api/v3_07/constants$4.java b/sdrplay-api/src/main/java/com/github/dsheirer/sdrplay/api/v3_07/constants$4.java new file mode 100644 index 000000000..937135618 --- /dev/null +++ b/sdrplay-api/src/main/java/com/github/dsheirer/sdrplay/api/v3_07/constants$4.java @@ -0,0 +1,29 @@ +// Generated by jextract + +package com.github.dsheirer.sdrplay.api.v3_07; + +import java.lang.foreign.FunctionDescriptor; +import java.lang.invoke.MethodHandle; +class constants$4 { + + static final FunctionDescriptor sdrplay_api_DisableHeartbeat_t$FUNC = FunctionDescriptor.of(Constants$root.C_LONG$LAYOUT); + static final MethodHandle sdrplay_api_DisableHeartbeat_t$MH = RuntimeHelper.downcallHandle( + constants$4.sdrplay_api_DisableHeartbeat_t$FUNC + ); + static final FunctionDescriptor sdrplay_api_DebugEnable_t$FUNC = FunctionDescriptor.of(Constants$root.C_LONG$LAYOUT, + Constants$root.C_POINTER$LAYOUT, + Constants$root.C_LONG$LAYOUT + ); + static final MethodHandle sdrplay_api_DebugEnable_t$MH = RuntimeHelper.downcallHandle( + constants$4.sdrplay_api_DebugEnable_t$FUNC + ); + static final FunctionDescriptor sdrplay_api_GetDeviceParams_t$FUNC = FunctionDescriptor.of(Constants$root.C_LONG$LAYOUT, + Constants$root.C_POINTER$LAYOUT, + Constants$root.C_POINTER$LAYOUT + ); + static final MethodHandle sdrplay_api_GetDeviceParams_t$MH = RuntimeHelper.downcallHandle( + constants$4.sdrplay_api_GetDeviceParams_t$FUNC + ); +} + + diff --git a/sdrplay-api/src/main/java/com/github/dsheirer/sdrplay/api/v3_07/constants$5.java b/sdrplay-api/src/main/java/com/github/dsheirer/sdrplay/api/v3_07/constants$5.java new file mode 100644 index 000000000..6350e37aa --- /dev/null +++ b/sdrplay-api/src/main/java/com/github/dsheirer/sdrplay/api/v3_07/constants$5.java @@ -0,0 +1,34 @@ +// Generated by jextract + +package com.github.dsheirer.sdrplay.api.v3_07; + +import java.lang.foreign.FunctionDescriptor; +import java.lang.invoke.MethodHandle; +class constants$5 { + + static final FunctionDescriptor sdrplay_api_Init_t$FUNC = FunctionDescriptor.of(Constants$root.C_LONG$LAYOUT, + Constants$root.C_POINTER$LAYOUT, + Constants$root.C_POINTER$LAYOUT, + Constants$root.C_POINTER$LAYOUT + ); + static final MethodHandle sdrplay_api_Init_t$MH = RuntimeHelper.downcallHandle( + constants$5.sdrplay_api_Init_t$FUNC + ); + static final FunctionDescriptor sdrplay_api_Uninit_t$FUNC = FunctionDescriptor.of(Constants$root.C_LONG$LAYOUT, + Constants$root.C_POINTER$LAYOUT + ); + static final MethodHandle sdrplay_api_Uninit_t$MH = RuntimeHelper.downcallHandle( + constants$5.sdrplay_api_Uninit_t$FUNC + ); + static final FunctionDescriptor sdrplay_api_Update_t$FUNC = FunctionDescriptor.of(Constants$root.C_LONG$LAYOUT, + Constants$root.C_POINTER$LAYOUT, + Constants$root.C_LONG$LAYOUT, + Constants$root.C_LONG$LAYOUT, + Constants$root.C_LONG$LAYOUT + ); + static final MethodHandle sdrplay_api_Update_t$MH = RuntimeHelper.downcallHandle( + constants$5.sdrplay_api_Update_t$FUNC + ); +} + + diff --git a/sdrplay-api/src/main/java/com/github/dsheirer/sdrplay/api/v3_07/constants$6.java b/sdrplay-api/src/main/java/com/github/dsheirer/sdrplay/api/v3_07/constants$6.java new file mode 100644 index 000000000..0ae887d52 --- /dev/null +++ b/sdrplay-api/src/main/java/com/github/dsheirer/sdrplay/api/v3_07/constants$6.java @@ -0,0 +1,38 @@ +// Generated by jextract + +package com.github.dsheirer.sdrplay.api.v3_07; + +import java.lang.foreign.FunctionDescriptor; +import java.lang.invoke.MethodHandle; +class constants$6 { + + static final FunctionDescriptor sdrplay_api_SwapRspDuoActiveTuner_t$FUNC = FunctionDescriptor.of(Constants$root.C_LONG$LAYOUT, + Constants$root.C_POINTER$LAYOUT, + Constants$root.C_POINTER$LAYOUT, + Constants$root.C_LONG$LAYOUT + ); + static final MethodHandle sdrplay_api_SwapRspDuoActiveTuner_t$MH = RuntimeHelper.downcallHandle( + constants$6.sdrplay_api_SwapRspDuoActiveTuner_t$FUNC + ); + static final FunctionDescriptor sdrplay_api_SwapRspDuoDualTunerModeSampleRate_t$FUNC = FunctionDescriptor.of(Constants$root.C_LONG$LAYOUT, + Constants$root.C_POINTER$LAYOUT + ); + static final MethodHandle sdrplay_api_SwapRspDuoDualTunerModeSampleRate_t$MH = RuntimeHelper.downcallHandle( + constants$6.sdrplay_api_SwapRspDuoDualTunerModeSampleRate_t$FUNC + ); + static final FunctionDescriptor sdrplay_api_SwapRspDuoMode_t$FUNC = FunctionDescriptor.of(Constants$root.C_LONG$LAYOUT, + Constants$root.C_POINTER$LAYOUT, + Constants$root.C_POINTER$LAYOUT, + Constants$root.C_LONG$LAYOUT, + Constants$root.C_DOUBLE$LAYOUT, + Constants$root.C_LONG$LAYOUT, + Constants$root.C_LONG$LAYOUT, + Constants$root.C_LONG$LAYOUT, + Constants$root.C_LONG$LAYOUT + ); + static final MethodHandle sdrplay_api_SwapRspDuoMode_t$MH = RuntimeHelper.downcallHandle( + constants$6.sdrplay_api_SwapRspDuoMode_t$FUNC + ); +} + + diff --git a/sdrplay-api/src/main/java/com/github/dsheirer/sdrplay/api/v3_07/constants$7.java b/sdrplay-api/src/main/java/com/github/dsheirer/sdrplay/api/v3_07/constants$7.java new file mode 100644 index 000000000..01b1cbc2a --- /dev/null +++ b/sdrplay-api/src/main/java/com/github/dsheirer/sdrplay/api/v3_07/constants$7.java @@ -0,0 +1,47 @@ +// Generated by jextract + +package com.github.dsheirer.sdrplay.api.v3_07; + +import java.lang.foreign.FunctionDescriptor; +import java.lang.invoke.MethodHandle; +class constants$7 { + + static final FunctionDescriptor sdrplay_api_Open$FUNC = FunctionDescriptor.of(Constants$root.C_LONG$LAYOUT); + static final MethodHandle sdrplay_api_Open$MH = RuntimeHelper.downcallHandle( + "sdrplay_api_Open", + constants$7.sdrplay_api_Open$FUNC + ); + static final FunctionDescriptor sdrplay_api_Close$FUNC = FunctionDescriptor.of(Constants$root.C_LONG$LAYOUT); + static final MethodHandle sdrplay_api_Close$MH = RuntimeHelper.downcallHandle( + "sdrplay_api_Close", + constants$7.sdrplay_api_Close$FUNC + ); + static final FunctionDescriptor sdrplay_api_ApiVersion$FUNC = FunctionDescriptor.of(Constants$root.C_LONG$LAYOUT, + Constants$root.C_POINTER$LAYOUT + ); + static final MethodHandle sdrplay_api_ApiVersion$MH = RuntimeHelper.downcallHandle( + "sdrplay_api_ApiVersion", + constants$7.sdrplay_api_ApiVersion$FUNC + ); + static final FunctionDescriptor sdrplay_api_LockDeviceApi$FUNC = FunctionDescriptor.of(Constants$root.C_LONG$LAYOUT); + static final MethodHandle sdrplay_api_LockDeviceApi$MH = RuntimeHelper.downcallHandle( + "sdrplay_api_LockDeviceApi", + constants$7.sdrplay_api_LockDeviceApi$FUNC + ); + static final FunctionDescriptor sdrplay_api_UnlockDeviceApi$FUNC = FunctionDescriptor.of(Constants$root.C_LONG$LAYOUT); + static final MethodHandle sdrplay_api_UnlockDeviceApi$MH = RuntimeHelper.downcallHandle( + "sdrplay_api_UnlockDeviceApi", + constants$7.sdrplay_api_UnlockDeviceApi$FUNC + ); + static final FunctionDescriptor sdrplay_api_GetDevices$FUNC = FunctionDescriptor.of(Constants$root.C_LONG$LAYOUT, + Constants$root.C_POINTER$LAYOUT, + Constants$root.C_POINTER$LAYOUT, + Constants$root.C_LONG$LAYOUT + ); + static final MethodHandle sdrplay_api_GetDevices$MH = RuntimeHelper.downcallHandle( + "sdrplay_api_GetDevices", + constants$7.sdrplay_api_GetDevices$FUNC + ); +} + + diff --git a/sdrplay-api/src/main/java/com/github/dsheirer/sdrplay/api/v3_07/constants$8.java b/sdrplay-api/src/main/java/com/github/dsheirer/sdrplay/api/v3_07/constants$8.java new file mode 100644 index 000000000..a63156010 --- /dev/null +++ b/sdrplay-api/src/main/java/com/github/dsheirer/sdrplay/api/v3_07/constants$8.java @@ -0,0 +1,52 @@ +// Generated by jextract + +package com.github.dsheirer.sdrplay.api.v3_07; + +import java.lang.foreign.FunctionDescriptor; +import java.lang.invoke.MethodHandle; +class constants$8 { + + static final FunctionDescriptor sdrplay_api_SelectDevice$FUNC = FunctionDescriptor.of(Constants$root.C_LONG$LAYOUT, + Constants$root.C_POINTER$LAYOUT + ); + static final MethodHandle sdrplay_api_SelectDevice$MH = RuntimeHelper.downcallHandle( + "sdrplay_api_SelectDevice", + constants$8.sdrplay_api_SelectDevice$FUNC + ); + static final FunctionDescriptor sdrplay_api_ReleaseDevice$FUNC = FunctionDescriptor.of(Constants$root.C_LONG$LAYOUT, + Constants$root.C_POINTER$LAYOUT + ); + static final MethodHandle sdrplay_api_ReleaseDevice$MH = RuntimeHelper.downcallHandle( + "sdrplay_api_ReleaseDevice", + constants$8.sdrplay_api_ReleaseDevice$FUNC + ); + static final FunctionDescriptor sdrplay_api_GetErrorString$FUNC = FunctionDescriptor.of(Constants$root.C_POINTER$LAYOUT, + Constants$root.C_LONG$LAYOUT + ); + static final MethodHandle sdrplay_api_GetErrorString$MH = RuntimeHelper.downcallHandle( + "sdrplay_api_GetErrorString", + constants$8.sdrplay_api_GetErrorString$FUNC + ); + static final FunctionDescriptor sdrplay_api_GetLastError$FUNC = FunctionDescriptor.of(Constants$root.C_POINTER$LAYOUT, + Constants$root.C_POINTER$LAYOUT + ); + static final MethodHandle sdrplay_api_GetLastError$MH = RuntimeHelper.downcallHandle( + "sdrplay_api_GetLastError", + constants$8.sdrplay_api_GetLastError$FUNC + ); + static final FunctionDescriptor sdrplay_api_DisableHeartbeat$FUNC = FunctionDescriptor.of(Constants$root.C_LONG$LAYOUT); + static final MethodHandle sdrplay_api_DisableHeartbeat$MH = RuntimeHelper.downcallHandle( + "sdrplay_api_DisableHeartbeat", + constants$8.sdrplay_api_DisableHeartbeat$FUNC + ); + static final FunctionDescriptor sdrplay_api_DebugEnable$FUNC = FunctionDescriptor.of(Constants$root.C_LONG$LAYOUT, + Constants$root.C_POINTER$LAYOUT, + Constants$root.C_LONG$LAYOUT + ); + static final MethodHandle sdrplay_api_DebugEnable$MH = RuntimeHelper.downcallHandle( + "sdrplay_api_DebugEnable", + constants$8.sdrplay_api_DebugEnable$FUNC + ); +} + + diff --git a/sdrplay-api/src/main/java/com/github/dsheirer/sdrplay/api/v3_07/constants$9.java b/sdrplay-api/src/main/java/com/github/dsheirer/sdrplay/api/v3_07/constants$9.java new file mode 100644 index 000000000..482c7addd --- /dev/null +++ b/sdrplay-api/src/main/java/com/github/dsheirer/sdrplay/api/v3_07/constants$9.java @@ -0,0 +1,62 @@ +// Generated by jextract + +package com.github.dsheirer.sdrplay.api.v3_07; + +import java.lang.foreign.FunctionDescriptor; +import java.lang.invoke.MethodHandle; +class constants$9 { + + static final FunctionDescriptor sdrplay_api_GetDeviceParams$FUNC = FunctionDescriptor.of(Constants$root.C_LONG$LAYOUT, + Constants$root.C_POINTER$LAYOUT, + Constants$root.C_POINTER$LAYOUT + ); + static final MethodHandle sdrplay_api_GetDeviceParams$MH = RuntimeHelper.downcallHandle( + "sdrplay_api_GetDeviceParams", + constants$9.sdrplay_api_GetDeviceParams$FUNC + ); + static final FunctionDescriptor sdrplay_api_Init$FUNC = FunctionDescriptor.of(Constants$root.C_LONG$LAYOUT, + Constants$root.C_POINTER$LAYOUT, + Constants$root.C_POINTER$LAYOUT, + Constants$root.C_POINTER$LAYOUT + ); + static final MethodHandle sdrplay_api_Init$MH = RuntimeHelper.downcallHandle( + "sdrplay_api_Init", + constants$9.sdrplay_api_Init$FUNC + ); + static final FunctionDescriptor sdrplay_api_Uninit$FUNC = FunctionDescriptor.of(Constants$root.C_LONG$LAYOUT, + Constants$root.C_POINTER$LAYOUT + ); + static final MethodHandle sdrplay_api_Uninit$MH = RuntimeHelper.downcallHandle( + "sdrplay_api_Uninit", + constants$9.sdrplay_api_Uninit$FUNC + ); + static final FunctionDescriptor sdrplay_api_Update$FUNC = FunctionDescriptor.of(Constants$root.C_LONG$LAYOUT, + Constants$root.C_POINTER$LAYOUT, + Constants$root.C_LONG$LAYOUT, + Constants$root.C_LONG$LAYOUT, + Constants$root.C_LONG$LAYOUT + ); + static final MethodHandle sdrplay_api_Update$MH = RuntimeHelper.downcallHandle( + "sdrplay_api_Update", + constants$9.sdrplay_api_Update$FUNC + ); + static final FunctionDescriptor sdrplay_api_SwapRspDuoActiveTuner$FUNC = FunctionDescriptor.of(Constants$root.C_LONG$LAYOUT, + Constants$root.C_POINTER$LAYOUT, + Constants$root.C_POINTER$LAYOUT, + Constants$root.C_LONG$LAYOUT + ); + static final MethodHandle sdrplay_api_SwapRspDuoActiveTuner$MH = RuntimeHelper.downcallHandle( + "sdrplay_api_SwapRspDuoActiveTuner", + constants$9.sdrplay_api_SwapRspDuoActiveTuner$FUNC + ); + static final FunctionDescriptor sdrplay_api_SwapRspDuoDualTunerModeSampleRate$FUNC = FunctionDescriptor.of(Constants$root.C_LONG$LAYOUT, + Constants$root.C_POINTER$LAYOUT, + Constants$root.C_POINTER$LAYOUT + ); + static final MethodHandle sdrplay_api_SwapRspDuoDualTunerModeSampleRate$MH = RuntimeHelper.downcallHandle( + "sdrplay_api_SwapRspDuoDualTunerModeSampleRate", + constants$9.sdrplay_api_SwapRspDuoDualTunerModeSampleRate$FUNC + ); +} + + diff --git a/sdrplay-api/src/main/java/com/github/dsheirer/sdrplay/api/v3_07/sdrplay_api_AgcT.java b/sdrplay-api/src/main/java/com/github/dsheirer/sdrplay/api/v3_07/sdrplay_api_AgcT.java new file mode 100644 index 000000000..f0344317e --- /dev/null +++ b/sdrplay-api/src/main/java/com/github/dsheirer/sdrplay/api/v3_07/sdrplay_api_AgcT.java @@ -0,0 +1,146 @@ +// Generated by jextract + +package com.github.dsheirer.sdrplay.api.v3_07; + +import java.lang.foreign.GroupLayout; +import java.lang.foreign.MemoryAddress; +import java.lang.foreign.MemoryLayout; +import java.lang.foreign.MemorySegment; +import java.lang.foreign.MemorySession; +import java.lang.foreign.SegmentAllocator; +import java.lang.invoke.VarHandle; +public class sdrplay_api_AgcT { + + static final GroupLayout $struct$LAYOUT = MemoryLayout.structLayout( + Constants$root.C_LONG$LAYOUT.withName("enable"), + Constants$root.C_LONG$LAYOUT.withName("setPoint_dBfs"), + Constants$root.C_SHORT$LAYOUT.withName("attack_ms"), + Constants$root.C_SHORT$LAYOUT.withName("decay_ms"), + Constants$root.C_SHORT$LAYOUT.withName("decay_delay_ms"), + Constants$root.C_SHORT$LAYOUT.withName("decay_threshold_dB"), + Constants$root.C_LONG$LAYOUT.withName("syncUpdate") + ); + public static MemoryLayout $LAYOUT() { + return sdrplay_api_AgcT.$struct$LAYOUT; + } + static final VarHandle enable$VH = $struct$LAYOUT.varHandle(MemoryLayout.PathElement.groupElement("enable")); + public static VarHandle enable$VH() { + return sdrplay_api_AgcT.enable$VH; + } + public static int enable$get(MemorySegment seg) { + return (int)sdrplay_api_AgcT.enable$VH.get(seg); + } + public static void enable$set( MemorySegment seg, int x) { + sdrplay_api_AgcT.enable$VH.set(seg, x); + } + public static int enable$get(MemorySegment seg, long index) { + return (int)sdrplay_api_AgcT.enable$VH.get(seg.asSlice(index*sizeof())); + } + public static void enable$set(MemorySegment seg, long index, int x) { + sdrplay_api_AgcT.enable$VH.set(seg.asSlice(index*sizeof()), x); + } + static final VarHandle setPoint_dBfs$VH = $struct$LAYOUT.varHandle(MemoryLayout.PathElement.groupElement("setPoint_dBfs")); + public static VarHandle setPoint_dBfs$VH() { + return sdrplay_api_AgcT.setPoint_dBfs$VH; + } + public static int setPoint_dBfs$get(MemorySegment seg) { + return (int)sdrplay_api_AgcT.setPoint_dBfs$VH.get(seg); + } + public static void setPoint_dBfs$set( MemorySegment seg, int x) { + sdrplay_api_AgcT.setPoint_dBfs$VH.set(seg, x); + } + public static int setPoint_dBfs$get(MemorySegment seg, long index) { + return (int)sdrplay_api_AgcT.setPoint_dBfs$VH.get(seg.asSlice(index*sizeof())); + } + public static void setPoint_dBfs$set(MemorySegment seg, long index, int x) { + sdrplay_api_AgcT.setPoint_dBfs$VH.set(seg.asSlice(index*sizeof()), x); + } + static final VarHandle attack_ms$VH = $struct$LAYOUT.varHandle(MemoryLayout.PathElement.groupElement("attack_ms")); + public static VarHandle attack_ms$VH() { + return sdrplay_api_AgcT.attack_ms$VH; + } + public static short attack_ms$get(MemorySegment seg) { + return (short)sdrplay_api_AgcT.attack_ms$VH.get(seg); + } + public static void attack_ms$set( MemorySegment seg, short x) { + sdrplay_api_AgcT.attack_ms$VH.set(seg, x); + } + public static short attack_ms$get(MemorySegment seg, long index) { + return (short)sdrplay_api_AgcT.attack_ms$VH.get(seg.asSlice(index*sizeof())); + } + public static void attack_ms$set(MemorySegment seg, long index, short x) { + sdrplay_api_AgcT.attack_ms$VH.set(seg.asSlice(index*sizeof()), x); + } + static final VarHandle decay_ms$VH = $struct$LAYOUT.varHandle(MemoryLayout.PathElement.groupElement("decay_ms")); + public static VarHandle decay_ms$VH() { + return sdrplay_api_AgcT.decay_ms$VH; + } + public static short decay_ms$get(MemorySegment seg) { + return (short)sdrplay_api_AgcT.decay_ms$VH.get(seg); + } + public static void decay_ms$set( MemorySegment seg, short x) { + sdrplay_api_AgcT.decay_ms$VH.set(seg, x); + } + public static short decay_ms$get(MemorySegment seg, long index) { + return (short)sdrplay_api_AgcT.decay_ms$VH.get(seg.asSlice(index*sizeof())); + } + public static void decay_ms$set(MemorySegment seg, long index, short x) { + sdrplay_api_AgcT.decay_ms$VH.set(seg.asSlice(index*sizeof()), x); + } + static final VarHandle decay_delay_ms$VH = $struct$LAYOUT.varHandle(MemoryLayout.PathElement.groupElement("decay_delay_ms")); + public static VarHandle decay_delay_ms$VH() { + return sdrplay_api_AgcT.decay_delay_ms$VH; + } + public static short decay_delay_ms$get(MemorySegment seg) { + return (short)sdrplay_api_AgcT.decay_delay_ms$VH.get(seg); + } + public static void decay_delay_ms$set( MemorySegment seg, short x) { + sdrplay_api_AgcT.decay_delay_ms$VH.set(seg, x); + } + public static short decay_delay_ms$get(MemorySegment seg, long index) { + return (short)sdrplay_api_AgcT.decay_delay_ms$VH.get(seg.asSlice(index*sizeof())); + } + public static void decay_delay_ms$set(MemorySegment seg, long index, short x) { + sdrplay_api_AgcT.decay_delay_ms$VH.set(seg.asSlice(index*sizeof()), x); + } + static final VarHandle decay_threshold_dB$VH = $struct$LAYOUT.varHandle(MemoryLayout.PathElement.groupElement("decay_threshold_dB")); + public static VarHandle decay_threshold_dB$VH() { + return sdrplay_api_AgcT.decay_threshold_dB$VH; + } + public static short decay_threshold_dB$get(MemorySegment seg) { + return (short)sdrplay_api_AgcT.decay_threshold_dB$VH.get(seg); + } + public static void decay_threshold_dB$set( MemorySegment seg, short x) { + sdrplay_api_AgcT.decay_threshold_dB$VH.set(seg, x); + } + public static short decay_threshold_dB$get(MemorySegment seg, long index) { + return (short)sdrplay_api_AgcT.decay_threshold_dB$VH.get(seg.asSlice(index*sizeof())); + } + public static void decay_threshold_dB$set(MemorySegment seg, long index, short x) { + sdrplay_api_AgcT.decay_threshold_dB$VH.set(seg.asSlice(index*sizeof()), x); + } + static final VarHandle syncUpdate$VH = $struct$LAYOUT.varHandle(MemoryLayout.PathElement.groupElement("syncUpdate")); + public static VarHandle syncUpdate$VH() { + return sdrplay_api_AgcT.syncUpdate$VH; + } + public static int syncUpdate$get(MemorySegment seg) { + return (int)sdrplay_api_AgcT.syncUpdate$VH.get(seg); + } + public static void syncUpdate$set( MemorySegment seg, int x) { + sdrplay_api_AgcT.syncUpdate$VH.set(seg, x); + } + public static int syncUpdate$get(MemorySegment seg, long index) { + return (int)sdrplay_api_AgcT.syncUpdate$VH.get(seg.asSlice(index*sizeof())); + } + public static void syncUpdate$set(MemorySegment seg, long index, int x) { + sdrplay_api_AgcT.syncUpdate$VH.set(seg.asSlice(index*sizeof()), x); + } + public static long sizeof() { return $LAYOUT().byteSize(); } + public static MemorySegment allocate(SegmentAllocator allocator) { return allocator.allocate($LAYOUT()); } + public static MemorySegment allocateArray(int len, SegmentAllocator allocator) { + return allocator.allocate(MemoryLayout.sequenceLayout(len, $LAYOUT())); + } + public static MemorySegment ofAddress(MemoryAddress addr, MemorySession session) { return RuntimeHelper.asArray(addr, $LAYOUT(), 1, session); } +} + + diff --git a/sdrplay-api/src/main/java/com/github/dsheirer/sdrplay/api/v3_07/sdrplay_api_ApiVersion_t.java b/sdrplay-api/src/main/java/com/github/dsheirer/sdrplay/api/v3_07/sdrplay_api_ApiVersion_t.java new file mode 100644 index 000000000..b86ca9f45 --- /dev/null +++ b/sdrplay-api/src/main/java/com/github/dsheirer/sdrplay/api/v3_07/sdrplay_api_ApiVersion_t.java @@ -0,0 +1,27 @@ +// Generated by jextract + +package com.github.dsheirer.sdrplay.api.v3_07; + +import java.lang.foreign.Addressable; +import java.lang.foreign.MemoryAddress; +import java.lang.foreign.MemorySegment; +import java.lang.foreign.MemorySession; +public interface sdrplay_api_ApiVersion_t { + + int apply(java.lang.foreign.MemoryAddress apiVer); + static MemorySegment allocate(sdrplay_api_ApiVersion_t fi, MemorySession session) { + return RuntimeHelper.upcallStub(sdrplay_api_ApiVersion_t.class, fi, constants$1.sdrplay_api_ApiVersion_t$FUNC, session); + } + static sdrplay_api_ApiVersion_t ofAddress(MemoryAddress addr, MemorySession session) { + MemorySegment symbol = MemorySegment.ofAddress(addr, 0, session); + return (java.lang.foreign.MemoryAddress _apiVer) -> { + try { + return (int)constants$1.sdrplay_api_ApiVersion_t$MH.invokeExact((Addressable)symbol, (java.lang.foreign.Addressable)_apiVer); + } catch (Throwable ex$) { + throw new AssertionError("should not reach here", ex$); + } + }; + } +} + + diff --git a/sdrplay-api/src/main/java/com/github/dsheirer/sdrplay/api/v3_07/sdrplay_api_CallbackFnsT.java b/sdrplay-api/src/main/java/com/github/dsheirer/sdrplay/api/v3_07/sdrplay_api_CallbackFnsT.java new file mode 100644 index 000000000..b7ebdb0a1 --- /dev/null +++ b/sdrplay-api/src/main/java/com/github/dsheirer/sdrplay/api/v3_07/sdrplay_api_CallbackFnsT.java @@ -0,0 +1,87 @@ +// Generated by jextract + +package com.github.dsheirer.sdrplay.api.v3_07; + +import java.lang.foreign.GroupLayout; +import java.lang.foreign.MemoryAddress; +import java.lang.foreign.MemoryLayout; +import java.lang.foreign.MemorySegment; +import java.lang.foreign.MemorySession; +import java.lang.foreign.SegmentAllocator; +import java.lang.invoke.VarHandle; +public class sdrplay_api_CallbackFnsT { + + static final GroupLayout $struct$LAYOUT = MemoryLayout.structLayout( + Constants$root.C_POINTER$LAYOUT.withName("StreamACbFn"), + Constants$root.C_POINTER$LAYOUT.withName("StreamBCbFn"), + Constants$root.C_POINTER$LAYOUT.withName("EventCbFn") + ); + public static MemoryLayout $LAYOUT() { + return sdrplay_api_CallbackFnsT.$struct$LAYOUT; + } + static final VarHandle StreamACbFn$VH = $struct$LAYOUT.varHandle(MemoryLayout.PathElement.groupElement("StreamACbFn")); + public static VarHandle StreamACbFn$VH() { + return sdrplay_api_CallbackFnsT.StreamACbFn$VH; + } + public static MemoryAddress StreamACbFn$get(MemorySegment seg) { + return (java.lang.foreign.MemoryAddress)sdrplay_api_CallbackFnsT.StreamACbFn$VH.get(seg); + } + public static void StreamACbFn$set( MemorySegment seg, MemoryAddress x) { + sdrplay_api_CallbackFnsT.StreamACbFn$VH.set(seg, x); + } + public static MemoryAddress StreamACbFn$get(MemorySegment seg, long index) { + return (java.lang.foreign.MemoryAddress)sdrplay_api_CallbackFnsT.StreamACbFn$VH.get(seg.asSlice(index*sizeof())); + } + public static void StreamACbFn$set(MemorySegment seg, long index, MemoryAddress x) { + sdrplay_api_CallbackFnsT.StreamACbFn$VH.set(seg.asSlice(index*sizeof()), x); + } + public static sdrplay_api_StreamCallback_t StreamACbFn (MemorySegment segment, MemorySession session) { + return sdrplay_api_StreamCallback_t.ofAddress(StreamACbFn$get(segment), session); + } + static final VarHandle StreamBCbFn$VH = $struct$LAYOUT.varHandle(MemoryLayout.PathElement.groupElement("StreamBCbFn")); + public static VarHandle StreamBCbFn$VH() { + return sdrplay_api_CallbackFnsT.StreamBCbFn$VH; + } + public static MemoryAddress StreamBCbFn$get(MemorySegment seg) { + return (java.lang.foreign.MemoryAddress)sdrplay_api_CallbackFnsT.StreamBCbFn$VH.get(seg); + } + public static void StreamBCbFn$set( MemorySegment seg, MemoryAddress x) { + sdrplay_api_CallbackFnsT.StreamBCbFn$VH.set(seg, x); + } + public static MemoryAddress StreamBCbFn$get(MemorySegment seg, long index) { + return (java.lang.foreign.MemoryAddress)sdrplay_api_CallbackFnsT.StreamBCbFn$VH.get(seg.asSlice(index*sizeof())); + } + public static void StreamBCbFn$set(MemorySegment seg, long index, MemoryAddress x) { + sdrplay_api_CallbackFnsT.StreamBCbFn$VH.set(seg.asSlice(index*sizeof()), x); + } + public static sdrplay_api_StreamCallback_t StreamBCbFn (MemorySegment segment, MemorySession session) { + return sdrplay_api_StreamCallback_t.ofAddress(StreamBCbFn$get(segment), session); + } + static final VarHandle EventCbFn$VH = $struct$LAYOUT.varHandle(MemoryLayout.PathElement.groupElement("EventCbFn")); + public static VarHandle EventCbFn$VH() { + return sdrplay_api_CallbackFnsT.EventCbFn$VH; + } + public static MemoryAddress EventCbFn$get(MemorySegment seg) { + return (java.lang.foreign.MemoryAddress)sdrplay_api_CallbackFnsT.EventCbFn$VH.get(seg); + } + public static void EventCbFn$set( MemorySegment seg, MemoryAddress x) { + sdrplay_api_CallbackFnsT.EventCbFn$VH.set(seg, x); + } + public static MemoryAddress EventCbFn$get(MemorySegment seg, long index) { + return (java.lang.foreign.MemoryAddress)sdrplay_api_CallbackFnsT.EventCbFn$VH.get(seg.asSlice(index*sizeof())); + } + public static void EventCbFn$set(MemorySegment seg, long index, MemoryAddress x) { + sdrplay_api_CallbackFnsT.EventCbFn$VH.set(seg.asSlice(index*sizeof()), x); + } + public static sdrplay_api_EventCallback_t EventCbFn (MemorySegment segment, MemorySession session) { + return sdrplay_api_EventCallback_t.ofAddress(EventCbFn$get(segment), session); + } + public static long sizeof() { return $LAYOUT().byteSize(); } + public static MemorySegment allocate(SegmentAllocator allocator) { return allocator.allocate($LAYOUT()); } + public static MemorySegment allocateArray(int len, SegmentAllocator allocator) { + return allocator.allocate(MemoryLayout.sequenceLayout(len, $LAYOUT())); + } + public static MemorySegment ofAddress(MemoryAddress addr, MemorySession session) { return RuntimeHelper.asArray(addr, $LAYOUT(), 1, session); } +} + + diff --git a/sdrplay-api/src/main/java/com/github/dsheirer/sdrplay/api/v3_07/sdrplay_api_Close_t.java b/sdrplay-api/src/main/java/com/github/dsheirer/sdrplay/api/v3_07/sdrplay_api_Close_t.java new file mode 100644 index 000000000..7fc96c078 --- /dev/null +++ b/sdrplay-api/src/main/java/com/github/dsheirer/sdrplay/api/v3_07/sdrplay_api_Close_t.java @@ -0,0 +1,27 @@ +// Generated by jextract + +package com.github.dsheirer.sdrplay.api.v3_07; + +import java.lang.foreign.Addressable; +import java.lang.foreign.MemoryAddress; +import java.lang.foreign.MemorySegment; +import java.lang.foreign.MemorySession; +public interface sdrplay_api_Close_t { + + int apply(); + static MemorySegment allocate(sdrplay_api_Close_t fi, MemorySession session) { + return RuntimeHelper.upcallStub(sdrplay_api_Close_t.class, fi, constants$1.sdrplay_api_Close_t$FUNC, session); + } + static sdrplay_api_Close_t ofAddress(MemoryAddress addr, MemorySession session) { + MemorySegment symbol = MemorySegment.ofAddress(addr, 0, session); + return () -> { + try { + return (int)constants$1.sdrplay_api_Close_t$MH.invokeExact((Addressable)symbol); + } catch (Throwable ex$) { + throw new AssertionError("should not reach here", ex$); + } + }; + } +} + + diff --git a/sdrplay-api/src/main/java/com/github/dsheirer/sdrplay/api/v3_07/sdrplay_api_ControlParamsT.java b/sdrplay-api/src/main/java/com/github/dsheirer/sdrplay/api/v3_07/sdrplay_api_ControlParamsT.java new file mode 100644 index 000000000..cbebfc4dd --- /dev/null +++ b/sdrplay-api/src/main/java/com/github/dsheirer/sdrplay/api/v3_07/sdrplay_api_ControlParamsT.java @@ -0,0 +1,72 @@ +// Generated by jextract + +package com.github.dsheirer.sdrplay.api.v3_07; + +import java.lang.foreign.GroupLayout; +import java.lang.foreign.MemoryAddress; +import java.lang.foreign.MemoryLayout; +import java.lang.foreign.MemorySegment; +import java.lang.foreign.MemorySession; +import java.lang.foreign.SegmentAllocator; +import java.lang.invoke.VarHandle; +public class sdrplay_api_ControlParamsT { + + static final GroupLayout $struct$LAYOUT = MemoryLayout.structLayout( + MemoryLayout.structLayout( + Constants$root.C_CHAR$LAYOUT.withName("DCenable"), + Constants$root.C_CHAR$LAYOUT.withName("IQenable") + ).withName("dcOffset"), + MemoryLayout.structLayout( + Constants$root.C_CHAR$LAYOUT.withName("enable"), + Constants$root.C_CHAR$LAYOUT.withName("decimationFactor"), + Constants$root.C_CHAR$LAYOUT.withName("wideBandSignal") + ).withName("decimation"), + MemoryLayout.paddingLayout(24), + MemoryLayout.structLayout( + Constants$root.C_LONG$LAYOUT.withName("enable"), + Constants$root.C_LONG$LAYOUT.withName("setPoint_dBfs"), + Constants$root.C_SHORT$LAYOUT.withName("attack_ms"), + Constants$root.C_SHORT$LAYOUT.withName("decay_ms"), + Constants$root.C_SHORT$LAYOUT.withName("decay_delay_ms"), + Constants$root.C_SHORT$LAYOUT.withName("decay_threshold_dB"), + Constants$root.C_LONG$LAYOUT.withName("syncUpdate") + ).withName("agc"), + Constants$root.C_LONG$LAYOUT.withName("adsbMode") + ); + public static MemoryLayout $LAYOUT() { + return sdrplay_api_ControlParamsT.$struct$LAYOUT; + } + public static MemorySegment dcOffset$slice(MemorySegment seg) { + return seg.asSlice(0, 2); + } + public static MemorySegment decimation$slice(MemorySegment seg) { + return seg.asSlice(2, 3); + } + public static MemorySegment agc$slice(MemorySegment seg) { + return seg.asSlice(8, 20); + } + static final VarHandle adsbMode$VH = $struct$LAYOUT.varHandle(MemoryLayout.PathElement.groupElement("adsbMode")); + public static VarHandle adsbMode$VH() { + return sdrplay_api_ControlParamsT.adsbMode$VH; + } + public static int adsbMode$get(MemorySegment seg) { + return (int)sdrplay_api_ControlParamsT.adsbMode$VH.get(seg); + } + public static void adsbMode$set( MemorySegment seg, int x) { + sdrplay_api_ControlParamsT.adsbMode$VH.set(seg, x); + } + public static int adsbMode$get(MemorySegment seg, long index) { + return (int)sdrplay_api_ControlParamsT.adsbMode$VH.get(seg.asSlice(index*sizeof())); + } + public static void adsbMode$set(MemorySegment seg, long index, int x) { + sdrplay_api_ControlParamsT.adsbMode$VH.set(seg.asSlice(index*sizeof()), x); + } + public static long sizeof() { return $LAYOUT().byteSize(); } + public static MemorySegment allocate(SegmentAllocator allocator) { return allocator.allocate($LAYOUT()); } + public static MemorySegment allocateArray(int len, SegmentAllocator allocator) { + return allocator.allocate(MemoryLayout.sequenceLayout(len, $LAYOUT())); + } + public static MemorySegment ofAddress(MemoryAddress addr, MemorySession session) { return RuntimeHelper.asArray(addr, $LAYOUT(), 1, session); } +} + + diff --git a/sdrplay-api/src/main/java/com/github/dsheirer/sdrplay/api/v3_07/sdrplay_api_DcOffsetT.java b/sdrplay-api/src/main/java/com/github/dsheirer/sdrplay/api/v3_07/sdrplay_api_DcOffsetT.java new file mode 100644 index 000000000..594c0c025 --- /dev/null +++ b/sdrplay-api/src/main/java/com/github/dsheirer/sdrplay/api/v3_07/sdrplay_api_DcOffsetT.java @@ -0,0 +1,61 @@ +// Generated by jextract + +package com.github.dsheirer.sdrplay.api.v3_07; + +import java.lang.foreign.GroupLayout; +import java.lang.foreign.MemoryAddress; +import java.lang.foreign.MemoryLayout; +import java.lang.foreign.MemorySegment; +import java.lang.foreign.MemorySession; +import java.lang.foreign.SegmentAllocator; +import java.lang.invoke.VarHandle; +public class sdrplay_api_DcOffsetT { + + static final GroupLayout $struct$LAYOUT = MemoryLayout.structLayout( + Constants$root.C_CHAR$LAYOUT.withName("DCenable"), + Constants$root.C_CHAR$LAYOUT.withName("IQenable") + ); + public static MemoryLayout $LAYOUT() { + return sdrplay_api_DcOffsetT.$struct$LAYOUT; + } + static final VarHandle DCenable$VH = $struct$LAYOUT.varHandle(MemoryLayout.PathElement.groupElement("DCenable")); + public static VarHandle DCenable$VH() { + return sdrplay_api_DcOffsetT.DCenable$VH; + } + public static byte DCenable$get(MemorySegment seg) { + return (byte)sdrplay_api_DcOffsetT.DCenable$VH.get(seg); + } + public static void DCenable$set( MemorySegment seg, byte x) { + sdrplay_api_DcOffsetT.DCenable$VH.set(seg, x); + } + public static byte DCenable$get(MemorySegment seg, long index) { + return (byte)sdrplay_api_DcOffsetT.DCenable$VH.get(seg.asSlice(index*sizeof())); + } + public static void DCenable$set(MemorySegment seg, long index, byte x) { + sdrplay_api_DcOffsetT.DCenable$VH.set(seg.asSlice(index*sizeof()), x); + } + static final VarHandle IQenable$VH = $struct$LAYOUT.varHandle(MemoryLayout.PathElement.groupElement("IQenable")); + public static VarHandle IQenable$VH() { + return sdrplay_api_DcOffsetT.IQenable$VH; + } + public static byte IQenable$get(MemorySegment seg) { + return (byte)sdrplay_api_DcOffsetT.IQenable$VH.get(seg); + } + public static void IQenable$set( MemorySegment seg, byte x) { + sdrplay_api_DcOffsetT.IQenable$VH.set(seg, x); + } + public static byte IQenable$get(MemorySegment seg, long index) { + return (byte)sdrplay_api_DcOffsetT.IQenable$VH.get(seg.asSlice(index*sizeof())); + } + public static void IQenable$set(MemorySegment seg, long index, byte x) { + sdrplay_api_DcOffsetT.IQenable$VH.set(seg.asSlice(index*sizeof()), x); + } + public static long sizeof() { return $LAYOUT().byteSize(); } + public static MemorySegment allocate(SegmentAllocator allocator) { return allocator.allocate($LAYOUT()); } + public static MemorySegment allocateArray(int len, SegmentAllocator allocator) { + return allocator.allocate(MemoryLayout.sequenceLayout(len, $LAYOUT())); + } + public static MemorySegment ofAddress(MemoryAddress addr, MemorySession session) { return RuntimeHelper.asArray(addr, $LAYOUT(), 1, session); } +} + + diff --git a/sdrplay-api/src/main/java/com/github/dsheirer/sdrplay/api/v3_07/sdrplay_api_DcOffsetTunerT.java b/sdrplay-api/src/main/java/com/github/dsheirer/sdrplay/api/v3_07/sdrplay_api_DcOffsetTunerT.java new file mode 100644 index 000000000..4d870467d --- /dev/null +++ b/sdrplay-api/src/main/java/com/github/dsheirer/sdrplay/api/v3_07/sdrplay_api_DcOffsetTunerT.java @@ -0,0 +1,96 @@ +// Generated by jextract + +package com.github.dsheirer.sdrplay.api.v3_07; + +import java.lang.foreign.GroupLayout; +import java.lang.foreign.MemoryAddress; +import java.lang.foreign.MemoryLayout; +import java.lang.foreign.MemorySegment; +import java.lang.foreign.MemorySession; +import java.lang.foreign.SegmentAllocator; +import java.lang.invoke.VarHandle; +public class sdrplay_api_DcOffsetTunerT { + + static final GroupLayout $struct$LAYOUT = MemoryLayout.structLayout( + Constants$root.C_CHAR$LAYOUT.withName("dcCal"), + Constants$root.C_CHAR$LAYOUT.withName("speedUp"), + MemoryLayout.paddingLayout(16), + Constants$root.C_LONG$LAYOUT.withName("trackTime"), + Constants$root.C_LONG$LAYOUT.withName("refreshRateTime") + ); + public static MemoryLayout $LAYOUT() { + return sdrplay_api_DcOffsetTunerT.$struct$LAYOUT; + } + static final VarHandle dcCal$VH = $struct$LAYOUT.varHandle(MemoryLayout.PathElement.groupElement("dcCal")); + public static VarHandle dcCal$VH() { + return sdrplay_api_DcOffsetTunerT.dcCal$VH; + } + public static byte dcCal$get(MemorySegment seg) { + return (byte)sdrplay_api_DcOffsetTunerT.dcCal$VH.get(seg); + } + public static void dcCal$set( MemorySegment seg, byte x) { + sdrplay_api_DcOffsetTunerT.dcCal$VH.set(seg, x); + } + public static byte dcCal$get(MemorySegment seg, long index) { + return (byte)sdrplay_api_DcOffsetTunerT.dcCal$VH.get(seg.asSlice(index*sizeof())); + } + public static void dcCal$set(MemorySegment seg, long index, byte x) { + sdrplay_api_DcOffsetTunerT.dcCal$VH.set(seg.asSlice(index*sizeof()), x); + } + static final VarHandle speedUp$VH = $struct$LAYOUT.varHandle(MemoryLayout.PathElement.groupElement("speedUp")); + public static VarHandle speedUp$VH() { + return sdrplay_api_DcOffsetTunerT.speedUp$VH; + } + public static byte speedUp$get(MemorySegment seg) { + return (byte)sdrplay_api_DcOffsetTunerT.speedUp$VH.get(seg); + } + public static void speedUp$set( MemorySegment seg, byte x) { + sdrplay_api_DcOffsetTunerT.speedUp$VH.set(seg, x); + } + public static byte speedUp$get(MemorySegment seg, long index) { + return (byte)sdrplay_api_DcOffsetTunerT.speedUp$VH.get(seg.asSlice(index*sizeof())); + } + public static void speedUp$set(MemorySegment seg, long index, byte x) { + sdrplay_api_DcOffsetTunerT.speedUp$VH.set(seg.asSlice(index*sizeof()), x); + } + static final VarHandle trackTime$VH = $struct$LAYOUT.varHandle(MemoryLayout.PathElement.groupElement("trackTime")); + public static VarHandle trackTime$VH() { + return sdrplay_api_DcOffsetTunerT.trackTime$VH; + } + public static int trackTime$get(MemorySegment seg) { + return (int)sdrplay_api_DcOffsetTunerT.trackTime$VH.get(seg); + } + public static void trackTime$set( MemorySegment seg, int x) { + sdrplay_api_DcOffsetTunerT.trackTime$VH.set(seg, x); + } + public static int trackTime$get(MemorySegment seg, long index) { + return (int)sdrplay_api_DcOffsetTunerT.trackTime$VH.get(seg.asSlice(index*sizeof())); + } + public static void trackTime$set(MemorySegment seg, long index, int x) { + sdrplay_api_DcOffsetTunerT.trackTime$VH.set(seg.asSlice(index*sizeof()), x); + } + static final VarHandle refreshRateTime$VH = $struct$LAYOUT.varHandle(MemoryLayout.PathElement.groupElement("refreshRateTime")); + public static VarHandle refreshRateTime$VH() { + return sdrplay_api_DcOffsetTunerT.refreshRateTime$VH; + } + public static int refreshRateTime$get(MemorySegment seg) { + return (int)sdrplay_api_DcOffsetTunerT.refreshRateTime$VH.get(seg); + } + public static void refreshRateTime$set( MemorySegment seg, int x) { + sdrplay_api_DcOffsetTunerT.refreshRateTime$VH.set(seg, x); + } + public static int refreshRateTime$get(MemorySegment seg, long index) { + return (int)sdrplay_api_DcOffsetTunerT.refreshRateTime$VH.get(seg.asSlice(index*sizeof())); + } + public static void refreshRateTime$set(MemorySegment seg, long index, int x) { + sdrplay_api_DcOffsetTunerT.refreshRateTime$VH.set(seg.asSlice(index*sizeof()), x); + } + public static long sizeof() { return $LAYOUT().byteSize(); } + public static MemorySegment allocate(SegmentAllocator allocator) { return allocator.allocate($LAYOUT()); } + public static MemorySegment allocateArray(int len, SegmentAllocator allocator) { + return allocator.allocate(MemoryLayout.sequenceLayout(len, $LAYOUT())); + } + public static MemorySegment ofAddress(MemoryAddress addr, MemorySession session) { return RuntimeHelper.asArray(addr, $LAYOUT(), 1, session); } +} + + diff --git a/sdrplay-api/src/main/java/com/github/dsheirer/sdrplay/api/v3_07/sdrplay_api_DebugEnable_t.java b/sdrplay-api/src/main/java/com/github/dsheirer/sdrplay/api/v3_07/sdrplay_api_DebugEnable_t.java new file mode 100644 index 000000000..7f70bb114 --- /dev/null +++ b/sdrplay-api/src/main/java/com/github/dsheirer/sdrplay/api/v3_07/sdrplay_api_DebugEnable_t.java @@ -0,0 +1,27 @@ +// Generated by jextract + +package com.github.dsheirer.sdrplay.api.v3_07; + +import java.lang.foreign.Addressable; +import java.lang.foreign.MemoryAddress; +import java.lang.foreign.MemorySegment; +import java.lang.foreign.MemorySession; +public interface sdrplay_api_DebugEnable_t { + + int apply(java.lang.foreign.MemoryAddress dev, int dbgLvl); + static MemorySegment allocate(sdrplay_api_DebugEnable_t fi, MemorySession session) { + return RuntimeHelper.upcallStub(sdrplay_api_DebugEnable_t.class, fi, constants$4.sdrplay_api_DebugEnable_t$FUNC, session); + } + static sdrplay_api_DebugEnable_t ofAddress(MemoryAddress addr, MemorySession session) { + MemorySegment symbol = MemorySegment.ofAddress(addr, 0, session); + return (java.lang.foreign.MemoryAddress _dev, int _dbgLvl) -> { + try { + return (int)constants$4.sdrplay_api_DebugEnable_t$MH.invokeExact((Addressable)symbol, (java.lang.foreign.Addressable)_dev, _dbgLvl); + } catch (Throwable ex$) { + throw new AssertionError("should not reach here", ex$); + } + }; + } +} + + diff --git a/sdrplay-api/src/main/java/com/github/dsheirer/sdrplay/api/v3_07/sdrplay_api_DecimationT.java b/sdrplay-api/src/main/java/com/github/dsheirer/sdrplay/api/v3_07/sdrplay_api_DecimationT.java new file mode 100644 index 000000000..f6acaf0c4 --- /dev/null +++ b/sdrplay-api/src/main/java/com/github/dsheirer/sdrplay/api/v3_07/sdrplay_api_DecimationT.java @@ -0,0 +1,78 @@ +// Generated by jextract + +package com.github.dsheirer.sdrplay.api.v3_07; + +import java.lang.foreign.GroupLayout; +import java.lang.foreign.MemoryAddress; +import java.lang.foreign.MemoryLayout; +import java.lang.foreign.MemorySegment; +import java.lang.foreign.MemorySession; +import java.lang.foreign.SegmentAllocator; +import java.lang.invoke.VarHandle; +public class sdrplay_api_DecimationT { + + static final GroupLayout $struct$LAYOUT = MemoryLayout.structLayout( + Constants$root.C_CHAR$LAYOUT.withName("enable"), + Constants$root.C_CHAR$LAYOUT.withName("decimationFactor"), + Constants$root.C_CHAR$LAYOUT.withName("wideBandSignal") + ); + public static MemoryLayout $LAYOUT() { + return sdrplay_api_DecimationT.$struct$LAYOUT; + } + static final VarHandle enable$VH = $struct$LAYOUT.varHandle(MemoryLayout.PathElement.groupElement("enable")); + public static VarHandle enable$VH() { + return sdrplay_api_DecimationT.enable$VH; + } + public static byte enable$get(MemorySegment seg) { + return (byte)sdrplay_api_DecimationT.enable$VH.get(seg); + } + public static void enable$set( MemorySegment seg, byte x) { + sdrplay_api_DecimationT.enable$VH.set(seg, x); + } + public static byte enable$get(MemorySegment seg, long index) { + return (byte)sdrplay_api_DecimationT.enable$VH.get(seg.asSlice(index*sizeof())); + } + public static void enable$set(MemorySegment seg, long index, byte x) { + sdrplay_api_DecimationT.enable$VH.set(seg.asSlice(index*sizeof()), x); + } + static final VarHandle decimationFactor$VH = $struct$LAYOUT.varHandle(MemoryLayout.PathElement.groupElement("decimationFactor")); + public static VarHandle decimationFactor$VH() { + return sdrplay_api_DecimationT.decimationFactor$VH; + } + public static byte decimationFactor$get(MemorySegment seg) { + return (byte)sdrplay_api_DecimationT.decimationFactor$VH.get(seg); + } + public static void decimationFactor$set( MemorySegment seg, byte x) { + sdrplay_api_DecimationT.decimationFactor$VH.set(seg, x); + } + public static byte decimationFactor$get(MemorySegment seg, long index) { + return (byte)sdrplay_api_DecimationT.decimationFactor$VH.get(seg.asSlice(index*sizeof())); + } + public static void decimationFactor$set(MemorySegment seg, long index, byte x) { + sdrplay_api_DecimationT.decimationFactor$VH.set(seg.asSlice(index*sizeof()), x); + } + static final VarHandle wideBandSignal$VH = $struct$LAYOUT.varHandle(MemoryLayout.PathElement.groupElement("wideBandSignal")); + public static VarHandle wideBandSignal$VH() { + return sdrplay_api_DecimationT.wideBandSignal$VH; + } + public static byte wideBandSignal$get(MemorySegment seg) { + return (byte)sdrplay_api_DecimationT.wideBandSignal$VH.get(seg); + } + public static void wideBandSignal$set( MemorySegment seg, byte x) { + sdrplay_api_DecimationT.wideBandSignal$VH.set(seg, x); + } + public static byte wideBandSignal$get(MemorySegment seg, long index) { + return (byte)sdrplay_api_DecimationT.wideBandSignal$VH.get(seg.asSlice(index*sizeof())); + } + public static void wideBandSignal$set(MemorySegment seg, long index, byte x) { + sdrplay_api_DecimationT.wideBandSignal$VH.set(seg.asSlice(index*sizeof()), x); + } + public static long sizeof() { return $LAYOUT().byteSize(); } + public static MemorySegment allocate(SegmentAllocator allocator) { return allocator.allocate($LAYOUT()); } + public static MemorySegment allocateArray(int len, SegmentAllocator allocator) { + return allocator.allocate(MemoryLayout.sequenceLayout(len, $LAYOUT())); + } + public static MemorySegment ofAddress(MemoryAddress addr, MemorySession session) { return RuntimeHelper.asArray(addr, $LAYOUT(), 1, session); } +} + + diff --git a/sdrplay-api/src/main/java/com/github/dsheirer/sdrplay/api/v3_07/sdrplay_api_DevParamsT.java b/sdrplay-api/src/main/java/com/github/dsheirer/sdrplay/api/v3_07/sdrplay_api_DevParamsT.java new file mode 100644 index 000000000..6dd22573e --- /dev/null +++ b/sdrplay-api/src/main/java/com/github/dsheirer/sdrplay/api/v3_07/sdrplay_api_DevParamsT.java @@ -0,0 +1,135 @@ +// Generated by jextract + +package com.github.dsheirer.sdrplay.api.v3_07; + +import java.lang.foreign.GroupLayout; +import java.lang.foreign.MemoryAddress; +import java.lang.foreign.MemoryLayout; +import java.lang.foreign.MemorySegment; +import java.lang.foreign.MemorySession; +import java.lang.foreign.SegmentAllocator; +import java.lang.invoke.VarHandle; +public class sdrplay_api_DevParamsT { + + static final GroupLayout $struct$LAYOUT = MemoryLayout.structLayout( + Constants$root.C_DOUBLE$LAYOUT.withName("ppm"), + MemoryLayout.structLayout( + Constants$root.C_DOUBLE$LAYOUT.withName("fsHz"), + Constants$root.C_CHAR$LAYOUT.withName("syncUpdate"), + Constants$root.C_CHAR$LAYOUT.withName("reCal"), + MemoryLayout.paddingLayout(48) + ).withName("fsFreq"), + MemoryLayout.structLayout( + Constants$root.C_LONG$LAYOUT.withName("sampleNum"), + Constants$root.C_LONG$LAYOUT.withName("period") + ).withName("syncUpdate"), + MemoryLayout.structLayout( + Constants$root.C_CHAR$LAYOUT.withName("resetGainUpdate"), + Constants$root.C_CHAR$LAYOUT.withName("resetRfUpdate"), + Constants$root.C_CHAR$LAYOUT.withName("resetFsUpdate") + ).withName("resetFlags"), + MemoryLayout.paddingLayout(8), + Constants$root.C_LONG$LAYOUT.withName("mode"), + Constants$root.C_LONG$LAYOUT.withName("samplesPerPkt"), + MemoryLayout.structLayout( + Constants$root.C_CHAR$LAYOUT.withName("rfNotchEnable"), + Constants$root.C_CHAR$LAYOUT.withName("rfDabNotchEnable") + ).withName("rsp1aParams"), + MemoryLayout.structLayout( + Constants$root.C_CHAR$LAYOUT.withName("extRefOutputEn") + ).withName("rsp2Params"), + MemoryLayout.paddingLayout(8), + MemoryLayout.structLayout( + Constants$root.C_LONG$LAYOUT.withName("extRefOutputEn") + ).withName("rspDuoParams"), + MemoryLayout.structLayout( + Constants$root.C_CHAR$LAYOUT.withName("hdrEnable"), + Constants$root.C_CHAR$LAYOUT.withName("biasTEnable"), + MemoryLayout.paddingLayout(16), + Constants$root.C_LONG$LAYOUT.withName("antennaSel"), + Constants$root.C_CHAR$LAYOUT.withName("rfNotchEnable"), + Constants$root.C_CHAR$LAYOUT.withName("rfDabNotchEnable"), + MemoryLayout.paddingLayout(16) + ).withName("rspDxParams") + ); + public static MemoryLayout $LAYOUT() { + return sdrplay_api_DevParamsT.$struct$LAYOUT; + } + static final VarHandle ppm$VH = $struct$LAYOUT.varHandle(MemoryLayout.PathElement.groupElement("ppm")); + public static VarHandle ppm$VH() { + return sdrplay_api_DevParamsT.ppm$VH; + } + public static double ppm$get(MemorySegment seg) { + return (double)sdrplay_api_DevParamsT.ppm$VH.get(seg); + } + public static void ppm$set( MemorySegment seg, double x) { + sdrplay_api_DevParamsT.ppm$VH.set(seg, x); + } + public static double ppm$get(MemorySegment seg, long index) { + return (double)sdrplay_api_DevParamsT.ppm$VH.get(seg.asSlice(index*sizeof())); + } + public static void ppm$set(MemorySegment seg, long index, double x) { + sdrplay_api_DevParamsT.ppm$VH.set(seg.asSlice(index*sizeof()), x); + } + public static MemorySegment fsFreq$slice(MemorySegment seg) { + return seg.asSlice(8, 16); + } + public static MemorySegment syncUpdate$slice(MemorySegment seg) { + return seg.asSlice(24, 8); + } + public static MemorySegment resetFlags$slice(MemorySegment seg) { + return seg.asSlice(32, 3); + } + static final VarHandle mode$VH = $struct$LAYOUT.varHandle(MemoryLayout.PathElement.groupElement("mode")); + public static VarHandle mode$VH() { + return sdrplay_api_DevParamsT.mode$VH; + } + public static int mode$get(MemorySegment seg) { + return (int)sdrplay_api_DevParamsT.mode$VH.get(seg); + } + public static void mode$set( MemorySegment seg, int x) { + sdrplay_api_DevParamsT.mode$VH.set(seg, x); + } + public static int mode$get(MemorySegment seg, long index) { + return (int)sdrplay_api_DevParamsT.mode$VH.get(seg.asSlice(index*sizeof())); + } + public static void mode$set(MemorySegment seg, long index, int x) { + sdrplay_api_DevParamsT.mode$VH.set(seg.asSlice(index*sizeof()), x); + } + static final VarHandle samplesPerPkt$VH = $struct$LAYOUT.varHandle(MemoryLayout.PathElement.groupElement("samplesPerPkt")); + public static VarHandle samplesPerPkt$VH() { + return sdrplay_api_DevParamsT.samplesPerPkt$VH; + } + public static int samplesPerPkt$get(MemorySegment seg) { + return (int)sdrplay_api_DevParamsT.samplesPerPkt$VH.get(seg); + } + public static void samplesPerPkt$set( MemorySegment seg, int x) { + sdrplay_api_DevParamsT.samplesPerPkt$VH.set(seg, x); + } + public static int samplesPerPkt$get(MemorySegment seg, long index) { + return (int)sdrplay_api_DevParamsT.samplesPerPkt$VH.get(seg.asSlice(index*sizeof())); + } + public static void samplesPerPkt$set(MemorySegment seg, long index, int x) { + sdrplay_api_DevParamsT.samplesPerPkt$VH.set(seg.asSlice(index*sizeof()), x); + } + public static MemorySegment rsp1aParams$slice(MemorySegment seg) { + return seg.asSlice(44, 2); + } + public static MemorySegment rsp2Params$slice(MemorySegment seg) { + return seg.asSlice(46, 1); + } + public static MemorySegment rspDuoParams$slice(MemorySegment seg) { + return seg.asSlice(48, 4); + } + public static MemorySegment rspDxParams$slice(MemorySegment seg) { + return seg.asSlice(52, 12); + } + public static long sizeof() { return $LAYOUT().byteSize(); } + public static MemorySegment allocate(SegmentAllocator allocator) { return allocator.allocate($LAYOUT()); } + public static MemorySegment allocateArray(int len, SegmentAllocator allocator) { + return allocator.allocate(MemoryLayout.sequenceLayout(len, $LAYOUT())); + } + public static MemorySegment ofAddress(MemoryAddress addr, MemorySession session) { return RuntimeHelper.asArray(addr, $LAYOUT(), 1, session); } +} + + diff --git a/sdrplay-api/src/main/java/com/github/dsheirer/sdrplay/api/v3_07/sdrplay_api_DeviceParamsT.java b/sdrplay-api/src/main/java/com/github/dsheirer/sdrplay/api/v3_07/sdrplay_api_DeviceParamsT.java new file mode 100644 index 000000000..4f9525e64 --- /dev/null +++ b/sdrplay-api/src/main/java/com/github/dsheirer/sdrplay/api/v3_07/sdrplay_api_DeviceParamsT.java @@ -0,0 +1,78 @@ +// Generated by jextract + +package com.github.dsheirer.sdrplay.api.v3_07; + +import java.lang.foreign.GroupLayout; +import java.lang.foreign.MemoryAddress; +import java.lang.foreign.MemoryLayout; +import java.lang.foreign.MemorySegment; +import java.lang.foreign.MemorySession; +import java.lang.foreign.SegmentAllocator; +import java.lang.invoke.VarHandle; +public class sdrplay_api_DeviceParamsT { + + static final GroupLayout $struct$LAYOUT = MemoryLayout.structLayout( + Constants$root.C_POINTER$LAYOUT.withName("devParams"), + Constants$root.C_POINTER$LAYOUT.withName("rxChannelA"), + Constants$root.C_POINTER$LAYOUT.withName("rxChannelB") + ); + public static MemoryLayout $LAYOUT() { + return sdrplay_api_DeviceParamsT.$struct$LAYOUT; + } + static final VarHandle devParams$VH = $struct$LAYOUT.varHandle(MemoryLayout.PathElement.groupElement("devParams")); + public static VarHandle devParams$VH() { + return sdrplay_api_DeviceParamsT.devParams$VH; + } + public static MemoryAddress devParams$get(MemorySegment seg) { + return (java.lang.foreign.MemoryAddress)sdrplay_api_DeviceParamsT.devParams$VH.get(seg); + } + public static void devParams$set( MemorySegment seg, MemoryAddress x) { + sdrplay_api_DeviceParamsT.devParams$VH.set(seg, x); + } + public static MemoryAddress devParams$get(MemorySegment seg, long index) { + return (java.lang.foreign.MemoryAddress)sdrplay_api_DeviceParamsT.devParams$VH.get(seg.asSlice(index*sizeof())); + } + public static void devParams$set(MemorySegment seg, long index, MemoryAddress x) { + sdrplay_api_DeviceParamsT.devParams$VH.set(seg.asSlice(index*sizeof()), x); + } + static final VarHandle rxChannelA$VH = $struct$LAYOUT.varHandle(MemoryLayout.PathElement.groupElement("rxChannelA")); + public static VarHandle rxChannelA$VH() { + return sdrplay_api_DeviceParamsT.rxChannelA$VH; + } + public static MemoryAddress rxChannelA$get(MemorySegment seg) { + return (java.lang.foreign.MemoryAddress)sdrplay_api_DeviceParamsT.rxChannelA$VH.get(seg); + } + public static void rxChannelA$set( MemorySegment seg, MemoryAddress x) { + sdrplay_api_DeviceParamsT.rxChannelA$VH.set(seg, x); + } + public static MemoryAddress rxChannelA$get(MemorySegment seg, long index) { + return (java.lang.foreign.MemoryAddress)sdrplay_api_DeviceParamsT.rxChannelA$VH.get(seg.asSlice(index*sizeof())); + } + public static void rxChannelA$set(MemorySegment seg, long index, MemoryAddress x) { + sdrplay_api_DeviceParamsT.rxChannelA$VH.set(seg.asSlice(index*sizeof()), x); + } + static final VarHandle rxChannelB$VH = $struct$LAYOUT.varHandle(MemoryLayout.PathElement.groupElement("rxChannelB")); + public static VarHandle rxChannelB$VH() { + return sdrplay_api_DeviceParamsT.rxChannelB$VH; + } + public static MemoryAddress rxChannelB$get(MemorySegment seg) { + return (java.lang.foreign.MemoryAddress)sdrplay_api_DeviceParamsT.rxChannelB$VH.get(seg); + } + public static void rxChannelB$set( MemorySegment seg, MemoryAddress x) { + sdrplay_api_DeviceParamsT.rxChannelB$VH.set(seg, x); + } + public static MemoryAddress rxChannelB$get(MemorySegment seg, long index) { + return (java.lang.foreign.MemoryAddress)sdrplay_api_DeviceParamsT.rxChannelB$VH.get(seg.asSlice(index*sizeof())); + } + public static void rxChannelB$set(MemorySegment seg, long index, MemoryAddress x) { + sdrplay_api_DeviceParamsT.rxChannelB$VH.set(seg.asSlice(index*sizeof()), x); + } + public static long sizeof() { return $LAYOUT().byteSize(); } + public static MemorySegment allocate(SegmentAllocator allocator) { return allocator.allocate($LAYOUT()); } + public static MemorySegment allocateArray(int len, SegmentAllocator allocator) { + return allocator.allocate(MemoryLayout.sequenceLayout(len, $LAYOUT())); + } + public static MemorySegment ofAddress(MemoryAddress addr, MemorySession session) { return RuntimeHelper.asArray(addr, $LAYOUT(), 1, session); } +} + + diff --git a/sdrplay-api/src/main/java/com/github/dsheirer/sdrplay/api/v3_07/sdrplay_api_DeviceT.java b/sdrplay-api/src/main/java/com/github/dsheirer/sdrplay/api/v3_07/sdrplay_api_DeviceT.java new file mode 100644 index 000000000..0782fd31d --- /dev/null +++ b/sdrplay-api/src/main/java/com/github/dsheirer/sdrplay/api/v3_07/sdrplay_api_DeviceT.java @@ -0,0 +1,118 @@ +// Generated by jextract + +package com.github.dsheirer.sdrplay.api.v3_07; + +import java.lang.foreign.GroupLayout; +import java.lang.foreign.MemoryAddress; +import java.lang.foreign.MemoryLayout; +import java.lang.foreign.MemorySegment; +import java.lang.foreign.MemorySession; +import java.lang.foreign.SegmentAllocator; +import java.lang.invoke.VarHandle; +public class sdrplay_api_DeviceT { + + static final GroupLayout $struct$LAYOUT = MemoryLayout.structLayout( + MemoryLayout.sequenceLayout(64, Constants$root.C_CHAR$LAYOUT).withName("SerNo"), + Constants$root.C_CHAR$LAYOUT.withName("hwVer"), + MemoryLayout.paddingLayout(24), + Constants$root.C_LONG$LAYOUT.withName("tuner"), + Constants$root.C_LONG$LAYOUT.withName("rspDuoMode"), + MemoryLayout.paddingLayout(32), + Constants$root.C_DOUBLE$LAYOUT.withName("rspDuoSampleFreq"), + Constants$root.C_POINTER$LAYOUT.withName("dev") + ); + public static MemoryLayout $LAYOUT() { + return sdrplay_api_DeviceT.$struct$LAYOUT; + } + public static MemorySegment SerNo$slice(MemorySegment seg) { + return seg.asSlice(0, 64); + } + static final VarHandle hwVer$VH = $struct$LAYOUT.varHandle(MemoryLayout.PathElement.groupElement("hwVer")); + public static VarHandle hwVer$VH() { + return sdrplay_api_DeviceT.hwVer$VH; + } + public static byte hwVer$get(MemorySegment seg) { + return (byte)sdrplay_api_DeviceT.hwVer$VH.get(seg); + } + public static void hwVer$set( MemorySegment seg, byte x) { + sdrplay_api_DeviceT.hwVer$VH.set(seg, x); + } + public static byte hwVer$get(MemorySegment seg, long index) { + return (byte)sdrplay_api_DeviceT.hwVer$VH.get(seg.asSlice(index*sizeof())); + } + public static void hwVer$set(MemorySegment seg, long index, byte x) { + sdrplay_api_DeviceT.hwVer$VH.set(seg.asSlice(index*sizeof()), x); + } + static final VarHandle tuner$VH = $struct$LAYOUT.varHandle(MemoryLayout.PathElement.groupElement("tuner")); + public static VarHandle tuner$VH() { + return sdrplay_api_DeviceT.tuner$VH; + } + public static int tuner$get(MemorySegment seg) { + return (int)sdrplay_api_DeviceT.tuner$VH.get(seg); + } + public static void tuner$set( MemorySegment seg, int x) { + sdrplay_api_DeviceT.tuner$VH.set(seg, x); + } + public static int tuner$get(MemorySegment seg, long index) { + return (int)sdrplay_api_DeviceT.tuner$VH.get(seg.asSlice(index*sizeof())); + } + public static void tuner$set(MemorySegment seg, long index, int x) { + sdrplay_api_DeviceT.tuner$VH.set(seg.asSlice(index*sizeof()), x); + } + static final VarHandle rspDuoMode$VH = $struct$LAYOUT.varHandle(MemoryLayout.PathElement.groupElement("rspDuoMode")); + public static VarHandle rspDuoMode$VH() { + return sdrplay_api_DeviceT.rspDuoMode$VH; + } + public static int rspDuoMode$get(MemorySegment seg) { + return (int)sdrplay_api_DeviceT.rspDuoMode$VH.get(seg); + } + public static void rspDuoMode$set( MemorySegment seg, int x) { + sdrplay_api_DeviceT.rspDuoMode$VH.set(seg, x); + } + public static int rspDuoMode$get(MemorySegment seg, long index) { + return (int)sdrplay_api_DeviceT.rspDuoMode$VH.get(seg.asSlice(index*sizeof())); + } + public static void rspDuoMode$set(MemorySegment seg, long index, int x) { + sdrplay_api_DeviceT.rspDuoMode$VH.set(seg.asSlice(index*sizeof()), x); + } + static final VarHandle rspDuoSampleFreq$VH = $struct$LAYOUT.varHandle(MemoryLayout.PathElement.groupElement("rspDuoSampleFreq")); + public static VarHandle rspDuoSampleFreq$VH() { + return sdrplay_api_DeviceT.rspDuoSampleFreq$VH; + } + public static double rspDuoSampleFreq$get(MemorySegment seg) { + return (double)sdrplay_api_DeviceT.rspDuoSampleFreq$VH.get(seg); + } + public static void rspDuoSampleFreq$set( MemorySegment seg, double x) { + sdrplay_api_DeviceT.rspDuoSampleFreq$VH.set(seg, x); + } + public static double rspDuoSampleFreq$get(MemorySegment seg, long index) { + return (double)sdrplay_api_DeviceT.rspDuoSampleFreq$VH.get(seg.asSlice(index*sizeof())); + } + public static void rspDuoSampleFreq$set(MemorySegment seg, long index, double x) { + sdrplay_api_DeviceT.rspDuoSampleFreq$VH.set(seg.asSlice(index*sizeof()), x); + } + static final VarHandle dev$VH = $struct$LAYOUT.varHandle(MemoryLayout.PathElement.groupElement("dev")); + public static VarHandle dev$VH() { + return sdrplay_api_DeviceT.dev$VH; + } + public static MemoryAddress dev$get(MemorySegment seg) { + return (java.lang.foreign.MemoryAddress)sdrplay_api_DeviceT.dev$VH.get(seg); + } + public static void dev$set( MemorySegment seg, MemoryAddress x) { + sdrplay_api_DeviceT.dev$VH.set(seg, x); + } + public static MemoryAddress dev$get(MemorySegment seg, long index) { + return (java.lang.foreign.MemoryAddress)sdrplay_api_DeviceT.dev$VH.get(seg.asSlice(index*sizeof())); + } + public static void dev$set(MemorySegment seg, long index, MemoryAddress x) { + sdrplay_api_DeviceT.dev$VH.set(seg.asSlice(index*sizeof()), x); + } + public static long sizeof() { return $LAYOUT().byteSize(); } + public static MemorySegment allocate(SegmentAllocator allocator) { return allocator.allocate($LAYOUT()); } + public static MemorySegment allocateArray(int len, SegmentAllocator allocator) { + return allocator.allocate(MemoryLayout.sequenceLayout(len, $LAYOUT())); + } + public static MemorySegment ofAddress(MemoryAddress addr, MemorySession session) { return RuntimeHelper.asArray(addr, $LAYOUT(), 1, session); } +} + + diff --git a/sdrplay-api/src/main/java/com/github/dsheirer/sdrplay/api/v3_07/sdrplay_api_DisableHeartbeat_t.java b/sdrplay-api/src/main/java/com/github/dsheirer/sdrplay/api/v3_07/sdrplay_api_DisableHeartbeat_t.java new file mode 100644 index 000000000..bb29a06fa --- /dev/null +++ b/sdrplay-api/src/main/java/com/github/dsheirer/sdrplay/api/v3_07/sdrplay_api_DisableHeartbeat_t.java @@ -0,0 +1,27 @@ +// Generated by jextract + +package com.github.dsheirer.sdrplay.api.v3_07; + +import java.lang.foreign.Addressable; +import java.lang.foreign.MemoryAddress; +import java.lang.foreign.MemorySegment; +import java.lang.foreign.MemorySession; +public interface sdrplay_api_DisableHeartbeat_t { + + int apply(); + static MemorySegment allocate(sdrplay_api_DisableHeartbeat_t fi, MemorySession session) { + return RuntimeHelper.upcallStub(sdrplay_api_DisableHeartbeat_t.class, fi, constants$4.sdrplay_api_DisableHeartbeat_t$FUNC, session); + } + static sdrplay_api_DisableHeartbeat_t ofAddress(MemoryAddress addr, MemorySession session) { + MemorySegment symbol = MemorySegment.ofAddress(addr, 0, session); + return () -> { + try { + return (int)constants$4.sdrplay_api_DisableHeartbeat_t$MH.invokeExact((Addressable)symbol); + } catch (Throwable ex$) { + throw new AssertionError("should not reach here", ex$); + } + }; + } +} + + diff --git a/sdrplay-api/src/main/java/com/github/dsheirer/sdrplay/api/v3_07/sdrplay_api_ErrorInfoT.java b/sdrplay-api/src/main/java/com/github/dsheirer/sdrplay/api/v3_07/sdrplay_api_ErrorInfoT.java new file mode 100644 index 000000000..373f42b13 --- /dev/null +++ b/sdrplay-api/src/main/java/com/github/dsheirer/sdrplay/api/v3_07/sdrplay_api_ErrorInfoT.java @@ -0,0 +1,56 @@ +// Generated by jextract + +package com.github.dsheirer.sdrplay.api.v3_07; + +import java.lang.foreign.GroupLayout; +import java.lang.foreign.MemoryAddress; +import java.lang.foreign.MemoryLayout; +import java.lang.foreign.MemorySegment; +import java.lang.foreign.MemorySession; +import java.lang.foreign.SegmentAllocator; +import java.lang.invoke.VarHandle; +public class sdrplay_api_ErrorInfoT { + + static final GroupLayout $struct$LAYOUT = MemoryLayout.structLayout( + MemoryLayout.sequenceLayout(256, Constants$root.C_CHAR$LAYOUT).withName("file"), + MemoryLayout.sequenceLayout(256, Constants$root.C_CHAR$LAYOUT).withName("function"), + Constants$root.C_LONG$LAYOUT.withName("line"), + MemoryLayout.sequenceLayout(1024, Constants$root.C_CHAR$LAYOUT).withName("message") + ); + public static MemoryLayout $LAYOUT() { + return sdrplay_api_ErrorInfoT.$struct$LAYOUT; + } + public static MemorySegment file$slice(MemorySegment seg) { + return seg.asSlice(0, 256); + } + public static MemorySegment function$slice(MemorySegment seg) { + return seg.asSlice(256, 256); + } + static final VarHandle line$VH = $struct$LAYOUT.varHandle(MemoryLayout.PathElement.groupElement("line")); + public static VarHandle line$VH() { + return sdrplay_api_ErrorInfoT.line$VH; + } + public static int line$get(MemorySegment seg) { + return (int)sdrplay_api_ErrorInfoT.line$VH.get(seg); + } + public static void line$set( MemorySegment seg, int x) { + sdrplay_api_ErrorInfoT.line$VH.set(seg, x); + } + public static int line$get(MemorySegment seg, long index) { + return (int)sdrplay_api_ErrorInfoT.line$VH.get(seg.asSlice(index*sizeof())); + } + public static void line$set(MemorySegment seg, long index, int x) { + sdrplay_api_ErrorInfoT.line$VH.set(seg.asSlice(index*sizeof()), x); + } + public static MemorySegment message$slice(MemorySegment seg) { + return seg.asSlice(516, 1024); + } + public static long sizeof() { return $LAYOUT().byteSize(); } + public static MemorySegment allocate(SegmentAllocator allocator) { return allocator.allocate($LAYOUT()); } + public static MemorySegment allocateArray(int len, SegmentAllocator allocator) { + return allocator.allocate(MemoryLayout.sequenceLayout(len, $LAYOUT())); + } + public static MemorySegment ofAddress(MemoryAddress addr, MemorySession session) { return RuntimeHelper.asArray(addr, $LAYOUT(), 1, session); } +} + + diff --git a/sdrplay-api/src/main/java/com/github/dsheirer/sdrplay/api/v3_07/sdrplay_api_EventCallback_t.java b/sdrplay-api/src/main/java/com/github/dsheirer/sdrplay/api/v3_07/sdrplay_api_EventCallback_t.java new file mode 100644 index 000000000..78a724ae9 --- /dev/null +++ b/sdrplay-api/src/main/java/com/github/dsheirer/sdrplay/api/v3_07/sdrplay_api_EventCallback_t.java @@ -0,0 +1,27 @@ +// Generated by jextract + +package com.github.dsheirer.sdrplay.api.v3_07; + +import java.lang.foreign.Addressable; +import java.lang.foreign.MemoryAddress; +import java.lang.foreign.MemorySegment; +import java.lang.foreign.MemorySession; +public interface sdrplay_api_EventCallback_t { + + void apply(int eventId, int tuner, java.lang.foreign.MemoryAddress params, java.lang.foreign.MemoryAddress cbContext); + static MemorySegment allocate(sdrplay_api_EventCallback_t fi, MemorySession session) { + return RuntimeHelper.upcallStub(sdrplay_api_EventCallback_t.class, fi, constants$0.sdrplay_api_EventCallback_t$FUNC, session); + } + static sdrplay_api_EventCallback_t ofAddress(MemoryAddress addr, MemorySession session) { + MemorySegment symbol = MemorySegment.ofAddress(addr, 0, session); + return (int _eventId, int _tuner, java.lang.foreign.MemoryAddress _params, java.lang.foreign.MemoryAddress _cbContext) -> { + try { + constants$0.sdrplay_api_EventCallback_t$MH.invokeExact((Addressable)symbol, _eventId, _tuner, (java.lang.foreign.Addressable)_params, (java.lang.foreign.Addressable)_cbContext); + } catch (Throwable ex$) { + throw new AssertionError("should not reach here", ex$); + } + }; + } +} + + diff --git a/sdrplay-api/src/main/java/com/github/dsheirer/sdrplay/api/v3_07/sdrplay_api_EventParamsT.java b/sdrplay-api/src/main/java/com/github/dsheirer/sdrplay/api/v3_07/sdrplay_api_EventParamsT.java new file mode 100644 index 000000000..3e8c49be6 --- /dev/null +++ b/sdrplay-api/src/main/java/com/github/dsheirer/sdrplay/api/v3_07/sdrplay_api_EventParamsT.java @@ -0,0 +1,46 @@ +// Generated by jextract + +package com.github.dsheirer.sdrplay.api.v3_07; + +import java.lang.foreign.GroupLayout; +import java.lang.foreign.MemoryAddress; +import java.lang.foreign.MemoryLayout; +import java.lang.foreign.MemorySegment; +import java.lang.foreign.MemorySession; +import java.lang.foreign.SegmentAllocator; +public class sdrplay_api_EventParamsT { + + static final GroupLayout $union$LAYOUT = MemoryLayout.unionLayout( + MemoryLayout.structLayout( + Constants$root.C_LONG$LAYOUT.withName("gRdB"), + Constants$root.C_LONG$LAYOUT.withName("lnaGRdB"), + Constants$root.C_DOUBLE$LAYOUT.withName("currGain") + ).withName("gainParams"), + MemoryLayout.structLayout( + Constants$root.C_LONG$LAYOUT.withName("powerOverloadChangeType") + ).withName("powerOverloadParams"), + MemoryLayout.structLayout( + Constants$root.C_LONG$LAYOUT.withName("modeChangeType") + ).withName("rspDuoModeParams") + ); + public static MemoryLayout $LAYOUT() { + return sdrplay_api_EventParamsT.$union$LAYOUT; + } + public static MemorySegment gainParams$slice(MemorySegment seg) { + return seg.asSlice(0, 16); + } + public static MemorySegment powerOverloadParams$slice(MemorySegment seg) { + return seg.asSlice(0, 4); + } + public static MemorySegment rspDuoModeParams$slice(MemorySegment seg) { + return seg.asSlice(0, 4); + } + public static long sizeof() { return $LAYOUT().byteSize(); } + public static MemorySegment allocate(SegmentAllocator allocator) { return allocator.allocate($LAYOUT()); } + public static MemorySegment allocateArray(int len, SegmentAllocator allocator) { + return allocator.allocate(MemoryLayout.sequenceLayout(len, $LAYOUT())); + } + public static MemorySegment ofAddress(MemoryAddress addr, MemorySession session) { return RuntimeHelper.asArray(addr, $LAYOUT(), 1, session); } +} + + diff --git a/sdrplay-api/src/main/java/com/github/dsheirer/sdrplay/api/v3_07/sdrplay_api_FsFreqT.java b/sdrplay-api/src/main/java/com/github/dsheirer/sdrplay/api/v3_07/sdrplay_api_FsFreqT.java new file mode 100644 index 000000000..94e55b3b3 --- /dev/null +++ b/sdrplay-api/src/main/java/com/github/dsheirer/sdrplay/api/v3_07/sdrplay_api_FsFreqT.java @@ -0,0 +1,79 @@ +// Generated by jextract + +package com.github.dsheirer.sdrplay.api.v3_07; + +import java.lang.foreign.GroupLayout; +import java.lang.foreign.MemoryAddress; +import java.lang.foreign.MemoryLayout; +import java.lang.foreign.MemorySegment; +import java.lang.foreign.MemorySession; +import java.lang.foreign.SegmentAllocator; +import java.lang.invoke.VarHandle; +public class sdrplay_api_FsFreqT { + + static final GroupLayout $struct$LAYOUT = MemoryLayout.structLayout( + Constants$root.C_DOUBLE$LAYOUT.withName("fsHz"), + Constants$root.C_CHAR$LAYOUT.withName("syncUpdate"), + Constants$root.C_CHAR$LAYOUT.withName("reCal"), + MemoryLayout.paddingLayout(48) + ); + public static MemoryLayout $LAYOUT() { + return sdrplay_api_FsFreqT.$struct$LAYOUT; + } + static final VarHandle fsHz$VH = $struct$LAYOUT.varHandle(MemoryLayout.PathElement.groupElement("fsHz")); + public static VarHandle fsHz$VH() { + return sdrplay_api_FsFreqT.fsHz$VH; + } + public static double fsHz$get(MemorySegment seg) { + return (double)sdrplay_api_FsFreqT.fsHz$VH.get(seg); + } + public static void fsHz$set( MemorySegment seg, double x) { + sdrplay_api_FsFreqT.fsHz$VH.set(seg, x); + } + public static double fsHz$get(MemorySegment seg, long index) { + return (double)sdrplay_api_FsFreqT.fsHz$VH.get(seg.asSlice(index*sizeof())); + } + public static void fsHz$set(MemorySegment seg, long index, double x) { + sdrplay_api_FsFreqT.fsHz$VH.set(seg.asSlice(index*sizeof()), x); + } + static final VarHandle syncUpdate$VH = $struct$LAYOUT.varHandle(MemoryLayout.PathElement.groupElement("syncUpdate")); + public static VarHandle syncUpdate$VH() { + return sdrplay_api_FsFreqT.syncUpdate$VH; + } + public static byte syncUpdate$get(MemorySegment seg) { + return (byte)sdrplay_api_FsFreqT.syncUpdate$VH.get(seg); + } + public static void syncUpdate$set( MemorySegment seg, byte x) { + sdrplay_api_FsFreqT.syncUpdate$VH.set(seg, x); + } + public static byte syncUpdate$get(MemorySegment seg, long index) { + return (byte)sdrplay_api_FsFreqT.syncUpdate$VH.get(seg.asSlice(index*sizeof())); + } + public static void syncUpdate$set(MemorySegment seg, long index, byte x) { + sdrplay_api_FsFreqT.syncUpdate$VH.set(seg.asSlice(index*sizeof()), x); + } + static final VarHandle reCal$VH = $struct$LAYOUT.varHandle(MemoryLayout.PathElement.groupElement("reCal")); + public static VarHandle reCal$VH() { + return sdrplay_api_FsFreqT.reCal$VH; + } + public static byte reCal$get(MemorySegment seg) { + return (byte)sdrplay_api_FsFreqT.reCal$VH.get(seg); + } + public static void reCal$set( MemorySegment seg, byte x) { + sdrplay_api_FsFreqT.reCal$VH.set(seg, x); + } + public static byte reCal$get(MemorySegment seg, long index) { + return (byte)sdrplay_api_FsFreqT.reCal$VH.get(seg.asSlice(index*sizeof())); + } + public static void reCal$set(MemorySegment seg, long index, byte x) { + sdrplay_api_FsFreqT.reCal$VH.set(seg.asSlice(index*sizeof()), x); + } + public static long sizeof() { return $LAYOUT().byteSize(); } + public static MemorySegment allocate(SegmentAllocator allocator) { return allocator.allocate($LAYOUT()); } + public static MemorySegment allocateArray(int len, SegmentAllocator allocator) { + return allocator.allocate(MemoryLayout.sequenceLayout(len, $LAYOUT())); + } + public static MemorySegment ofAddress(MemoryAddress addr, MemorySession session) { return RuntimeHelper.asArray(addr, $LAYOUT(), 1, session); } +} + + diff --git a/sdrplay-api/src/main/java/com/github/dsheirer/sdrplay/api/v3_07/sdrplay_api_GainCbParamT.java b/sdrplay-api/src/main/java/com/github/dsheirer/sdrplay/api/v3_07/sdrplay_api_GainCbParamT.java new file mode 100644 index 000000000..437e99f3d --- /dev/null +++ b/sdrplay-api/src/main/java/com/github/dsheirer/sdrplay/api/v3_07/sdrplay_api_GainCbParamT.java @@ -0,0 +1,78 @@ +// Generated by jextract + +package com.github.dsheirer.sdrplay.api.v3_07; + +import java.lang.foreign.GroupLayout; +import java.lang.foreign.MemoryAddress; +import java.lang.foreign.MemoryLayout; +import java.lang.foreign.MemorySegment; +import java.lang.foreign.MemorySession; +import java.lang.foreign.SegmentAllocator; +import java.lang.invoke.VarHandle; +public class sdrplay_api_GainCbParamT { + + static final GroupLayout $struct$LAYOUT = MemoryLayout.structLayout( + Constants$root.C_LONG$LAYOUT.withName("gRdB"), + Constants$root.C_LONG$LAYOUT.withName("lnaGRdB"), + Constants$root.C_DOUBLE$LAYOUT.withName("currGain") + ); + public static MemoryLayout $LAYOUT() { + return sdrplay_api_GainCbParamT.$struct$LAYOUT; + } + static final VarHandle gRdB$VH = $struct$LAYOUT.varHandle(MemoryLayout.PathElement.groupElement("gRdB")); + public static VarHandle gRdB$VH() { + return sdrplay_api_GainCbParamT.gRdB$VH; + } + public static int gRdB$get(MemorySegment seg) { + return (int)sdrplay_api_GainCbParamT.gRdB$VH.get(seg); + } + public static void gRdB$set( MemorySegment seg, int x) { + sdrplay_api_GainCbParamT.gRdB$VH.set(seg, x); + } + public static int gRdB$get(MemorySegment seg, long index) { + return (int)sdrplay_api_GainCbParamT.gRdB$VH.get(seg.asSlice(index*sizeof())); + } + public static void gRdB$set(MemorySegment seg, long index, int x) { + sdrplay_api_GainCbParamT.gRdB$VH.set(seg.asSlice(index*sizeof()), x); + } + static final VarHandle lnaGRdB$VH = $struct$LAYOUT.varHandle(MemoryLayout.PathElement.groupElement("lnaGRdB")); + public static VarHandle lnaGRdB$VH() { + return sdrplay_api_GainCbParamT.lnaGRdB$VH; + } + public static int lnaGRdB$get(MemorySegment seg) { + return (int)sdrplay_api_GainCbParamT.lnaGRdB$VH.get(seg); + } + public static void lnaGRdB$set( MemorySegment seg, int x) { + sdrplay_api_GainCbParamT.lnaGRdB$VH.set(seg, x); + } + public static int lnaGRdB$get(MemorySegment seg, long index) { + return (int)sdrplay_api_GainCbParamT.lnaGRdB$VH.get(seg.asSlice(index*sizeof())); + } + public static void lnaGRdB$set(MemorySegment seg, long index, int x) { + sdrplay_api_GainCbParamT.lnaGRdB$VH.set(seg.asSlice(index*sizeof()), x); + } + static final VarHandle currGain$VH = $struct$LAYOUT.varHandle(MemoryLayout.PathElement.groupElement("currGain")); + public static VarHandle currGain$VH() { + return sdrplay_api_GainCbParamT.currGain$VH; + } + public static double currGain$get(MemorySegment seg) { + return (double)sdrplay_api_GainCbParamT.currGain$VH.get(seg); + } + public static void currGain$set( MemorySegment seg, double x) { + sdrplay_api_GainCbParamT.currGain$VH.set(seg, x); + } + public static double currGain$get(MemorySegment seg, long index) { + return (double)sdrplay_api_GainCbParamT.currGain$VH.get(seg.asSlice(index*sizeof())); + } + public static void currGain$set(MemorySegment seg, long index, double x) { + sdrplay_api_GainCbParamT.currGain$VH.set(seg.asSlice(index*sizeof()), x); + } + public static long sizeof() { return $LAYOUT().byteSize(); } + public static MemorySegment allocate(SegmentAllocator allocator) { return allocator.allocate($LAYOUT()); } + public static MemorySegment allocateArray(int len, SegmentAllocator allocator) { + return allocator.allocate(MemoryLayout.sequenceLayout(len, $LAYOUT())); + } + public static MemorySegment ofAddress(MemoryAddress addr, MemorySession session) { return RuntimeHelper.asArray(addr, $LAYOUT(), 1, session); } +} + + diff --git a/sdrplay-api/src/main/java/com/github/dsheirer/sdrplay/api/v3_07/sdrplay_api_GainT.java b/sdrplay-api/src/main/java/com/github/dsheirer/sdrplay/api/v3_07/sdrplay_api_GainT.java new file mode 100644 index 000000000..4416db86d --- /dev/null +++ b/sdrplay-api/src/main/java/com/github/dsheirer/sdrplay/api/v3_07/sdrplay_api_GainT.java @@ -0,0 +1,104 @@ +// Generated by jextract + +package com.github.dsheirer.sdrplay.api.v3_07; + +import java.lang.foreign.GroupLayout; +import java.lang.foreign.MemoryAddress; +import java.lang.foreign.MemoryLayout; +import java.lang.foreign.MemorySegment; +import java.lang.foreign.MemorySession; +import java.lang.foreign.SegmentAllocator; +import java.lang.invoke.VarHandle; +public class sdrplay_api_GainT { + + static final GroupLayout $struct$LAYOUT = MemoryLayout.structLayout( + Constants$root.C_LONG$LAYOUT.withName("gRdB"), + Constants$root.C_CHAR$LAYOUT.withName("LNAstate"), + Constants$root.C_CHAR$LAYOUT.withName("syncUpdate"), + MemoryLayout.paddingLayout(16), + Constants$root.C_LONG$LAYOUT.withName("minGr"), + MemoryLayout.structLayout( + Constants$root.C_FLOAT$LAYOUT.withName("curr"), + Constants$root.C_FLOAT$LAYOUT.withName("max"), + Constants$root.C_FLOAT$LAYOUT.withName("min") + ).withName("gainVals") + ); + public static MemoryLayout $LAYOUT() { + return sdrplay_api_GainT.$struct$LAYOUT; + } + static final VarHandle gRdB$VH = $struct$LAYOUT.varHandle(MemoryLayout.PathElement.groupElement("gRdB")); + public static VarHandle gRdB$VH() { + return sdrplay_api_GainT.gRdB$VH; + } + public static int gRdB$get(MemorySegment seg) { + return (int)sdrplay_api_GainT.gRdB$VH.get(seg); + } + public static void gRdB$set( MemorySegment seg, int x) { + sdrplay_api_GainT.gRdB$VH.set(seg, x); + } + public static int gRdB$get(MemorySegment seg, long index) { + return (int)sdrplay_api_GainT.gRdB$VH.get(seg.asSlice(index*sizeof())); + } + public static void gRdB$set(MemorySegment seg, long index, int x) { + sdrplay_api_GainT.gRdB$VH.set(seg.asSlice(index*sizeof()), x); + } + static final VarHandle LNAstate$VH = $struct$LAYOUT.varHandle(MemoryLayout.PathElement.groupElement("LNAstate")); + public static VarHandle LNAstate$VH() { + return sdrplay_api_GainT.LNAstate$VH; + } + public static byte LNAstate$get(MemorySegment seg) { + return (byte)sdrplay_api_GainT.LNAstate$VH.get(seg); + } + public static void LNAstate$set( MemorySegment seg, byte x) { + sdrplay_api_GainT.LNAstate$VH.set(seg, x); + } + public static byte LNAstate$get(MemorySegment seg, long index) { + return (byte)sdrplay_api_GainT.LNAstate$VH.get(seg.asSlice(index*sizeof())); + } + public static void LNAstate$set(MemorySegment seg, long index, byte x) { + sdrplay_api_GainT.LNAstate$VH.set(seg.asSlice(index*sizeof()), x); + } + static final VarHandle syncUpdate$VH = $struct$LAYOUT.varHandle(MemoryLayout.PathElement.groupElement("syncUpdate")); + public static VarHandle syncUpdate$VH() { + return sdrplay_api_GainT.syncUpdate$VH; + } + public static byte syncUpdate$get(MemorySegment seg) { + return (byte)sdrplay_api_GainT.syncUpdate$VH.get(seg); + } + public static void syncUpdate$set( MemorySegment seg, byte x) { + sdrplay_api_GainT.syncUpdate$VH.set(seg, x); + } + public static byte syncUpdate$get(MemorySegment seg, long index) { + return (byte)sdrplay_api_GainT.syncUpdate$VH.get(seg.asSlice(index*sizeof())); + } + public static void syncUpdate$set(MemorySegment seg, long index, byte x) { + sdrplay_api_GainT.syncUpdate$VH.set(seg.asSlice(index*sizeof()), x); + } + static final VarHandle minGr$VH = $struct$LAYOUT.varHandle(MemoryLayout.PathElement.groupElement("minGr")); + public static VarHandle minGr$VH() { + return sdrplay_api_GainT.minGr$VH; + } + public static int minGr$get(MemorySegment seg) { + return (int)sdrplay_api_GainT.minGr$VH.get(seg); + } + public static void minGr$set( MemorySegment seg, int x) { + sdrplay_api_GainT.minGr$VH.set(seg, x); + } + public static int minGr$get(MemorySegment seg, long index) { + return (int)sdrplay_api_GainT.minGr$VH.get(seg.asSlice(index*sizeof())); + } + public static void minGr$set(MemorySegment seg, long index, int x) { + sdrplay_api_GainT.minGr$VH.set(seg.asSlice(index*sizeof()), x); + } + public static MemorySegment gainVals$slice(MemorySegment seg) { + return seg.asSlice(12, 12); + } + public static long sizeof() { return $LAYOUT().byteSize(); } + public static MemorySegment allocate(SegmentAllocator allocator) { return allocator.allocate($LAYOUT()); } + public static MemorySegment allocateArray(int len, SegmentAllocator allocator) { + return allocator.allocate(MemoryLayout.sequenceLayout(len, $LAYOUT())); + } + public static MemorySegment ofAddress(MemoryAddress addr, MemorySession session) { return RuntimeHelper.asArray(addr, $LAYOUT(), 1, session); } +} + + diff --git a/sdrplay-api/src/main/java/com/github/dsheirer/sdrplay/api/v3_07/sdrplay_api_GainValuesT.java b/sdrplay-api/src/main/java/com/github/dsheirer/sdrplay/api/v3_07/sdrplay_api_GainValuesT.java new file mode 100644 index 000000000..8c1c0aa05 --- /dev/null +++ b/sdrplay-api/src/main/java/com/github/dsheirer/sdrplay/api/v3_07/sdrplay_api_GainValuesT.java @@ -0,0 +1,78 @@ +// Generated by jextract + +package com.github.dsheirer.sdrplay.api.v3_07; + +import java.lang.foreign.GroupLayout; +import java.lang.foreign.MemoryAddress; +import java.lang.foreign.MemoryLayout; +import java.lang.foreign.MemorySegment; +import java.lang.foreign.MemorySession; +import java.lang.foreign.SegmentAllocator; +import java.lang.invoke.VarHandle; +public class sdrplay_api_GainValuesT { + + static final GroupLayout $struct$LAYOUT = MemoryLayout.structLayout( + Constants$root.C_FLOAT$LAYOUT.withName("curr"), + Constants$root.C_FLOAT$LAYOUT.withName("max"), + Constants$root.C_FLOAT$LAYOUT.withName("min") + ); + public static MemoryLayout $LAYOUT() { + return sdrplay_api_GainValuesT.$struct$LAYOUT; + } + static final VarHandle curr$VH = $struct$LAYOUT.varHandle(MemoryLayout.PathElement.groupElement("curr")); + public static VarHandle curr$VH() { + return sdrplay_api_GainValuesT.curr$VH; + } + public static float curr$get(MemorySegment seg) { + return (float)sdrplay_api_GainValuesT.curr$VH.get(seg); + } + public static void curr$set( MemorySegment seg, float x) { + sdrplay_api_GainValuesT.curr$VH.set(seg, x); + } + public static float curr$get(MemorySegment seg, long index) { + return (float)sdrplay_api_GainValuesT.curr$VH.get(seg.asSlice(index*sizeof())); + } + public static void curr$set(MemorySegment seg, long index, float x) { + sdrplay_api_GainValuesT.curr$VH.set(seg.asSlice(index*sizeof()), x); + } + static final VarHandle max$VH = $struct$LAYOUT.varHandle(MemoryLayout.PathElement.groupElement("max")); + public static VarHandle max$VH() { + return sdrplay_api_GainValuesT.max$VH; + } + public static float max$get(MemorySegment seg) { + return (float)sdrplay_api_GainValuesT.max$VH.get(seg); + } + public static void max$set( MemorySegment seg, float x) { + sdrplay_api_GainValuesT.max$VH.set(seg, x); + } + public static float max$get(MemorySegment seg, long index) { + return (float)sdrplay_api_GainValuesT.max$VH.get(seg.asSlice(index*sizeof())); + } + public static void max$set(MemorySegment seg, long index, float x) { + sdrplay_api_GainValuesT.max$VH.set(seg.asSlice(index*sizeof()), x); + } + static final VarHandle min$VH = $struct$LAYOUT.varHandle(MemoryLayout.PathElement.groupElement("min")); + public static VarHandle min$VH() { + return sdrplay_api_GainValuesT.min$VH; + } + public static float min$get(MemorySegment seg) { + return (float)sdrplay_api_GainValuesT.min$VH.get(seg); + } + public static void min$set( MemorySegment seg, float x) { + sdrplay_api_GainValuesT.min$VH.set(seg, x); + } + public static float min$get(MemorySegment seg, long index) { + return (float)sdrplay_api_GainValuesT.min$VH.get(seg.asSlice(index*sizeof())); + } + public static void min$set(MemorySegment seg, long index, float x) { + sdrplay_api_GainValuesT.min$VH.set(seg.asSlice(index*sizeof()), x); + } + public static long sizeof() { return $LAYOUT().byteSize(); } + public static MemorySegment allocate(SegmentAllocator allocator) { return allocator.allocate($LAYOUT()); } + public static MemorySegment allocateArray(int len, SegmentAllocator allocator) { + return allocator.allocate(MemoryLayout.sequenceLayout(len, $LAYOUT())); + } + public static MemorySegment ofAddress(MemoryAddress addr, MemorySession session) { return RuntimeHelper.asArray(addr, $LAYOUT(), 1, session); } +} + + diff --git a/sdrplay-api/src/main/java/com/github/dsheirer/sdrplay/api/v3_07/sdrplay_api_GetDeviceParams_t.java b/sdrplay-api/src/main/java/com/github/dsheirer/sdrplay/api/v3_07/sdrplay_api_GetDeviceParams_t.java new file mode 100644 index 000000000..cdda61777 --- /dev/null +++ b/sdrplay-api/src/main/java/com/github/dsheirer/sdrplay/api/v3_07/sdrplay_api_GetDeviceParams_t.java @@ -0,0 +1,27 @@ +// Generated by jextract + +package com.github.dsheirer.sdrplay.api.v3_07; + +import java.lang.foreign.Addressable; +import java.lang.foreign.MemoryAddress; +import java.lang.foreign.MemorySegment; +import java.lang.foreign.MemorySession; +public interface sdrplay_api_GetDeviceParams_t { + + int apply(java.lang.foreign.MemoryAddress dev, java.lang.foreign.MemoryAddress deviceParams); + static MemorySegment allocate(sdrplay_api_GetDeviceParams_t fi, MemorySession session) { + return RuntimeHelper.upcallStub(sdrplay_api_GetDeviceParams_t.class, fi, constants$4.sdrplay_api_GetDeviceParams_t$FUNC, session); + } + static sdrplay_api_GetDeviceParams_t ofAddress(MemoryAddress addr, MemorySession session) { + MemorySegment symbol = MemorySegment.ofAddress(addr, 0, session); + return (java.lang.foreign.MemoryAddress _dev, java.lang.foreign.MemoryAddress _deviceParams) -> { + try { + return (int)constants$4.sdrplay_api_GetDeviceParams_t$MH.invokeExact((Addressable)symbol, (java.lang.foreign.Addressable)_dev, (java.lang.foreign.Addressable)_deviceParams); + } catch (Throwable ex$) { + throw new AssertionError("should not reach here", ex$); + } + }; + } +} + + diff --git a/sdrplay-api/src/main/java/com/github/dsheirer/sdrplay/api/v3_07/sdrplay_api_GetDevices_t.java b/sdrplay-api/src/main/java/com/github/dsheirer/sdrplay/api/v3_07/sdrplay_api_GetDevices_t.java new file mode 100644 index 000000000..862320a6b --- /dev/null +++ b/sdrplay-api/src/main/java/com/github/dsheirer/sdrplay/api/v3_07/sdrplay_api_GetDevices_t.java @@ -0,0 +1,27 @@ +// Generated by jextract + +package com.github.dsheirer.sdrplay.api.v3_07; + +import java.lang.foreign.Addressable; +import java.lang.foreign.MemoryAddress; +import java.lang.foreign.MemorySegment; +import java.lang.foreign.MemorySession; +public interface sdrplay_api_GetDevices_t { + + int apply(java.lang.foreign.MemoryAddress devices, java.lang.foreign.MemoryAddress numDevs, int maxDevs); + static MemorySegment allocate(sdrplay_api_GetDevices_t fi, MemorySession session) { + return RuntimeHelper.upcallStub(sdrplay_api_GetDevices_t.class, fi, constants$2.sdrplay_api_GetDevices_t$FUNC, session); + } + static sdrplay_api_GetDevices_t ofAddress(MemoryAddress addr, MemorySession session) { + MemorySegment symbol = MemorySegment.ofAddress(addr, 0, session); + return (java.lang.foreign.MemoryAddress _devices, java.lang.foreign.MemoryAddress _numDevs, int _maxDevs) -> { + try { + return (int)constants$2.sdrplay_api_GetDevices_t$MH.invokeExact((Addressable)symbol, (java.lang.foreign.Addressable)_devices, (java.lang.foreign.Addressable)_numDevs, _maxDevs); + } catch (Throwable ex$) { + throw new AssertionError("should not reach here", ex$); + } + }; + } +} + + diff --git a/sdrplay-api/src/main/java/com/github/dsheirer/sdrplay/api/v3_07/sdrplay_api_GetErrorString_t.java b/sdrplay-api/src/main/java/com/github/dsheirer/sdrplay/api/v3_07/sdrplay_api_GetErrorString_t.java new file mode 100644 index 000000000..6d9c160a3 --- /dev/null +++ b/sdrplay-api/src/main/java/com/github/dsheirer/sdrplay/api/v3_07/sdrplay_api_GetErrorString_t.java @@ -0,0 +1,27 @@ +// Generated by jextract + +package com.github.dsheirer.sdrplay.api.v3_07; + +import java.lang.foreign.Addressable; +import java.lang.foreign.MemoryAddress; +import java.lang.foreign.MemorySegment; +import java.lang.foreign.MemorySession; +public interface sdrplay_api_GetErrorString_t { + + java.lang.foreign.Addressable apply(int err); + static MemorySegment allocate(sdrplay_api_GetErrorString_t fi, MemorySession session) { + return RuntimeHelper.upcallStub(sdrplay_api_GetErrorString_t.class, fi, constants$3.sdrplay_api_GetErrorString_t$FUNC, session); + } + static sdrplay_api_GetErrorString_t ofAddress(MemoryAddress addr, MemorySession session) { + MemorySegment symbol = MemorySegment.ofAddress(addr, 0, session); + return (int _err) -> { + try { + return (java.lang.foreign.Addressable)(java.lang.foreign.MemoryAddress)constants$3.sdrplay_api_GetErrorString_t$MH.invokeExact((Addressable)symbol, _err); + } catch (Throwable ex$) { + throw new AssertionError("should not reach here", ex$); + } + }; + } +} + + diff --git a/sdrplay-api/src/main/java/com/github/dsheirer/sdrplay/api/v3_07/sdrplay_api_GetLastError_t.java b/sdrplay-api/src/main/java/com/github/dsheirer/sdrplay/api/v3_07/sdrplay_api_GetLastError_t.java new file mode 100644 index 000000000..582b28573 --- /dev/null +++ b/sdrplay-api/src/main/java/com/github/dsheirer/sdrplay/api/v3_07/sdrplay_api_GetLastError_t.java @@ -0,0 +1,27 @@ +// Generated by jextract + +package com.github.dsheirer.sdrplay.api.v3_07; + +import java.lang.foreign.Addressable; +import java.lang.foreign.MemoryAddress; +import java.lang.foreign.MemorySegment; +import java.lang.foreign.MemorySession; +public interface sdrplay_api_GetLastError_t { + + java.lang.foreign.Addressable apply(java.lang.foreign.MemoryAddress device); + static MemorySegment allocate(sdrplay_api_GetLastError_t fi, MemorySession session) { + return RuntimeHelper.upcallStub(sdrplay_api_GetLastError_t.class, fi, constants$3.sdrplay_api_GetLastError_t$FUNC, session); + } + static sdrplay_api_GetLastError_t ofAddress(MemoryAddress addr, MemorySession session) { + MemorySegment symbol = MemorySegment.ofAddress(addr, 0, session); + return (java.lang.foreign.MemoryAddress _device) -> { + try { + return (java.lang.foreign.Addressable)(java.lang.foreign.MemoryAddress)constants$3.sdrplay_api_GetLastError_t$MH.invokeExact((Addressable)symbol, (java.lang.foreign.Addressable)_device); + } catch (Throwable ex$) { + throw new AssertionError("should not reach here", ex$); + } + }; + } +} + + diff --git a/sdrplay-api/src/main/java/com/github/dsheirer/sdrplay/api/v3_07/sdrplay_api_Init_t.java b/sdrplay-api/src/main/java/com/github/dsheirer/sdrplay/api/v3_07/sdrplay_api_Init_t.java new file mode 100644 index 000000000..8a81e82d9 --- /dev/null +++ b/sdrplay-api/src/main/java/com/github/dsheirer/sdrplay/api/v3_07/sdrplay_api_Init_t.java @@ -0,0 +1,27 @@ +// Generated by jextract + +package com.github.dsheirer.sdrplay.api.v3_07; + +import java.lang.foreign.Addressable; +import java.lang.foreign.MemoryAddress; +import java.lang.foreign.MemorySegment; +import java.lang.foreign.MemorySession; +public interface sdrplay_api_Init_t { + + int apply(java.lang.foreign.MemoryAddress dev, java.lang.foreign.MemoryAddress callbackFns, java.lang.foreign.MemoryAddress cbContext); + static MemorySegment allocate(sdrplay_api_Init_t fi, MemorySession session) { + return RuntimeHelper.upcallStub(sdrplay_api_Init_t.class, fi, constants$5.sdrplay_api_Init_t$FUNC, session); + } + static sdrplay_api_Init_t ofAddress(MemoryAddress addr, MemorySession session) { + MemorySegment symbol = MemorySegment.ofAddress(addr, 0, session); + return (java.lang.foreign.MemoryAddress _dev, java.lang.foreign.MemoryAddress _callbackFns, java.lang.foreign.MemoryAddress _cbContext) -> { + try { + return (int)constants$5.sdrplay_api_Init_t$MH.invokeExact((Addressable)symbol, (java.lang.foreign.Addressable)_dev, (java.lang.foreign.Addressable)_callbackFns, (java.lang.foreign.Addressable)_cbContext); + } catch (Throwable ex$) { + throw new AssertionError("should not reach here", ex$); + } + }; + } +} + + diff --git a/sdrplay-api/src/main/java/com/github/dsheirer/sdrplay/api/v3_07/sdrplay_api_LockDeviceApi_t.java b/sdrplay-api/src/main/java/com/github/dsheirer/sdrplay/api/v3_07/sdrplay_api_LockDeviceApi_t.java new file mode 100644 index 000000000..9a69199b3 --- /dev/null +++ b/sdrplay-api/src/main/java/com/github/dsheirer/sdrplay/api/v3_07/sdrplay_api_LockDeviceApi_t.java @@ -0,0 +1,27 @@ +// Generated by jextract + +package com.github.dsheirer.sdrplay.api.v3_07; + +import java.lang.foreign.Addressable; +import java.lang.foreign.MemoryAddress; +import java.lang.foreign.MemorySegment; +import java.lang.foreign.MemorySession; +public interface sdrplay_api_LockDeviceApi_t { + + int apply(); + static MemorySegment allocate(sdrplay_api_LockDeviceApi_t fi, MemorySession session) { + return RuntimeHelper.upcallStub(sdrplay_api_LockDeviceApi_t.class, fi, constants$1.sdrplay_api_LockDeviceApi_t$FUNC, session); + } + static sdrplay_api_LockDeviceApi_t ofAddress(MemoryAddress addr, MemorySession session) { + MemorySegment symbol = MemorySegment.ofAddress(addr, 0, session); + return () -> { + try { + return (int)constants$1.sdrplay_api_LockDeviceApi_t$MH.invokeExact((Addressable)symbol); + } catch (Throwable ex$) { + throw new AssertionError("should not reach here", ex$); + } + }; + } +} + + diff --git a/sdrplay-api/src/main/java/com/github/dsheirer/sdrplay/api/v3_07/sdrplay_api_Open_t.java b/sdrplay-api/src/main/java/com/github/dsheirer/sdrplay/api/v3_07/sdrplay_api_Open_t.java new file mode 100644 index 000000000..d09836636 --- /dev/null +++ b/sdrplay-api/src/main/java/com/github/dsheirer/sdrplay/api/v3_07/sdrplay_api_Open_t.java @@ -0,0 +1,27 @@ +// Generated by jextract + +package com.github.dsheirer.sdrplay.api.v3_07; + +import java.lang.foreign.Addressable; +import java.lang.foreign.MemoryAddress; +import java.lang.foreign.MemorySegment; +import java.lang.foreign.MemorySession; +public interface sdrplay_api_Open_t { + + int apply(); + static MemorySegment allocate(sdrplay_api_Open_t fi, MemorySession session) { + return RuntimeHelper.upcallStub(sdrplay_api_Open_t.class, fi, constants$0.sdrplay_api_Open_t$FUNC, session); + } + static sdrplay_api_Open_t ofAddress(MemoryAddress addr, MemorySession session) { + MemorySegment symbol = MemorySegment.ofAddress(addr, 0, session); + return () -> { + try { + return (int)constants$0.sdrplay_api_Open_t$MH.invokeExact((Addressable)symbol); + } catch (Throwable ex$) { + throw new AssertionError("should not reach here", ex$); + } + }; + } +} + + diff --git a/sdrplay-api/src/main/java/com/github/dsheirer/sdrplay/api/v3_07/sdrplay_api_PowerOverloadCbParamT.java b/sdrplay-api/src/main/java/com/github/dsheirer/sdrplay/api/v3_07/sdrplay_api_PowerOverloadCbParamT.java new file mode 100644 index 000000000..9a1a5d80f --- /dev/null +++ b/sdrplay-api/src/main/java/com/github/dsheirer/sdrplay/api/v3_07/sdrplay_api_PowerOverloadCbParamT.java @@ -0,0 +1,44 @@ +// Generated by jextract + +package com.github.dsheirer.sdrplay.api.v3_07; + +import java.lang.foreign.GroupLayout; +import java.lang.foreign.MemoryAddress; +import java.lang.foreign.MemoryLayout; +import java.lang.foreign.MemorySegment; +import java.lang.foreign.MemorySession; +import java.lang.foreign.SegmentAllocator; +import java.lang.invoke.VarHandle; +public class sdrplay_api_PowerOverloadCbParamT { + + static final GroupLayout $struct$LAYOUT = MemoryLayout.structLayout( + Constants$root.C_LONG$LAYOUT.withName("powerOverloadChangeType") + ); + public static MemoryLayout $LAYOUT() { + return sdrplay_api_PowerOverloadCbParamT.$struct$LAYOUT; + } + static final VarHandle powerOverloadChangeType$VH = $struct$LAYOUT.varHandle(MemoryLayout.PathElement.groupElement("powerOverloadChangeType")); + public static VarHandle powerOverloadChangeType$VH() { + return sdrplay_api_PowerOverloadCbParamT.powerOverloadChangeType$VH; + } + public static int powerOverloadChangeType$get(MemorySegment seg) { + return (int)sdrplay_api_PowerOverloadCbParamT.powerOverloadChangeType$VH.get(seg); + } + public static void powerOverloadChangeType$set( MemorySegment seg, int x) { + sdrplay_api_PowerOverloadCbParamT.powerOverloadChangeType$VH.set(seg, x); + } + public static int powerOverloadChangeType$get(MemorySegment seg, long index) { + return (int)sdrplay_api_PowerOverloadCbParamT.powerOverloadChangeType$VH.get(seg.asSlice(index*sizeof())); + } + public static void powerOverloadChangeType$set(MemorySegment seg, long index, int x) { + sdrplay_api_PowerOverloadCbParamT.powerOverloadChangeType$VH.set(seg.asSlice(index*sizeof()), x); + } + public static long sizeof() { return $LAYOUT().byteSize(); } + public static MemorySegment allocate(SegmentAllocator allocator) { return allocator.allocate($LAYOUT()); } + public static MemorySegment allocateArray(int len, SegmentAllocator allocator) { + return allocator.allocate(MemoryLayout.sequenceLayout(len, $LAYOUT())); + } + public static MemorySegment ofAddress(MemoryAddress addr, MemorySession session) { return RuntimeHelper.asArray(addr, $LAYOUT(), 1, session); } +} + + diff --git a/sdrplay-api/src/main/java/com/github/dsheirer/sdrplay/api/v3_07/sdrplay_api_ReleaseDevice_t.java b/sdrplay-api/src/main/java/com/github/dsheirer/sdrplay/api/v3_07/sdrplay_api_ReleaseDevice_t.java new file mode 100644 index 000000000..e5ae69066 --- /dev/null +++ b/sdrplay-api/src/main/java/com/github/dsheirer/sdrplay/api/v3_07/sdrplay_api_ReleaseDevice_t.java @@ -0,0 +1,27 @@ +// Generated by jextract + +package com.github.dsheirer.sdrplay.api.v3_07; + +import java.lang.foreign.Addressable; +import java.lang.foreign.MemoryAddress; +import java.lang.foreign.MemorySegment; +import java.lang.foreign.MemorySession; +public interface sdrplay_api_ReleaseDevice_t { + + int apply(java.lang.foreign.MemoryAddress device); + static MemorySegment allocate(sdrplay_api_ReleaseDevice_t fi, MemorySession session) { + return RuntimeHelper.upcallStub(sdrplay_api_ReleaseDevice_t.class, fi, constants$3.sdrplay_api_ReleaseDevice_t$FUNC, session); + } + static sdrplay_api_ReleaseDevice_t ofAddress(MemoryAddress addr, MemorySession session) { + MemorySegment symbol = MemorySegment.ofAddress(addr, 0, session); + return (java.lang.foreign.MemoryAddress _device) -> { + try { + return (int)constants$3.sdrplay_api_ReleaseDevice_t$MH.invokeExact((Addressable)symbol, (java.lang.foreign.Addressable)_device); + } catch (Throwable ex$) { + throw new AssertionError("should not reach here", ex$); + } + }; + } +} + + diff --git a/sdrplay-api/src/main/java/com/github/dsheirer/sdrplay/api/v3_07/sdrplay_api_ResetFlagsT.java b/sdrplay-api/src/main/java/com/github/dsheirer/sdrplay/api/v3_07/sdrplay_api_ResetFlagsT.java new file mode 100644 index 000000000..30399c091 --- /dev/null +++ b/sdrplay-api/src/main/java/com/github/dsheirer/sdrplay/api/v3_07/sdrplay_api_ResetFlagsT.java @@ -0,0 +1,78 @@ +// Generated by jextract + +package com.github.dsheirer.sdrplay.api.v3_07; + +import java.lang.foreign.GroupLayout; +import java.lang.foreign.MemoryAddress; +import java.lang.foreign.MemoryLayout; +import java.lang.foreign.MemorySegment; +import java.lang.foreign.MemorySession; +import java.lang.foreign.SegmentAllocator; +import java.lang.invoke.VarHandle; +public class sdrplay_api_ResetFlagsT { + + static final GroupLayout $struct$LAYOUT = MemoryLayout.structLayout( + Constants$root.C_CHAR$LAYOUT.withName("resetGainUpdate"), + Constants$root.C_CHAR$LAYOUT.withName("resetRfUpdate"), + Constants$root.C_CHAR$LAYOUT.withName("resetFsUpdate") + ); + public static MemoryLayout $LAYOUT() { + return sdrplay_api_ResetFlagsT.$struct$LAYOUT; + } + static final VarHandle resetGainUpdate$VH = $struct$LAYOUT.varHandle(MemoryLayout.PathElement.groupElement("resetGainUpdate")); + public static VarHandle resetGainUpdate$VH() { + return sdrplay_api_ResetFlagsT.resetGainUpdate$VH; + } + public static byte resetGainUpdate$get(MemorySegment seg) { + return (byte)sdrplay_api_ResetFlagsT.resetGainUpdate$VH.get(seg); + } + public static void resetGainUpdate$set( MemorySegment seg, byte x) { + sdrplay_api_ResetFlagsT.resetGainUpdate$VH.set(seg, x); + } + public static byte resetGainUpdate$get(MemorySegment seg, long index) { + return (byte)sdrplay_api_ResetFlagsT.resetGainUpdate$VH.get(seg.asSlice(index*sizeof())); + } + public static void resetGainUpdate$set(MemorySegment seg, long index, byte x) { + sdrplay_api_ResetFlagsT.resetGainUpdate$VH.set(seg.asSlice(index*sizeof()), x); + } + static final VarHandle resetRfUpdate$VH = $struct$LAYOUT.varHandle(MemoryLayout.PathElement.groupElement("resetRfUpdate")); + public static VarHandle resetRfUpdate$VH() { + return sdrplay_api_ResetFlagsT.resetRfUpdate$VH; + } + public static byte resetRfUpdate$get(MemorySegment seg) { + return (byte)sdrplay_api_ResetFlagsT.resetRfUpdate$VH.get(seg); + } + public static void resetRfUpdate$set( MemorySegment seg, byte x) { + sdrplay_api_ResetFlagsT.resetRfUpdate$VH.set(seg, x); + } + public static byte resetRfUpdate$get(MemorySegment seg, long index) { + return (byte)sdrplay_api_ResetFlagsT.resetRfUpdate$VH.get(seg.asSlice(index*sizeof())); + } + public static void resetRfUpdate$set(MemorySegment seg, long index, byte x) { + sdrplay_api_ResetFlagsT.resetRfUpdate$VH.set(seg.asSlice(index*sizeof()), x); + } + static final VarHandle resetFsUpdate$VH = $struct$LAYOUT.varHandle(MemoryLayout.PathElement.groupElement("resetFsUpdate")); + public static VarHandle resetFsUpdate$VH() { + return sdrplay_api_ResetFlagsT.resetFsUpdate$VH; + } + public static byte resetFsUpdate$get(MemorySegment seg) { + return (byte)sdrplay_api_ResetFlagsT.resetFsUpdate$VH.get(seg); + } + public static void resetFsUpdate$set( MemorySegment seg, byte x) { + sdrplay_api_ResetFlagsT.resetFsUpdate$VH.set(seg, x); + } + public static byte resetFsUpdate$get(MemorySegment seg, long index) { + return (byte)sdrplay_api_ResetFlagsT.resetFsUpdate$VH.get(seg.asSlice(index*sizeof())); + } + public static void resetFsUpdate$set(MemorySegment seg, long index, byte x) { + sdrplay_api_ResetFlagsT.resetFsUpdate$VH.set(seg.asSlice(index*sizeof()), x); + } + public static long sizeof() { return $LAYOUT().byteSize(); } + public static MemorySegment allocate(SegmentAllocator allocator) { return allocator.allocate($LAYOUT()); } + public static MemorySegment allocateArray(int len, SegmentAllocator allocator) { + return allocator.allocate(MemoryLayout.sequenceLayout(len, $LAYOUT())); + } + public static MemorySegment ofAddress(MemoryAddress addr, MemorySession session) { return RuntimeHelper.asArray(addr, $LAYOUT(), 1, session); } +} + + diff --git a/sdrplay-api/src/main/java/com/github/dsheirer/sdrplay/api/v3_07/sdrplay_api_RfFreqT.java b/sdrplay-api/src/main/java/com/github/dsheirer/sdrplay/api/v3_07/sdrplay_api_RfFreqT.java new file mode 100644 index 000000000..7dbeb6781 --- /dev/null +++ b/sdrplay-api/src/main/java/com/github/dsheirer/sdrplay/api/v3_07/sdrplay_api_RfFreqT.java @@ -0,0 +1,62 @@ +// Generated by jextract + +package com.github.dsheirer.sdrplay.api.v3_07; + +import java.lang.foreign.GroupLayout; +import java.lang.foreign.MemoryAddress; +import java.lang.foreign.MemoryLayout; +import java.lang.foreign.MemorySegment; +import java.lang.foreign.MemorySession; +import java.lang.foreign.SegmentAllocator; +import java.lang.invoke.VarHandle; +public class sdrplay_api_RfFreqT { + + static final GroupLayout $struct$LAYOUT = MemoryLayout.structLayout( + Constants$root.C_DOUBLE$LAYOUT.withName("rfHz"), + Constants$root.C_CHAR$LAYOUT.withName("syncUpdate"), + MemoryLayout.paddingLayout(56) + ); + public static MemoryLayout $LAYOUT() { + return sdrplay_api_RfFreqT.$struct$LAYOUT; + } + static final VarHandle rfHz$VH = $struct$LAYOUT.varHandle(MemoryLayout.PathElement.groupElement("rfHz")); + public static VarHandle rfHz$VH() { + return sdrplay_api_RfFreqT.rfHz$VH; + } + public static double rfHz$get(MemorySegment seg) { + return (double)sdrplay_api_RfFreqT.rfHz$VH.get(seg); + } + public static void rfHz$set( MemorySegment seg, double x) { + sdrplay_api_RfFreqT.rfHz$VH.set(seg, x); + } + public static double rfHz$get(MemorySegment seg, long index) { + return (double)sdrplay_api_RfFreqT.rfHz$VH.get(seg.asSlice(index*sizeof())); + } + public static void rfHz$set(MemorySegment seg, long index, double x) { + sdrplay_api_RfFreqT.rfHz$VH.set(seg.asSlice(index*sizeof()), x); + } + static final VarHandle syncUpdate$VH = $struct$LAYOUT.varHandle(MemoryLayout.PathElement.groupElement("syncUpdate")); + public static VarHandle syncUpdate$VH() { + return sdrplay_api_RfFreqT.syncUpdate$VH; + } + public static byte syncUpdate$get(MemorySegment seg) { + return (byte)sdrplay_api_RfFreqT.syncUpdate$VH.get(seg); + } + public static void syncUpdate$set( MemorySegment seg, byte x) { + sdrplay_api_RfFreqT.syncUpdate$VH.set(seg, x); + } + public static byte syncUpdate$get(MemorySegment seg, long index) { + return (byte)sdrplay_api_RfFreqT.syncUpdate$VH.get(seg.asSlice(index*sizeof())); + } + public static void syncUpdate$set(MemorySegment seg, long index, byte x) { + sdrplay_api_RfFreqT.syncUpdate$VH.set(seg.asSlice(index*sizeof()), x); + } + public static long sizeof() { return $LAYOUT().byteSize(); } + public static MemorySegment allocate(SegmentAllocator allocator) { return allocator.allocate($LAYOUT()); } + public static MemorySegment allocateArray(int len, SegmentAllocator allocator) { + return allocator.allocate(MemoryLayout.sequenceLayout(len, $LAYOUT())); + } + public static MemorySegment ofAddress(MemoryAddress addr, MemorySession session) { return RuntimeHelper.asArray(addr, $LAYOUT(), 1, session); } +} + + diff --git a/sdrplay-api/src/main/java/com/github/dsheirer/sdrplay/api/v3_07/sdrplay_api_Rsp1aParamsT.java b/sdrplay-api/src/main/java/com/github/dsheirer/sdrplay/api/v3_07/sdrplay_api_Rsp1aParamsT.java new file mode 100644 index 000000000..230048e6c --- /dev/null +++ b/sdrplay-api/src/main/java/com/github/dsheirer/sdrplay/api/v3_07/sdrplay_api_Rsp1aParamsT.java @@ -0,0 +1,61 @@ +// Generated by jextract + +package com.github.dsheirer.sdrplay.api.v3_07; + +import java.lang.foreign.GroupLayout; +import java.lang.foreign.MemoryAddress; +import java.lang.foreign.MemoryLayout; +import java.lang.foreign.MemorySegment; +import java.lang.foreign.MemorySession; +import java.lang.foreign.SegmentAllocator; +import java.lang.invoke.VarHandle; +public class sdrplay_api_Rsp1aParamsT { + + static final GroupLayout $struct$LAYOUT = MemoryLayout.structLayout( + Constants$root.C_CHAR$LAYOUT.withName("rfNotchEnable"), + Constants$root.C_CHAR$LAYOUT.withName("rfDabNotchEnable") + ); + public static MemoryLayout $LAYOUT() { + return sdrplay_api_Rsp1aParamsT.$struct$LAYOUT; + } + static final VarHandle rfNotchEnable$VH = $struct$LAYOUT.varHandle(MemoryLayout.PathElement.groupElement("rfNotchEnable")); + public static VarHandle rfNotchEnable$VH() { + return sdrplay_api_Rsp1aParamsT.rfNotchEnable$VH; + } + public static byte rfNotchEnable$get(MemorySegment seg) { + return (byte)sdrplay_api_Rsp1aParamsT.rfNotchEnable$VH.get(seg); + } + public static void rfNotchEnable$set( MemorySegment seg, byte x) { + sdrplay_api_Rsp1aParamsT.rfNotchEnable$VH.set(seg, x); + } + public static byte rfNotchEnable$get(MemorySegment seg, long index) { + return (byte)sdrplay_api_Rsp1aParamsT.rfNotchEnable$VH.get(seg.asSlice(index*sizeof())); + } + public static void rfNotchEnable$set(MemorySegment seg, long index, byte x) { + sdrplay_api_Rsp1aParamsT.rfNotchEnable$VH.set(seg.asSlice(index*sizeof()), x); + } + static final VarHandle rfDabNotchEnable$VH = $struct$LAYOUT.varHandle(MemoryLayout.PathElement.groupElement("rfDabNotchEnable")); + public static VarHandle rfDabNotchEnable$VH() { + return sdrplay_api_Rsp1aParamsT.rfDabNotchEnable$VH; + } + public static byte rfDabNotchEnable$get(MemorySegment seg) { + return (byte)sdrplay_api_Rsp1aParamsT.rfDabNotchEnable$VH.get(seg); + } + public static void rfDabNotchEnable$set( MemorySegment seg, byte x) { + sdrplay_api_Rsp1aParamsT.rfDabNotchEnable$VH.set(seg, x); + } + public static byte rfDabNotchEnable$get(MemorySegment seg, long index) { + return (byte)sdrplay_api_Rsp1aParamsT.rfDabNotchEnable$VH.get(seg.asSlice(index*sizeof())); + } + public static void rfDabNotchEnable$set(MemorySegment seg, long index, byte x) { + sdrplay_api_Rsp1aParamsT.rfDabNotchEnable$VH.set(seg.asSlice(index*sizeof()), x); + } + public static long sizeof() { return $LAYOUT().byteSize(); } + public static MemorySegment allocate(SegmentAllocator allocator) { return allocator.allocate($LAYOUT()); } + public static MemorySegment allocateArray(int len, SegmentAllocator allocator) { + return allocator.allocate(MemoryLayout.sequenceLayout(len, $LAYOUT())); + } + public static MemorySegment ofAddress(MemoryAddress addr, MemorySession session) { return RuntimeHelper.asArray(addr, $LAYOUT(), 1, session); } +} + + diff --git a/sdrplay-api/src/main/java/com/github/dsheirer/sdrplay/api/v3_07/sdrplay_api_Rsp1aTunerParamsT.java b/sdrplay-api/src/main/java/com/github/dsheirer/sdrplay/api/v3_07/sdrplay_api_Rsp1aTunerParamsT.java new file mode 100644 index 000000000..a2139d913 --- /dev/null +++ b/sdrplay-api/src/main/java/com/github/dsheirer/sdrplay/api/v3_07/sdrplay_api_Rsp1aTunerParamsT.java @@ -0,0 +1,44 @@ +// Generated by jextract + +package com.github.dsheirer.sdrplay.api.v3_07; + +import java.lang.foreign.GroupLayout; +import java.lang.foreign.MemoryAddress; +import java.lang.foreign.MemoryLayout; +import java.lang.foreign.MemorySegment; +import java.lang.foreign.MemorySession; +import java.lang.foreign.SegmentAllocator; +import java.lang.invoke.VarHandle; +public class sdrplay_api_Rsp1aTunerParamsT { + + static final GroupLayout $struct$LAYOUT = MemoryLayout.structLayout( + Constants$root.C_CHAR$LAYOUT.withName("biasTEnable") + ); + public static MemoryLayout $LAYOUT() { + return sdrplay_api_Rsp1aTunerParamsT.$struct$LAYOUT; + } + static final VarHandle biasTEnable$VH = $struct$LAYOUT.varHandle(MemoryLayout.PathElement.groupElement("biasTEnable")); + public static VarHandle biasTEnable$VH() { + return sdrplay_api_Rsp1aTunerParamsT.biasTEnable$VH; + } + public static byte biasTEnable$get(MemorySegment seg) { + return (byte)sdrplay_api_Rsp1aTunerParamsT.biasTEnable$VH.get(seg); + } + public static void biasTEnable$set( MemorySegment seg, byte x) { + sdrplay_api_Rsp1aTunerParamsT.biasTEnable$VH.set(seg, x); + } + public static byte biasTEnable$get(MemorySegment seg, long index) { + return (byte)sdrplay_api_Rsp1aTunerParamsT.biasTEnable$VH.get(seg.asSlice(index*sizeof())); + } + public static void biasTEnable$set(MemorySegment seg, long index, byte x) { + sdrplay_api_Rsp1aTunerParamsT.biasTEnable$VH.set(seg.asSlice(index*sizeof()), x); + } + public static long sizeof() { return $LAYOUT().byteSize(); } + public static MemorySegment allocate(SegmentAllocator allocator) { return allocator.allocate($LAYOUT()); } + public static MemorySegment allocateArray(int len, SegmentAllocator allocator) { + return allocator.allocate(MemoryLayout.sequenceLayout(len, $LAYOUT())); + } + public static MemorySegment ofAddress(MemoryAddress addr, MemorySession session) { return RuntimeHelper.asArray(addr, $LAYOUT(), 1, session); } +} + + diff --git a/sdrplay-api/src/main/java/com/github/dsheirer/sdrplay/api/v3_07/sdrplay_api_Rsp2ParamsT.java b/sdrplay-api/src/main/java/com/github/dsheirer/sdrplay/api/v3_07/sdrplay_api_Rsp2ParamsT.java new file mode 100644 index 000000000..9894d3751 --- /dev/null +++ b/sdrplay-api/src/main/java/com/github/dsheirer/sdrplay/api/v3_07/sdrplay_api_Rsp2ParamsT.java @@ -0,0 +1,44 @@ +// Generated by jextract + +package com.github.dsheirer.sdrplay.api.v3_07; + +import java.lang.foreign.GroupLayout; +import java.lang.foreign.MemoryAddress; +import java.lang.foreign.MemoryLayout; +import java.lang.foreign.MemorySegment; +import java.lang.foreign.MemorySession; +import java.lang.foreign.SegmentAllocator; +import java.lang.invoke.VarHandle; +public class sdrplay_api_Rsp2ParamsT { + + static final GroupLayout $struct$LAYOUT = MemoryLayout.structLayout( + Constants$root.C_CHAR$LAYOUT.withName("extRefOutputEn") + ); + public static MemoryLayout $LAYOUT() { + return sdrplay_api_Rsp2ParamsT.$struct$LAYOUT; + } + static final VarHandle extRefOutputEn$VH = $struct$LAYOUT.varHandle(MemoryLayout.PathElement.groupElement("extRefOutputEn")); + public static VarHandle extRefOutputEn$VH() { + return sdrplay_api_Rsp2ParamsT.extRefOutputEn$VH; + } + public static byte extRefOutputEn$get(MemorySegment seg) { + return (byte)sdrplay_api_Rsp2ParamsT.extRefOutputEn$VH.get(seg); + } + public static void extRefOutputEn$set( MemorySegment seg, byte x) { + sdrplay_api_Rsp2ParamsT.extRefOutputEn$VH.set(seg, x); + } + public static byte extRefOutputEn$get(MemorySegment seg, long index) { + return (byte)sdrplay_api_Rsp2ParamsT.extRefOutputEn$VH.get(seg.asSlice(index*sizeof())); + } + public static void extRefOutputEn$set(MemorySegment seg, long index, byte x) { + sdrplay_api_Rsp2ParamsT.extRefOutputEn$VH.set(seg.asSlice(index*sizeof()), x); + } + public static long sizeof() { return $LAYOUT().byteSize(); } + public static MemorySegment allocate(SegmentAllocator allocator) { return allocator.allocate($LAYOUT()); } + public static MemorySegment allocateArray(int len, SegmentAllocator allocator) { + return allocator.allocate(MemoryLayout.sequenceLayout(len, $LAYOUT())); + } + public static MemorySegment ofAddress(MemoryAddress addr, MemorySession session) { return RuntimeHelper.asArray(addr, $LAYOUT(), 1, session); } +} + + diff --git a/sdrplay-api/src/main/java/com/github/dsheirer/sdrplay/api/v3_07/sdrplay_api_Rsp2TunerParamsT.java b/sdrplay-api/src/main/java/com/github/dsheirer/sdrplay/api/v3_07/sdrplay_api_Rsp2TunerParamsT.java new file mode 100644 index 000000000..0943f422d --- /dev/null +++ b/sdrplay-api/src/main/java/com/github/dsheirer/sdrplay/api/v3_07/sdrplay_api_Rsp2TunerParamsT.java @@ -0,0 +1,97 @@ +// Generated by jextract + +package com.github.dsheirer.sdrplay.api.v3_07; + +import java.lang.foreign.GroupLayout; +import java.lang.foreign.MemoryAddress; +import java.lang.foreign.MemoryLayout; +import java.lang.foreign.MemorySegment; +import java.lang.foreign.MemorySession; +import java.lang.foreign.SegmentAllocator; +import java.lang.invoke.VarHandle; +public class sdrplay_api_Rsp2TunerParamsT { + + static final GroupLayout $struct$LAYOUT = MemoryLayout.structLayout( + Constants$root.C_CHAR$LAYOUT.withName("biasTEnable"), + MemoryLayout.paddingLayout(24), + Constants$root.C_LONG$LAYOUT.withName("amPortSel"), + Constants$root.C_LONG$LAYOUT.withName("antennaSel"), + Constants$root.C_CHAR$LAYOUT.withName("rfNotchEnable"), + MemoryLayout.paddingLayout(24) + ); + public static MemoryLayout $LAYOUT() { + return sdrplay_api_Rsp2TunerParamsT.$struct$LAYOUT; + } + static final VarHandle biasTEnable$VH = $struct$LAYOUT.varHandle(MemoryLayout.PathElement.groupElement("biasTEnable")); + public static VarHandle biasTEnable$VH() { + return sdrplay_api_Rsp2TunerParamsT.biasTEnable$VH; + } + public static byte biasTEnable$get(MemorySegment seg) { + return (byte)sdrplay_api_Rsp2TunerParamsT.biasTEnable$VH.get(seg); + } + public static void biasTEnable$set( MemorySegment seg, byte x) { + sdrplay_api_Rsp2TunerParamsT.biasTEnable$VH.set(seg, x); + } + public static byte biasTEnable$get(MemorySegment seg, long index) { + return (byte)sdrplay_api_Rsp2TunerParamsT.biasTEnable$VH.get(seg.asSlice(index*sizeof())); + } + public static void biasTEnable$set(MemorySegment seg, long index, byte x) { + sdrplay_api_Rsp2TunerParamsT.biasTEnable$VH.set(seg.asSlice(index*sizeof()), x); + } + static final VarHandle amPortSel$VH = $struct$LAYOUT.varHandle(MemoryLayout.PathElement.groupElement("amPortSel")); + public static VarHandle amPortSel$VH() { + return sdrplay_api_Rsp2TunerParamsT.amPortSel$VH; + } + public static int amPortSel$get(MemorySegment seg) { + return (int)sdrplay_api_Rsp2TunerParamsT.amPortSel$VH.get(seg); + } + public static void amPortSel$set( MemorySegment seg, int x) { + sdrplay_api_Rsp2TunerParamsT.amPortSel$VH.set(seg, x); + } + public static int amPortSel$get(MemorySegment seg, long index) { + return (int)sdrplay_api_Rsp2TunerParamsT.amPortSel$VH.get(seg.asSlice(index*sizeof())); + } + public static void amPortSel$set(MemorySegment seg, long index, int x) { + sdrplay_api_Rsp2TunerParamsT.amPortSel$VH.set(seg.asSlice(index*sizeof()), x); + } + static final VarHandle antennaSel$VH = $struct$LAYOUT.varHandle(MemoryLayout.PathElement.groupElement("antennaSel")); + public static VarHandle antennaSel$VH() { + return sdrplay_api_Rsp2TunerParamsT.antennaSel$VH; + } + public static int antennaSel$get(MemorySegment seg) { + return (int)sdrplay_api_Rsp2TunerParamsT.antennaSel$VH.get(seg); + } + public static void antennaSel$set( MemorySegment seg, int x) { + sdrplay_api_Rsp2TunerParamsT.antennaSel$VH.set(seg, x); + } + public static int antennaSel$get(MemorySegment seg, long index) { + return (int)sdrplay_api_Rsp2TunerParamsT.antennaSel$VH.get(seg.asSlice(index*sizeof())); + } + public static void antennaSel$set(MemorySegment seg, long index, int x) { + sdrplay_api_Rsp2TunerParamsT.antennaSel$VH.set(seg.asSlice(index*sizeof()), x); + } + static final VarHandle rfNotchEnable$VH = $struct$LAYOUT.varHandle(MemoryLayout.PathElement.groupElement("rfNotchEnable")); + public static VarHandle rfNotchEnable$VH() { + return sdrplay_api_Rsp2TunerParamsT.rfNotchEnable$VH; + } + public static byte rfNotchEnable$get(MemorySegment seg) { + return (byte)sdrplay_api_Rsp2TunerParamsT.rfNotchEnable$VH.get(seg); + } + public static void rfNotchEnable$set( MemorySegment seg, byte x) { + sdrplay_api_Rsp2TunerParamsT.rfNotchEnable$VH.set(seg, x); + } + public static byte rfNotchEnable$get(MemorySegment seg, long index) { + return (byte)sdrplay_api_Rsp2TunerParamsT.rfNotchEnable$VH.get(seg.asSlice(index*sizeof())); + } + public static void rfNotchEnable$set(MemorySegment seg, long index, byte x) { + sdrplay_api_Rsp2TunerParamsT.rfNotchEnable$VH.set(seg.asSlice(index*sizeof()), x); + } + public static long sizeof() { return $LAYOUT().byteSize(); } + public static MemorySegment allocate(SegmentAllocator allocator) { return allocator.allocate($LAYOUT()); } + public static MemorySegment allocateArray(int len, SegmentAllocator allocator) { + return allocator.allocate(MemoryLayout.sequenceLayout(len, $LAYOUT())); + } + public static MemorySegment ofAddress(MemoryAddress addr, MemorySession session) { return RuntimeHelper.asArray(addr, $LAYOUT(), 1, session); } +} + + diff --git a/sdrplay-api/src/main/java/com/github/dsheirer/sdrplay/api/v3_07/sdrplay_api_RspDuoModeCbParamT.java b/sdrplay-api/src/main/java/com/github/dsheirer/sdrplay/api/v3_07/sdrplay_api_RspDuoModeCbParamT.java new file mode 100644 index 000000000..e874cf37c --- /dev/null +++ b/sdrplay-api/src/main/java/com/github/dsheirer/sdrplay/api/v3_07/sdrplay_api_RspDuoModeCbParamT.java @@ -0,0 +1,44 @@ +// Generated by jextract + +package com.github.dsheirer.sdrplay.api.v3_07; + +import java.lang.foreign.GroupLayout; +import java.lang.foreign.MemoryAddress; +import java.lang.foreign.MemoryLayout; +import java.lang.foreign.MemorySegment; +import java.lang.foreign.MemorySession; +import java.lang.foreign.SegmentAllocator; +import java.lang.invoke.VarHandle; +public class sdrplay_api_RspDuoModeCbParamT { + + static final GroupLayout $struct$LAYOUT = MemoryLayout.structLayout( + Constants$root.C_LONG$LAYOUT.withName("modeChangeType") + ); + public static MemoryLayout $LAYOUT() { + return sdrplay_api_RspDuoModeCbParamT.$struct$LAYOUT; + } + static final VarHandle modeChangeType$VH = $struct$LAYOUT.varHandle(MemoryLayout.PathElement.groupElement("modeChangeType")); + public static VarHandle modeChangeType$VH() { + return sdrplay_api_RspDuoModeCbParamT.modeChangeType$VH; + } + public static int modeChangeType$get(MemorySegment seg) { + return (int)sdrplay_api_RspDuoModeCbParamT.modeChangeType$VH.get(seg); + } + public static void modeChangeType$set( MemorySegment seg, int x) { + sdrplay_api_RspDuoModeCbParamT.modeChangeType$VH.set(seg, x); + } + public static int modeChangeType$get(MemorySegment seg, long index) { + return (int)sdrplay_api_RspDuoModeCbParamT.modeChangeType$VH.get(seg.asSlice(index*sizeof())); + } + public static void modeChangeType$set(MemorySegment seg, long index, int x) { + sdrplay_api_RspDuoModeCbParamT.modeChangeType$VH.set(seg.asSlice(index*sizeof()), x); + } + public static long sizeof() { return $LAYOUT().byteSize(); } + public static MemorySegment allocate(SegmentAllocator allocator) { return allocator.allocate($LAYOUT()); } + public static MemorySegment allocateArray(int len, SegmentAllocator allocator) { + return allocator.allocate(MemoryLayout.sequenceLayout(len, $LAYOUT())); + } + public static MemorySegment ofAddress(MemoryAddress addr, MemorySession session) { return RuntimeHelper.asArray(addr, $LAYOUT(), 1, session); } +} + + diff --git a/sdrplay-api/src/main/java/com/github/dsheirer/sdrplay/api/v3_07/sdrplay_api_RspDuoParamsT.java b/sdrplay-api/src/main/java/com/github/dsheirer/sdrplay/api/v3_07/sdrplay_api_RspDuoParamsT.java new file mode 100644 index 000000000..320ef4c95 --- /dev/null +++ b/sdrplay-api/src/main/java/com/github/dsheirer/sdrplay/api/v3_07/sdrplay_api_RspDuoParamsT.java @@ -0,0 +1,44 @@ +// Generated by jextract + +package com.github.dsheirer.sdrplay.api.v3_07; + +import java.lang.foreign.GroupLayout; +import java.lang.foreign.MemoryAddress; +import java.lang.foreign.MemoryLayout; +import java.lang.foreign.MemorySegment; +import java.lang.foreign.MemorySession; +import java.lang.foreign.SegmentAllocator; +import java.lang.invoke.VarHandle; +public class sdrplay_api_RspDuoParamsT { + + static final GroupLayout $struct$LAYOUT = MemoryLayout.structLayout( + Constants$root.C_LONG$LAYOUT.withName("extRefOutputEn") + ); + public static MemoryLayout $LAYOUT() { + return sdrplay_api_RspDuoParamsT.$struct$LAYOUT; + } + static final VarHandle extRefOutputEn$VH = $struct$LAYOUT.varHandle(MemoryLayout.PathElement.groupElement("extRefOutputEn")); + public static VarHandle extRefOutputEn$VH() { + return sdrplay_api_RspDuoParamsT.extRefOutputEn$VH; + } + public static int extRefOutputEn$get(MemorySegment seg) { + return (int)sdrplay_api_RspDuoParamsT.extRefOutputEn$VH.get(seg); + } + public static void extRefOutputEn$set( MemorySegment seg, int x) { + sdrplay_api_RspDuoParamsT.extRefOutputEn$VH.set(seg, x); + } + public static int extRefOutputEn$get(MemorySegment seg, long index) { + return (int)sdrplay_api_RspDuoParamsT.extRefOutputEn$VH.get(seg.asSlice(index*sizeof())); + } + public static void extRefOutputEn$set(MemorySegment seg, long index, int x) { + sdrplay_api_RspDuoParamsT.extRefOutputEn$VH.set(seg.asSlice(index*sizeof()), x); + } + public static long sizeof() { return $LAYOUT().byteSize(); } + public static MemorySegment allocate(SegmentAllocator allocator) { return allocator.allocate($LAYOUT()); } + public static MemorySegment allocateArray(int len, SegmentAllocator allocator) { + return allocator.allocate(MemoryLayout.sequenceLayout(len, $LAYOUT())); + } + public static MemorySegment ofAddress(MemoryAddress addr, MemorySession session) { return RuntimeHelper.asArray(addr, $LAYOUT(), 1, session); } +} + + diff --git a/sdrplay-api/src/main/java/com/github/dsheirer/sdrplay/api/v3_07/sdrplay_api_RspDuoTunerParamsT.java b/sdrplay-api/src/main/java/com/github/dsheirer/sdrplay/api/v3_07/sdrplay_api_RspDuoTunerParamsT.java new file mode 100644 index 000000000..b22abff47 --- /dev/null +++ b/sdrplay-api/src/main/java/com/github/dsheirer/sdrplay/api/v3_07/sdrplay_api_RspDuoTunerParamsT.java @@ -0,0 +1,114 @@ +// Generated by jextract + +package com.github.dsheirer.sdrplay.api.v3_07; + +import java.lang.foreign.GroupLayout; +import java.lang.foreign.MemoryAddress; +import java.lang.foreign.MemoryLayout; +import java.lang.foreign.MemorySegment; +import java.lang.foreign.MemorySession; +import java.lang.foreign.SegmentAllocator; +import java.lang.invoke.VarHandle; +public class sdrplay_api_RspDuoTunerParamsT { + + static final GroupLayout $struct$LAYOUT = MemoryLayout.structLayout( + Constants$root.C_CHAR$LAYOUT.withName("biasTEnable"), + MemoryLayout.paddingLayout(24), + Constants$root.C_LONG$LAYOUT.withName("tuner1AmPortSel"), + Constants$root.C_CHAR$LAYOUT.withName("tuner1AmNotchEnable"), + Constants$root.C_CHAR$LAYOUT.withName("rfNotchEnable"), + Constants$root.C_CHAR$LAYOUT.withName("rfDabNotchEnable"), + MemoryLayout.paddingLayout(8) + ); + public static MemoryLayout $LAYOUT() { + return sdrplay_api_RspDuoTunerParamsT.$struct$LAYOUT; + } + static final VarHandle biasTEnable$VH = $struct$LAYOUT.varHandle(MemoryLayout.PathElement.groupElement("biasTEnable")); + public static VarHandle biasTEnable$VH() { + return sdrplay_api_RspDuoTunerParamsT.biasTEnable$VH; + } + public static byte biasTEnable$get(MemorySegment seg) { + return (byte)sdrplay_api_RspDuoTunerParamsT.biasTEnable$VH.get(seg); + } + public static void biasTEnable$set( MemorySegment seg, byte x) { + sdrplay_api_RspDuoTunerParamsT.biasTEnable$VH.set(seg, x); + } + public static byte biasTEnable$get(MemorySegment seg, long index) { + return (byte)sdrplay_api_RspDuoTunerParamsT.biasTEnable$VH.get(seg.asSlice(index*sizeof())); + } + public static void biasTEnable$set(MemorySegment seg, long index, byte x) { + sdrplay_api_RspDuoTunerParamsT.biasTEnable$VH.set(seg.asSlice(index*sizeof()), x); + } + static final VarHandle tuner1AmPortSel$VH = $struct$LAYOUT.varHandle(MemoryLayout.PathElement.groupElement("tuner1AmPortSel")); + public static VarHandle tuner1AmPortSel$VH() { + return sdrplay_api_RspDuoTunerParamsT.tuner1AmPortSel$VH; + } + public static int tuner1AmPortSel$get(MemorySegment seg) { + return (int)sdrplay_api_RspDuoTunerParamsT.tuner1AmPortSel$VH.get(seg); + } + public static void tuner1AmPortSel$set( MemorySegment seg, int x) { + sdrplay_api_RspDuoTunerParamsT.tuner1AmPortSel$VH.set(seg, x); + } + public static int tuner1AmPortSel$get(MemorySegment seg, long index) { + return (int)sdrplay_api_RspDuoTunerParamsT.tuner1AmPortSel$VH.get(seg.asSlice(index*sizeof())); + } + public static void tuner1AmPortSel$set(MemorySegment seg, long index, int x) { + sdrplay_api_RspDuoTunerParamsT.tuner1AmPortSel$VH.set(seg.asSlice(index*sizeof()), x); + } + static final VarHandle tuner1AmNotchEnable$VH = $struct$LAYOUT.varHandle(MemoryLayout.PathElement.groupElement("tuner1AmNotchEnable")); + public static VarHandle tuner1AmNotchEnable$VH() { + return sdrplay_api_RspDuoTunerParamsT.tuner1AmNotchEnable$VH; + } + public static byte tuner1AmNotchEnable$get(MemorySegment seg) { + return (byte)sdrplay_api_RspDuoTunerParamsT.tuner1AmNotchEnable$VH.get(seg); + } + public static void tuner1AmNotchEnable$set( MemorySegment seg, byte x) { + sdrplay_api_RspDuoTunerParamsT.tuner1AmNotchEnable$VH.set(seg, x); + } + public static byte tuner1AmNotchEnable$get(MemorySegment seg, long index) { + return (byte)sdrplay_api_RspDuoTunerParamsT.tuner1AmNotchEnable$VH.get(seg.asSlice(index*sizeof())); + } + public static void tuner1AmNotchEnable$set(MemorySegment seg, long index, byte x) { + sdrplay_api_RspDuoTunerParamsT.tuner1AmNotchEnable$VH.set(seg.asSlice(index*sizeof()), x); + } + static final VarHandle rfNotchEnable$VH = $struct$LAYOUT.varHandle(MemoryLayout.PathElement.groupElement("rfNotchEnable")); + public static VarHandle rfNotchEnable$VH() { + return sdrplay_api_RspDuoTunerParamsT.rfNotchEnable$VH; + } + public static byte rfNotchEnable$get(MemorySegment seg) { + return (byte)sdrplay_api_RspDuoTunerParamsT.rfNotchEnable$VH.get(seg); + } + public static void rfNotchEnable$set( MemorySegment seg, byte x) { + sdrplay_api_RspDuoTunerParamsT.rfNotchEnable$VH.set(seg, x); + } + public static byte rfNotchEnable$get(MemorySegment seg, long index) { + return (byte)sdrplay_api_RspDuoTunerParamsT.rfNotchEnable$VH.get(seg.asSlice(index*sizeof())); + } + public static void rfNotchEnable$set(MemorySegment seg, long index, byte x) { + sdrplay_api_RspDuoTunerParamsT.rfNotchEnable$VH.set(seg.asSlice(index*sizeof()), x); + } + static final VarHandle rfDabNotchEnable$VH = $struct$LAYOUT.varHandle(MemoryLayout.PathElement.groupElement("rfDabNotchEnable")); + public static VarHandle rfDabNotchEnable$VH() { + return sdrplay_api_RspDuoTunerParamsT.rfDabNotchEnable$VH; + } + public static byte rfDabNotchEnable$get(MemorySegment seg) { + return (byte)sdrplay_api_RspDuoTunerParamsT.rfDabNotchEnable$VH.get(seg); + } + public static void rfDabNotchEnable$set( MemorySegment seg, byte x) { + sdrplay_api_RspDuoTunerParamsT.rfDabNotchEnable$VH.set(seg, x); + } + public static byte rfDabNotchEnable$get(MemorySegment seg, long index) { + return (byte)sdrplay_api_RspDuoTunerParamsT.rfDabNotchEnable$VH.get(seg.asSlice(index*sizeof())); + } + public static void rfDabNotchEnable$set(MemorySegment seg, long index, byte x) { + sdrplay_api_RspDuoTunerParamsT.rfDabNotchEnable$VH.set(seg.asSlice(index*sizeof()), x); + } + public static long sizeof() { return $LAYOUT().byteSize(); } + public static MemorySegment allocate(SegmentAllocator allocator) { return allocator.allocate($LAYOUT()); } + public static MemorySegment allocateArray(int len, SegmentAllocator allocator) { + return allocator.allocate(MemoryLayout.sequenceLayout(len, $LAYOUT())); + } + public static MemorySegment ofAddress(MemoryAddress addr, MemorySession session) { return RuntimeHelper.asArray(addr, $LAYOUT(), 1, session); } +} + + diff --git a/sdrplay-api/src/main/java/com/github/dsheirer/sdrplay/api/v3_07/sdrplay_api_RspDxParamsT.java b/sdrplay-api/src/main/java/com/github/dsheirer/sdrplay/api/v3_07/sdrplay_api_RspDxParamsT.java new file mode 100644 index 000000000..a64be491b --- /dev/null +++ b/sdrplay-api/src/main/java/com/github/dsheirer/sdrplay/api/v3_07/sdrplay_api_RspDxParamsT.java @@ -0,0 +1,114 @@ +// Generated by jextract + +package com.github.dsheirer.sdrplay.api.v3_07; + +import java.lang.foreign.GroupLayout; +import java.lang.foreign.MemoryAddress; +import java.lang.foreign.MemoryLayout; +import java.lang.foreign.MemorySegment; +import java.lang.foreign.MemorySession; +import java.lang.foreign.SegmentAllocator; +import java.lang.invoke.VarHandle; +public class sdrplay_api_RspDxParamsT { + + static final GroupLayout $struct$LAYOUT = MemoryLayout.structLayout( + Constants$root.C_CHAR$LAYOUT.withName("hdrEnable"), + Constants$root.C_CHAR$LAYOUT.withName("biasTEnable"), + MemoryLayout.paddingLayout(16), + Constants$root.C_LONG$LAYOUT.withName("antennaSel"), + Constants$root.C_CHAR$LAYOUT.withName("rfNotchEnable"), + Constants$root.C_CHAR$LAYOUT.withName("rfDabNotchEnable"), + MemoryLayout.paddingLayout(16) + ); + public static MemoryLayout $LAYOUT() { + return sdrplay_api_RspDxParamsT.$struct$LAYOUT; + } + static final VarHandle hdrEnable$VH = $struct$LAYOUT.varHandle(MemoryLayout.PathElement.groupElement("hdrEnable")); + public static VarHandle hdrEnable$VH() { + return sdrplay_api_RspDxParamsT.hdrEnable$VH; + } + public static byte hdrEnable$get(MemorySegment seg) { + return (byte)sdrplay_api_RspDxParamsT.hdrEnable$VH.get(seg); + } + public static void hdrEnable$set( MemorySegment seg, byte x) { + sdrplay_api_RspDxParamsT.hdrEnable$VH.set(seg, x); + } + public static byte hdrEnable$get(MemorySegment seg, long index) { + return (byte)sdrplay_api_RspDxParamsT.hdrEnable$VH.get(seg.asSlice(index*sizeof())); + } + public static void hdrEnable$set(MemorySegment seg, long index, byte x) { + sdrplay_api_RspDxParamsT.hdrEnable$VH.set(seg.asSlice(index*sizeof()), x); + } + static final VarHandle biasTEnable$VH = $struct$LAYOUT.varHandle(MemoryLayout.PathElement.groupElement("biasTEnable")); + public static VarHandle biasTEnable$VH() { + return sdrplay_api_RspDxParamsT.biasTEnable$VH; + } + public static byte biasTEnable$get(MemorySegment seg) { + return (byte)sdrplay_api_RspDxParamsT.biasTEnable$VH.get(seg); + } + public static void biasTEnable$set( MemorySegment seg, byte x) { + sdrplay_api_RspDxParamsT.biasTEnable$VH.set(seg, x); + } + public static byte biasTEnable$get(MemorySegment seg, long index) { + return (byte)sdrplay_api_RspDxParamsT.biasTEnable$VH.get(seg.asSlice(index*sizeof())); + } + public static void biasTEnable$set(MemorySegment seg, long index, byte x) { + sdrplay_api_RspDxParamsT.biasTEnable$VH.set(seg.asSlice(index*sizeof()), x); + } + static final VarHandle antennaSel$VH = $struct$LAYOUT.varHandle(MemoryLayout.PathElement.groupElement("antennaSel")); + public static VarHandle antennaSel$VH() { + return sdrplay_api_RspDxParamsT.antennaSel$VH; + } + public static int antennaSel$get(MemorySegment seg) { + return (int)sdrplay_api_RspDxParamsT.antennaSel$VH.get(seg); + } + public static void antennaSel$set( MemorySegment seg, int x) { + sdrplay_api_RspDxParamsT.antennaSel$VH.set(seg, x); + } + public static int antennaSel$get(MemorySegment seg, long index) { + return (int)sdrplay_api_RspDxParamsT.antennaSel$VH.get(seg.asSlice(index*sizeof())); + } + public static void antennaSel$set(MemorySegment seg, long index, int x) { + sdrplay_api_RspDxParamsT.antennaSel$VH.set(seg.asSlice(index*sizeof()), x); + } + static final VarHandle rfNotchEnable$VH = $struct$LAYOUT.varHandle(MemoryLayout.PathElement.groupElement("rfNotchEnable")); + public static VarHandle rfNotchEnable$VH() { + return sdrplay_api_RspDxParamsT.rfNotchEnable$VH; + } + public static byte rfNotchEnable$get(MemorySegment seg) { + return (byte)sdrplay_api_RspDxParamsT.rfNotchEnable$VH.get(seg); + } + public static void rfNotchEnable$set( MemorySegment seg, byte x) { + sdrplay_api_RspDxParamsT.rfNotchEnable$VH.set(seg, x); + } + public static byte rfNotchEnable$get(MemorySegment seg, long index) { + return (byte)sdrplay_api_RspDxParamsT.rfNotchEnable$VH.get(seg.asSlice(index*sizeof())); + } + public static void rfNotchEnable$set(MemorySegment seg, long index, byte x) { + sdrplay_api_RspDxParamsT.rfNotchEnable$VH.set(seg.asSlice(index*sizeof()), x); + } + static final VarHandle rfDabNotchEnable$VH = $struct$LAYOUT.varHandle(MemoryLayout.PathElement.groupElement("rfDabNotchEnable")); + public static VarHandle rfDabNotchEnable$VH() { + return sdrplay_api_RspDxParamsT.rfDabNotchEnable$VH; + } + public static byte rfDabNotchEnable$get(MemorySegment seg) { + return (byte)sdrplay_api_RspDxParamsT.rfDabNotchEnable$VH.get(seg); + } + public static void rfDabNotchEnable$set( MemorySegment seg, byte x) { + sdrplay_api_RspDxParamsT.rfDabNotchEnable$VH.set(seg, x); + } + public static byte rfDabNotchEnable$get(MemorySegment seg, long index) { + return (byte)sdrplay_api_RspDxParamsT.rfDabNotchEnable$VH.get(seg.asSlice(index*sizeof())); + } + public static void rfDabNotchEnable$set(MemorySegment seg, long index, byte x) { + sdrplay_api_RspDxParamsT.rfDabNotchEnable$VH.set(seg.asSlice(index*sizeof()), x); + } + public static long sizeof() { return $LAYOUT().byteSize(); } + public static MemorySegment allocate(SegmentAllocator allocator) { return allocator.allocate($LAYOUT()); } + public static MemorySegment allocateArray(int len, SegmentAllocator allocator) { + return allocator.allocate(MemoryLayout.sequenceLayout(len, $LAYOUT())); + } + public static MemorySegment ofAddress(MemoryAddress addr, MemorySession session) { return RuntimeHelper.asArray(addr, $LAYOUT(), 1, session); } +} + + diff --git a/sdrplay-api/src/main/java/com/github/dsheirer/sdrplay/api/v3_07/sdrplay_api_RspDxTunerParamsT.java b/sdrplay-api/src/main/java/com/github/dsheirer/sdrplay/api/v3_07/sdrplay_api_RspDxTunerParamsT.java new file mode 100644 index 000000000..531b614a3 --- /dev/null +++ b/sdrplay-api/src/main/java/com/github/dsheirer/sdrplay/api/v3_07/sdrplay_api_RspDxTunerParamsT.java @@ -0,0 +1,44 @@ +// Generated by jextract + +package com.github.dsheirer.sdrplay.api.v3_07; + +import java.lang.foreign.GroupLayout; +import java.lang.foreign.MemoryAddress; +import java.lang.foreign.MemoryLayout; +import java.lang.foreign.MemorySegment; +import java.lang.foreign.MemorySession; +import java.lang.foreign.SegmentAllocator; +import java.lang.invoke.VarHandle; +public class sdrplay_api_RspDxTunerParamsT { + + static final GroupLayout $struct$LAYOUT = MemoryLayout.structLayout( + Constants$root.C_LONG$LAYOUT.withName("hdrBw") + ); + public static MemoryLayout $LAYOUT() { + return sdrplay_api_RspDxTunerParamsT.$struct$LAYOUT; + } + static final VarHandle hdrBw$VH = $struct$LAYOUT.varHandle(MemoryLayout.PathElement.groupElement("hdrBw")); + public static VarHandle hdrBw$VH() { + return sdrplay_api_RspDxTunerParamsT.hdrBw$VH; + } + public static int hdrBw$get(MemorySegment seg) { + return (int)sdrplay_api_RspDxTunerParamsT.hdrBw$VH.get(seg); + } + public static void hdrBw$set( MemorySegment seg, int x) { + sdrplay_api_RspDxTunerParamsT.hdrBw$VH.set(seg, x); + } + public static int hdrBw$get(MemorySegment seg, long index) { + return (int)sdrplay_api_RspDxTunerParamsT.hdrBw$VH.get(seg.asSlice(index*sizeof())); + } + public static void hdrBw$set(MemorySegment seg, long index, int x) { + sdrplay_api_RspDxTunerParamsT.hdrBw$VH.set(seg.asSlice(index*sizeof()), x); + } + public static long sizeof() { return $LAYOUT().byteSize(); } + public static MemorySegment allocate(SegmentAllocator allocator) { return allocator.allocate($LAYOUT()); } + public static MemorySegment allocateArray(int len, SegmentAllocator allocator) { + return allocator.allocate(MemoryLayout.sequenceLayout(len, $LAYOUT())); + } + public static MemorySegment ofAddress(MemoryAddress addr, MemorySession session) { return RuntimeHelper.asArray(addr, $LAYOUT(), 1, session); } +} + + diff --git a/sdrplay-api/src/main/java/com/github/dsheirer/sdrplay/api/v3_07/sdrplay_api_RxChannelParamsT.java b/sdrplay-api/src/main/java/com/github/dsheirer/sdrplay/api/v3_07/sdrplay_api_RxChannelParamsT.java new file mode 100644 index 000000000..1a374f7ab --- /dev/null +++ b/sdrplay-api/src/main/java/com/github/dsheirer/sdrplay/api/v3_07/sdrplay_api_RxChannelParamsT.java @@ -0,0 +1,122 @@ +// Generated by jextract + +package com.github.dsheirer.sdrplay.api.v3_07; + +import java.lang.foreign.GroupLayout; +import java.lang.foreign.MemoryAddress; +import java.lang.foreign.MemoryLayout; +import java.lang.foreign.MemorySegment; +import java.lang.foreign.MemorySession; +import java.lang.foreign.SegmentAllocator; +public class sdrplay_api_RxChannelParamsT { + + static final GroupLayout $struct$LAYOUT = MemoryLayout.structLayout( + MemoryLayout.structLayout( + Constants$root.C_LONG$LAYOUT.withName("bwType"), + Constants$root.C_LONG$LAYOUT.withName("ifType"), + Constants$root.C_LONG$LAYOUT.withName("loMode"), + MemoryLayout.structLayout( + Constants$root.C_LONG$LAYOUT.withName("gRdB"), + Constants$root.C_CHAR$LAYOUT.withName("LNAstate"), + Constants$root.C_CHAR$LAYOUT.withName("syncUpdate"), + MemoryLayout.paddingLayout(16), + Constants$root.C_LONG$LAYOUT.withName("minGr"), + MemoryLayout.structLayout( + Constants$root.C_FLOAT$LAYOUT.withName("curr"), + Constants$root.C_FLOAT$LAYOUT.withName("max"), + Constants$root.C_FLOAT$LAYOUT.withName("min") + ).withName("gainVals") + ).withName("gain"), + MemoryLayout.paddingLayout(32), + MemoryLayout.structLayout( + Constants$root.C_DOUBLE$LAYOUT.withName("rfHz"), + Constants$root.C_CHAR$LAYOUT.withName("syncUpdate"), + MemoryLayout.paddingLayout(56) + ).withName("rfFreq"), + MemoryLayout.structLayout( + Constants$root.C_CHAR$LAYOUT.withName("dcCal"), + Constants$root.C_CHAR$LAYOUT.withName("speedUp"), + MemoryLayout.paddingLayout(16), + Constants$root.C_LONG$LAYOUT.withName("trackTime"), + Constants$root.C_LONG$LAYOUT.withName("refreshRateTime") + ).withName("dcOffsetTuner"), + MemoryLayout.paddingLayout(32) + ).withName("tunerParams"), + MemoryLayout.structLayout( + MemoryLayout.structLayout( + Constants$root.C_CHAR$LAYOUT.withName("DCenable"), + Constants$root.C_CHAR$LAYOUT.withName("IQenable") + ).withName("dcOffset"), + MemoryLayout.structLayout( + Constants$root.C_CHAR$LAYOUT.withName("enable"), + Constants$root.C_CHAR$LAYOUT.withName("decimationFactor"), + Constants$root.C_CHAR$LAYOUT.withName("wideBandSignal") + ).withName("decimation"), + MemoryLayout.paddingLayout(24), + MemoryLayout.structLayout( + Constants$root.C_LONG$LAYOUT.withName("enable"), + Constants$root.C_LONG$LAYOUT.withName("setPoint_dBfs"), + Constants$root.C_SHORT$LAYOUT.withName("attack_ms"), + Constants$root.C_SHORT$LAYOUT.withName("decay_ms"), + Constants$root.C_SHORT$LAYOUT.withName("decay_delay_ms"), + Constants$root.C_SHORT$LAYOUT.withName("decay_threshold_dB"), + Constants$root.C_LONG$LAYOUT.withName("syncUpdate") + ).withName("agc"), + Constants$root.C_LONG$LAYOUT.withName("adsbMode") + ).withName("ctrlParams"), + MemoryLayout.structLayout( + Constants$root.C_CHAR$LAYOUT.withName("biasTEnable") + ).withName("rsp1aTunerParams"), + MemoryLayout.paddingLayout(24), + MemoryLayout.structLayout( + Constants$root.C_CHAR$LAYOUT.withName("biasTEnable"), + MemoryLayout.paddingLayout(24), + Constants$root.C_LONG$LAYOUT.withName("amPortSel"), + Constants$root.C_LONG$LAYOUT.withName("antennaSel"), + Constants$root.C_CHAR$LAYOUT.withName("rfNotchEnable"), + MemoryLayout.paddingLayout(24) + ).withName("rsp2TunerParams"), + MemoryLayout.structLayout( + Constants$root.C_CHAR$LAYOUT.withName("biasTEnable"), + MemoryLayout.paddingLayout(24), + Constants$root.C_LONG$LAYOUT.withName("tuner1AmPortSel"), + Constants$root.C_CHAR$LAYOUT.withName("tuner1AmNotchEnable"), + Constants$root.C_CHAR$LAYOUT.withName("rfNotchEnable"), + Constants$root.C_CHAR$LAYOUT.withName("rfDabNotchEnable"), + MemoryLayout.paddingLayout(8) + ).withName("rspDuoTunerParams"), + MemoryLayout.structLayout( + Constants$root.C_LONG$LAYOUT.withName("hdrBw") + ).withName("rspDxTunerParams"), + MemoryLayout.paddingLayout(32) + ); + public static MemoryLayout $LAYOUT() { + return sdrplay_api_RxChannelParamsT.$struct$LAYOUT; + } + public static MemorySegment tunerParams$slice(MemorySegment seg) { + return seg.asSlice(0, 72); + } + public static MemorySegment ctrlParams$slice(MemorySegment seg) { + return seg.asSlice(72, 32); + } + public static MemorySegment rsp1aTunerParams$slice(MemorySegment seg) { + return seg.asSlice(104, 1); + } + public static MemorySegment rsp2TunerParams$slice(MemorySegment seg) { + return seg.asSlice(108, 16); + } + public static MemorySegment rspDuoTunerParams$slice(MemorySegment seg) { + return seg.asSlice(124, 12); + } + public static MemorySegment rspDxTunerParams$slice(MemorySegment seg) { + return seg.asSlice(136, 4); + } + public static long sizeof() { return $LAYOUT().byteSize(); } + public static MemorySegment allocate(SegmentAllocator allocator) { return allocator.allocate($LAYOUT()); } + public static MemorySegment allocateArray(int len, SegmentAllocator allocator) { + return allocator.allocate(MemoryLayout.sequenceLayout(len, $LAYOUT())); + } + public static MemorySegment ofAddress(MemoryAddress addr, MemorySession session) { return RuntimeHelper.asArray(addr, $LAYOUT(), 1, session); } +} + + diff --git a/sdrplay-api/src/main/java/com/github/dsheirer/sdrplay/api/v3_07/sdrplay_api_SelectDevice_t.java b/sdrplay-api/src/main/java/com/github/dsheirer/sdrplay/api/v3_07/sdrplay_api_SelectDevice_t.java new file mode 100644 index 000000000..8e20a84da --- /dev/null +++ b/sdrplay-api/src/main/java/com/github/dsheirer/sdrplay/api/v3_07/sdrplay_api_SelectDevice_t.java @@ -0,0 +1,27 @@ +// Generated by jextract + +package com.github.dsheirer.sdrplay.api.v3_07; + +import java.lang.foreign.Addressable; +import java.lang.foreign.MemoryAddress; +import java.lang.foreign.MemorySegment; +import java.lang.foreign.MemorySession; +public interface sdrplay_api_SelectDevice_t { + + int apply(java.lang.foreign.MemoryAddress device); + static MemorySegment allocate(sdrplay_api_SelectDevice_t fi, MemorySession session) { + return RuntimeHelper.upcallStub(sdrplay_api_SelectDevice_t.class, fi, constants$2.sdrplay_api_SelectDevice_t$FUNC, session); + } + static sdrplay_api_SelectDevice_t ofAddress(MemoryAddress addr, MemorySession session) { + MemorySegment symbol = MemorySegment.ofAddress(addr, 0, session); + return (java.lang.foreign.MemoryAddress _device) -> { + try { + return (int)constants$2.sdrplay_api_SelectDevice_t$MH.invokeExact((Addressable)symbol, (java.lang.foreign.Addressable)_device); + } catch (Throwable ex$) { + throw new AssertionError("should not reach here", ex$); + } + }; + } +} + + diff --git a/sdrplay-api/src/main/java/com/github/dsheirer/sdrplay/api/v3_07/sdrplay_api_StreamCallback_t.java b/sdrplay-api/src/main/java/com/github/dsheirer/sdrplay/api/v3_07/sdrplay_api_StreamCallback_t.java new file mode 100644 index 000000000..36af2f587 --- /dev/null +++ b/sdrplay-api/src/main/java/com/github/dsheirer/sdrplay/api/v3_07/sdrplay_api_StreamCallback_t.java @@ -0,0 +1,27 @@ +// Generated by jextract + +package com.github.dsheirer.sdrplay.api.v3_07; + +import java.lang.foreign.Addressable; +import java.lang.foreign.MemoryAddress; +import java.lang.foreign.MemorySegment; +import java.lang.foreign.MemorySession; +public interface sdrplay_api_StreamCallback_t { + + void apply(java.lang.foreign.MemoryAddress xi, java.lang.foreign.MemoryAddress xq, java.lang.foreign.MemoryAddress params, int numSamples, int reset, java.lang.foreign.MemoryAddress cbContext); + static MemorySegment allocate(sdrplay_api_StreamCallback_t fi, MemorySession session) { + return RuntimeHelper.upcallStub(sdrplay_api_StreamCallback_t.class, fi, constants$0.sdrplay_api_StreamCallback_t$FUNC, session); + } + static sdrplay_api_StreamCallback_t ofAddress(MemoryAddress addr, MemorySession session) { + MemorySegment symbol = MemorySegment.ofAddress(addr, 0, session); + return (java.lang.foreign.MemoryAddress _xi, java.lang.foreign.MemoryAddress _xq, java.lang.foreign.MemoryAddress _params, int _numSamples, int _reset, java.lang.foreign.MemoryAddress _cbContext) -> { + try { + constants$0.sdrplay_api_StreamCallback_t$MH.invokeExact((Addressable)symbol, (java.lang.foreign.Addressable)_xi, (java.lang.foreign.Addressable)_xq, (java.lang.foreign.Addressable)_params, _numSamples, _reset, (java.lang.foreign.Addressable)_cbContext); + } catch (Throwable ex$) { + throw new AssertionError("should not reach here", ex$); + } + }; + } +} + + diff --git a/sdrplay-api/src/main/java/com/github/dsheirer/sdrplay/api/v3_07/sdrplay_api_StreamCbParamsT.java b/sdrplay-api/src/main/java/com/github/dsheirer/sdrplay/api/v3_07/sdrplay_api_StreamCbParamsT.java new file mode 100644 index 000000000..ef2805a71 --- /dev/null +++ b/sdrplay-api/src/main/java/com/github/dsheirer/sdrplay/api/v3_07/sdrplay_api_StreamCbParamsT.java @@ -0,0 +1,112 @@ +// Generated by jextract + +package com.github.dsheirer.sdrplay.api.v3_07; + +import java.lang.foreign.GroupLayout; +import java.lang.foreign.MemoryAddress; +import java.lang.foreign.MemoryLayout; +import java.lang.foreign.MemorySegment; +import java.lang.foreign.MemorySession; +import java.lang.foreign.SegmentAllocator; +import java.lang.invoke.VarHandle; +public class sdrplay_api_StreamCbParamsT { + + static final GroupLayout $struct$LAYOUT = MemoryLayout.structLayout( + Constants$root.C_LONG$LAYOUT.withName("firstSampleNum"), + Constants$root.C_LONG$LAYOUT.withName("grChanged"), + Constants$root.C_LONG$LAYOUT.withName("rfChanged"), + Constants$root.C_LONG$LAYOUT.withName("fsChanged"), + Constants$root.C_LONG$LAYOUT.withName("numSamples") + ); + public static MemoryLayout $LAYOUT() { + return sdrplay_api_StreamCbParamsT.$struct$LAYOUT; + } + static final VarHandle firstSampleNum$VH = $struct$LAYOUT.varHandle(MemoryLayout.PathElement.groupElement("firstSampleNum")); + public static VarHandle firstSampleNum$VH() { + return sdrplay_api_StreamCbParamsT.firstSampleNum$VH; + } + public static int firstSampleNum$get(MemorySegment seg) { + return (int)sdrplay_api_StreamCbParamsT.firstSampleNum$VH.get(seg); + } + public static void firstSampleNum$set( MemorySegment seg, int x) { + sdrplay_api_StreamCbParamsT.firstSampleNum$VH.set(seg, x); + } + public static int firstSampleNum$get(MemorySegment seg, long index) { + return (int)sdrplay_api_StreamCbParamsT.firstSampleNum$VH.get(seg.asSlice(index*sizeof())); + } + public static void firstSampleNum$set(MemorySegment seg, long index, int x) { + sdrplay_api_StreamCbParamsT.firstSampleNum$VH.set(seg.asSlice(index*sizeof()), x); + } + static final VarHandle grChanged$VH = $struct$LAYOUT.varHandle(MemoryLayout.PathElement.groupElement("grChanged")); + public static VarHandle grChanged$VH() { + return sdrplay_api_StreamCbParamsT.grChanged$VH; + } + public static int grChanged$get(MemorySegment seg) { + return (int)sdrplay_api_StreamCbParamsT.grChanged$VH.get(seg); + } + public static void grChanged$set( MemorySegment seg, int x) { + sdrplay_api_StreamCbParamsT.grChanged$VH.set(seg, x); + } + public static int grChanged$get(MemorySegment seg, long index) { + return (int)sdrplay_api_StreamCbParamsT.grChanged$VH.get(seg.asSlice(index*sizeof())); + } + public static void grChanged$set(MemorySegment seg, long index, int x) { + sdrplay_api_StreamCbParamsT.grChanged$VH.set(seg.asSlice(index*sizeof()), x); + } + static final VarHandle rfChanged$VH = $struct$LAYOUT.varHandle(MemoryLayout.PathElement.groupElement("rfChanged")); + public static VarHandle rfChanged$VH() { + return sdrplay_api_StreamCbParamsT.rfChanged$VH; + } + public static int rfChanged$get(MemorySegment seg) { + return (int)sdrplay_api_StreamCbParamsT.rfChanged$VH.get(seg); + } + public static void rfChanged$set( MemorySegment seg, int x) { + sdrplay_api_StreamCbParamsT.rfChanged$VH.set(seg, x); + } + public static int rfChanged$get(MemorySegment seg, long index) { + return (int)sdrplay_api_StreamCbParamsT.rfChanged$VH.get(seg.asSlice(index*sizeof())); + } + public static void rfChanged$set(MemorySegment seg, long index, int x) { + sdrplay_api_StreamCbParamsT.rfChanged$VH.set(seg.asSlice(index*sizeof()), x); + } + static final VarHandle fsChanged$VH = $struct$LAYOUT.varHandle(MemoryLayout.PathElement.groupElement("fsChanged")); + public static VarHandle fsChanged$VH() { + return sdrplay_api_StreamCbParamsT.fsChanged$VH; + } + public static int fsChanged$get(MemorySegment seg) { + return (int)sdrplay_api_StreamCbParamsT.fsChanged$VH.get(seg); + } + public static void fsChanged$set( MemorySegment seg, int x) { + sdrplay_api_StreamCbParamsT.fsChanged$VH.set(seg, x); + } + public static int fsChanged$get(MemorySegment seg, long index) { + return (int)sdrplay_api_StreamCbParamsT.fsChanged$VH.get(seg.asSlice(index*sizeof())); + } + public static void fsChanged$set(MemorySegment seg, long index, int x) { + sdrplay_api_StreamCbParamsT.fsChanged$VH.set(seg.asSlice(index*sizeof()), x); + } + static final VarHandle numSamples$VH = $struct$LAYOUT.varHandle(MemoryLayout.PathElement.groupElement("numSamples")); + public static VarHandle numSamples$VH() { + return sdrplay_api_StreamCbParamsT.numSamples$VH; + } + public static int numSamples$get(MemorySegment seg) { + return (int)sdrplay_api_StreamCbParamsT.numSamples$VH.get(seg); + } + public static void numSamples$set( MemorySegment seg, int x) { + sdrplay_api_StreamCbParamsT.numSamples$VH.set(seg, x); + } + public static int numSamples$get(MemorySegment seg, long index) { + return (int)sdrplay_api_StreamCbParamsT.numSamples$VH.get(seg.asSlice(index*sizeof())); + } + public static void numSamples$set(MemorySegment seg, long index, int x) { + sdrplay_api_StreamCbParamsT.numSamples$VH.set(seg.asSlice(index*sizeof()), x); + } + public static long sizeof() { return $LAYOUT().byteSize(); } + public static MemorySegment allocate(SegmentAllocator allocator) { return allocator.allocate($LAYOUT()); } + public static MemorySegment allocateArray(int len, SegmentAllocator allocator) { + return allocator.allocate(MemoryLayout.sequenceLayout(len, $LAYOUT())); + } + public static MemorySegment ofAddress(MemoryAddress addr, MemorySession session) { return RuntimeHelper.asArray(addr, $LAYOUT(), 1, session); } +} + + diff --git a/sdrplay-api/src/main/java/com/github/dsheirer/sdrplay/api/v3_07/sdrplay_api_SwapRspDuoActiveTuner_t.java b/sdrplay-api/src/main/java/com/github/dsheirer/sdrplay/api/v3_07/sdrplay_api_SwapRspDuoActiveTuner_t.java new file mode 100644 index 000000000..83798c8fa --- /dev/null +++ b/sdrplay-api/src/main/java/com/github/dsheirer/sdrplay/api/v3_07/sdrplay_api_SwapRspDuoActiveTuner_t.java @@ -0,0 +1,27 @@ +// Generated by jextract + +package com.github.dsheirer.sdrplay.api.v3_07; + +import java.lang.foreign.Addressable; +import java.lang.foreign.MemoryAddress; +import java.lang.foreign.MemorySegment; +import java.lang.foreign.MemorySession; +public interface sdrplay_api_SwapRspDuoActiveTuner_t { + + int apply(java.lang.foreign.MemoryAddress dev, java.lang.foreign.MemoryAddress tuner, int tuner1AmPortSel); + static MemorySegment allocate(sdrplay_api_SwapRspDuoActiveTuner_t fi, MemorySession session) { + return RuntimeHelper.upcallStub(sdrplay_api_SwapRspDuoActiveTuner_t.class, fi, constants$6.sdrplay_api_SwapRspDuoActiveTuner_t$FUNC, session); + } + static sdrplay_api_SwapRspDuoActiveTuner_t ofAddress(MemoryAddress addr, MemorySession session) { + MemorySegment symbol = MemorySegment.ofAddress(addr, 0, session); + return (java.lang.foreign.MemoryAddress _dev, java.lang.foreign.MemoryAddress _tuner, int _tuner1AmPortSel) -> { + try { + return (int)constants$6.sdrplay_api_SwapRspDuoActiveTuner_t$MH.invokeExact((Addressable)symbol, (java.lang.foreign.Addressable)_dev, (java.lang.foreign.Addressable)_tuner, _tuner1AmPortSel); + } catch (Throwable ex$) { + throw new AssertionError("should not reach here", ex$); + } + }; + } +} + + diff --git a/sdrplay-api/src/main/java/com/github/dsheirer/sdrplay/api/v3_07/sdrplay_api_SwapRspDuoDualTunerModeSampleRate_t.java b/sdrplay-api/src/main/java/com/github/dsheirer/sdrplay/api/v3_07/sdrplay_api_SwapRspDuoDualTunerModeSampleRate_t.java new file mode 100644 index 000000000..1f496ba29 --- /dev/null +++ b/sdrplay-api/src/main/java/com/github/dsheirer/sdrplay/api/v3_07/sdrplay_api_SwapRspDuoDualTunerModeSampleRate_t.java @@ -0,0 +1,27 @@ +// Generated by jextract + +package com.github.dsheirer.sdrplay.api.v3_07; + +import java.lang.foreign.Addressable; +import java.lang.foreign.MemoryAddress; +import java.lang.foreign.MemorySegment; +import java.lang.foreign.MemorySession; +public interface sdrplay_api_SwapRspDuoDualTunerModeSampleRate_t { + + int apply(java.lang.foreign.MemoryAddress currentSampleRate); + static MemorySegment allocate(sdrplay_api_SwapRspDuoDualTunerModeSampleRate_t fi, MemorySession session) { + return RuntimeHelper.upcallStub(sdrplay_api_SwapRspDuoDualTunerModeSampleRate_t.class, fi, constants$6.sdrplay_api_SwapRspDuoDualTunerModeSampleRate_t$FUNC, session); + } + static sdrplay_api_SwapRspDuoDualTunerModeSampleRate_t ofAddress(MemoryAddress addr, MemorySession session) { + MemorySegment symbol = MemorySegment.ofAddress(addr, 0, session); + return (java.lang.foreign.MemoryAddress _currentSampleRate) -> { + try { + return (int)constants$6.sdrplay_api_SwapRspDuoDualTunerModeSampleRate_t$MH.invokeExact((Addressable)symbol, (java.lang.foreign.Addressable)_currentSampleRate); + } catch (Throwable ex$) { + throw new AssertionError("should not reach here", ex$); + } + }; + } +} + + diff --git a/sdrplay-api/src/main/java/com/github/dsheirer/sdrplay/api/v3_07/sdrplay_api_SwapRspDuoMode_t.java b/sdrplay-api/src/main/java/com/github/dsheirer/sdrplay/api/v3_07/sdrplay_api_SwapRspDuoMode_t.java new file mode 100644 index 000000000..707a59dc8 --- /dev/null +++ b/sdrplay-api/src/main/java/com/github/dsheirer/sdrplay/api/v3_07/sdrplay_api_SwapRspDuoMode_t.java @@ -0,0 +1,27 @@ +// Generated by jextract + +package com.github.dsheirer.sdrplay.api.v3_07; + +import java.lang.foreign.Addressable; +import java.lang.foreign.MemoryAddress; +import java.lang.foreign.MemorySegment; +import java.lang.foreign.MemorySession; +public interface sdrplay_api_SwapRspDuoMode_t { + + int apply(java.lang.foreign.MemoryAddress currDevice, java.lang.foreign.MemoryAddress deviceParams, int rspDuoMode, double sampleRate, int tuner, int bwType, int ifType, int tuner1AmPortSel); + static MemorySegment allocate(sdrplay_api_SwapRspDuoMode_t fi, MemorySession session) { + return RuntimeHelper.upcallStub(sdrplay_api_SwapRspDuoMode_t.class, fi, constants$6.sdrplay_api_SwapRspDuoMode_t$FUNC, session); + } + static sdrplay_api_SwapRspDuoMode_t ofAddress(MemoryAddress addr, MemorySession session) { + MemorySegment symbol = MemorySegment.ofAddress(addr, 0, session); + return (java.lang.foreign.MemoryAddress _currDevice, java.lang.foreign.MemoryAddress _deviceParams, int _rspDuoMode, double _sampleRate, int _tuner, int _bwType, int _ifType, int _tuner1AmPortSel) -> { + try { + return (int)constants$6.sdrplay_api_SwapRspDuoMode_t$MH.invokeExact((Addressable)symbol, (java.lang.foreign.Addressable)_currDevice, (java.lang.foreign.Addressable)_deviceParams, _rspDuoMode, _sampleRate, _tuner, _bwType, _ifType, _tuner1AmPortSel); + } catch (Throwable ex$) { + throw new AssertionError("should not reach here", ex$); + } + }; + } +} + + diff --git a/sdrplay-api/src/main/java/com/github/dsheirer/sdrplay/api/v3_07/sdrplay_api_SyncUpdateT.java b/sdrplay-api/src/main/java/com/github/dsheirer/sdrplay/api/v3_07/sdrplay_api_SyncUpdateT.java new file mode 100644 index 000000000..d60d8d484 --- /dev/null +++ b/sdrplay-api/src/main/java/com/github/dsheirer/sdrplay/api/v3_07/sdrplay_api_SyncUpdateT.java @@ -0,0 +1,61 @@ +// Generated by jextract + +package com.github.dsheirer.sdrplay.api.v3_07; + +import java.lang.foreign.GroupLayout; +import java.lang.foreign.MemoryAddress; +import java.lang.foreign.MemoryLayout; +import java.lang.foreign.MemorySegment; +import java.lang.foreign.MemorySession; +import java.lang.foreign.SegmentAllocator; +import java.lang.invoke.VarHandle; +public class sdrplay_api_SyncUpdateT { + + static final GroupLayout $struct$LAYOUT = MemoryLayout.structLayout( + Constants$root.C_LONG$LAYOUT.withName("sampleNum"), + Constants$root.C_LONG$LAYOUT.withName("period") + ); + public static MemoryLayout $LAYOUT() { + return sdrplay_api_SyncUpdateT.$struct$LAYOUT; + } + static final VarHandle sampleNum$VH = $struct$LAYOUT.varHandle(MemoryLayout.PathElement.groupElement("sampleNum")); + public static VarHandle sampleNum$VH() { + return sdrplay_api_SyncUpdateT.sampleNum$VH; + } + public static int sampleNum$get(MemorySegment seg) { + return (int)sdrplay_api_SyncUpdateT.sampleNum$VH.get(seg); + } + public static void sampleNum$set( MemorySegment seg, int x) { + sdrplay_api_SyncUpdateT.sampleNum$VH.set(seg, x); + } + public static int sampleNum$get(MemorySegment seg, long index) { + return (int)sdrplay_api_SyncUpdateT.sampleNum$VH.get(seg.asSlice(index*sizeof())); + } + public static void sampleNum$set(MemorySegment seg, long index, int x) { + sdrplay_api_SyncUpdateT.sampleNum$VH.set(seg.asSlice(index*sizeof()), x); + } + static final VarHandle period$VH = $struct$LAYOUT.varHandle(MemoryLayout.PathElement.groupElement("period")); + public static VarHandle period$VH() { + return sdrplay_api_SyncUpdateT.period$VH; + } + public static int period$get(MemorySegment seg) { + return (int)sdrplay_api_SyncUpdateT.period$VH.get(seg); + } + public static void period$set( MemorySegment seg, int x) { + sdrplay_api_SyncUpdateT.period$VH.set(seg, x); + } + public static int period$get(MemorySegment seg, long index) { + return (int)sdrplay_api_SyncUpdateT.period$VH.get(seg.asSlice(index*sizeof())); + } + public static void period$set(MemorySegment seg, long index, int x) { + sdrplay_api_SyncUpdateT.period$VH.set(seg.asSlice(index*sizeof()), x); + } + public static long sizeof() { return $LAYOUT().byteSize(); } + public static MemorySegment allocate(SegmentAllocator allocator) { return allocator.allocate($LAYOUT()); } + public static MemorySegment allocateArray(int len, SegmentAllocator allocator) { + return allocator.allocate(MemoryLayout.sequenceLayout(len, $LAYOUT())); + } + public static MemorySegment ofAddress(MemoryAddress addr, MemorySession session) { return RuntimeHelper.asArray(addr, $LAYOUT(), 1, session); } +} + + diff --git a/sdrplay-api/src/main/java/com/github/dsheirer/sdrplay/api/v3_07/sdrplay_api_TunerParamsT.java b/sdrplay-api/src/main/java/com/github/dsheirer/sdrplay/api/v3_07/sdrplay_api_TunerParamsT.java new file mode 100644 index 000000000..1a946c66e --- /dev/null +++ b/sdrplay-api/src/main/java/com/github/dsheirer/sdrplay/api/v3_07/sdrplay_api_TunerParamsT.java @@ -0,0 +1,113 @@ +// Generated by jextract + +package com.github.dsheirer.sdrplay.api.v3_07; + +import java.lang.foreign.GroupLayout; +import java.lang.foreign.MemoryAddress; +import java.lang.foreign.MemoryLayout; +import java.lang.foreign.MemorySegment; +import java.lang.foreign.MemorySession; +import java.lang.foreign.SegmentAllocator; +import java.lang.invoke.VarHandle; +public class sdrplay_api_TunerParamsT { + + static final GroupLayout $struct$LAYOUT = MemoryLayout.structLayout( + Constants$root.C_LONG$LAYOUT.withName("bwType"), + Constants$root.C_LONG$LAYOUT.withName("ifType"), + Constants$root.C_LONG$LAYOUT.withName("loMode"), + MemoryLayout.structLayout( + Constants$root.C_LONG$LAYOUT.withName("gRdB"), + Constants$root.C_CHAR$LAYOUT.withName("LNAstate"), + Constants$root.C_CHAR$LAYOUT.withName("syncUpdate"), + MemoryLayout.paddingLayout(16), + Constants$root.C_LONG$LAYOUT.withName("minGr"), + MemoryLayout.structLayout( + Constants$root.C_FLOAT$LAYOUT.withName("curr"), + Constants$root.C_FLOAT$LAYOUT.withName("max"), + Constants$root.C_FLOAT$LAYOUT.withName("min") + ).withName("gainVals") + ).withName("gain"), + MemoryLayout.paddingLayout(32), + MemoryLayout.structLayout( + Constants$root.C_DOUBLE$LAYOUT.withName("rfHz"), + Constants$root.C_CHAR$LAYOUT.withName("syncUpdate"), + MemoryLayout.paddingLayout(56) + ).withName("rfFreq"), + MemoryLayout.structLayout( + Constants$root.C_CHAR$LAYOUT.withName("dcCal"), + Constants$root.C_CHAR$LAYOUT.withName("speedUp"), + MemoryLayout.paddingLayout(16), + Constants$root.C_LONG$LAYOUT.withName("trackTime"), + Constants$root.C_LONG$LAYOUT.withName("refreshRateTime") + ).withName("dcOffsetTuner"), + MemoryLayout.paddingLayout(32) + ); + public static MemoryLayout $LAYOUT() { + return sdrplay_api_TunerParamsT.$struct$LAYOUT; + } + static final VarHandle bwType$VH = $struct$LAYOUT.varHandle(MemoryLayout.PathElement.groupElement("bwType")); + public static VarHandle bwType$VH() { + return sdrplay_api_TunerParamsT.bwType$VH; + } + public static int bwType$get(MemorySegment seg) { + return (int)sdrplay_api_TunerParamsT.bwType$VH.get(seg); + } + public static void bwType$set( MemorySegment seg, int x) { + sdrplay_api_TunerParamsT.bwType$VH.set(seg, x); + } + public static int bwType$get(MemorySegment seg, long index) { + return (int)sdrplay_api_TunerParamsT.bwType$VH.get(seg.asSlice(index*sizeof())); + } + public static void bwType$set(MemorySegment seg, long index, int x) { + sdrplay_api_TunerParamsT.bwType$VH.set(seg.asSlice(index*sizeof()), x); + } + static final VarHandle ifType$VH = $struct$LAYOUT.varHandle(MemoryLayout.PathElement.groupElement("ifType")); + public static VarHandle ifType$VH() { + return sdrplay_api_TunerParamsT.ifType$VH; + } + public static int ifType$get(MemorySegment seg) { + return (int)sdrplay_api_TunerParamsT.ifType$VH.get(seg); + } + public static void ifType$set( MemorySegment seg, int x) { + sdrplay_api_TunerParamsT.ifType$VH.set(seg, x); + } + public static int ifType$get(MemorySegment seg, long index) { + return (int)sdrplay_api_TunerParamsT.ifType$VH.get(seg.asSlice(index*sizeof())); + } + public static void ifType$set(MemorySegment seg, long index, int x) { + sdrplay_api_TunerParamsT.ifType$VH.set(seg.asSlice(index*sizeof()), x); + } + static final VarHandle loMode$VH = $struct$LAYOUT.varHandle(MemoryLayout.PathElement.groupElement("loMode")); + public static VarHandle loMode$VH() { + return sdrplay_api_TunerParamsT.loMode$VH; + } + public static int loMode$get(MemorySegment seg) { + return (int)sdrplay_api_TunerParamsT.loMode$VH.get(seg); + } + public static void loMode$set( MemorySegment seg, int x) { + sdrplay_api_TunerParamsT.loMode$VH.set(seg, x); + } + public static int loMode$get(MemorySegment seg, long index) { + return (int)sdrplay_api_TunerParamsT.loMode$VH.get(seg.asSlice(index*sizeof())); + } + public static void loMode$set(MemorySegment seg, long index, int x) { + sdrplay_api_TunerParamsT.loMode$VH.set(seg.asSlice(index*sizeof()), x); + } + public static MemorySegment gain$slice(MemorySegment seg) { + return seg.asSlice(12, 24); + } + public static MemorySegment rfFreq$slice(MemorySegment seg) { + return seg.asSlice(40, 16); + } + public static MemorySegment dcOffsetTuner$slice(MemorySegment seg) { + return seg.asSlice(56, 12); + } + public static long sizeof() { return $LAYOUT().byteSize(); } + public static MemorySegment allocate(SegmentAllocator allocator) { return allocator.allocate($LAYOUT()); } + public static MemorySegment allocateArray(int len, SegmentAllocator allocator) { + return allocator.allocate(MemoryLayout.sequenceLayout(len, $LAYOUT())); + } + public static MemorySegment ofAddress(MemoryAddress addr, MemorySession session) { return RuntimeHelper.asArray(addr, $LAYOUT(), 1, session); } +} + + diff --git a/sdrplay-api/src/main/java/com/github/dsheirer/sdrplay/api/v3_07/sdrplay_api_Uninit_t.java b/sdrplay-api/src/main/java/com/github/dsheirer/sdrplay/api/v3_07/sdrplay_api_Uninit_t.java new file mode 100644 index 000000000..8b5ed1cd7 --- /dev/null +++ b/sdrplay-api/src/main/java/com/github/dsheirer/sdrplay/api/v3_07/sdrplay_api_Uninit_t.java @@ -0,0 +1,27 @@ +// Generated by jextract + +package com.github.dsheirer.sdrplay.api.v3_07; + +import java.lang.foreign.Addressable; +import java.lang.foreign.MemoryAddress; +import java.lang.foreign.MemorySegment; +import java.lang.foreign.MemorySession; +public interface sdrplay_api_Uninit_t { + + int apply(java.lang.foreign.MemoryAddress dev); + static MemorySegment allocate(sdrplay_api_Uninit_t fi, MemorySession session) { + return RuntimeHelper.upcallStub(sdrplay_api_Uninit_t.class, fi, constants$5.sdrplay_api_Uninit_t$FUNC, session); + } + static sdrplay_api_Uninit_t ofAddress(MemoryAddress addr, MemorySession session) { + MemorySegment symbol = MemorySegment.ofAddress(addr, 0, session); + return (java.lang.foreign.MemoryAddress _dev) -> { + try { + return (int)constants$5.sdrplay_api_Uninit_t$MH.invokeExact((Addressable)symbol, (java.lang.foreign.Addressable)_dev); + } catch (Throwable ex$) { + throw new AssertionError("should not reach here", ex$); + } + }; + } +} + + diff --git a/sdrplay-api/src/main/java/com/github/dsheirer/sdrplay/api/v3_07/sdrplay_api_UnlockDeviceApi_t.java b/sdrplay-api/src/main/java/com/github/dsheirer/sdrplay/api/v3_07/sdrplay_api_UnlockDeviceApi_t.java new file mode 100644 index 000000000..ddf868f77 --- /dev/null +++ b/sdrplay-api/src/main/java/com/github/dsheirer/sdrplay/api/v3_07/sdrplay_api_UnlockDeviceApi_t.java @@ -0,0 +1,27 @@ +// Generated by jextract + +package com.github.dsheirer.sdrplay.api.v3_07; + +import java.lang.foreign.Addressable; +import java.lang.foreign.MemoryAddress; +import java.lang.foreign.MemorySegment; +import java.lang.foreign.MemorySession; +public interface sdrplay_api_UnlockDeviceApi_t { + + int apply(); + static MemorySegment allocate(sdrplay_api_UnlockDeviceApi_t fi, MemorySession session) { + return RuntimeHelper.upcallStub(sdrplay_api_UnlockDeviceApi_t.class, fi, constants$2.sdrplay_api_UnlockDeviceApi_t$FUNC, session); + } + static sdrplay_api_UnlockDeviceApi_t ofAddress(MemoryAddress addr, MemorySession session) { + MemorySegment symbol = MemorySegment.ofAddress(addr, 0, session); + return () -> { + try { + return (int)constants$2.sdrplay_api_UnlockDeviceApi_t$MH.invokeExact((Addressable)symbol); + } catch (Throwable ex$) { + throw new AssertionError("should not reach here", ex$); + } + }; + } +} + + diff --git a/sdrplay-api/src/main/java/com/github/dsheirer/sdrplay/api/v3_07/sdrplay_api_Update_t.java b/sdrplay-api/src/main/java/com/github/dsheirer/sdrplay/api/v3_07/sdrplay_api_Update_t.java new file mode 100644 index 000000000..e8feb3926 --- /dev/null +++ b/sdrplay-api/src/main/java/com/github/dsheirer/sdrplay/api/v3_07/sdrplay_api_Update_t.java @@ -0,0 +1,27 @@ +// Generated by jextract + +package com.github.dsheirer.sdrplay.api.v3_07; + +import java.lang.foreign.Addressable; +import java.lang.foreign.MemoryAddress; +import java.lang.foreign.MemorySegment; +import java.lang.foreign.MemorySession; +public interface sdrplay_api_Update_t { + + int apply(java.lang.foreign.MemoryAddress dev, int tuner, int reasonForUpdate, int reasonForUpdateExt1); + static MemorySegment allocate(sdrplay_api_Update_t fi, MemorySession session) { + return RuntimeHelper.upcallStub(sdrplay_api_Update_t.class, fi, constants$5.sdrplay_api_Update_t$FUNC, session); + } + static sdrplay_api_Update_t ofAddress(MemoryAddress addr, MemorySession session) { + MemorySegment symbol = MemorySegment.ofAddress(addr, 0, session); + return (java.lang.foreign.MemoryAddress _dev, int _tuner, int _reasonForUpdate, int _reasonForUpdateExt1) -> { + try { + return (int)constants$5.sdrplay_api_Update_t$MH.invokeExact((Addressable)symbol, (java.lang.foreign.Addressable)_dev, _tuner, _reasonForUpdate, _reasonForUpdateExt1); + } catch (Throwable ex$) { + throw new AssertionError("should not reach here", ex$); + } + }; + } +} + + diff --git a/sdrplay-api/src/main/java/com/github/dsheirer/sdrplay/api/v3_07/sdrplay_api_h.java b/sdrplay-api/src/main/java/com/github/dsheirer/sdrplay/api/v3_07/sdrplay_api_h.java new file mode 100644 index 000000000..380403eb0 --- /dev/null +++ b/sdrplay-api/src/main/java/com/github/dsheirer/sdrplay/api/v3_07/sdrplay_api_h.java @@ -0,0 +1,734 @@ +// Generated by jextract + +package com.github.dsheirer.sdrplay.api.v3_07; + +import java.lang.foreign.Addressable; +import java.lang.foreign.MemoryAddress; +import java.lang.invoke.MethodHandle; + +import static java.lang.foreign.ValueLayout.OfAddress; +import static java.lang.foreign.ValueLayout.OfByte; +import static java.lang.foreign.ValueLayout.OfDouble; +import static java.lang.foreign.ValueLayout.OfFloat; +import static java.lang.foreign.ValueLayout.OfInt; +import static java.lang.foreign.ValueLayout.OfLong; +import static java.lang.foreign.ValueLayout.OfShort; +public class sdrplay_api_h { + + /* package-private */ sdrplay_api_h() {} + public static OfByte C_CHAR = Constants$root.C_CHAR$LAYOUT; + public static OfShort C_SHORT = Constants$root.C_SHORT$LAYOUT; + public static OfInt C_INT = Constants$root.C_LONG$LAYOUT; + public static OfInt C_LONG = Constants$root.C_LONG$LAYOUT; + public static OfLong C_LONG_LONG = Constants$root.C_LONG_LONG$LAYOUT; + public static OfFloat C_FLOAT = Constants$root.C_FLOAT$LAYOUT; + public static OfDouble C_DOUBLE = Constants$root.C_DOUBLE$LAYOUT; + public static OfAddress C_POINTER = Constants$root.C_POINTER$LAYOUT; + public static int RSPIA_NUM_LNA_STATES() { + return (int)10L; + } + public static int RSPIA_NUM_LNA_STATES_AM() { + return (int)7L; + } + public static int RSPIA_NUM_LNA_STATES_LBAND() { + return (int)9L; + } + public static int RSPII_NUM_LNA_STATES() { + return (int)9L; + } + public static int RSPII_NUM_LNA_STATES_AMPORT() { + return (int)5L; + } + public static int RSPII_NUM_LNA_STATES_420MHZ() { + return (int)6L; + } + public static int RSPDUO_NUM_LNA_STATES() { + return (int)10L; + } + public static int RSPDUO_NUM_LNA_STATES_AMPORT() { + return (int)5L; + } + public static int RSPDUO_NUM_LNA_STATES_AM() { + return (int)7L; + } + public static int RSPDUO_NUM_LNA_STATES_LBAND() { + return (int)9L; + } + public static int RSPDX_NUM_LNA_STATES() { + return (int)28L; + } + public static int RSPDX_NUM_LNA_STATES_AMPORT2_0_12() { + return (int)19L; + } + public static int RSPDX_NUM_LNA_STATES_AMPORT2_12_60() { + return (int)20L; + } + public static int RSPDX_NUM_LNA_STATES_VHF_BAND3() { + return (int)27L; + } + public static int RSPDX_NUM_LNA_STATES_420MHZ() { + return (int)21L; + } + public static int RSPDX_NUM_LNA_STATES_LBAND() { + return (int)19L; + } + public static int RSPDX_NUM_LNA_STATES_DX() { + return (int)26L; + } + public static int sdrplay_api_Rsp2_ANTENNA_A() { + return (int)5L; + } + public static int sdrplay_api_Rsp2_ANTENNA_B() { + return (int)6L; + } + public static int sdrplay_api_Rsp2_AMPORT_1() { + return (int)1L; + } + public static int sdrplay_api_Rsp2_AMPORT_2() { + return (int)0L; + } + public static int sdrplay_api_RspDuoMode_Unknown() { + return (int)0L; + } + public static int sdrplay_api_RspDuoMode_Single_Tuner() { + return (int)1L; + } + public static int sdrplay_api_RspDuoMode_Dual_Tuner() { + return (int)2L; + } + public static int sdrplay_api_RspDuoMode_Master() { + return (int)4L; + } + public static int sdrplay_api_RspDuoMode_Slave() { + return (int)8L; + } + public static int sdrplay_api_RspDuo_AMPORT_1() { + return (int)1L; + } + public static int sdrplay_api_RspDuo_AMPORT_2() { + return (int)0L; + } + public static int sdrplay_api_BW_Undefined() { + return (int)0L; + } + public static int sdrplay_api_BW_0_200() { + return (int)200L; + } + public static int sdrplay_api_BW_0_300() { + return (int)300L; + } + public static int sdrplay_api_BW_0_600() { + return (int)600L; + } + public static int sdrplay_api_BW_1_536() { + return (int)1536L; + } + public static int sdrplay_api_BW_5_000() { + return (int)5000L; + } + public static int sdrplay_api_BW_6_000() { + return (int)6000L; + } + public static int sdrplay_api_BW_7_000() { + return (int)7000L; + } + public static int sdrplay_api_BW_8_000() { + return (int)8000L; + } + public static int sdrplay_api_IF_Undefined() { + return (int)-1L; + } + public static int sdrplay_api_IF_Zero() { + return (int)0L; + } + public static int sdrplay_api_IF_0_450() { + return (int)450L; + } + public static int sdrplay_api_IF_1_620() { + return (int)1620L; + } + public static int sdrplay_api_IF_2_048() { + return (int)2048L; + } + public static int sdrplay_api_LO_Undefined() { + return (int)0L; + } + public static int sdrplay_api_LO_Auto() { + return (int)1L; + } + public static int sdrplay_api_LO_120MHz() { + return (int)2L; + } + public static int sdrplay_api_LO_144MHz() { + return (int)3L; + } + public static int sdrplay_api_LO_168MHz() { + return (int)4L; + } + public static int sdrplay_api_EXTENDED_MIN_GR() { + return (int)0L; + } + public static int sdrplay_api_NORMAL_MIN_GR() { + return (int)20L; + } + public static int sdrplay_api_Tuner_Neither() { + return (int)0L; + } + public static int sdrplay_api_Tuner_A() { + return (int)1L; + } + public static int sdrplay_api_Tuner_B() { + return (int)2L; + } + public static int sdrplay_api_Tuner_Both() { + return (int)3L; + } + public static int sdrplay_api_RspDx_ANTENNA_A() { + return (int)0L; + } + public static int sdrplay_api_RspDx_ANTENNA_B() { + return (int)1L; + } + public static int sdrplay_api_RspDx_ANTENNA_C() { + return (int)2L; + } + public static int sdrplay_api_RspDx_HDRMODE_BW_0_200() { + return (int)0L; + } + public static int sdrplay_api_RspDx_HDRMODE_BW_0_500() { + return (int)1L; + } + public static int sdrplay_api_RspDx_HDRMODE_BW_1_200() { + return (int)2L; + } + public static int sdrplay_api_RspDx_HDRMODE_BW_1_700() { + return (int)3L; + } + public static int sdrplay_api_ISOCH() { + return (int)0L; + } + public static int sdrplay_api_BULK() { + return (int)1L; + } + public static int sdrplay_api_AGC_DISABLE() { + return (int)0L; + } + public static int sdrplay_api_AGC_100HZ() { + return (int)1L; + } + public static int sdrplay_api_AGC_50HZ() { + return (int)2L; + } + public static int sdrplay_api_AGC_5HZ() { + return (int)3L; + } + public static int sdrplay_api_AGC_CTRL_EN() { + return (int)4L; + } + public static int sdrplay_api_ADSB_DECIMATION() { + return (int)0L; + } + public static int sdrplay_api_ADSB_NO_DECIMATION_LOWPASS() { + return (int)1L; + } + public static int sdrplay_api_ADSB_NO_DECIMATION_BANDPASS_2MHZ() { + return (int)2L; + } + public static int sdrplay_api_ADSB_NO_DECIMATION_BANDPASS_3MHZ() { + return (int)3L; + } + public static int sdrplay_api_Overload_Detected() { + return (int)0L; + } + public static int sdrplay_api_Overload_Corrected() { + return (int)1L; + } + public static int sdrplay_api_MasterInitialised() { + return (int)0L; + } + public static int sdrplay_api_SlaveAttached() { + return (int)1L; + } + public static int sdrplay_api_SlaveDetached() { + return (int)2L; + } + public static int sdrplay_api_SlaveInitialised() { + return (int)3L; + } + public static int sdrplay_api_SlaveUninitialised() { + return (int)4L; + } + public static int sdrplay_api_MasterDllDisappeared() { + return (int)5L; + } + public static int sdrplay_api_SlaveDllDisappeared() { + return (int)6L; + } + public static int sdrplay_api_GainChange() { + return (int)0L; + } + public static int sdrplay_api_PowerOverloadChange() { + return (int)1L; + } + public static int sdrplay_api_DeviceRemoved() { + return (int)2L; + } + public static int sdrplay_api_RspDuoModeChange() { + return (int)3L; + } + public static OfAddress HANDLE = Constants$root.C_POINTER$LAYOUT; + public static int sdrplay_api_Success() { + return (int)0L; + } + public static int sdrplay_api_Fail() { + return (int)1L; + } + public static int sdrplay_api_InvalidParam() { + return (int)2L; + } + public static int sdrplay_api_OutOfRange() { + return (int)3L; + } + public static int sdrplay_api_GainUpdateError() { + return (int)4L; + } + public static int sdrplay_api_RfUpdateError() { + return (int)5L; + } + public static int sdrplay_api_FsUpdateError() { + return (int)6L; + } + public static int sdrplay_api_HwError() { + return (int)7L; + } + public static int sdrplay_api_AliasingError() { + return (int)8L; + } + public static int sdrplay_api_AlreadyInitialised() { + return (int)9L; + } + public static int sdrplay_api_NotInitialised() { + return (int)10L; + } + public static int sdrplay_api_NotEnabled() { + return (int)11L; + } + public static int sdrplay_api_HwVerError() { + return (int)12L; + } + public static int sdrplay_api_OutOfMemError() { + return (int)13L; + } + public static int sdrplay_api_ServiceNotResponding() { + return (int)14L; + } + public static int sdrplay_api_StartPending() { + return (int)15L; + } + public static int sdrplay_api_StopPending() { + return (int)16L; + } + public static int sdrplay_api_InvalidMode() { + return (int)17L; + } + public static int sdrplay_api_FailedVerification1() { + return (int)18L; + } + public static int sdrplay_api_FailedVerification2() { + return (int)19L; + } + public static int sdrplay_api_FailedVerification3() { + return (int)20L; + } + public static int sdrplay_api_FailedVerification4() { + return (int)21L; + } + public static int sdrplay_api_FailedVerification5() { + return (int)22L; + } + public static int sdrplay_api_FailedVerification6() { + return (int)23L; + } + public static int sdrplay_api_InvalidServiceVersion() { + return (int)24L; + } + public static int sdrplay_api_Update_None() { + return (int)0L; + } + public static int sdrplay_api_Update_Dev_Fs() { + return (int)1L; + } + public static int sdrplay_api_Update_Dev_Ppm() { + return (int)2L; + } + public static int sdrplay_api_Update_Dev_SyncUpdate() { + return (int)4L; + } + public static int sdrplay_api_Update_Dev_ResetFlags() { + return (int)8L; + } + public static int sdrplay_api_Update_Rsp1a_BiasTControl() { + return (int)16L; + } + public static int sdrplay_api_Update_Rsp1a_RfNotchControl() { + return (int)32L; + } + public static int sdrplay_api_Update_Rsp1a_RfDabNotchControl() { + return (int)64L; + } + public static int sdrplay_api_Update_Rsp2_BiasTControl() { + return (int)128L; + } + public static int sdrplay_api_Update_Rsp2_AmPortSelect() { + return (int)256L; + } + public static int sdrplay_api_Update_Rsp2_AntennaControl() { + return (int)512L; + } + public static int sdrplay_api_Update_Rsp2_RfNotchControl() { + return (int)1024L; + } + public static int sdrplay_api_Update_Rsp2_ExtRefControl() { + return (int)2048L; + } + public static int sdrplay_api_Update_RspDuo_ExtRefControl() { + return (int)4096L; + } + public static int sdrplay_api_Update_Master_Spare_1() { + return (int)8192L; + } + public static int sdrplay_api_Update_Master_Spare_2() { + return (int)16384L; + } + public static int sdrplay_api_Update_Tuner_Gr() { + return (int)32768L; + } + public static int sdrplay_api_Update_Tuner_GrLimits() { + return (int)65536L; + } + public static int sdrplay_api_Update_Tuner_Frf() { + return (int)131072L; + } + public static int sdrplay_api_Update_Tuner_BwType() { + return (int)262144L; + } + public static int sdrplay_api_Update_Tuner_IfType() { + return (int)524288L; + } + public static int sdrplay_api_Update_Tuner_DcOffset() { + return (int)1048576L; + } + public static int sdrplay_api_Update_Tuner_LoMode() { + return (int)2097152L; + } + public static int sdrplay_api_Update_Ctrl_DCoffsetIQimbalance() { + return (int)4194304L; + } + public static int sdrplay_api_Update_Ctrl_Decimation() { + return (int)8388608L; + } + public static int sdrplay_api_Update_Ctrl_Agc() { + return (int)16777216L; + } + public static int sdrplay_api_Update_Ctrl_AdsbMode() { + return (int)33554432L; + } + public static int sdrplay_api_Update_Ctrl_OverloadMsgAck() { + return (int)67108864L; + } + public static int sdrplay_api_Update_RspDuo_BiasTControl() { + return (int)134217728L; + } + public static int sdrplay_api_Update_RspDuo_AmPortSelect() { + return (int)268435456L; + } + public static int sdrplay_api_Update_RspDuo_Tuner1AmNotchControl() { + return (int)536870912L; + } + public static int sdrplay_api_Update_RspDuo_RfNotchControl() { + return (int)1073741824L; + } + public static int sdrplay_api_Update_RspDuo_RfDabNotchControl() { + return (int)-2147483648L; + } + public static int sdrplay_api_Update_Ext1_None() { + return (int)0L; + } + public static int sdrplay_api_Update_RspDx_HdrEnable() { + return (int)1L; + } + public static int sdrplay_api_Update_RspDx_BiasTControl() { + return (int)2L; + } + public static int sdrplay_api_Update_RspDx_AntennaControl() { + return (int)4L; + } + public static int sdrplay_api_Update_RspDx_RfNotchControl() { + return (int)8L; + } + public static int sdrplay_api_Update_RspDx_RfDabNotchControl() { + return (int)16L; + } + public static int sdrplay_api_Update_RspDx_HdrBw() { + return (int)32L; + } + public static int sdrplay_api_DbgLvl_Disable() { + return (int)0L; + } + public static int sdrplay_api_DbgLvl_Verbose() { + return (int)1L; + } + public static int sdrplay_api_DbgLvl_Warning() { + return (int)2L; + } + public static int sdrplay_api_DbgLvl_Error() { + return (int)3L; + } + public static int sdrplay_api_DbgLvl_Message() { + return (int)4L; + } + public static MethodHandle sdrplay_api_Open$MH() { + return RuntimeHelper.requireNonNull(constants$7.sdrplay_api_Open$MH,"sdrplay_api_Open"); + } + public static int sdrplay_api_Open () { + var mh$ = sdrplay_api_Open$MH(); + try { + return (int)mh$.invokeExact(); + } catch (Throwable ex$) { + throw new AssertionError("should not reach here", ex$); + } + } + public static MethodHandle sdrplay_api_Close$MH() { + return RuntimeHelper.requireNonNull(constants$7.sdrplay_api_Close$MH,"sdrplay_api_Close"); + } + public static int sdrplay_api_Close () { + var mh$ = sdrplay_api_Close$MH(); + try { + return (int)mh$.invokeExact(); + } catch (Throwable ex$) { + throw new AssertionError("should not reach here", ex$); + } + } + public static MethodHandle sdrplay_api_ApiVersion$MH() { + return RuntimeHelper.requireNonNull(constants$7.sdrplay_api_ApiVersion$MH,"sdrplay_api_ApiVersion"); + } + public static int sdrplay_api_ApiVersion ( Addressable apiVer) { + var mh$ = sdrplay_api_ApiVersion$MH(); + try { + return (int)mh$.invokeExact(apiVer); + } catch (Throwable ex$) { + throw new AssertionError("should not reach here", ex$); + } + } + public static MethodHandle sdrplay_api_LockDeviceApi$MH() { + return RuntimeHelper.requireNonNull(constants$7.sdrplay_api_LockDeviceApi$MH,"sdrplay_api_LockDeviceApi"); + } + public static int sdrplay_api_LockDeviceApi () { + var mh$ = sdrplay_api_LockDeviceApi$MH(); + try { + return (int)mh$.invokeExact(); + } catch (Throwable ex$) { + throw new AssertionError("should not reach here", ex$); + } + } + public static MethodHandle sdrplay_api_UnlockDeviceApi$MH() { + return RuntimeHelper.requireNonNull(constants$7.sdrplay_api_UnlockDeviceApi$MH,"sdrplay_api_UnlockDeviceApi"); + } + public static int sdrplay_api_UnlockDeviceApi () { + var mh$ = sdrplay_api_UnlockDeviceApi$MH(); + try { + return (int)mh$.invokeExact(); + } catch (Throwable ex$) { + throw new AssertionError("should not reach here", ex$); + } + } + public static MethodHandle sdrplay_api_GetDevices$MH() { + return RuntimeHelper.requireNonNull(constants$7.sdrplay_api_GetDevices$MH,"sdrplay_api_GetDevices"); + } + public static int sdrplay_api_GetDevices ( Addressable devices, Addressable numDevs, int maxDevs) { + var mh$ = sdrplay_api_GetDevices$MH(); + try { + return (int)mh$.invokeExact(devices, numDevs, maxDevs); + } catch (Throwable ex$) { + throw new AssertionError("should not reach here", ex$); + } + } + public static MethodHandle sdrplay_api_SelectDevice$MH() { + return RuntimeHelper.requireNonNull(constants$8.sdrplay_api_SelectDevice$MH,"sdrplay_api_SelectDevice"); + } + public static int sdrplay_api_SelectDevice ( Addressable device) { + var mh$ = sdrplay_api_SelectDevice$MH(); + try { + return (int)mh$.invokeExact(device); + } catch (Throwable ex$) { + throw new AssertionError("should not reach here", ex$); + } + } + public static MethodHandle sdrplay_api_ReleaseDevice$MH() { + return RuntimeHelper.requireNonNull(constants$8.sdrplay_api_ReleaseDevice$MH,"sdrplay_api_ReleaseDevice"); + } + public static int sdrplay_api_ReleaseDevice ( Addressable device) { + var mh$ = sdrplay_api_ReleaseDevice$MH(); + try { + return (int)mh$.invokeExact(device); + } catch (Throwable ex$) { + throw new AssertionError("should not reach here", ex$); + } + } + public static MethodHandle sdrplay_api_GetErrorString$MH() { + return RuntimeHelper.requireNonNull(constants$8.sdrplay_api_GetErrorString$MH,"sdrplay_api_GetErrorString"); + } + public static MemoryAddress sdrplay_api_GetErrorString ( int err) { + var mh$ = sdrplay_api_GetErrorString$MH(); + try { + return (java.lang.foreign.MemoryAddress)mh$.invokeExact(err); + } catch (Throwable ex$) { + throw new AssertionError("should not reach here", ex$); + } + } + public static MethodHandle sdrplay_api_GetLastError$MH() { + return RuntimeHelper.requireNonNull(constants$8.sdrplay_api_GetLastError$MH,"sdrplay_api_GetLastError"); + } + public static MemoryAddress sdrplay_api_GetLastError ( Addressable device) { + var mh$ = sdrplay_api_GetLastError$MH(); + try { + return (java.lang.foreign.MemoryAddress)mh$.invokeExact(device); + } catch (Throwable ex$) { + throw new AssertionError("should not reach here", ex$); + } + } + public static MethodHandle sdrplay_api_DisableHeartbeat$MH() { + return RuntimeHelper.requireNonNull(constants$8.sdrplay_api_DisableHeartbeat$MH,"sdrplay_api_DisableHeartbeat"); + } + public static int sdrplay_api_DisableHeartbeat () { + var mh$ = sdrplay_api_DisableHeartbeat$MH(); + try { + return (int)mh$.invokeExact(); + } catch (Throwable ex$) { + throw new AssertionError("should not reach here", ex$); + } + } + public static MethodHandle sdrplay_api_DebugEnable$MH() { + return RuntimeHelper.requireNonNull(constants$8.sdrplay_api_DebugEnable$MH,"sdrplay_api_DebugEnable"); + } + public static int sdrplay_api_DebugEnable ( Addressable dev, int enable) { + var mh$ = sdrplay_api_DebugEnable$MH(); + try { + return (int)mh$.invokeExact(dev, enable); + } catch (Throwable ex$) { + throw new AssertionError("should not reach here", ex$); + } + } + public static MethodHandle sdrplay_api_GetDeviceParams$MH() { + return RuntimeHelper.requireNonNull(constants$9.sdrplay_api_GetDeviceParams$MH,"sdrplay_api_GetDeviceParams"); + } + public static int sdrplay_api_GetDeviceParams ( Addressable dev, Addressable deviceParams) { + var mh$ = sdrplay_api_GetDeviceParams$MH(); + try { + return (int)mh$.invokeExact(dev, deviceParams); + } catch (Throwable ex$) { + throw new AssertionError("should not reach here", ex$); + } + } + public static MethodHandle sdrplay_api_Init$MH() { + return RuntimeHelper.requireNonNull(constants$9.sdrplay_api_Init$MH,"sdrplay_api_Init"); + } + public static int sdrplay_api_Init ( Addressable dev, Addressable callbackFns, Addressable cbContext) { + var mh$ = sdrplay_api_Init$MH(); + try { + return (int)mh$.invokeExact(dev, callbackFns, cbContext); + } catch (Throwable ex$) { + throw new AssertionError("should not reach here", ex$); + } + } + public static MethodHandle sdrplay_api_Uninit$MH() { + return RuntimeHelper.requireNonNull(constants$9.sdrplay_api_Uninit$MH,"sdrplay_api_Uninit"); + } + public static int sdrplay_api_Uninit ( Addressable dev) { + var mh$ = sdrplay_api_Uninit$MH(); + try { + return (int)mh$.invokeExact(dev); + } catch (Throwable ex$) { + throw new AssertionError("should not reach here", ex$); + } + } + public static MethodHandle sdrplay_api_Update$MH() { + return RuntimeHelper.requireNonNull(constants$9.sdrplay_api_Update$MH,"sdrplay_api_Update"); + } + public static int sdrplay_api_Update ( Addressable dev, int tuner, int reasonForUpdate, int reasonForUpdateExt1) { + var mh$ = sdrplay_api_Update$MH(); + try { + return (int)mh$.invokeExact(dev, tuner, reasonForUpdate, reasonForUpdateExt1); + } catch (Throwable ex$) { + throw new AssertionError("should not reach here", ex$); + } + } + public static MethodHandle sdrplay_api_SwapRspDuoActiveTuner$MH() { + return RuntimeHelper.requireNonNull(constants$9.sdrplay_api_SwapRspDuoActiveTuner$MH,"sdrplay_api_SwapRspDuoActiveTuner"); + } + public static int sdrplay_api_SwapRspDuoActiveTuner ( Addressable dev, Addressable currentTuner, int tuner1AmPortSel) { + var mh$ = sdrplay_api_SwapRspDuoActiveTuner$MH(); + try { + return (int)mh$.invokeExact(dev, currentTuner, tuner1AmPortSel); + } catch (Throwable ex$) { + throw new AssertionError("should not reach here", ex$); + } + } + public static MethodHandle sdrplay_api_SwapRspDuoDualTunerModeSampleRate$MH() { + return RuntimeHelper.requireNonNull(constants$9.sdrplay_api_SwapRspDuoDualTunerModeSampleRate$MH,"sdrplay_api_SwapRspDuoDualTunerModeSampleRate"); + } + public static int sdrplay_api_SwapRspDuoDualTunerModeSampleRate ( Addressable dev, Addressable currentSampleRate) { + var mh$ = sdrplay_api_SwapRspDuoDualTunerModeSampleRate$MH(); + try { + return (int)mh$.invokeExact(dev, currentSampleRate); + } catch (Throwable ex$) { + throw new AssertionError("should not reach here", ex$); + } + } + public static MethodHandle sdrplay_api_SwapRspDuoMode$MH() { + return RuntimeHelper.requireNonNull(constants$10.sdrplay_api_SwapRspDuoMode$MH,"sdrplay_api_SwapRspDuoMode"); + } + public static int sdrplay_api_SwapRspDuoMode ( Addressable currDevice, Addressable deviceParams, int rspDuoMode, double sampleRate, int tuner, int bwType, int ifType, int tuner1AmPortSel) { + var mh$ = sdrplay_api_SwapRspDuoMode$MH(); + try { + return (int)mh$.invokeExact(currDevice, deviceParams, rspDuoMode, sampleRate, tuner, bwType, ifType, tuner1AmPortSel); + } catch (Throwable ex$) { + throw new AssertionError("should not reach here", ex$); + } + } + public static int MAX_BB_GR() { + return (int)59L; + } + public static float SDRPLAY_API_VERSION() { + return 3.07f; + } + public static int SDRPLAY_MAX_DEVICES() { + return (int)16L; + } + public static int SDRPLAY_MAX_TUNERS_PER_DEVICE() { + return (int)2L; + } + public static int SDRPLAY_MAX_SER_NO_LEN() { + return (int)64L; + } + public static int SDRPLAY_MAX_ROOT_NM_LEN() { + return (int)32L; + } + public static int SDRPLAY_RSP1_ID() { + return (int)1L; + } + public static int SDRPLAY_RSP1A_ID() { + return (int)255L; + } + public static int SDRPLAY_RSP2_ID() { + return (int)2L; + } + public static int SDRPLAY_RSPduo_ID() { + return (int)3L; + } + public static int SDRPLAY_RSPdx_ID() { + return (int)4L; + } +} + + diff --git a/sdrplay-api/src/main/java/com/github/dsheirer/sdrplay/api/v3_08/Constants$root.java b/sdrplay-api/src/main/java/com/github/dsheirer/sdrplay/api/v3_08/Constants$root.java new file mode 100644 index 000000000..59c0b3b40 --- /dev/null +++ b/sdrplay-api/src/main/java/com/github/dsheirer/sdrplay/api/v3_08/Constants$root.java @@ -0,0 +1,34 @@ +// Generated by jextract + +package com.github.dsheirer.sdrplay.api.v3_08; + +import static java.lang.foreign.ValueLayout.ADDRESS; +import static java.lang.foreign.ValueLayout.JAVA_BOOLEAN; +import static java.lang.foreign.ValueLayout.JAVA_BYTE; +import static java.lang.foreign.ValueLayout.JAVA_DOUBLE; +import static java.lang.foreign.ValueLayout.JAVA_FLOAT; +import static java.lang.foreign.ValueLayout.JAVA_INT; +import static java.lang.foreign.ValueLayout.JAVA_LONG; +import static java.lang.foreign.ValueLayout.JAVA_SHORT; +import static java.lang.foreign.ValueLayout.OfAddress; +import static java.lang.foreign.ValueLayout.OfBoolean; +import static java.lang.foreign.ValueLayout.OfByte; +import static java.lang.foreign.ValueLayout.OfDouble; +import static java.lang.foreign.ValueLayout.OfFloat; +import static java.lang.foreign.ValueLayout.OfInt; +import static java.lang.foreign.ValueLayout.OfLong; +import static java.lang.foreign.ValueLayout.OfShort; +public class Constants$root { + + static final OfBoolean C_BOOL$LAYOUT = JAVA_BOOLEAN; + static final OfByte C_CHAR$LAYOUT = JAVA_BYTE; + static final OfShort C_SHORT$LAYOUT = JAVA_SHORT.withBitAlignment(16); + static final OfInt C_INT$LAYOUT = JAVA_INT.withBitAlignment(32); + static final OfInt C_LONG$LAYOUT = JAVA_INT.withBitAlignment(32); + static final OfLong C_LONG_LONG$LAYOUT = JAVA_LONG.withBitAlignment(64); + static final OfFloat C_FLOAT$LAYOUT = JAVA_FLOAT.withBitAlignment(32); + static final OfDouble C_DOUBLE$LAYOUT = JAVA_DOUBLE.withBitAlignment(64); + static final OfAddress C_POINTER$LAYOUT = ADDRESS.withBitAlignment(64); +} + + diff --git a/sdrplay-api/src/main/java/com/github/dsheirer/sdrplay/api/v3_08/RuntimeHelper.java b/sdrplay-api/src/main/java/com/github/dsheirer/sdrplay/api/v3_08/RuntimeHelper.java new file mode 100644 index 000000000..15adbf055 --- /dev/null +++ b/sdrplay-api/src/main/java/com/github/dsheirer/sdrplay/api/v3_08/RuntimeHelper.java @@ -0,0 +1,228 @@ +package com.github.dsheirer.sdrplay.api.v3_08; +// Generated by jextract + +import java.lang.foreign.Addressable; +import java.lang.foreign.FunctionDescriptor; +import java.lang.foreign.GroupLayout; +import java.lang.foreign.Linker; +import java.lang.foreign.MemoryAddress; +import java.lang.foreign.MemoryLayout; +import java.lang.foreign.MemorySegment; +import java.lang.foreign.MemorySession; +import java.lang.foreign.SegmentAllocator; +import java.lang.foreign.SymbolLookup; +import java.lang.foreign.ValueLayout; +import java.lang.invoke.MethodHandle; +import java.lang.invoke.MethodHandles; +import java.lang.invoke.MethodType; + +import static java.lang.foreign.ValueLayout.ADDRESS; +import static java.lang.foreign.ValueLayout.JAVA_DOUBLE; +import static java.lang.foreign.ValueLayout.JAVA_LONG; + +final class RuntimeHelper { + + private RuntimeHelper() {} + private final static Linker LINKER = Linker.nativeLinker(); + private final static ClassLoader LOADER = RuntimeHelper.class.getClassLoader(); + private final static MethodHandles.Lookup MH_LOOKUP = MethodHandles.lookup(); + private final static SymbolLookup SYMBOL_LOOKUP; + + final static SegmentAllocator CONSTANT_ALLOCATOR = + (size, align) -> MemorySegment.allocateNative(size, align, MemorySession.openImplicit()); + + static { +// System.loadLibrary("libsdrplay_api"); + SymbolLookup loaderLookup = SymbolLookup.loaderLookup(); + SYMBOL_LOOKUP = name -> loaderLookup.lookup(name).or(() -> LINKER.defaultLookup().lookup(name)); + } + + static T requireNonNull(T obj, String symbolName) { + if (obj == null) { + throw new UnsatisfiedLinkError("unresolved symbol: " + symbolName); + } + return obj; + } + + private final static SegmentAllocator THROWING_ALLOCATOR = (x, y) -> { throw new AssertionError("should not reach here"); }; + + static final MemorySegment lookupGlobalVariable(String name, MemoryLayout layout) { + return SYMBOL_LOOKUP.lookup(name).map(symbol -> MemorySegment.ofAddress(symbol.address(), layout.byteSize(), MemorySession.openShared())).orElse(null); + } + + static final MethodHandle downcallHandle(String name, FunctionDescriptor fdesc) { + return SYMBOL_LOOKUP.lookup(name). + map(addr -> LINKER.downcallHandle(addr, fdesc)). + orElse(null); + } + + static final MethodHandle downcallHandle(FunctionDescriptor fdesc) { + return LINKER.downcallHandle(fdesc); + } + + static final MethodHandle downcallHandleVariadic(String name, FunctionDescriptor fdesc) { + return SYMBOL_LOOKUP.lookup(name). + map(addr -> VarargsInvoker.make(addr, fdesc)). + orElse(null); + } + + static final MemorySegment upcallStub(Class fi, Z z, FunctionDescriptor fdesc, MemorySession session) { + try { + MethodHandle handle = MH_LOOKUP.findVirtual(fi, "apply", Linker.upcallType(fdesc)); + handle = handle.bindTo(z); + return LINKER.upcallStub(handle, fdesc, session); + } catch (Throwable ex) { + throw new AssertionError(ex); + } + } + + static MemorySegment asArray(MemoryAddress addr, MemoryLayout layout, int numElements, MemorySession session) { + return MemorySegment.ofAddress(addr, numElements * layout.byteSize(), session); + } + + // Internals only below this point + + private static class VarargsInvoker { + private static final MethodHandle INVOKE_MH; + private final MemorySegment symbol; + private final FunctionDescriptor function; + + private VarargsInvoker(MemorySegment symbol, FunctionDescriptor function) { + this.symbol = symbol; + this.function = function; + } + + static { + try { + INVOKE_MH = MethodHandles.lookup().findVirtual(VarargsInvoker.class, "invoke", MethodType.methodType(Object.class, SegmentAllocator.class, Object[].class)); + } catch (ReflectiveOperationException e) { + throw new RuntimeException(e); + } + } + + static MethodHandle make(MemorySegment symbol, FunctionDescriptor function) { + VarargsInvoker invoker = new VarargsInvoker(symbol, function); + MethodHandle handle = INVOKE_MH.bindTo(invoker).asCollector(Object[].class, function.argumentLayouts().size() + 1); + MethodType mtype = MethodType.methodType(function.returnLayout().isPresent() ? carrier(function.returnLayout().get(), true) : void.class); + for (MemoryLayout layout : function.argumentLayouts()) { + mtype = mtype.appendParameterTypes(carrier(layout, false)); + } + mtype = mtype.appendParameterTypes(Object[].class); + if (mtype.returnType().equals(MemorySegment.class)) { + mtype = mtype.insertParameterTypes(0, SegmentAllocator.class); + } else { + handle = MethodHandles.insertArguments(handle, 0, THROWING_ALLOCATOR); + } + return handle.asType(mtype); + } + + static Class carrier(MemoryLayout layout, boolean ret) { + if (layout instanceof ValueLayout valueLayout) { + return (ret || valueLayout.carrier() != MemoryAddress.class) ? + valueLayout.carrier() : Addressable.class; + } else if (layout instanceof GroupLayout) { + return MemorySegment.class; + } else { + throw new AssertionError("Cannot get here!"); + } + } + + private Object invoke(SegmentAllocator allocator, Object[] args) throws Throwable { + // one trailing Object[] + int nNamedArgs = function.argumentLayouts().size(); + assert(args.length == nNamedArgs + 1); + // The last argument is the array of vararg collector + Object[] unnamedArgs = (Object[]) args[args.length - 1]; + + int argsCount = nNamedArgs + unnamedArgs.length; + Class[] argTypes = new Class[argsCount]; + MemoryLayout[] argLayouts = new MemoryLayout[nNamedArgs + unnamedArgs.length]; + + int pos = 0; + for (pos = 0; pos < nNamedArgs; pos++) { + argLayouts[pos] = function.argumentLayouts().get(pos); + } + + assert pos == nNamedArgs; + for (Object o: unnamedArgs) { + argLayouts[pos] = variadicLayout(normalize(o.getClass())); + pos++; + } + assert pos == argsCount; + + FunctionDescriptor f = (function.returnLayout().isEmpty()) ? + FunctionDescriptor.ofVoid(argLayouts) : + FunctionDescriptor.of(function.returnLayout().get(), argLayouts); + MethodHandle mh = LINKER.downcallHandle(symbol, f); + if (mh.type().returnType() == MemorySegment.class) { + mh = mh.bindTo(allocator); + } + // flatten argument list so that it can be passed to an asSpreader MH + Object[] allArgs = new Object[nNamedArgs + unnamedArgs.length]; + System.arraycopy(args, 0, allArgs, 0, nNamedArgs); + System.arraycopy(unnamedArgs, 0, allArgs, nNamedArgs, unnamedArgs.length); + + return mh.asSpreader(Object[].class, argsCount).invoke(allArgs); + } + + private static Class unboxIfNeeded(Class clazz) { + if (clazz == Boolean.class) { + return boolean.class; + } else if (clazz == Void.class) { + return void.class; + } else if (clazz == Byte.class) { + return byte.class; + } else if (clazz == Character.class) { + return char.class; + } else if (clazz == Short.class) { + return short.class; + } else if (clazz == Integer.class) { + return int.class; + } else if (clazz == Long.class) { + return long.class; + } else if (clazz == Float.class) { + return float.class; + } else if (clazz == Double.class) { + return double.class; + } else { + return clazz; + } + } + + private Class promote(Class c) { + if (c == byte.class || c == char.class || c == short.class || c == int.class) { + return long.class; + } else if (c == float.class) { + return double.class; + } else { + return c; + } + } + + private Class normalize(Class c) { + c = unboxIfNeeded(c); + if (c.isPrimitive()) { + return promote(c); + } + if (MemoryAddress.class.isAssignableFrom(c)) { + return MemoryAddress.class; + } + if (MemorySegment.class.isAssignableFrom(c)) { + return MemorySegment.class; + } + throw new IllegalArgumentException("Invalid type for ABI: " + c.getTypeName()); + } + + private MemoryLayout variadicLayout(Class c) { + if (c == long.class) { + return JAVA_LONG; + } else if (c == double.class) { + return JAVA_DOUBLE; + } else if (MemoryAddress.class.isAssignableFrom(c)) { + return ADDRESS; + } else { + throw new IllegalArgumentException("Unhandled variadic argument class: " + c); + } + } + } +} diff --git a/sdrplay-api/src/main/java/com/github/dsheirer/sdrplay/api/v3_08/constants$0.java b/sdrplay-api/src/main/java/com/github/dsheirer/sdrplay/api/v3_08/constants$0.java new file mode 100644 index 000000000..5db56877a --- /dev/null +++ b/sdrplay-api/src/main/java/com/github/dsheirer/sdrplay/api/v3_08/constants$0.java @@ -0,0 +1,35 @@ +// Generated by jextract + +package com.github.dsheirer.sdrplay.api.v3_08; + +import java.lang.foreign.FunctionDescriptor; +import java.lang.invoke.MethodHandle; +class constants$0 { + + static final FunctionDescriptor sdrplay_api_StreamCallback_t$FUNC = FunctionDescriptor.ofVoid( + Constants$root.C_POINTER$LAYOUT, + Constants$root.C_POINTER$LAYOUT, + Constants$root.C_POINTER$LAYOUT, + Constants$root.C_LONG$LAYOUT, + Constants$root.C_LONG$LAYOUT, + Constants$root.C_POINTER$LAYOUT + ); + static final MethodHandle sdrplay_api_StreamCallback_t$MH = RuntimeHelper.downcallHandle( + constants$0.sdrplay_api_StreamCallback_t$FUNC + ); + static final FunctionDescriptor sdrplay_api_EventCallback_t$FUNC = FunctionDescriptor.ofVoid( + Constants$root.C_LONG$LAYOUT, + Constants$root.C_LONG$LAYOUT, + Constants$root.C_POINTER$LAYOUT, + Constants$root.C_POINTER$LAYOUT + ); + static final MethodHandle sdrplay_api_EventCallback_t$MH = RuntimeHelper.downcallHandle( + constants$0.sdrplay_api_EventCallback_t$FUNC + ); + static final FunctionDescriptor sdrplay_api_Open_t$FUNC = FunctionDescriptor.of(Constants$root.C_LONG$LAYOUT); + static final MethodHandle sdrplay_api_Open_t$MH = RuntimeHelper.downcallHandle( + constants$0.sdrplay_api_Open_t$FUNC + ); +} + + diff --git a/sdrplay-api/src/main/java/com/github/dsheirer/sdrplay/api/v3_08/constants$1.java b/sdrplay-api/src/main/java/com/github/dsheirer/sdrplay/api/v3_08/constants$1.java new file mode 100644 index 000000000..7c879d8f1 --- /dev/null +++ b/sdrplay-api/src/main/java/com/github/dsheirer/sdrplay/api/v3_08/constants$1.java @@ -0,0 +1,25 @@ +// Generated by jextract + +package com.github.dsheirer.sdrplay.api.v3_08; + +import java.lang.foreign.FunctionDescriptor; +import java.lang.invoke.MethodHandle; +class constants$1 { + + static final FunctionDescriptor sdrplay_api_Close_t$FUNC = FunctionDescriptor.of(Constants$root.C_LONG$LAYOUT); + static final MethodHandle sdrplay_api_Close_t$MH = RuntimeHelper.downcallHandle( + constants$1.sdrplay_api_Close_t$FUNC + ); + static final FunctionDescriptor sdrplay_api_ApiVersion_t$FUNC = FunctionDescriptor.of(Constants$root.C_LONG$LAYOUT, + Constants$root.C_POINTER$LAYOUT + ); + static final MethodHandle sdrplay_api_ApiVersion_t$MH = RuntimeHelper.downcallHandle( + constants$1.sdrplay_api_ApiVersion_t$FUNC + ); + static final FunctionDescriptor sdrplay_api_LockDeviceApi_t$FUNC = FunctionDescriptor.of(Constants$root.C_LONG$LAYOUT); + static final MethodHandle sdrplay_api_LockDeviceApi_t$MH = RuntimeHelper.downcallHandle( + constants$1.sdrplay_api_LockDeviceApi_t$FUNC + ); +} + + diff --git a/sdrplay-api/src/main/java/com/github/dsheirer/sdrplay/api/v3_08/constants$10.java b/sdrplay-api/src/main/java/com/github/dsheirer/sdrplay/api/v3_08/constants$10.java new file mode 100644 index 000000000..aaaaa0251 --- /dev/null +++ b/sdrplay-api/src/main/java/com/github/dsheirer/sdrplay/api/v3_08/constants$10.java @@ -0,0 +1,25 @@ +// Generated by jextract + +package com.github.dsheirer.sdrplay.api.v3_08; + +import java.lang.foreign.FunctionDescriptor; +import java.lang.invoke.MethodHandle; +class constants$10 { + + static final FunctionDescriptor sdrplay_api_SwapRspDuoMode$FUNC = FunctionDescriptor.of(Constants$root.C_LONG$LAYOUT, + Constants$root.C_POINTER$LAYOUT, + Constants$root.C_POINTER$LAYOUT, + Constants$root.C_LONG$LAYOUT, + Constants$root.C_DOUBLE$LAYOUT, + Constants$root.C_LONG$LAYOUT, + Constants$root.C_LONG$LAYOUT, + Constants$root.C_LONG$LAYOUT, + Constants$root.C_LONG$LAYOUT + ); + static final MethodHandle sdrplay_api_SwapRspDuoMode$MH = RuntimeHelper.downcallHandle( + "sdrplay_api_SwapRspDuoMode", + constants$10.sdrplay_api_SwapRspDuoMode$FUNC + ); +} + + diff --git a/sdrplay-api/src/main/java/com/github/dsheirer/sdrplay/api/v3_08/constants$2.java b/sdrplay-api/src/main/java/com/github/dsheirer/sdrplay/api/v3_08/constants$2.java new file mode 100644 index 000000000..870d3eef2 --- /dev/null +++ b/sdrplay-api/src/main/java/com/github/dsheirer/sdrplay/api/v3_08/constants$2.java @@ -0,0 +1,29 @@ +// Generated by jextract + +package com.github.dsheirer.sdrplay.api.v3_08; + +import java.lang.foreign.FunctionDescriptor; +import java.lang.invoke.MethodHandle; +class constants$2 { + + static final FunctionDescriptor sdrplay_api_UnlockDeviceApi_t$FUNC = FunctionDescriptor.of(Constants$root.C_LONG$LAYOUT); + static final MethodHandle sdrplay_api_UnlockDeviceApi_t$MH = RuntimeHelper.downcallHandle( + constants$2.sdrplay_api_UnlockDeviceApi_t$FUNC + ); + static final FunctionDescriptor sdrplay_api_GetDevices_t$FUNC = FunctionDescriptor.of(Constants$root.C_LONG$LAYOUT, + Constants$root.C_POINTER$LAYOUT, + Constants$root.C_POINTER$LAYOUT, + Constants$root.C_LONG$LAYOUT + ); + static final MethodHandle sdrplay_api_GetDevices_t$MH = RuntimeHelper.downcallHandle( + constants$2.sdrplay_api_GetDevices_t$FUNC + ); + static final FunctionDescriptor sdrplay_api_SelectDevice_t$FUNC = FunctionDescriptor.of(Constants$root.C_LONG$LAYOUT, + Constants$root.C_POINTER$LAYOUT + ); + static final MethodHandle sdrplay_api_SelectDevice_t$MH = RuntimeHelper.downcallHandle( + constants$2.sdrplay_api_SelectDevice_t$FUNC + ); +} + + diff --git a/sdrplay-api/src/main/java/com/github/dsheirer/sdrplay/api/v3_08/constants$3.java b/sdrplay-api/src/main/java/com/github/dsheirer/sdrplay/api/v3_08/constants$3.java new file mode 100644 index 000000000..2be759d82 --- /dev/null +++ b/sdrplay-api/src/main/java/com/github/dsheirer/sdrplay/api/v3_08/constants$3.java @@ -0,0 +1,29 @@ +// Generated by jextract + +package com.github.dsheirer.sdrplay.api.v3_08; + +import java.lang.foreign.FunctionDescriptor; +import java.lang.invoke.MethodHandle; +class constants$3 { + + static final FunctionDescriptor sdrplay_api_ReleaseDevice_t$FUNC = FunctionDescriptor.of(Constants$root.C_LONG$LAYOUT, + Constants$root.C_POINTER$LAYOUT + ); + static final MethodHandle sdrplay_api_ReleaseDevice_t$MH = RuntimeHelper.downcallHandle( + constants$3.sdrplay_api_ReleaseDevice_t$FUNC + ); + static final FunctionDescriptor sdrplay_api_GetErrorString_t$FUNC = FunctionDescriptor.of(Constants$root.C_POINTER$LAYOUT, + Constants$root.C_LONG$LAYOUT + ); + static final MethodHandle sdrplay_api_GetErrorString_t$MH = RuntimeHelper.downcallHandle( + constants$3.sdrplay_api_GetErrorString_t$FUNC + ); + static final FunctionDescriptor sdrplay_api_GetLastError_t$FUNC = FunctionDescriptor.of(Constants$root.C_POINTER$LAYOUT, + Constants$root.C_POINTER$LAYOUT + ); + static final MethodHandle sdrplay_api_GetLastError_t$MH = RuntimeHelper.downcallHandle( + constants$3.sdrplay_api_GetLastError_t$FUNC + ); +} + + diff --git a/sdrplay-api/src/main/java/com/github/dsheirer/sdrplay/api/v3_08/constants$4.java b/sdrplay-api/src/main/java/com/github/dsheirer/sdrplay/api/v3_08/constants$4.java new file mode 100644 index 000000000..1453fdf7f --- /dev/null +++ b/sdrplay-api/src/main/java/com/github/dsheirer/sdrplay/api/v3_08/constants$4.java @@ -0,0 +1,29 @@ +// Generated by jextract + +package com.github.dsheirer.sdrplay.api.v3_08; + +import java.lang.foreign.FunctionDescriptor; +import java.lang.invoke.MethodHandle; +class constants$4 { + + static final FunctionDescriptor sdrplay_api_DisableHeartbeat_t$FUNC = FunctionDescriptor.of(Constants$root.C_LONG$LAYOUT); + static final MethodHandle sdrplay_api_DisableHeartbeat_t$MH = RuntimeHelper.downcallHandle( + constants$4.sdrplay_api_DisableHeartbeat_t$FUNC + ); + static final FunctionDescriptor sdrplay_api_DebugEnable_t$FUNC = FunctionDescriptor.of(Constants$root.C_LONG$LAYOUT, + Constants$root.C_POINTER$LAYOUT, + Constants$root.C_LONG$LAYOUT + ); + static final MethodHandle sdrplay_api_DebugEnable_t$MH = RuntimeHelper.downcallHandle( + constants$4.sdrplay_api_DebugEnable_t$FUNC + ); + static final FunctionDescriptor sdrplay_api_GetDeviceParams_t$FUNC = FunctionDescriptor.of(Constants$root.C_LONG$LAYOUT, + Constants$root.C_POINTER$LAYOUT, + Constants$root.C_POINTER$LAYOUT + ); + static final MethodHandle sdrplay_api_GetDeviceParams_t$MH = RuntimeHelper.downcallHandle( + constants$4.sdrplay_api_GetDeviceParams_t$FUNC + ); +} + + diff --git a/sdrplay-api/src/main/java/com/github/dsheirer/sdrplay/api/v3_08/constants$5.java b/sdrplay-api/src/main/java/com/github/dsheirer/sdrplay/api/v3_08/constants$5.java new file mode 100644 index 000000000..5cf82e9b0 --- /dev/null +++ b/sdrplay-api/src/main/java/com/github/dsheirer/sdrplay/api/v3_08/constants$5.java @@ -0,0 +1,34 @@ +// Generated by jextract + +package com.github.dsheirer.sdrplay.api.v3_08; + +import java.lang.foreign.FunctionDescriptor; +import java.lang.invoke.MethodHandle; +class constants$5 { + + static final FunctionDescriptor sdrplay_api_Init_t$FUNC = FunctionDescriptor.of(Constants$root.C_LONG$LAYOUT, + Constants$root.C_POINTER$LAYOUT, + Constants$root.C_POINTER$LAYOUT, + Constants$root.C_POINTER$LAYOUT + ); + static final MethodHandle sdrplay_api_Init_t$MH = RuntimeHelper.downcallHandle( + constants$5.sdrplay_api_Init_t$FUNC + ); + static final FunctionDescriptor sdrplay_api_Uninit_t$FUNC = FunctionDescriptor.of(Constants$root.C_LONG$LAYOUT, + Constants$root.C_POINTER$LAYOUT + ); + static final MethodHandle sdrplay_api_Uninit_t$MH = RuntimeHelper.downcallHandle( + constants$5.sdrplay_api_Uninit_t$FUNC + ); + static final FunctionDescriptor sdrplay_api_Update_t$FUNC = FunctionDescriptor.of(Constants$root.C_LONG$LAYOUT, + Constants$root.C_POINTER$LAYOUT, + Constants$root.C_LONG$LAYOUT, + Constants$root.C_LONG$LAYOUT, + Constants$root.C_LONG$LAYOUT + ); + static final MethodHandle sdrplay_api_Update_t$MH = RuntimeHelper.downcallHandle( + constants$5.sdrplay_api_Update_t$FUNC + ); +} + + diff --git a/sdrplay-api/src/main/java/com/github/dsheirer/sdrplay/api/v3_08/constants$6.java b/sdrplay-api/src/main/java/com/github/dsheirer/sdrplay/api/v3_08/constants$6.java new file mode 100644 index 000000000..a861cc2c2 --- /dev/null +++ b/sdrplay-api/src/main/java/com/github/dsheirer/sdrplay/api/v3_08/constants$6.java @@ -0,0 +1,39 @@ +// Generated by jextract + +package com.github.dsheirer.sdrplay.api.v3_08; + +import java.lang.foreign.FunctionDescriptor; +import java.lang.invoke.MethodHandle; +class constants$6 { + + static final FunctionDescriptor sdrplay_api_SwapRspDuoActiveTuner_t$FUNC = FunctionDescriptor.of(Constants$root.C_LONG$LAYOUT, + Constants$root.C_POINTER$LAYOUT, + Constants$root.C_POINTER$LAYOUT, + Constants$root.C_LONG$LAYOUT + ); + static final MethodHandle sdrplay_api_SwapRspDuoActiveTuner_t$MH = RuntimeHelper.downcallHandle( + constants$6.sdrplay_api_SwapRspDuoActiveTuner_t$FUNC + ); + static final FunctionDescriptor sdrplay_api_SwapRspDuoDualTunerModeSampleRate_t$FUNC = FunctionDescriptor.of(Constants$root.C_LONG$LAYOUT, + Constants$root.C_POINTER$LAYOUT, + Constants$root.C_DOUBLE$LAYOUT + ); + static final MethodHandle sdrplay_api_SwapRspDuoDualTunerModeSampleRate_t$MH = RuntimeHelper.downcallHandle( + constants$6.sdrplay_api_SwapRspDuoDualTunerModeSampleRate_t$FUNC + ); + static final FunctionDescriptor sdrplay_api_SwapRspDuoMode_t$FUNC = FunctionDescriptor.of(Constants$root.C_LONG$LAYOUT, + Constants$root.C_POINTER$LAYOUT, + Constants$root.C_POINTER$LAYOUT, + Constants$root.C_LONG$LAYOUT, + Constants$root.C_DOUBLE$LAYOUT, + Constants$root.C_LONG$LAYOUT, + Constants$root.C_LONG$LAYOUT, + Constants$root.C_LONG$LAYOUT, + Constants$root.C_LONG$LAYOUT + ); + static final MethodHandle sdrplay_api_SwapRspDuoMode_t$MH = RuntimeHelper.downcallHandle( + constants$6.sdrplay_api_SwapRspDuoMode_t$FUNC + ); +} + + diff --git a/sdrplay-api/src/main/java/com/github/dsheirer/sdrplay/api/v3_08/constants$7.java b/sdrplay-api/src/main/java/com/github/dsheirer/sdrplay/api/v3_08/constants$7.java new file mode 100644 index 000000000..84eb47d85 --- /dev/null +++ b/sdrplay-api/src/main/java/com/github/dsheirer/sdrplay/api/v3_08/constants$7.java @@ -0,0 +1,47 @@ +// Generated by jextract + +package com.github.dsheirer.sdrplay.api.v3_08; + +import java.lang.foreign.FunctionDescriptor; +import java.lang.invoke.MethodHandle; +class constants$7 { + + static final FunctionDescriptor sdrplay_api_Open$FUNC = FunctionDescriptor.of(Constants$root.C_LONG$LAYOUT); + static final MethodHandle sdrplay_api_Open$MH = RuntimeHelper.downcallHandle( + "sdrplay_api_Open", + constants$7.sdrplay_api_Open$FUNC + ); + static final FunctionDescriptor sdrplay_api_Close$FUNC = FunctionDescriptor.of(Constants$root.C_LONG$LAYOUT); + static final MethodHandle sdrplay_api_Close$MH = RuntimeHelper.downcallHandle( + "sdrplay_api_Close", + constants$7.sdrplay_api_Close$FUNC + ); + static final FunctionDescriptor sdrplay_api_ApiVersion$FUNC = FunctionDescriptor.of(Constants$root.C_LONG$LAYOUT, + Constants$root.C_POINTER$LAYOUT + ); + static final MethodHandle sdrplay_api_ApiVersion$MH = RuntimeHelper.downcallHandle( + "sdrplay_api_ApiVersion", + constants$7.sdrplay_api_ApiVersion$FUNC + ); + static final FunctionDescriptor sdrplay_api_LockDeviceApi$FUNC = FunctionDescriptor.of(Constants$root.C_LONG$LAYOUT); + static final MethodHandle sdrplay_api_LockDeviceApi$MH = RuntimeHelper.downcallHandle( + "sdrplay_api_LockDeviceApi", + constants$7.sdrplay_api_LockDeviceApi$FUNC + ); + static final FunctionDescriptor sdrplay_api_UnlockDeviceApi$FUNC = FunctionDescriptor.of(Constants$root.C_LONG$LAYOUT); + static final MethodHandle sdrplay_api_UnlockDeviceApi$MH = RuntimeHelper.downcallHandle( + "sdrplay_api_UnlockDeviceApi", + constants$7.sdrplay_api_UnlockDeviceApi$FUNC + ); + static final FunctionDescriptor sdrplay_api_GetDevices$FUNC = FunctionDescriptor.of(Constants$root.C_LONG$LAYOUT, + Constants$root.C_POINTER$LAYOUT, + Constants$root.C_POINTER$LAYOUT, + Constants$root.C_LONG$LAYOUT + ); + static final MethodHandle sdrplay_api_GetDevices$MH = RuntimeHelper.downcallHandle( + "sdrplay_api_GetDevices", + constants$7.sdrplay_api_GetDevices$FUNC + ); +} + + diff --git a/sdrplay-api/src/main/java/com/github/dsheirer/sdrplay/api/v3_08/constants$8.java b/sdrplay-api/src/main/java/com/github/dsheirer/sdrplay/api/v3_08/constants$8.java new file mode 100644 index 000000000..e5b60bce5 --- /dev/null +++ b/sdrplay-api/src/main/java/com/github/dsheirer/sdrplay/api/v3_08/constants$8.java @@ -0,0 +1,52 @@ +// Generated by jextract + +package com.github.dsheirer.sdrplay.api.v3_08; + +import java.lang.foreign.FunctionDescriptor; +import java.lang.invoke.MethodHandle; +class constants$8 { + + static final FunctionDescriptor sdrplay_api_SelectDevice$FUNC = FunctionDescriptor.of(Constants$root.C_LONG$LAYOUT, + Constants$root.C_POINTER$LAYOUT + ); + static final MethodHandle sdrplay_api_SelectDevice$MH = RuntimeHelper.downcallHandle( + "sdrplay_api_SelectDevice", + constants$8.sdrplay_api_SelectDevice$FUNC + ); + static final FunctionDescriptor sdrplay_api_ReleaseDevice$FUNC = FunctionDescriptor.of(Constants$root.C_LONG$LAYOUT, + Constants$root.C_POINTER$LAYOUT + ); + static final MethodHandle sdrplay_api_ReleaseDevice$MH = RuntimeHelper.downcallHandle( + "sdrplay_api_ReleaseDevice", + constants$8.sdrplay_api_ReleaseDevice$FUNC + ); + static final FunctionDescriptor sdrplay_api_GetErrorString$FUNC = FunctionDescriptor.of(Constants$root.C_POINTER$LAYOUT, + Constants$root.C_LONG$LAYOUT + ); + static final MethodHandle sdrplay_api_GetErrorString$MH = RuntimeHelper.downcallHandle( + "sdrplay_api_GetErrorString", + constants$8.sdrplay_api_GetErrorString$FUNC + ); + static final FunctionDescriptor sdrplay_api_GetLastError$FUNC = FunctionDescriptor.of(Constants$root.C_POINTER$LAYOUT, + Constants$root.C_POINTER$LAYOUT + ); + static final MethodHandle sdrplay_api_GetLastError$MH = RuntimeHelper.downcallHandle( + "sdrplay_api_GetLastError", + constants$8.sdrplay_api_GetLastError$FUNC + ); + static final FunctionDescriptor sdrplay_api_DisableHeartbeat$FUNC = FunctionDescriptor.of(Constants$root.C_LONG$LAYOUT); + static final MethodHandle sdrplay_api_DisableHeartbeat$MH = RuntimeHelper.downcallHandle( + "sdrplay_api_DisableHeartbeat", + constants$8.sdrplay_api_DisableHeartbeat$FUNC + ); + static final FunctionDescriptor sdrplay_api_DebugEnable$FUNC = FunctionDescriptor.of(Constants$root.C_LONG$LAYOUT, + Constants$root.C_POINTER$LAYOUT, + Constants$root.C_LONG$LAYOUT + ); + static final MethodHandle sdrplay_api_DebugEnable$MH = RuntimeHelper.downcallHandle( + "sdrplay_api_DebugEnable", + constants$8.sdrplay_api_DebugEnable$FUNC + ); +} + + diff --git a/sdrplay-api/src/main/java/com/github/dsheirer/sdrplay/api/v3_08/constants$9.java b/sdrplay-api/src/main/java/com/github/dsheirer/sdrplay/api/v3_08/constants$9.java new file mode 100644 index 000000000..74f5fc68e --- /dev/null +++ b/sdrplay-api/src/main/java/com/github/dsheirer/sdrplay/api/v3_08/constants$9.java @@ -0,0 +1,63 @@ +// Generated by jextract + +package com.github.dsheirer.sdrplay.api.v3_08; + +import java.lang.foreign.FunctionDescriptor; +import java.lang.invoke.MethodHandle; +class constants$9 { + + static final FunctionDescriptor sdrplay_api_GetDeviceParams$FUNC = FunctionDescriptor.of(Constants$root.C_LONG$LAYOUT, + Constants$root.C_POINTER$LAYOUT, + Constants$root.C_POINTER$LAYOUT + ); + static final MethodHandle sdrplay_api_GetDeviceParams$MH = RuntimeHelper.downcallHandle( + "sdrplay_api_GetDeviceParams", + constants$9.sdrplay_api_GetDeviceParams$FUNC + ); + static final FunctionDescriptor sdrplay_api_Init$FUNC = FunctionDescriptor.of(Constants$root.C_LONG$LAYOUT, + Constants$root.C_POINTER$LAYOUT, + Constants$root.C_POINTER$LAYOUT, + Constants$root.C_POINTER$LAYOUT + ); + static final MethodHandle sdrplay_api_Init$MH = RuntimeHelper.downcallHandle( + "sdrplay_api_Init", + constants$9.sdrplay_api_Init$FUNC + ); + static final FunctionDescriptor sdrplay_api_Uninit$FUNC = FunctionDescriptor.of(Constants$root.C_LONG$LAYOUT, + Constants$root.C_POINTER$LAYOUT + ); + static final MethodHandle sdrplay_api_Uninit$MH = RuntimeHelper.downcallHandle( + "sdrplay_api_Uninit", + constants$9.sdrplay_api_Uninit$FUNC + ); + static final FunctionDescriptor sdrplay_api_Update$FUNC = FunctionDescriptor.of(Constants$root.C_LONG$LAYOUT, + Constants$root.C_POINTER$LAYOUT, + Constants$root.C_LONG$LAYOUT, + Constants$root.C_LONG$LAYOUT, + Constants$root.C_LONG$LAYOUT + ); + static final MethodHandle sdrplay_api_Update$MH = RuntimeHelper.downcallHandle( + "sdrplay_api_Update", + constants$9.sdrplay_api_Update$FUNC + ); + static final FunctionDescriptor sdrplay_api_SwapRspDuoActiveTuner$FUNC = FunctionDescriptor.of(Constants$root.C_LONG$LAYOUT, + Constants$root.C_POINTER$LAYOUT, + Constants$root.C_POINTER$LAYOUT, + Constants$root.C_LONG$LAYOUT + ); + static final MethodHandle sdrplay_api_SwapRspDuoActiveTuner$MH = RuntimeHelper.downcallHandle( + "sdrplay_api_SwapRspDuoActiveTuner", + constants$9.sdrplay_api_SwapRspDuoActiveTuner$FUNC + ); + static final FunctionDescriptor sdrplay_api_SwapRspDuoDualTunerModeSampleRate$FUNC = FunctionDescriptor.of(Constants$root.C_LONG$LAYOUT, + Constants$root.C_POINTER$LAYOUT, + Constants$root.C_POINTER$LAYOUT, + Constants$root.C_DOUBLE$LAYOUT + ); + static final MethodHandle sdrplay_api_SwapRspDuoDualTunerModeSampleRate$MH = RuntimeHelper.downcallHandle( + "sdrplay_api_SwapRspDuoDualTunerModeSampleRate", + constants$9.sdrplay_api_SwapRspDuoDualTunerModeSampleRate$FUNC + ); +} + + diff --git a/sdrplay-api/src/main/java/com/github/dsheirer/sdrplay/api/v3_08/sdrplay_api_AgcT.java b/sdrplay-api/src/main/java/com/github/dsheirer/sdrplay/api/v3_08/sdrplay_api_AgcT.java new file mode 100644 index 000000000..3b901e400 --- /dev/null +++ b/sdrplay-api/src/main/java/com/github/dsheirer/sdrplay/api/v3_08/sdrplay_api_AgcT.java @@ -0,0 +1,146 @@ +// Generated by jextract + +package com.github.dsheirer.sdrplay.api.v3_08; + +import java.lang.foreign.GroupLayout; +import java.lang.foreign.MemoryAddress; +import java.lang.foreign.MemoryLayout; +import java.lang.foreign.MemorySegment; +import java.lang.foreign.MemorySession; +import java.lang.foreign.SegmentAllocator; +import java.lang.invoke.VarHandle; +public class sdrplay_api_AgcT { + + static final GroupLayout $struct$LAYOUT = MemoryLayout.structLayout( + Constants$root.C_LONG$LAYOUT.withName("enable"), + Constants$root.C_LONG$LAYOUT.withName("setPoint_dBfs"), + Constants$root.C_SHORT$LAYOUT.withName("attack_ms"), + Constants$root.C_SHORT$LAYOUT.withName("decay_ms"), + Constants$root.C_SHORT$LAYOUT.withName("decay_delay_ms"), + Constants$root.C_SHORT$LAYOUT.withName("decay_threshold_dB"), + Constants$root.C_LONG$LAYOUT.withName("syncUpdate") + ); + public static MemoryLayout $LAYOUT() { + return sdrplay_api_AgcT.$struct$LAYOUT; + } + static final VarHandle enable$VH = $struct$LAYOUT.varHandle(MemoryLayout.PathElement.groupElement("enable")); + public static VarHandle enable$VH() { + return sdrplay_api_AgcT.enable$VH; + } + public static int enable$get(MemorySegment seg) { + return (int)sdrplay_api_AgcT.enable$VH.get(seg); + } + public static void enable$set( MemorySegment seg, int x) { + sdrplay_api_AgcT.enable$VH.set(seg, x); + } + public static int enable$get(MemorySegment seg, long index) { + return (int)sdrplay_api_AgcT.enable$VH.get(seg.asSlice(index*sizeof())); + } + public static void enable$set(MemorySegment seg, long index, int x) { + sdrplay_api_AgcT.enable$VH.set(seg.asSlice(index*sizeof()), x); + } + static final VarHandle setPoint_dBfs$VH = $struct$LAYOUT.varHandle(MemoryLayout.PathElement.groupElement("setPoint_dBfs")); + public static VarHandle setPoint_dBfs$VH() { + return sdrplay_api_AgcT.setPoint_dBfs$VH; + } + public static int setPoint_dBfs$get(MemorySegment seg) { + return (int)sdrplay_api_AgcT.setPoint_dBfs$VH.get(seg); + } + public static void setPoint_dBfs$set( MemorySegment seg, int x) { + sdrplay_api_AgcT.setPoint_dBfs$VH.set(seg, x); + } + public static int setPoint_dBfs$get(MemorySegment seg, long index) { + return (int)sdrplay_api_AgcT.setPoint_dBfs$VH.get(seg.asSlice(index*sizeof())); + } + public static void setPoint_dBfs$set(MemorySegment seg, long index, int x) { + sdrplay_api_AgcT.setPoint_dBfs$VH.set(seg.asSlice(index*sizeof()), x); + } + static final VarHandle attack_ms$VH = $struct$LAYOUT.varHandle(MemoryLayout.PathElement.groupElement("attack_ms")); + public static VarHandle attack_ms$VH() { + return sdrplay_api_AgcT.attack_ms$VH; + } + public static short attack_ms$get(MemorySegment seg) { + return (short)sdrplay_api_AgcT.attack_ms$VH.get(seg); + } + public static void attack_ms$set( MemorySegment seg, short x) { + sdrplay_api_AgcT.attack_ms$VH.set(seg, x); + } + public static short attack_ms$get(MemorySegment seg, long index) { + return (short)sdrplay_api_AgcT.attack_ms$VH.get(seg.asSlice(index*sizeof())); + } + public static void attack_ms$set(MemorySegment seg, long index, short x) { + sdrplay_api_AgcT.attack_ms$VH.set(seg.asSlice(index*sizeof()), x); + } + static final VarHandle decay_ms$VH = $struct$LAYOUT.varHandle(MemoryLayout.PathElement.groupElement("decay_ms")); + public static VarHandle decay_ms$VH() { + return sdrplay_api_AgcT.decay_ms$VH; + } + public static short decay_ms$get(MemorySegment seg) { + return (short)sdrplay_api_AgcT.decay_ms$VH.get(seg); + } + public static void decay_ms$set( MemorySegment seg, short x) { + sdrplay_api_AgcT.decay_ms$VH.set(seg, x); + } + public static short decay_ms$get(MemorySegment seg, long index) { + return (short)sdrplay_api_AgcT.decay_ms$VH.get(seg.asSlice(index*sizeof())); + } + public static void decay_ms$set(MemorySegment seg, long index, short x) { + sdrplay_api_AgcT.decay_ms$VH.set(seg.asSlice(index*sizeof()), x); + } + static final VarHandle decay_delay_ms$VH = $struct$LAYOUT.varHandle(MemoryLayout.PathElement.groupElement("decay_delay_ms")); + public static VarHandle decay_delay_ms$VH() { + return sdrplay_api_AgcT.decay_delay_ms$VH; + } + public static short decay_delay_ms$get(MemorySegment seg) { + return (short)sdrplay_api_AgcT.decay_delay_ms$VH.get(seg); + } + public static void decay_delay_ms$set( MemorySegment seg, short x) { + sdrplay_api_AgcT.decay_delay_ms$VH.set(seg, x); + } + public static short decay_delay_ms$get(MemorySegment seg, long index) { + return (short)sdrplay_api_AgcT.decay_delay_ms$VH.get(seg.asSlice(index*sizeof())); + } + public static void decay_delay_ms$set(MemorySegment seg, long index, short x) { + sdrplay_api_AgcT.decay_delay_ms$VH.set(seg.asSlice(index*sizeof()), x); + } + static final VarHandle decay_threshold_dB$VH = $struct$LAYOUT.varHandle(MemoryLayout.PathElement.groupElement("decay_threshold_dB")); + public static VarHandle decay_threshold_dB$VH() { + return sdrplay_api_AgcT.decay_threshold_dB$VH; + } + public static short decay_threshold_dB$get(MemorySegment seg) { + return (short)sdrplay_api_AgcT.decay_threshold_dB$VH.get(seg); + } + public static void decay_threshold_dB$set( MemorySegment seg, short x) { + sdrplay_api_AgcT.decay_threshold_dB$VH.set(seg, x); + } + public static short decay_threshold_dB$get(MemorySegment seg, long index) { + return (short)sdrplay_api_AgcT.decay_threshold_dB$VH.get(seg.asSlice(index*sizeof())); + } + public static void decay_threshold_dB$set(MemorySegment seg, long index, short x) { + sdrplay_api_AgcT.decay_threshold_dB$VH.set(seg.asSlice(index*sizeof()), x); + } + static final VarHandle syncUpdate$VH = $struct$LAYOUT.varHandle(MemoryLayout.PathElement.groupElement("syncUpdate")); + public static VarHandle syncUpdate$VH() { + return sdrplay_api_AgcT.syncUpdate$VH; + } + public static int syncUpdate$get(MemorySegment seg) { + return (int)sdrplay_api_AgcT.syncUpdate$VH.get(seg); + } + public static void syncUpdate$set( MemorySegment seg, int x) { + sdrplay_api_AgcT.syncUpdate$VH.set(seg, x); + } + public static int syncUpdate$get(MemorySegment seg, long index) { + return (int)sdrplay_api_AgcT.syncUpdate$VH.get(seg.asSlice(index*sizeof())); + } + public static void syncUpdate$set(MemorySegment seg, long index, int x) { + sdrplay_api_AgcT.syncUpdate$VH.set(seg.asSlice(index*sizeof()), x); + } + public static long sizeof() { return $LAYOUT().byteSize(); } + public static MemorySegment allocate(SegmentAllocator allocator) { return allocator.allocate($LAYOUT()); } + public static MemorySegment allocateArray(int len, SegmentAllocator allocator) { + return allocator.allocate(MemoryLayout.sequenceLayout(len, $LAYOUT())); + } + public static MemorySegment ofAddress(MemoryAddress addr, MemorySession session) { return RuntimeHelper.asArray(addr, $LAYOUT(), 1, session); } +} + + diff --git a/sdrplay-api/src/main/java/com/github/dsheirer/sdrplay/api/v3_08/sdrplay_api_ApiVersion_t.java b/sdrplay-api/src/main/java/com/github/dsheirer/sdrplay/api/v3_08/sdrplay_api_ApiVersion_t.java new file mode 100644 index 000000000..53b4cd921 --- /dev/null +++ b/sdrplay-api/src/main/java/com/github/dsheirer/sdrplay/api/v3_08/sdrplay_api_ApiVersion_t.java @@ -0,0 +1,27 @@ +// Generated by jextract + +package com.github.dsheirer.sdrplay.api.v3_08; + +import java.lang.foreign.Addressable; +import java.lang.foreign.MemoryAddress; +import java.lang.foreign.MemorySegment; +import java.lang.foreign.MemorySession; +public interface sdrplay_api_ApiVersion_t { + + int apply(java.lang.foreign.MemoryAddress apiVer); + static MemorySegment allocate(sdrplay_api_ApiVersion_t fi, MemorySession session) { + return RuntimeHelper.upcallStub(sdrplay_api_ApiVersion_t.class, fi, constants$1.sdrplay_api_ApiVersion_t$FUNC, session); + } + static sdrplay_api_ApiVersion_t ofAddress(MemoryAddress addr, MemorySession session) { + MemorySegment symbol = MemorySegment.ofAddress(addr, 0, session); + return (java.lang.foreign.MemoryAddress _apiVer) -> { + try { + return (int)constants$1.sdrplay_api_ApiVersion_t$MH.invokeExact((Addressable)symbol, (java.lang.foreign.Addressable)_apiVer); + } catch (Throwable ex$) { + throw new AssertionError("should not reach here", ex$); + } + }; + } +} + + diff --git a/sdrplay-api/src/main/java/com/github/dsheirer/sdrplay/api/v3_08/sdrplay_api_CallbackFnsT.java b/sdrplay-api/src/main/java/com/github/dsheirer/sdrplay/api/v3_08/sdrplay_api_CallbackFnsT.java new file mode 100644 index 000000000..caeceea40 --- /dev/null +++ b/sdrplay-api/src/main/java/com/github/dsheirer/sdrplay/api/v3_08/sdrplay_api_CallbackFnsT.java @@ -0,0 +1,87 @@ +// Generated by jextract + +package com.github.dsheirer.sdrplay.api.v3_08; + +import java.lang.foreign.GroupLayout; +import java.lang.foreign.MemoryAddress; +import java.lang.foreign.MemoryLayout; +import java.lang.foreign.MemorySegment; +import java.lang.foreign.MemorySession; +import java.lang.foreign.SegmentAllocator; +import java.lang.invoke.VarHandle; +public class sdrplay_api_CallbackFnsT { + + static final GroupLayout $struct$LAYOUT = MemoryLayout.structLayout( + Constants$root.C_POINTER$LAYOUT.withName("StreamACbFn"), + Constants$root.C_POINTER$LAYOUT.withName("StreamBCbFn"), + Constants$root.C_POINTER$LAYOUT.withName("EventCbFn") + ); + public static MemoryLayout $LAYOUT() { + return sdrplay_api_CallbackFnsT.$struct$LAYOUT; + } + static final VarHandle StreamACbFn$VH = $struct$LAYOUT.varHandle(MemoryLayout.PathElement.groupElement("StreamACbFn")); + public static VarHandle StreamACbFn$VH() { + return sdrplay_api_CallbackFnsT.StreamACbFn$VH; + } + public static MemoryAddress StreamACbFn$get(MemorySegment seg) { + return (java.lang.foreign.MemoryAddress)sdrplay_api_CallbackFnsT.StreamACbFn$VH.get(seg); + } + public static void StreamACbFn$set( MemorySegment seg, MemoryAddress x) { + sdrplay_api_CallbackFnsT.StreamACbFn$VH.set(seg, x); + } + public static MemoryAddress StreamACbFn$get(MemorySegment seg, long index) { + return (java.lang.foreign.MemoryAddress)sdrplay_api_CallbackFnsT.StreamACbFn$VH.get(seg.asSlice(index*sizeof())); + } + public static void StreamACbFn$set(MemorySegment seg, long index, MemoryAddress x) { + sdrplay_api_CallbackFnsT.StreamACbFn$VH.set(seg.asSlice(index*sizeof()), x); + } + public static sdrplay_api_StreamCallback_t StreamACbFn (MemorySegment segment, MemorySession session) { + return sdrplay_api_StreamCallback_t.ofAddress(StreamACbFn$get(segment), session); + } + static final VarHandle StreamBCbFn$VH = $struct$LAYOUT.varHandle(MemoryLayout.PathElement.groupElement("StreamBCbFn")); + public static VarHandle StreamBCbFn$VH() { + return sdrplay_api_CallbackFnsT.StreamBCbFn$VH; + } + public static MemoryAddress StreamBCbFn$get(MemorySegment seg) { + return (java.lang.foreign.MemoryAddress)sdrplay_api_CallbackFnsT.StreamBCbFn$VH.get(seg); + } + public static void StreamBCbFn$set( MemorySegment seg, MemoryAddress x) { + sdrplay_api_CallbackFnsT.StreamBCbFn$VH.set(seg, x); + } + public static MemoryAddress StreamBCbFn$get(MemorySegment seg, long index) { + return (java.lang.foreign.MemoryAddress)sdrplay_api_CallbackFnsT.StreamBCbFn$VH.get(seg.asSlice(index*sizeof())); + } + public static void StreamBCbFn$set(MemorySegment seg, long index, MemoryAddress x) { + sdrplay_api_CallbackFnsT.StreamBCbFn$VH.set(seg.asSlice(index*sizeof()), x); + } + public static sdrplay_api_StreamCallback_t StreamBCbFn (MemorySegment segment, MemorySession session) { + return sdrplay_api_StreamCallback_t.ofAddress(StreamBCbFn$get(segment), session); + } + static final VarHandle EventCbFn$VH = $struct$LAYOUT.varHandle(MemoryLayout.PathElement.groupElement("EventCbFn")); + public static VarHandle EventCbFn$VH() { + return sdrplay_api_CallbackFnsT.EventCbFn$VH; + } + public static MemoryAddress EventCbFn$get(MemorySegment seg) { + return (java.lang.foreign.MemoryAddress)sdrplay_api_CallbackFnsT.EventCbFn$VH.get(seg); + } + public static void EventCbFn$set( MemorySegment seg, MemoryAddress x) { + sdrplay_api_CallbackFnsT.EventCbFn$VH.set(seg, x); + } + public static MemoryAddress EventCbFn$get(MemorySegment seg, long index) { + return (java.lang.foreign.MemoryAddress)sdrplay_api_CallbackFnsT.EventCbFn$VH.get(seg.asSlice(index*sizeof())); + } + public static void EventCbFn$set(MemorySegment seg, long index, MemoryAddress x) { + sdrplay_api_CallbackFnsT.EventCbFn$VH.set(seg.asSlice(index*sizeof()), x); + } + public static sdrplay_api_EventCallback_t EventCbFn (MemorySegment segment, MemorySession session) { + return sdrplay_api_EventCallback_t.ofAddress(EventCbFn$get(segment), session); + } + public static long sizeof() { return $LAYOUT().byteSize(); } + public static MemorySegment allocate(SegmentAllocator allocator) { return allocator.allocate($LAYOUT()); } + public static MemorySegment allocateArray(int len, SegmentAllocator allocator) { + return allocator.allocate(MemoryLayout.sequenceLayout(len, $LAYOUT())); + } + public static MemorySegment ofAddress(MemoryAddress addr, MemorySession session) { return RuntimeHelper.asArray(addr, $LAYOUT(), 1, session); } +} + + diff --git a/sdrplay-api/src/main/java/com/github/dsheirer/sdrplay/api/v3_08/sdrplay_api_Close_t.java b/sdrplay-api/src/main/java/com/github/dsheirer/sdrplay/api/v3_08/sdrplay_api_Close_t.java new file mode 100644 index 000000000..776889103 --- /dev/null +++ b/sdrplay-api/src/main/java/com/github/dsheirer/sdrplay/api/v3_08/sdrplay_api_Close_t.java @@ -0,0 +1,27 @@ +// Generated by jextract + +package com.github.dsheirer.sdrplay.api.v3_08; + +import java.lang.foreign.Addressable; +import java.lang.foreign.MemoryAddress; +import java.lang.foreign.MemorySegment; +import java.lang.foreign.MemorySession; +public interface sdrplay_api_Close_t { + + int apply(); + static MemorySegment allocate(sdrplay_api_Close_t fi, MemorySession session) { + return RuntimeHelper.upcallStub(sdrplay_api_Close_t.class, fi, constants$1.sdrplay_api_Close_t$FUNC, session); + } + static sdrplay_api_Close_t ofAddress(MemoryAddress addr, MemorySession session) { + MemorySegment symbol = MemorySegment.ofAddress(addr, 0, session); + return () -> { + try { + return (int)constants$1.sdrplay_api_Close_t$MH.invokeExact((Addressable)symbol); + } catch (Throwable ex$) { + throw new AssertionError("should not reach here", ex$); + } + }; + } +} + + diff --git a/sdrplay-api/src/main/java/com/github/dsheirer/sdrplay/api/v3_08/sdrplay_api_ControlParamsT.java b/sdrplay-api/src/main/java/com/github/dsheirer/sdrplay/api/v3_08/sdrplay_api_ControlParamsT.java new file mode 100644 index 000000000..74c8e4047 --- /dev/null +++ b/sdrplay-api/src/main/java/com/github/dsheirer/sdrplay/api/v3_08/sdrplay_api_ControlParamsT.java @@ -0,0 +1,72 @@ +// Generated by jextract + +package com.github.dsheirer.sdrplay.api.v3_08; + +import java.lang.foreign.GroupLayout; +import java.lang.foreign.MemoryAddress; +import java.lang.foreign.MemoryLayout; +import java.lang.foreign.MemorySegment; +import java.lang.foreign.MemorySession; +import java.lang.foreign.SegmentAllocator; +import java.lang.invoke.VarHandle; +public class sdrplay_api_ControlParamsT { + + static final GroupLayout $struct$LAYOUT = MemoryLayout.structLayout( + MemoryLayout.structLayout( + Constants$root.C_CHAR$LAYOUT.withName("DCenable"), + Constants$root.C_CHAR$LAYOUT.withName("IQenable") + ).withName("dcOffset"), + MemoryLayout.structLayout( + Constants$root.C_CHAR$LAYOUT.withName("enable"), + Constants$root.C_CHAR$LAYOUT.withName("decimationFactor"), + Constants$root.C_CHAR$LAYOUT.withName("wideBandSignal") + ).withName("decimation"), + MemoryLayout.paddingLayout(24), + MemoryLayout.structLayout( + Constants$root.C_LONG$LAYOUT.withName("enable"), + Constants$root.C_LONG$LAYOUT.withName("setPoint_dBfs"), + Constants$root.C_SHORT$LAYOUT.withName("attack_ms"), + Constants$root.C_SHORT$LAYOUT.withName("decay_ms"), + Constants$root.C_SHORT$LAYOUT.withName("decay_delay_ms"), + Constants$root.C_SHORT$LAYOUT.withName("decay_threshold_dB"), + Constants$root.C_LONG$LAYOUT.withName("syncUpdate") + ).withName("agc"), + Constants$root.C_LONG$LAYOUT.withName("adsbMode") + ); + public static MemoryLayout $LAYOUT() { + return sdrplay_api_ControlParamsT.$struct$LAYOUT; + } + public static MemorySegment dcOffset$slice(MemorySegment seg) { + return seg.asSlice(0, 2); + } + public static MemorySegment decimation$slice(MemorySegment seg) { + return seg.asSlice(2, 3); + } + public static MemorySegment agc$slice(MemorySegment seg) { + return seg.asSlice(8, 20); + } + static final VarHandle adsbMode$VH = $struct$LAYOUT.varHandle(MemoryLayout.PathElement.groupElement("adsbMode")); + public static VarHandle adsbMode$VH() { + return sdrplay_api_ControlParamsT.adsbMode$VH; + } + public static int adsbMode$get(MemorySegment seg) { + return (int)sdrplay_api_ControlParamsT.adsbMode$VH.get(seg); + } + public static void adsbMode$set( MemorySegment seg, int x) { + sdrplay_api_ControlParamsT.adsbMode$VH.set(seg, x); + } + public static int adsbMode$get(MemorySegment seg, long index) { + return (int)sdrplay_api_ControlParamsT.adsbMode$VH.get(seg.asSlice(index*sizeof())); + } + public static void adsbMode$set(MemorySegment seg, long index, int x) { + sdrplay_api_ControlParamsT.adsbMode$VH.set(seg.asSlice(index*sizeof()), x); + } + public static long sizeof() { return $LAYOUT().byteSize(); } + public static MemorySegment allocate(SegmentAllocator allocator) { return allocator.allocate($LAYOUT()); } + public static MemorySegment allocateArray(int len, SegmentAllocator allocator) { + return allocator.allocate(MemoryLayout.sequenceLayout(len, $LAYOUT())); + } + public static MemorySegment ofAddress(MemoryAddress addr, MemorySession session) { return RuntimeHelper.asArray(addr, $LAYOUT(), 1, session); } +} + + diff --git a/sdrplay-api/src/main/java/com/github/dsheirer/sdrplay/api/v3_08/sdrplay_api_DcOffsetT.java b/sdrplay-api/src/main/java/com/github/dsheirer/sdrplay/api/v3_08/sdrplay_api_DcOffsetT.java new file mode 100644 index 000000000..0b4565a03 --- /dev/null +++ b/sdrplay-api/src/main/java/com/github/dsheirer/sdrplay/api/v3_08/sdrplay_api_DcOffsetT.java @@ -0,0 +1,61 @@ +// Generated by jextract + +package com.github.dsheirer.sdrplay.api.v3_08; + +import java.lang.foreign.GroupLayout; +import java.lang.foreign.MemoryAddress; +import java.lang.foreign.MemoryLayout; +import java.lang.foreign.MemorySegment; +import java.lang.foreign.MemorySession; +import java.lang.foreign.SegmentAllocator; +import java.lang.invoke.VarHandle; +public class sdrplay_api_DcOffsetT { + + static final GroupLayout $struct$LAYOUT = MemoryLayout.structLayout( + Constants$root.C_CHAR$LAYOUT.withName("DCenable"), + Constants$root.C_CHAR$LAYOUT.withName("IQenable") + ); + public static MemoryLayout $LAYOUT() { + return sdrplay_api_DcOffsetT.$struct$LAYOUT; + } + static final VarHandle DCenable$VH = $struct$LAYOUT.varHandle(MemoryLayout.PathElement.groupElement("DCenable")); + public static VarHandle DCenable$VH() { + return sdrplay_api_DcOffsetT.DCenable$VH; + } + public static byte DCenable$get(MemorySegment seg) { + return (byte)sdrplay_api_DcOffsetT.DCenable$VH.get(seg); + } + public static void DCenable$set( MemorySegment seg, byte x) { + sdrplay_api_DcOffsetT.DCenable$VH.set(seg, x); + } + public static byte DCenable$get(MemorySegment seg, long index) { + return (byte)sdrplay_api_DcOffsetT.DCenable$VH.get(seg.asSlice(index*sizeof())); + } + public static void DCenable$set(MemorySegment seg, long index, byte x) { + sdrplay_api_DcOffsetT.DCenable$VH.set(seg.asSlice(index*sizeof()), x); + } + static final VarHandle IQenable$VH = $struct$LAYOUT.varHandle(MemoryLayout.PathElement.groupElement("IQenable")); + public static VarHandle IQenable$VH() { + return sdrplay_api_DcOffsetT.IQenable$VH; + } + public static byte IQenable$get(MemorySegment seg) { + return (byte)sdrplay_api_DcOffsetT.IQenable$VH.get(seg); + } + public static void IQenable$set( MemorySegment seg, byte x) { + sdrplay_api_DcOffsetT.IQenable$VH.set(seg, x); + } + public static byte IQenable$get(MemorySegment seg, long index) { + return (byte)sdrplay_api_DcOffsetT.IQenable$VH.get(seg.asSlice(index*sizeof())); + } + public static void IQenable$set(MemorySegment seg, long index, byte x) { + sdrplay_api_DcOffsetT.IQenable$VH.set(seg.asSlice(index*sizeof()), x); + } + public static long sizeof() { return $LAYOUT().byteSize(); } + public static MemorySegment allocate(SegmentAllocator allocator) { return allocator.allocate($LAYOUT()); } + public static MemorySegment allocateArray(int len, SegmentAllocator allocator) { + return allocator.allocate(MemoryLayout.sequenceLayout(len, $LAYOUT())); + } + public static MemorySegment ofAddress(MemoryAddress addr, MemorySession session) { return RuntimeHelper.asArray(addr, $LAYOUT(), 1, session); } +} + + diff --git a/sdrplay-api/src/main/java/com/github/dsheirer/sdrplay/api/v3_08/sdrplay_api_DcOffsetTunerT.java b/sdrplay-api/src/main/java/com/github/dsheirer/sdrplay/api/v3_08/sdrplay_api_DcOffsetTunerT.java new file mode 100644 index 000000000..eeb25400d --- /dev/null +++ b/sdrplay-api/src/main/java/com/github/dsheirer/sdrplay/api/v3_08/sdrplay_api_DcOffsetTunerT.java @@ -0,0 +1,96 @@ +// Generated by jextract + +package com.github.dsheirer.sdrplay.api.v3_08; + +import java.lang.foreign.GroupLayout; +import java.lang.foreign.MemoryAddress; +import java.lang.foreign.MemoryLayout; +import java.lang.foreign.MemorySegment; +import java.lang.foreign.MemorySession; +import java.lang.foreign.SegmentAllocator; +import java.lang.invoke.VarHandle; +public class sdrplay_api_DcOffsetTunerT { + + static final GroupLayout $struct$LAYOUT = MemoryLayout.structLayout( + Constants$root.C_CHAR$LAYOUT.withName("dcCal"), + Constants$root.C_CHAR$LAYOUT.withName("speedUp"), + MemoryLayout.paddingLayout(16), + Constants$root.C_LONG$LAYOUT.withName("trackTime"), + Constants$root.C_LONG$LAYOUT.withName("refreshRateTime") + ); + public static MemoryLayout $LAYOUT() { + return sdrplay_api_DcOffsetTunerT.$struct$LAYOUT; + } + static final VarHandle dcCal$VH = $struct$LAYOUT.varHandle(MemoryLayout.PathElement.groupElement("dcCal")); + public static VarHandle dcCal$VH() { + return sdrplay_api_DcOffsetTunerT.dcCal$VH; + } + public static byte dcCal$get(MemorySegment seg) { + return (byte)sdrplay_api_DcOffsetTunerT.dcCal$VH.get(seg); + } + public static void dcCal$set( MemorySegment seg, byte x) { + sdrplay_api_DcOffsetTunerT.dcCal$VH.set(seg, x); + } + public static byte dcCal$get(MemorySegment seg, long index) { + return (byte)sdrplay_api_DcOffsetTunerT.dcCal$VH.get(seg.asSlice(index*sizeof())); + } + public static void dcCal$set(MemorySegment seg, long index, byte x) { + sdrplay_api_DcOffsetTunerT.dcCal$VH.set(seg.asSlice(index*sizeof()), x); + } + static final VarHandle speedUp$VH = $struct$LAYOUT.varHandle(MemoryLayout.PathElement.groupElement("speedUp")); + public static VarHandle speedUp$VH() { + return sdrplay_api_DcOffsetTunerT.speedUp$VH; + } + public static byte speedUp$get(MemorySegment seg) { + return (byte)sdrplay_api_DcOffsetTunerT.speedUp$VH.get(seg); + } + public static void speedUp$set( MemorySegment seg, byte x) { + sdrplay_api_DcOffsetTunerT.speedUp$VH.set(seg, x); + } + public static byte speedUp$get(MemorySegment seg, long index) { + return (byte)sdrplay_api_DcOffsetTunerT.speedUp$VH.get(seg.asSlice(index*sizeof())); + } + public static void speedUp$set(MemorySegment seg, long index, byte x) { + sdrplay_api_DcOffsetTunerT.speedUp$VH.set(seg.asSlice(index*sizeof()), x); + } + static final VarHandle trackTime$VH = $struct$LAYOUT.varHandle(MemoryLayout.PathElement.groupElement("trackTime")); + public static VarHandle trackTime$VH() { + return sdrplay_api_DcOffsetTunerT.trackTime$VH; + } + public static int trackTime$get(MemorySegment seg) { + return (int)sdrplay_api_DcOffsetTunerT.trackTime$VH.get(seg); + } + public static void trackTime$set( MemorySegment seg, int x) { + sdrplay_api_DcOffsetTunerT.trackTime$VH.set(seg, x); + } + public static int trackTime$get(MemorySegment seg, long index) { + return (int)sdrplay_api_DcOffsetTunerT.trackTime$VH.get(seg.asSlice(index*sizeof())); + } + public static void trackTime$set(MemorySegment seg, long index, int x) { + sdrplay_api_DcOffsetTunerT.trackTime$VH.set(seg.asSlice(index*sizeof()), x); + } + static final VarHandle refreshRateTime$VH = $struct$LAYOUT.varHandle(MemoryLayout.PathElement.groupElement("refreshRateTime")); + public static VarHandle refreshRateTime$VH() { + return sdrplay_api_DcOffsetTunerT.refreshRateTime$VH; + } + public static int refreshRateTime$get(MemorySegment seg) { + return (int)sdrplay_api_DcOffsetTunerT.refreshRateTime$VH.get(seg); + } + public static void refreshRateTime$set( MemorySegment seg, int x) { + sdrplay_api_DcOffsetTunerT.refreshRateTime$VH.set(seg, x); + } + public static int refreshRateTime$get(MemorySegment seg, long index) { + return (int)sdrplay_api_DcOffsetTunerT.refreshRateTime$VH.get(seg.asSlice(index*sizeof())); + } + public static void refreshRateTime$set(MemorySegment seg, long index, int x) { + sdrplay_api_DcOffsetTunerT.refreshRateTime$VH.set(seg.asSlice(index*sizeof()), x); + } + public static long sizeof() { return $LAYOUT().byteSize(); } + public static MemorySegment allocate(SegmentAllocator allocator) { return allocator.allocate($LAYOUT()); } + public static MemorySegment allocateArray(int len, SegmentAllocator allocator) { + return allocator.allocate(MemoryLayout.sequenceLayout(len, $LAYOUT())); + } + public static MemorySegment ofAddress(MemoryAddress addr, MemorySession session) { return RuntimeHelper.asArray(addr, $LAYOUT(), 1, session); } +} + + diff --git a/sdrplay-api/src/main/java/com/github/dsheirer/sdrplay/api/v3_08/sdrplay_api_DebugEnable_t.java b/sdrplay-api/src/main/java/com/github/dsheirer/sdrplay/api/v3_08/sdrplay_api_DebugEnable_t.java new file mode 100644 index 000000000..b5ec4cd7c --- /dev/null +++ b/sdrplay-api/src/main/java/com/github/dsheirer/sdrplay/api/v3_08/sdrplay_api_DebugEnable_t.java @@ -0,0 +1,27 @@ +// Generated by jextract + +package com.github.dsheirer.sdrplay.api.v3_08; + +import java.lang.foreign.Addressable; +import java.lang.foreign.MemoryAddress; +import java.lang.foreign.MemorySegment; +import java.lang.foreign.MemorySession; +public interface sdrplay_api_DebugEnable_t { + + int apply(java.lang.foreign.MemoryAddress dev, int dbgLvl); + static MemorySegment allocate(sdrplay_api_DebugEnable_t fi, MemorySession session) { + return RuntimeHelper.upcallStub(sdrplay_api_DebugEnable_t.class, fi, constants$4.sdrplay_api_DebugEnable_t$FUNC, session); + } + static sdrplay_api_DebugEnable_t ofAddress(MemoryAddress addr, MemorySession session) { + MemorySegment symbol = MemorySegment.ofAddress(addr, 0, session); + return (java.lang.foreign.MemoryAddress _dev, int _dbgLvl) -> { + try { + return (int)constants$4.sdrplay_api_DebugEnable_t$MH.invokeExact((Addressable)symbol, (java.lang.foreign.Addressable)_dev, _dbgLvl); + } catch (Throwable ex$) { + throw new AssertionError("should not reach here", ex$); + } + }; + } +} + + diff --git a/sdrplay-api/src/main/java/com/github/dsheirer/sdrplay/api/v3_08/sdrplay_api_DecimationT.java b/sdrplay-api/src/main/java/com/github/dsheirer/sdrplay/api/v3_08/sdrplay_api_DecimationT.java new file mode 100644 index 000000000..8d8fe1c81 --- /dev/null +++ b/sdrplay-api/src/main/java/com/github/dsheirer/sdrplay/api/v3_08/sdrplay_api_DecimationT.java @@ -0,0 +1,78 @@ +// Generated by jextract + +package com.github.dsheirer.sdrplay.api.v3_08; + +import java.lang.foreign.GroupLayout; +import java.lang.foreign.MemoryAddress; +import java.lang.foreign.MemoryLayout; +import java.lang.foreign.MemorySegment; +import java.lang.foreign.MemorySession; +import java.lang.foreign.SegmentAllocator; +import java.lang.invoke.VarHandle; +public class sdrplay_api_DecimationT { + + static final GroupLayout $struct$LAYOUT = MemoryLayout.structLayout( + Constants$root.C_CHAR$LAYOUT.withName("enable"), + Constants$root.C_CHAR$LAYOUT.withName("decimationFactor"), + Constants$root.C_CHAR$LAYOUT.withName("wideBandSignal") + ); + public static MemoryLayout $LAYOUT() { + return sdrplay_api_DecimationT.$struct$LAYOUT; + } + static final VarHandle enable$VH = $struct$LAYOUT.varHandle(MemoryLayout.PathElement.groupElement("enable")); + public static VarHandle enable$VH() { + return sdrplay_api_DecimationT.enable$VH; + } + public static byte enable$get(MemorySegment seg) { + return (byte)sdrplay_api_DecimationT.enable$VH.get(seg); + } + public static void enable$set( MemorySegment seg, byte x) { + sdrplay_api_DecimationT.enable$VH.set(seg, x); + } + public static byte enable$get(MemorySegment seg, long index) { + return (byte)sdrplay_api_DecimationT.enable$VH.get(seg.asSlice(index*sizeof())); + } + public static void enable$set(MemorySegment seg, long index, byte x) { + sdrplay_api_DecimationT.enable$VH.set(seg.asSlice(index*sizeof()), x); + } + static final VarHandle decimationFactor$VH = $struct$LAYOUT.varHandle(MemoryLayout.PathElement.groupElement("decimationFactor")); + public static VarHandle decimationFactor$VH() { + return sdrplay_api_DecimationT.decimationFactor$VH; + } + public static byte decimationFactor$get(MemorySegment seg) { + return (byte)sdrplay_api_DecimationT.decimationFactor$VH.get(seg); + } + public static void decimationFactor$set( MemorySegment seg, byte x) { + sdrplay_api_DecimationT.decimationFactor$VH.set(seg, x); + } + public static byte decimationFactor$get(MemorySegment seg, long index) { + return (byte)sdrplay_api_DecimationT.decimationFactor$VH.get(seg.asSlice(index*sizeof())); + } + public static void decimationFactor$set(MemorySegment seg, long index, byte x) { + sdrplay_api_DecimationT.decimationFactor$VH.set(seg.asSlice(index*sizeof()), x); + } + static final VarHandle wideBandSignal$VH = $struct$LAYOUT.varHandle(MemoryLayout.PathElement.groupElement("wideBandSignal")); + public static VarHandle wideBandSignal$VH() { + return sdrplay_api_DecimationT.wideBandSignal$VH; + } + public static byte wideBandSignal$get(MemorySegment seg) { + return (byte)sdrplay_api_DecimationT.wideBandSignal$VH.get(seg); + } + public static void wideBandSignal$set( MemorySegment seg, byte x) { + sdrplay_api_DecimationT.wideBandSignal$VH.set(seg, x); + } + public static byte wideBandSignal$get(MemorySegment seg, long index) { + return (byte)sdrplay_api_DecimationT.wideBandSignal$VH.get(seg.asSlice(index*sizeof())); + } + public static void wideBandSignal$set(MemorySegment seg, long index, byte x) { + sdrplay_api_DecimationT.wideBandSignal$VH.set(seg.asSlice(index*sizeof()), x); + } + public static long sizeof() { return $LAYOUT().byteSize(); } + public static MemorySegment allocate(SegmentAllocator allocator) { return allocator.allocate($LAYOUT()); } + public static MemorySegment allocateArray(int len, SegmentAllocator allocator) { + return allocator.allocate(MemoryLayout.sequenceLayout(len, $LAYOUT())); + } + public static MemorySegment ofAddress(MemoryAddress addr, MemorySession session) { return RuntimeHelper.asArray(addr, $LAYOUT(), 1, session); } +} + + diff --git a/sdrplay-api/src/main/java/com/github/dsheirer/sdrplay/api/v3_08/sdrplay_api_DevParamsT.java b/sdrplay-api/src/main/java/com/github/dsheirer/sdrplay/api/v3_08/sdrplay_api_DevParamsT.java new file mode 100644 index 000000000..0424f37b7 --- /dev/null +++ b/sdrplay-api/src/main/java/com/github/dsheirer/sdrplay/api/v3_08/sdrplay_api_DevParamsT.java @@ -0,0 +1,135 @@ +// Generated by jextract + +package com.github.dsheirer.sdrplay.api.v3_08; + +import java.lang.foreign.GroupLayout; +import java.lang.foreign.MemoryAddress; +import java.lang.foreign.MemoryLayout; +import java.lang.foreign.MemorySegment; +import java.lang.foreign.MemorySession; +import java.lang.foreign.SegmentAllocator; +import java.lang.invoke.VarHandle; +public class sdrplay_api_DevParamsT { + + static final GroupLayout $struct$LAYOUT = MemoryLayout.structLayout( + Constants$root.C_DOUBLE$LAYOUT.withName("ppm"), + MemoryLayout.structLayout( + Constants$root.C_DOUBLE$LAYOUT.withName("fsHz"), + Constants$root.C_CHAR$LAYOUT.withName("syncUpdate"), + Constants$root.C_CHAR$LAYOUT.withName("reCal"), + MemoryLayout.paddingLayout(48) + ).withName("fsFreq"), + MemoryLayout.structLayout( + Constants$root.C_LONG$LAYOUT.withName("sampleNum"), + Constants$root.C_LONG$LAYOUT.withName("period") + ).withName("syncUpdate"), + MemoryLayout.structLayout( + Constants$root.C_CHAR$LAYOUT.withName("resetGainUpdate"), + Constants$root.C_CHAR$LAYOUT.withName("resetRfUpdate"), + Constants$root.C_CHAR$LAYOUT.withName("resetFsUpdate") + ).withName("resetFlags"), + MemoryLayout.paddingLayout(8), + Constants$root.C_LONG$LAYOUT.withName("mode"), + Constants$root.C_LONG$LAYOUT.withName("samplesPerPkt"), + MemoryLayout.structLayout( + Constants$root.C_CHAR$LAYOUT.withName("rfNotchEnable"), + Constants$root.C_CHAR$LAYOUT.withName("rfDabNotchEnable") + ).withName("rsp1aParams"), + MemoryLayout.structLayout( + Constants$root.C_CHAR$LAYOUT.withName("extRefOutputEn") + ).withName("rsp2Params"), + MemoryLayout.paddingLayout(8), + MemoryLayout.structLayout( + Constants$root.C_LONG$LAYOUT.withName("extRefOutputEn") + ).withName("rspDuoParams"), + MemoryLayout.structLayout( + Constants$root.C_CHAR$LAYOUT.withName("hdrEnable"), + Constants$root.C_CHAR$LAYOUT.withName("biasTEnable"), + MemoryLayout.paddingLayout(16), + Constants$root.C_LONG$LAYOUT.withName("antennaSel"), + Constants$root.C_CHAR$LAYOUT.withName("rfNotchEnable"), + Constants$root.C_CHAR$LAYOUT.withName("rfDabNotchEnable"), + MemoryLayout.paddingLayout(16) + ).withName("rspDxParams") + ); + public static MemoryLayout $LAYOUT() { + return sdrplay_api_DevParamsT.$struct$LAYOUT; + } + static final VarHandle ppm$VH = $struct$LAYOUT.varHandle(MemoryLayout.PathElement.groupElement("ppm")); + public static VarHandle ppm$VH() { + return sdrplay_api_DevParamsT.ppm$VH; + } + public static double ppm$get(MemorySegment seg) { + return (double)sdrplay_api_DevParamsT.ppm$VH.get(seg); + } + public static void ppm$set( MemorySegment seg, double x) { + sdrplay_api_DevParamsT.ppm$VH.set(seg, x); + } + public static double ppm$get(MemorySegment seg, long index) { + return (double)sdrplay_api_DevParamsT.ppm$VH.get(seg.asSlice(index*sizeof())); + } + public static void ppm$set(MemorySegment seg, long index, double x) { + sdrplay_api_DevParamsT.ppm$VH.set(seg.asSlice(index*sizeof()), x); + } + public static MemorySegment fsFreq$slice(MemorySegment seg) { + return seg.asSlice(8, 16); + } + public static MemorySegment syncUpdate$slice(MemorySegment seg) { + return seg.asSlice(24, 8); + } + public static MemorySegment resetFlags$slice(MemorySegment seg) { + return seg.asSlice(32, 3); + } + static final VarHandle mode$VH = $struct$LAYOUT.varHandle(MemoryLayout.PathElement.groupElement("mode")); + public static VarHandle mode$VH() { + return sdrplay_api_DevParamsT.mode$VH; + } + public static int mode$get(MemorySegment seg) { + return (int)sdrplay_api_DevParamsT.mode$VH.get(seg); + } + public static void mode$set( MemorySegment seg, int x) { + sdrplay_api_DevParamsT.mode$VH.set(seg, x); + } + public static int mode$get(MemorySegment seg, long index) { + return (int)sdrplay_api_DevParamsT.mode$VH.get(seg.asSlice(index*sizeof())); + } + public static void mode$set(MemorySegment seg, long index, int x) { + sdrplay_api_DevParamsT.mode$VH.set(seg.asSlice(index*sizeof()), x); + } + static final VarHandle samplesPerPkt$VH = $struct$LAYOUT.varHandle(MemoryLayout.PathElement.groupElement("samplesPerPkt")); + public static VarHandle samplesPerPkt$VH() { + return sdrplay_api_DevParamsT.samplesPerPkt$VH; + } + public static int samplesPerPkt$get(MemorySegment seg) { + return (int)sdrplay_api_DevParamsT.samplesPerPkt$VH.get(seg); + } + public static void samplesPerPkt$set( MemorySegment seg, int x) { + sdrplay_api_DevParamsT.samplesPerPkt$VH.set(seg, x); + } + public static int samplesPerPkt$get(MemorySegment seg, long index) { + return (int)sdrplay_api_DevParamsT.samplesPerPkt$VH.get(seg.asSlice(index*sizeof())); + } + public static void samplesPerPkt$set(MemorySegment seg, long index, int x) { + sdrplay_api_DevParamsT.samplesPerPkt$VH.set(seg.asSlice(index*sizeof()), x); + } + public static MemorySegment rsp1aParams$slice(MemorySegment seg) { + return seg.asSlice(44, 2); + } + public static MemorySegment rsp2Params$slice(MemorySegment seg) { + return seg.asSlice(46, 1); + } + public static MemorySegment rspDuoParams$slice(MemorySegment seg) { + return seg.asSlice(48, 4); + } + public static MemorySegment rspDxParams$slice(MemorySegment seg) { + return seg.asSlice(52, 12); + } + public static long sizeof() { return $LAYOUT().byteSize(); } + public static MemorySegment allocate(SegmentAllocator allocator) { return allocator.allocate($LAYOUT()); } + public static MemorySegment allocateArray(int len, SegmentAllocator allocator) { + return allocator.allocate(MemoryLayout.sequenceLayout(len, $LAYOUT())); + } + public static MemorySegment ofAddress(MemoryAddress addr, MemorySession session) { return RuntimeHelper.asArray(addr, $LAYOUT(), 1, session); } +} + + diff --git a/sdrplay-api/src/main/java/com/github/dsheirer/sdrplay/api/v3_08/sdrplay_api_DeviceParamsT.java b/sdrplay-api/src/main/java/com/github/dsheirer/sdrplay/api/v3_08/sdrplay_api_DeviceParamsT.java new file mode 100644 index 000000000..0dbae360d --- /dev/null +++ b/sdrplay-api/src/main/java/com/github/dsheirer/sdrplay/api/v3_08/sdrplay_api_DeviceParamsT.java @@ -0,0 +1,78 @@ +// Generated by jextract + +package com.github.dsheirer.sdrplay.api.v3_08; + +import java.lang.foreign.GroupLayout; +import java.lang.foreign.MemoryAddress; +import java.lang.foreign.MemoryLayout; +import java.lang.foreign.MemorySegment; +import java.lang.foreign.MemorySession; +import java.lang.foreign.SegmentAllocator; +import java.lang.invoke.VarHandle; +public class sdrplay_api_DeviceParamsT { + + static final GroupLayout $struct$LAYOUT = MemoryLayout.structLayout( + Constants$root.C_POINTER$LAYOUT.withName("devParams"), + Constants$root.C_POINTER$LAYOUT.withName("rxChannelA"), + Constants$root.C_POINTER$LAYOUT.withName("rxChannelB") + ); + public static MemoryLayout $LAYOUT() { + return sdrplay_api_DeviceParamsT.$struct$LAYOUT; + } + static final VarHandle devParams$VH = $struct$LAYOUT.varHandle(MemoryLayout.PathElement.groupElement("devParams")); + public static VarHandle devParams$VH() { + return sdrplay_api_DeviceParamsT.devParams$VH; + } + public static MemoryAddress devParams$get(MemorySegment seg) { + return (java.lang.foreign.MemoryAddress)sdrplay_api_DeviceParamsT.devParams$VH.get(seg); + } + public static void devParams$set( MemorySegment seg, MemoryAddress x) { + sdrplay_api_DeviceParamsT.devParams$VH.set(seg, x); + } + public static MemoryAddress devParams$get(MemorySegment seg, long index) { + return (java.lang.foreign.MemoryAddress)sdrplay_api_DeviceParamsT.devParams$VH.get(seg.asSlice(index*sizeof())); + } + public static void devParams$set(MemorySegment seg, long index, MemoryAddress x) { + sdrplay_api_DeviceParamsT.devParams$VH.set(seg.asSlice(index*sizeof()), x); + } + static final VarHandle rxChannelA$VH = $struct$LAYOUT.varHandle(MemoryLayout.PathElement.groupElement("rxChannelA")); + public static VarHandle rxChannelA$VH() { + return sdrplay_api_DeviceParamsT.rxChannelA$VH; + } + public static MemoryAddress rxChannelA$get(MemorySegment seg) { + return (java.lang.foreign.MemoryAddress)sdrplay_api_DeviceParamsT.rxChannelA$VH.get(seg); + } + public static void rxChannelA$set( MemorySegment seg, MemoryAddress x) { + sdrplay_api_DeviceParamsT.rxChannelA$VH.set(seg, x); + } + public static MemoryAddress rxChannelA$get(MemorySegment seg, long index) { + return (java.lang.foreign.MemoryAddress)sdrplay_api_DeviceParamsT.rxChannelA$VH.get(seg.asSlice(index*sizeof())); + } + public static void rxChannelA$set(MemorySegment seg, long index, MemoryAddress x) { + sdrplay_api_DeviceParamsT.rxChannelA$VH.set(seg.asSlice(index*sizeof()), x); + } + static final VarHandle rxChannelB$VH = $struct$LAYOUT.varHandle(MemoryLayout.PathElement.groupElement("rxChannelB")); + public static VarHandle rxChannelB$VH() { + return sdrplay_api_DeviceParamsT.rxChannelB$VH; + } + public static MemoryAddress rxChannelB$get(MemorySegment seg) { + return (java.lang.foreign.MemoryAddress)sdrplay_api_DeviceParamsT.rxChannelB$VH.get(seg); + } + public static void rxChannelB$set( MemorySegment seg, MemoryAddress x) { + sdrplay_api_DeviceParamsT.rxChannelB$VH.set(seg, x); + } + public static MemoryAddress rxChannelB$get(MemorySegment seg, long index) { + return (java.lang.foreign.MemoryAddress)sdrplay_api_DeviceParamsT.rxChannelB$VH.get(seg.asSlice(index*sizeof())); + } + public static void rxChannelB$set(MemorySegment seg, long index, MemoryAddress x) { + sdrplay_api_DeviceParamsT.rxChannelB$VH.set(seg.asSlice(index*sizeof()), x); + } + public static long sizeof() { return $LAYOUT().byteSize(); } + public static MemorySegment allocate(SegmentAllocator allocator) { return allocator.allocate($LAYOUT()); } + public static MemorySegment allocateArray(int len, SegmentAllocator allocator) { + return allocator.allocate(MemoryLayout.sequenceLayout(len, $LAYOUT())); + } + public static MemorySegment ofAddress(MemoryAddress addr, MemorySession session) { return RuntimeHelper.asArray(addr, $LAYOUT(), 1, session); } +} + + diff --git a/sdrplay-api/src/main/java/com/github/dsheirer/sdrplay/api/v3_08/sdrplay_api_DeviceT.java b/sdrplay-api/src/main/java/com/github/dsheirer/sdrplay/api/v3_08/sdrplay_api_DeviceT.java new file mode 100644 index 000000000..e578f52f3 --- /dev/null +++ b/sdrplay-api/src/main/java/com/github/dsheirer/sdrplay/api/v3_08/sdrplay_api_DeviceT.java @@ -0,0 +1,135 @@ +// Generated by jextract + +package com.github.dsheirer.sdrplay.api.v3_08; + +import java.lang.foreign.GroupLayout; +import java.lang.foreign.MemoryAddress; +import java.lang.foreign.MemoryLayout; +import java.lang.foreign.MemorySegment; +import java.lang.foreign.MemorySession; +import java.lang.foreign.SegmentAllocator; +import java.lang.invoke.VarHandle; +public class sdrplay_api_DeviceT { + + static final GroupLayout $struct$LAYOUT = MemoryLayout.structLayout( + MemoryLayout.sequenceLayout(64, Constants$root.C_CHAR$LAYOUT).withName("SerNo"), + Constants$root.C_CHAR$LAYOUT.withName("hwVer"), + MemoryLayout.paddingLayout(24), + Constants$root.C_LONG$LAYOUT.withName("tuner"), + Constants$root.C_LONG$LAYOUT.withName("rspDuoMode"), + Constants$root.C_CHAR$LAYOUT.withName("valid"), + MemoryLayout.paddingLayout(24), + Constants$root.C_DOUBLE$LAYOUT.withName("rspDuoSampleFreq"), + Constants$root.C_POINTER$LAYOUT.withName("dev") + ); + public static MemoryLayout $LAYOUT() { + return sdrplay_api_DeviceT.$struct$LAYOUT; + } + public static MemorySegment SerNo$slice(MemorySegment seg) { + return seg.asSlice(0, 64); + } + static final VarHandle hwVer$VH = $struct$LAYOUT.varHandle(MemoryLayout.PathElement.groupElement("hwVer")); + public static VarHandle hwVer$VH() { + return sdrplay_api_DeviceT.hwVer$VH; + } + public static byte hwVer$get(MemorySegment seg) { + return (byte)sdrplay_api_DeviceT.hwVer$VH.get(seg); + } + public static void hwVer$set( MemorySegment seg, byte x) { + sdrplay_api_DeviceT.hwVer$VH.set(seg, x); + } + public static byte hwVer$get(MemorySegment seg, long index) { + return (byte)sdrplay_api_DeviceT.hwVer$VH.get(seg.asSlice(index*sizeof())); + } + public static void hwVer$set(MemorySegment seg, long index, byte x) { + sdrplay_api_DeviceT.hwVer$VH.set(seg.asSlice(index*sizeof()), x); + } + static final VarHandle tuner$VH = $struct$LAYOUT.varHandle(MemoryLayout.PathElement.groupElement("tuner")); + public static VarHandle tuner$VH() { + return sdrplay_api_DeviceT.tuner$VH; + } + public static int tuner$get(MemorySegment seg) { + return (int)sdrplay_api_DeviceT.tuner$VH.get(seg); + } + public static void tuner$set( MemorySegment seg, int x) { + sdrplay_api_DeviceT.tuner$VH.set(seg, x); + } + public static int tuner$get(MemorySegment seg, long index) { + return (int)sdrplay_api_DeviceT.tuner$VH.get(seg.asSlice(index*sizeof())); + } + public static void tuner$set(MemorySegment seg, long index, int x) { + sdrplay_api_DeviceT.tuner$VH.set(seg.asSlice(index*sizeof()), x); + } + static final VarHandle rspDuoMode$VH = $struct$LAYOUT.varHandle(MemoryLayout.PathElement.groupElement("rspDuoMode")); + public static VarHandle rspDuoMode$VH() { + return sdrplay_api_DeviceT.rspDuoMode$VH; + } + public static int rspDuoMode$get(MemorySegment seg) { + return (int)sdrplay_api_DeviceT.rspDuoMode$VH.get(seg); + } + public static void rspDuoMode$set( MemorySegment seg, int x) { + sdrplay_api_DeviceT.rspDuoMode$VH.set(seg, x); + } + public static int rspDuoMode$get(MemorySegment seg, long index) { + return (int)sdrplay_api_DeviceT.rspDuoMode$VH.get(seg.asSlice(index*sizeof())); + } + public static void rspDuoMode$set(MemorySegment seg, long index, int x) { + sdrplay_api_DeviceT.rspDuoMode$VH.set(seg.asSlice(index*sizeof()), x); + } + static final VarHandle valid$VH = $struct$LAYOUT.varHandle(MemoryLayout.PathElement.groupElement("valid")); + public static VarHandle valid$VH() { + return sdrplay_api_DeviceT.valid$VH; + } + public static byte valid$get(MemorySegment seg) { + return (byte)sdrplay_api_DeviceT.valid$VH.get(seg); + } + public static void valid$set( MemorySegment seg, byte x) { + sdrplay_api_DeviceT.valid$VH.set(seg, x); + } + public static byte valid$get(MemorySegment seg, long index) { + return (byte)sdrplay_api_DeviceT.valid$VH.get(seg.asSlice(index*sizeof())); + } + public static void valid$set(MemorySegment seg, long index, byte x) { + sdrplay_api_DeviceT.valid$VH.set(seg.asSlice(index*sizeof()), x); + } + static final VarHandle rspDuoSampleFreq$VH = $struct$LAYOUT.varHandle(MemoryLayout.PathElement.groupElement("rspDuoSampleFreq")); + public static VarHandle rspDuoSampleFreq$VH() { + return sdrplay_api_DeviceT.rspDuoSampleFreq$VH; + } + public static double rspDuoSampleFreq$get(MemorySegment seg) { + return (double)sdrplay_api_DeviceT.rspDuoSampleFreq$VH.get(seg); + } + public static void rspDuoSampleFreq$set( MemorySegment seg, double x) { + sdrplay_api_DeviceT.rspDuoSampleFreq$VH.set(seg, x); + } + public static double rspDuoSampleFreq$get(MemorySegment seg, long index) { + return (double)sdrplay_api_DeviceT.rspDuoSampleFreq$VH.get(seg.asSlice(index*sizeof())); + } + public static void rspDuoSampleFreq$set(MemorySegment seg, long index, double x) { + sdrplay_api_DeviceT.rspDuoSampleFreq$VH.set(seg.asSlice(index*sizeof()), x); + } + static final VarHandle dev$VH = $struct$LAYOUT.varHandle(MemoryLayout.PathElement.groupElement("dev")); + public static VarHandle dev$VH() { + return sdrplay_api_DeviceT.dev$VH; + } + public static MemoryAddress dev$get(MemorySegment seg) { + return (java.lang.foreign.MemoryAddress)sdrplay_api_DeviceT.dev$VH.get(seg); + } + public static void dev$set( MemorySegment seg, MemoryAddress x) { + sdrplay_api_DeviceT.dev$VH.set(seg, x); + } + public static MemoryAddress dev$get(MemorySegment seg, long index) { + return (java.lang.foreign.MemoryAddress)sdrplay_api_DeviceT.dev$VH.get(seg.asSlice(index*sizeof())); + } + public static void dev$set(MemorySegment seg, long index, MemoryAddress x) { + sdrplay_api_DeviceT.dev$VH.set(seg.asSlice(index*sizeof()), x); + } + public static long sizeof() { return $LAYOUT().byteSize(); } + public static MemorySegment allocate(SegmentAllocator allocator) { return allocator.allocate($LAYOUT()); } + public static MemorySegment allocateArray(int len, SegmentAllocator allocator) { + return allocator.allocate(MemoryLayout.sequenceLayout(len, $LAYOUT())); + } + public static MemorySegment ofAddress(MemoryAddress addr, MemorySession session) { return RuntimeHelper.asArray(addr, $LAYOUT(), 1, session); } +} + + diff --git a/sdrplay-api/src/main/java/com/github/dsheirer/sdrplay/api/v3_08/sdrplay_api_DisableHeartbeat_t.java b/sdrplay-api/src/main/java/com/github/dsheirer/sdrplay/api/v3_08/sdrplay_api_DisableHeartbeat_t.java new file mode 100644 index 000000000..6c3e5bbe1 --- /dev/null +++ b/sdrplay-api/src/main/java/com/github/dsheirer/sdrplay/api/v3_08/sdrplay_api_DisableHeartbeat_t.java @@ -0,0 +1,27 @@ +// Generated by jextract + +package com.github.dsheirer.sdrplay.api.v3_08; + +import java.lang.foreign.Addressable; +import java.lang.foreign.MemoryAddress; +import java.lang.foreign.MemorySegment; +import java.lang.foreign.MemorySession; +public interface sdrplay_api_DisableHeartbeat_t { + + int apply(); + static MemorySegment allocate(sdrplay_api_DisableHeartbeat_t fi, MemorySession session) { + return RuntimeHelper.upcallStub(sdrplay_api_DisableHeartbeat_t.class, fi, constants$4.sdrplay_api_DisableHeartbeat_t$FUNC, session); + } + static sdrplay_api_DisableHeartbeat_t ofAddress(MemoryAddress addr, MemorySession session) { + MemorySegment symbol = MemorySegment.ofAddress(addr, 0, session); + return () -> { + try { + return (int)constants$4.sdrplay_api_DisableHeartbeat_t$MH.invokeExact((Addressable)symbol); + } catch (Throwable ex$) { + throw new AssertionError("should not reach here", ex$); + } + }; + } +} + + diff --git a/sdrplay-api/src/main/java/com/github/dsheirer/sdrplay/api/v3_08/sdrplay_api_ErrorInfoT.java b/sdrplay-api/src/main/java/com/github/dsheirer/sdrplay/api/v3_08/sdrplay_api_ErrorInfoT.java new file mode 100644 index 000000000..262dcc868 --- /dev/null +++ b/sdrplay-api/src/main/java/com/github/dsheirer/sdrplay/api/v3_08/sdrplay_api_ErrorInfoT.java @@ -0,0 +1,56 @@ +// Generated by jextract + +package com.github.dsheirer.sdrplay.api.v3_08; + +import java.lang.foreign.GroupLayout; +import java.lang.foreign.MemoryAddress; +import java.lang.foreign.MemoryLayout; +import java.lang.foreign.MemorySegment; +import java.lang.foreign.MemorySession; +import java.lang.foreign.SegmentAllocator; +import java.lang.invoke.VarHandle; +public class sdrplay_api_ErrorInfoT { + + static final GroupLayout $struct$LAYOUT = MemoryLayout.structLayout( + MemoryLayout.sequenceLayout(256, Constants$root.C_CHAR$LAYOUT).withName("file"), + MemoryLayout.sequenceLayout(256, Constants$root.C_CHAR$LAYOUT).withName("function"), + Constants$root.C_LONG$LAYOUT.withName("line"), + MemoryLayout.sequenceLayout(1024, Constants$root.C_CHAR$LAYOUT).withName("message") + ); + public static MemoryLayout $LAYOUT() { + return sdrplay_api_ErrorInfoT.$struct$LAYOUT; + } + public static MemorySegment file$slice(MemorySegment seg) { + return seg.asSlice(0, 256); + } + public static MemorySegment function$slice(MemorySegment seg) { + return seg.asSlice(256, 256); + } + static final VarHandle line$VH = $struct$LAYOUT.varHandle(MemoryLayout.PathElement.groupElement("line")); + public static VarHandle line$VH() { + return sdrplay_api_ErrorInfoT.line$VH; + } + public static int line$get(MemorySegment seg) { + return (int)sdrplay_api_ErrorInfoT.line$VH.get(seg); + } + public static void line$set( MemorySegment seg, int x) { + sdrplay_api_ErrorInfoT.line$VH.set(seg, x); + } + public static int line$get(MemorySegment seg, long index) { + return (int)sdrplay_api_ErrorInfoT.line$VH.get(seg.asSlice(index*sizeof())); + } + public static void line$set(MemorySegment seg, long index, int x) { + sdrplay_api_ErrorInfoT.line$VH.set(seg.asSlice(index*sizeof()), x); + } + public static MemorySegment message$slice(MemorySegment seg) { + return seg.asSlice(516, 1024); + } + public static long sizeof() { return $LAYOUT().byteSize(); } + public static MemorySegment allocate(SegmentAllocator allocator) { return allocator.allocate($LAYOUT()); } + public static MemorySegment allocateArray(int len, SegmentAllocator allocator) { + return allocator.allocate(MemoryLayout.sequenceLayout(len, $LAYOUT())); + } + public static MemorySegment ofAddress(MemoryAddress addr, MemorySession session) { return RuntimeHelper.asArray(addr, $LAYOUT(), 1, session); } +} + + diff --git a/sdrplay-api/src/main/java/com/github/dsheirer/sdrplay/api/v3_08/sdrplay_api_EventCallback_t.java b/sdrplay-api/src/main/java/com/github/dsheirer/sdrplay/api/v3_08/sdrplay_api_EventCallback_t.java new file mode 100644 index 000000000..3d4f5edd8 --- /dev/null +++ b/sdrplay-api/src/main/java/com/github/dsheirer/sdrplay/api/v3_08/sdrplay_api_EventCallback_t.java @@ -0,0 +1,27 @@ +// Generated by jextract + +package com.github.dsheirer.sdrplay.api.v3_08; + +import java.lang.foreign.Addressable; +import java.lang.foreign.MemoryAddress; +import java.lang.foreign.MemorySegment; +import java.lang.foreign.MemorySession; +public interface sdrplay_api_EventCallback_t { + + void apply(int eventId, int tuner, java.lang.foreign.MemoryAddress params, java.lang.foreign.MemoryAddress cbContext); + static MemorySegment allocate(sdrplay_api_EventCallback_t fi, MemorySession session) { + return RuntimeHelper.upcallStub(sdrplay_api_EventCallback_t.class, fi, constants$0.sdrplay_api_EventCallback_t$FUNC, session); + } + static sdrplay_api_EventCallback_t ofAddress(MemoryAddress addr, MemorySession session) { + MemorySegment symbol = MemorySegment.ofAddress(addr, 0, session); + return (int _eventId, int _tuner, java.lang.foreign.MemoryAddress _params, java.lang.foreign.MemoryAddress _cbContext) -> { + try { + constants$0.sdrplay_api_EventCallback_t$MH.invokeExact((Addressable)symbol, _eventId, _tuner, (java.lang.foreign.Addressable)_params, (java.lang.foreign.Addressable)_cbContext); + } catch (Throwable ex$) { + throw new AssertionError("should not reach here", ex$); + } + }; + } +} + + diff --git a/sdrplay-api/src/main/java/com/github/dsheirer/sdrplay/api/v3_08/sdrplay_api_EventParamsT.java b/sdrplay-api/src/main/java/com/github/dsheirer/sdrplay/api/v3_08/sdrplay_api_EventParamsT.java new file mode 100644 index 000000000..8cebd0c1f --- /dev/null +++ b/sdrplay-api/src/main/java/com/github/dsheirer/sdrplay/api/v3_08/sdrplay_api_EventParamsT.java @@ -0,0 +1,46 @@ +// Generated by jextract + +package com.github.dsheirer.sdrplay.api.v3_08; + +import java.lang.foreign.GroupLayout; +import java.lang.foreign.MemoryAddress; +import java.lang.foreign.MemoryLayout; +import java.lang.foreign.MemorySegment; +import java.lang.foreign.MemorySession; +import java.lang.foreign.SegmentAllocator; +public class sdrplay_api_EventParamsT { + + static final GroupLayout $union$LAYOUT = MemoryLayout.unionLayout( + MemoryLayout.structLayout( + Constants$root.C_LONG$LAYOUT.withName("gRdB"), + Constants$root.C_LONG$LAYOUT.withName("lnaGRdB"), + Constants$root.C_DOUBLE$LAYOUT.withName("currGain") + ).withName("gainParams"), + MemoryLayout.structLayout( + Constants$root.C_LONG$LAYOUT.withName("powerOverloadChangeType") + ).withName("powerOverloadParams"), + MemoryLayout.structLayout( + Constants$root.C_LONG$LAYOUT.withName("modeChangeType") + ).withName("rspDuoModeParams") + ); + public static MemoryLayout $LAYOUT() { + return sdrplay_api_EventParamsT.$union$LAYOUT; + } + public static MemorySegment gainParams$slice(MemorySegment seg) { + return seg.asSlice(0, 16); + } + public static MemorySegment powerOverloadParams$slice(MemorySegment seg) { + return seg.asSlice(0, 4); + } + public static MemorySegment rspDuoModeParams$slice(MemorySegment seg) { + return seg.asSlice(0, 4); + } + public static long sizeof() { return $LAYOUT().byteSize(); } + public static MemorySegment allocate(SegmentAllocator allocator) { return allocator.allocate($LAYOUT()); } + public static MemorySegment allocateArray(int len, SegmentAllocator allocator) { + return allocator.allocate(MemoryLayout.sequenceLayout(len, $LAYOUT())); + } + public static MemorySegment ofAddress(MemoryAddress addr, MemorySession session) { return RuntimeHelper.asArray(addr, $LAYOUT(), 1, session); } +} + + diff --git a/sdrplay-api/src/main/java/com/github/dsheirer/sdrplay/api/v3_08/sdrplay_api_FsFreqT.java b/sdrplay-api/src/main/java/com/github/dsheirer/sdrplay/api/v3_08/sdrplay_api_FsFreqT.java new file mode 100644 index 000000000..bdbfc5f8e --- /dev/null +++ b/sdrplay-api/src/main/java/com/github/dsheirer/sdrplay/api/v3_08/sdrplay_api_FsFreqT.java @@ -0,0 +1,79 @@ +// Generated by jextract + +package com.github.dsheirer.sdrplay.api.v3_08; + +import java.lang.foreign.GroupLayout; +import java.lang.foreign.MemoryAddress; +import java.lang.foreign.MemoryLayout; +import java.lang.foreign.MemorySegment; +import java.lang.foreign.MemorySession; +import java.lang.foreign.SegmentAllocator; +import java.lang.invoke.VarHandle; +public class sdrplay_api_FsFreqT { + + static final GroupLayout $struct$LAYOUT = MemoryLayout.structLayout( + Constants$root.C_DOUBLE$LAYOUT.withName("fsHz"), + Constants$root.C_CHAR$LAYOUT.withName("syncUpdate"), + Constants$root.C_CHAR$LAYOUT.withName("reCal"), + MemoryLayout.paddingLayout(48) + ); + public static MemoryLayout $LAYOUT() { + return sdrplay_api_FsFreqT.$struct$LAYOUT; + } + static final VarHandle fsHz$VH = $struct$LAYOUT.varHandle(MemoryLayout.PathElement.groupElement("fsHz")); + public static VarHandle fsHz$VH() { + return sdrplay_api_FsFreqT.fsHz$VH; + } + public static double fsHz$get(MemorySegment seg) { + return (double)sdrplay_api_FsFreqT.fsHz$VH.get(seg); + } + public static void fsHz$set( MemorySegment seg, double x) { + sdrplay_api_FsFreqT.fsHz$VH.set(seg, x); + } + public static double fsHz$get(MemorySegment seg, long index) { + return (double)sdrplay_api_FsFreqT.fsHz$VH.get(seg.asSlice(index*sizeof())); + } + public static void fsHz$set(MemorySegment seg, long index, double x) { + sdrplay_api_FsFreqT.fsHz$VH.set(seg.asSlice(index*sizeof()), x); + } + static final VarHandle syncUpdate$VH = $struct$LAYOUT.varHandle(MemoryLayout.PathElement.groupElement("syncUpdate")); + public static VarHandle syncUpdate$VH() { + return sdrplay_api_FsFreqT.syncUpdate$VH; + } + public static byte syncUpdate$get(MemorySegment seg) { + return (byte)sdrplay_api_FsFreqT.syncUpdate$VH.get(seg); + } + public static void syncUpdate$set( MemorySegment seg, byte x) { + sdrplay_api_FsFreqT.syncUpdate$VH.set(seg, x); + } + public static byte syncUpdate$get(MemorySegment seg, long index) { + return (byte)sdrplay_api_FsFreqT.syncUpdate$VH.get(seg.asSlice(index*sizeof())); + } + public static void syncUpdate$set(MemorySegment seg, long index, byte x) { + sdrplay_api_FsFreqT.syncUpdate$VH.set(seg.asSlice(index*sizeof()), x); + } + static final VarHandle reCal$VH = $struct$LAYOUT.varHandle(MemoryLayout.PathElement.groupElement("reCal")); + public static VarHandle reCal$VH() { + return sdrplay_api_FsFreqT.reCal$VH; + } + public static byte reCal$get(MemorySegment seg) { + return (byte)sdrplay_api_FsFreqT.reCal$VH.get(seg); + } + public static void reCal$set( MemorySegment seg, byte x) { + sdrplay_api_FsFreqT.reCal$VH.set(seg, x); + } + public static byte reCal$get(MemorySegment seg, long index) { + return (byte)sdrplay_api_FsFreqT.reCal$VH.get(seg.asSlice(index*sizeof())); + } + public static void reCal$set(MemorySegment seg, long index, byte x) { + sdrplay_api_FsFreqT.reCal$VH.set(seg.asSlice(index*sizeof()), x); + } + public static long sizeof() { return $LAYOUT().byteSize(); } + public static MemorySegment allocate(SegmentAllocator allocator) { return allocator.allocate($LAYOUT()); } + public static MemorySegment allocateArray(int len, SegmentAllocator allocator) { + return allocator.allocate(MemoryLayout.sequenceLayout(len, $LAYOUT())); + } + public static MemorySegment ofAddress(MemoryAddress addr, MemorySession session) { return RuntimeHelper.asArray(addr, $LAYOUT(), 1, session); } +} + + diff --git a/sdrplay-api/src/main/java/com/github/dsheirer/sdrplay/api/v3_08/sdrplay_api_GainCbParamT.java b/sdrplay-api/src/main/java/com/github/dsheirer/sdrplay/api/v3_08/sdrplay_api_GainCbParamT.java new file mode 100644 index 000000000..e2da8a2be --- /dev/null +++ b/sdrplay-api/src/main/java/com/github/dsheirer/sdrplay/api/v3_08/sdrplay_api_GainCbParamT.java @@ -0,0 +1,78 @@ +// Generated by jextract + +package com.github.dsheirer.sdrplay.api.v3_08; + +import java.lang.foreign.GroupLayout; +import java.lang.foreign.MemoryAddress; +import java.lang.foreign.MemoryLayout; +import java.lang.foreign.MemorySegment; +import java.lang.foreign.MemorySession; +import java.lang.foreign.SegmentAllocator; +import java.lang.invoke.VarHandle; +public class sdrplay_api_GainCbParamT { + + static final GroupLayout $struct$LAYOUT = MemoryLayout.structLayout( + Constants$root.C_LONG$LAYOUT.withName("gRdB"), + Constants$root.C_LONG$LAYOUT.withName("lnaGRdB"), + Constants$root.C_DOUBLE$LAYOUT.withName("currGain") + ); + public static MemoryLayout $LAYOUT() { + return sdrplay_api_GainCbParamT.$struct$LAYOUT; + } + static final VarHandle gRdB$VH = $struct$LAYOUT.varHandle(MemoryLayout.PathElement.groupElement("gRdB")); + public static VarHandle gRdB$VH() { + return sdrplay_api_GainCbParamT.gRdB$VH; + } + public static int gRdB$get(MemorySegment seg) { + return (int)sdrplay_api_GainCbParamT.gRdB$VH.get(seg); + } + public static void gRdB$set( MemorySegment seg, int x) { + sdrplay_api_GainCbParamT.gRdB$VH.set(seg, x); + } + public static int gRdB$get(MemorySegment seg, long index) { + return (int)sdrplay_api_GainCbParamT.gRdB$VH.get(seg.asSlice(index*sizeof())); + } + public static void gRdB$set(MemorySegment seg, long index, int x) { + sdrplay_api_GainCbParamT.gRdB$VH.set(seg.asSlice(index*sizeof()), x); + } + static final VarHandle lnaGRdB$VH = $struct$LAYOUT.varHandle(MemoryLayout.PathElement.groupElement("lnaGRdB")); + public static VarHandle lnaGRdB$VH() { + return sdrplay_api_GainCbParamT.lnaGRdB$VH; + } + public static int lnaGRdB$get(MemorySegment seg) { + return (int)sdrplay_api_GainCbParamT.lnaGRdB$VH.get(seg); + } + public static void lnaGRdB$set( MemorySegment seg, int x) { + sdrplay_api_GainCbParamT.lnaGRdB$VH.set(seg, x); + } + public static int lnaGRdB$get(MemorySegment seg, long index) { + return (int)sdrplay_api_GainCbParamT.lnaGRdB$VH.get(seg.asSlice(index*sizeof())); + } + public static void lnaGRdB$set(MemorySegment seg, long index, int x) { + sdrplay_api_GainCbParamT.lnaGRdB$VH.set(seg.asSlice(index*sizeof()), x); + } + static final VarHandle currGain$VH = $struct$LAYOUT.varHandle(MemoryLayout.PathElement.groupElement("currGain")); + public static VarHandle currGain$VH() { + return sdrplay_api_GainCbParamT.currGain$VH; + } + public static double currGain$get(MemorySegment seg) { + return (double)sdrplay_api_GainCbParamT.currGain$VH.get(seg); + } + public static void currGain$set( MemorySegment seg, double x) { + sdrplay_api_GainCbParamT.currGain$VH.set(seg, x); + } + public static double currGain$get(MemorySegment seg, long index) { + return (double)sdrplay_api_GainCbParamT.currGain$VH.get(seg.asSlice(index*sizeof())); + } + public static void currGain$set(MemorySegment seg, long index, double x) { + sdrplay_api_GainCbParamT.currGain$VH.set(seg.asSlice(index*sizeof()), x); + } + public static long sizeof() { return $LAYOUT().byteSize(); } + public static MemorySegment allocate(SegmentAllocator allocator) { return allocator.allocate($LAYOUT()); } + public static MemorySegment allocateArray(int len, SegmentAllocator allocator) { + return allocator.allocate(MemoryLayout.sequenceLayout(len, $LAYOUT())); + } + public static MemorySegment ofAddress(MemoryAddress addr, MemorySession session) { return RuntimeHelper.asArray(addr, $LAYOUT(), 1, session); } +} + + diff --git a/sdrplay-api/src/main/java/com/github/dsheirer/sdrplay/api/v3_08/sdrplay_api_GainT.java b/sdrplay-api/src/main/java/com/github/dsheirer/sdrplay/api/v3_08/sdrplay_api_GainT.java new file mode 100644 index 000000000..48db78e45 --- /dev/null +++ b/sdrplay-api/src/main/java/com/github/dsheirer/sdrplay/api/v3_08/sdrplay_api_GainT.java @@ -0,0 +1,104 @@ +// Generated by jextract + +package com.github.dsheirer.sdrplay.api.v3_08; + +import java.lang.foreign.GroupLayout; +import java.lang.foreign.MemoryAddress; +import java.lang.foreign.MemoryLayout; +import java.lang.foreign.MemorySegment; +import java.lang.foreign.MemorySession; +import java.lang.foreign.SegmentAllocator; +import java.lang.invoke.VarHandle; +public class sdrplay_api_GainT { + + static final GroupLayout $struct$LAYOUT = MemoryLayout.structLayout( + Constants$root.C_LONG$LAYOUT.withName("gRdB"), + Constants$root.C_CHAR$LAYOUT.withName("LNAstate"), + Constants$root.C_CHAR$LAYOUT.withName("syncUpdate"), + MemoryLayout.paddingLayout(16), + Constants$root.C_LONG$LAYOUT.withName("minGr"), + MemoryLayout.structLayout( + Constants$root.C_FLOAT$LAYOUT.withName("curr"), + Constants$root.C_FLOAT$LAYOUT.withName("max"), + Constants$root.C_FLOAT$LAYOUT.withName("min") + ).withName("gainVals") + ); + public static MemoryLayout $LAYOUT() { + return sdrplay_api_GainT.$struct$LAYOUT; + } + static final VarHandle gRdB$VH = $struct$LAYOUT.varHandle(MemoryLayout.PathElement.groupElement("gRdB")); + public static VarHandle gRdB$VH() { + return sdrplay_api_GainT.gRdB$VH; + } + public static int gRdB$get(MemorySegment seg) { + return (int)sdrplay_api_GainT.gRdB$VH.get(seg); + } + public static void gRdB$set( MemorySegment seg, int x) { + sdrplay_api_GainT.gRdB$VH.set(seg, x); + } + public static int gRdB$get(MemorySegment seg, long index) { + return (int)sdrplay_api_GainT.gRdB$VH.get(seg.asSlice(index*sizeof())); + } + public static void gRdB$set(MemorySegment seg, long index, int x) { + sdrplay_api_GainT.gRdB$VH.set(seg.asSlice(index*sizeof()), x); + } + static final VarHandle LNAstate$VH = $struct$LAYOUT.varHandle(MemoryLayout.PathElement.groupElement("LNAstate")); + public static VarHandle LNAstate$VH() { + return sdrplay_api_GainT.LNAstate$VH; + } + public static byte LNAstate$get(MemorySegment seg) { + return (byte)sdrplay_api_GainT.LNAstate$VH.get(seg); + } + public static void LNAstate$set( MemorySegment seg, byte x) { + sdrplay_api_GainT.LNAstate$VH.set(seg, x); + } + public static byte LNAstate$get(MemorySegment seg, long index) { + return (byte)sdrplay_api_GainT.LNAstate$VH.get(seg.asSlice(index*sizeof())); + } + public static void LNAstate$set(MemorySegment seg, long index, byte x) { + sdrplay_api_GainT.LNAstate$VH.set(seg.asSlice(index*sizeof()), x); + } + static final VarHandle syncUpdate$VH = $struct$LAYOUT.varHandle(MemoryLayout.PathElement.groupElement("syncUpdate")); + public static VarHandle syncUpdate$VH() { + return sdrplay_api_GainT.syncUpdate$VH; + } + public static byte syncUpdate$get(MemorySegment seg) { + return (byte)sdrplay_api_GainT.syncUpdate$VH.get(seg); + } + public static void syncUpdate$set( MemorySegment seg, byte x) { + sdrplay_api_GainT.syncUpdate$VH.set(seg, x); + } + public static byte syncUpdate$get(MemorySegment seg, long index) { + return (byte)sdrplay_api_GainT.syncUpdate$VH.get(seg.asSlice(index*sizeof())); + } + public static void syncUpdate$set(MemorySegment seg, long index, byte x) { + sdrplay_api_GainT.syncUpdate$VH.set(seg.asSlice(index*sizeof()), x); + } + static final VarHandle minGr$VH = $struct$LAYOUT.varHandle(MemoryLayout.PathElement.groupElement("minGr")); + public static VarHandle minGr$VH() { + return sdrplay_api_GainT.minGr$VH; + } + public static int minGr$get(MemorySegment seg) { + return (int)sdrplay_api_GainT.minGr$VH.get(seg); + } + public static void minGr$set( MemorySegment seg, int x) { + sdrplay_api_GainT.minGr$VH.set(seg, x); + } + public static int minGr$get(MemorySegment seg, long index) { + return (int)sdrplay_api_GainT.minGr$VH.get(seg.asSlice(index*sizeof())); + } + public static void minGr$set(MemorySegment seg, long index, int x) { + sdrplay_api_GainT.minGr$VH.set(seg.asSlice(index*sizeof()), x); + } + public static MemorySegment gainVals$slice(MemorySegment seg) { + return seg.asSlice(12, 12); + } + public static long sizeof() { return $LAYOUT().byteSize(); } + public static MemorySegment allocate(SegmentAllocator allocator) { return allocator.allocate($LAYOUT()); } + public static MemorySegment allocateArray(int len, SegmentAllocator allocator) { + return allocator.allocate(MemoryLayout.sequenceLayout(len, $LAYOUT())); + } + public static MemorySegment ofAddress(MemoryAddress addr, MemorySession session) { return RuntimeHelper.asArray(addr, $LAYOUT(), 1, session); } +} + + diff --git a/sdrplay-api/src/main/java/com/github/dsheirer/sdrplay/api/v3_08/sdrplay_api_GainValuesT.java b/sdrplay-api/src/main/java/com/github/dsheirer/sdrplay/api/v3_08/sdrplay_api_GainValuesT.java new file mode 100644 index 000000000..7e4b26f11 --- /dev/null +++ b/sdrplay-api/src/main/java/com/github/dsheirer/sdrplay/api/v3_08/sdrplay_api_GainValuesT.java @@ -0,0 +1,78 @@ +// Generated by jextract + +package com.github.dsheirer.sdrplay.api.v3_08; + +import java.lang.foreign.GroupLayout; +import java.lang.foreign.MemoryAddress; +import java.lang.foreign.MemoryLayout; +import java.lang.foreign.MemorySegment; +import java.lang.foreign.MemorySession; +import java.lang.foreign.SegmentAllocator; +import java.lang.invoke.VarHandle; +public class sdrplay_api_GainValuesT { + + static final GroupLayout $struct$LAYOUT = MemoryLayout.structLayout( + Constants$root.C_FLOAT$LAYOUT.withName("curr"), + Constants$root.C_FLOAT$LAYOUT.withName("max"), + Constants$root.C_FLOAT$LAYOUT.withName("min") + ); + public static MemoryLayout $LAYOUT() { + return sdrplay_api_GainValuesT.$struct$LAYOUT; + } + static final VarHandle curr$VH = $struct$LAYOUT.varHandle(MemoryLayout.PathElement.groupElement("curr")); + public static VarHandle curr$VH() { + return sdrplay_api_GainValuesT.curr$VH; + } + public static float curr$get(MemorySegment seg) { + return (float)sdrplay_api_GainValuesT.curr$VH.get(seg); + } + public static void curr$set( MemorySegment seg, float x) { + sdrplay_api_GainValuesT.curr$VH.set(seg, x); + } + public static float curr$get(MemorySegment seg, long index) { + return (float)sdrplay_api_GainValuesT.curr$VH.get(seg.asSlice(index*sizeof())); + } + public static void curr$set(MemorySegment seg, long index, float x) { + sdrplay_api_GainValuesT.curr$VH.set(seg.asSlice(index*sizeof()), x); + } + static final VarHandle max$VH = $struct$LAYOUT.varHandle(MemoryLayout.PathElement.groupElement("max")); + public static VarHandle max$VH() { + return sdrplay_api_GainValuesT.max$VH; + } + public static float max$get(MemorySegment seg) { + return (float)sdrplay_api_GainValuesT.max$VH.get(seg); + } + public static void max$set( MemorySegment seg, float x) { + sdrplay_api_GainValuesT.max$VH.set(seg, x); + } + public static float max$get(MemorySegment seg, long index) { + return (float)sdrplay_api_GainValuesT.max$VH.get(seg.asSlice(index*sizeof())); + } + public static void max$set(MemorySegment seg, long index, float x) { + sdrplay_api_GainValuesT.max$VH.set(seg.asSlice(index*sizeof()), x); + } + static final VarHandle min$VH = $struct$LAYOUT.varHandle(MemoryLayout.PathElement.groupElement("min")); + public static VarHandle min$VH() { + return sdrplay_api_GainValuesT.min$VH; + } + public static float min$get(MemorySegment seg) { + return (float)sdrplay_api_GainValuesT.min$VH.get(seg); + } + public static void min$set( MemorySegment seg, float x) { + sdrplay_api_GainValuesT.min$VH.set(seg, x); + } + public static float min$get(MemorySegment seg, long index) { + return (float)sdrplay_api_GainValuesT.min$VH.get(seg.asSlice(index*sizeof())); + } + public static void min$set(MemorySegment seg, long index, float x) { + sdrplay_api_GainValuesT.min$VH.set(seg.asSlice(index*sizeof()), x); + } + public static long sizeof() { return $LAYOUT().byteSize(); } + public static MemorySegment allocate(SegmentAllocator allocator) { return allocator.allocate($LAYOUT()); } + public static MemorySegment allocateArray(int len, SegmentAllocator allocator) { + return allocator.allocate(MemoryLayout.sequenceLayout(len, $LAYOUT())); + } + public static MemorySegment ofAddress(MemoryAddress addr, MemorySession session) { return RuntimeHelper.asArray(addr, $LAYOUT(), 1, session); } +} + + diff --git a/sdrplay-api/src/main/java/com/github/dsheirer/sdrplay/api/v3_08/sdrplay_api_GetDeviceParams_t.java b/sdrplay-api/src/main/java/com/github/dsheirer/sdrplay/api/v3_08/sdrplay_api_GetDeviceParams_t.java new file mode 100644 index 000000000..6644f606b --- /dev/null +++ b/sdrplay-api/src/main/java/com/github/dsheirer/sdrplay/api/v3_08/sdrplay_api_GetDeviceParams_t.java @@ -0,0 +1,27 @@ +// Generated by jextract + +package com.github.dsheirer.sdrplay.api.v3_08; + +import java.lang.foreign.Addressable; +import java.lang.foreign.MemoryAddress; +import java.lang.foreign.MemorySegment; +import java.lang.foreign.MemorySession; +public interface sdrplay_api_GetDeviceParams_t { + + int apply(java.lang.foreign.MemoryAddress dev, java.lang.foreign.MemoryAddress deviceParams); + static MemorySegment allocate(sdrplay_api_GetDeviceParams_t fi, MemorySession session) { + return RuntimeHelper.upcallStub(sdrplay_api_GetDeviceParams_t.class, fi, constants$4.sdrplay_api_GetDeviceParams_t$FUNC, session); + } + static sdrplay_api_GetDeviceParams_t ofAddress(MemoryAddress addr, MemorySession session) { + MemorySegment symbol = MemorySegment.ofAddress(addr, 0, session); + return (java.lang.foreign.MemoryAddress _dev, java.lang.foreign.MemoryAddress _deviceParams) -> { + try { + return (int)constants$4.sdrplay_api_GetDeviceParams_t$MH.invokeExact((Addressable)symbol, (java.lang.foreign.Addressable)_dev, (java.lang.foreign.Addressable)_deviceParams); + } catch (Throwable ex$) { + throw new AssertionError("should not reach here", ex$); + } + }; + } +} + + diff --git a/sdrplay-api/src/main/java/com/github/dsheirer/sdrplay/api/v3_08/sdrplay_api_GetDevices_t.java b/sdrplay-api/src/main/java/com/github/dsheirer/sdrplay/api/v3_08/sdrplay_api_GetDevices_t.java new file mode 100644 index 000000000..ae53feb31 --- /dev/null +++ b/sdrplay-api/src/main/java/com/github/dsheirer/sdrplay/api/v3_08/sdrplay_api_GetDevices_t.java @@ -0,0 +1,27 @@ +// Generated by jextract + +package com.github.dsheirer.sdrplay.api.v3_08; + +import java.lang.foreign.Addressable; +import java.lang.foreign.MemoryAddress; +import java.lang.foreign.MemorySegment; +import java.lang.foreign.MemorySession; +public interface sdrplay_api_GetDevices_t { + + int apply(java.lang.foreign.MemoryAddress devices, java.lang.foreign.MemoryAddress numDevs, int maxDevs); + static MemorySegment allocate(sdrplay_api_GetDevices_t fi, MemorySession session) { + return RuntimeHelper.upcallStub(sdrplay_api_GetDevices_t.class, fi, constants$2.sdrplay_api_GetDevices_t$FUNC, session); + } + static sdrplay_api_GetDevices_t ofAddress(MemoryAddress addr, MemorySession session) { + MemorySegment symbol = MemorySegment.ofAddress(addr, 0, session); + return (java.lang.foreign.MemoryAddress _devices, java.lang.foreign.MemoryAddress _numDevs, int _maxDevs) -> { + try { + return (int)constants$2.sdrplay_api_GetDevices_t$MH.invokeExact((Addressable)symbol, (java.lang.foreign.Addressable)_devices, (java.lang.foreign.Addressable)_numDevs, _maxDevs); + } catch (Throwable ex$) { + throw new AssertionError("should not reach here", ex$); + } + }; + } +} + + diff --git a/sdrplay-api/src/main/java/com/github/dsheirer/sdrplay/api/v3_08/sdrplay_api_GetErrorString_t.java b/sdrplay-api/src/main/java/com/github/dsheirer/sdrplay/api/v3_08/sdrplay_api_GetErrorString_t.java new file mode 100644 index 000000000..63316412d --- /dev/null +++ b/sdrplay-api/src/main/java/com/github/dsheirer/sdrplay/api/v3_08/sdrplay_api_GetErrorString_t.java @@ -0,0 +1,27 @@ +// Generated by jextract + +package com.github.dsheirer.sdrplay.api.v3_08; + +import java.lang.foreign.Addressable; +import java.lang.foreign.MemoryAddress; +import java.lang.foreign.MemorySegment; +import java.lang.foreign.MemorySession; +public interface sdrplay_api_GetErrorString_t { + + java.lang.foreign.Addressable apply(int err); + static MemorySegment allocate(sdrplay_api_GetErrorString_t fi, MemorySession session) { + return RuntimeHelper.upcallStub(sdrplay_api_GetErrorString_t.class, fi, constants$3.sdrplay_api_GetErrorString_t$FUNC, session); + } + static sdrplay_api_GetErrorString_t ofAddress(MemoryAddress addr, MemorySession session) { + MemorySegment symbol = MemorySegment.ofAddress(addr, 0, session); + return (int _err) -> { + try { + return (java.lang.foreign.Addressable)(java.lang.foreign.MemoryAddress)constants$3.sdrplay_api_GetErrorString_t$MH.invokeExact((Addressable)symbol, _err); + } catch (Throwable ex$) { + throw new AssertionError("should not reach here", ex$); + } + }; + } +} + + diff --git a/sdrplay-api/src/main/java/com/github/dsheirer/sdrplay/api/v3_08/sdrplay_api_GetLastError_t.java b/sdrplay-api/src/main/java/com/github/dsheirer/sdrplay/api/v3_08/sdrplay_api_GetLastError_t.java new file mode 100644 index 000000000..ccb2f928d --- /dev/null +++ b/sdrplay-api/src/main/java/com/github/dsheirer/sdrplay/api/v3_08/sdrplay_api_GetLastError_t.java @@ -0,0 +1,27 @@ +// Generated by jextract + +package com.github.dsheirer.sdrplay.api.v3_08; + +import java.lang.foreign.Addressable; +import java.lang.foreign.MemoryAddress; +import java.lang.foreign.MemorySegment; +import java.lang.foreign.MemorySession; +public interface sdrplay_api_GetLastError_t { + + java.lang.foreign.Addressable apply(java.lang.foreign.MemoryAddress device); + static MemorySegment allocate(sdrplay_api_GetLastError_t fi, MemorySession session) { + return RuntimeHelper.upcallStub(sdrplay_api_GetLastError_t.class, fi, constants$3.sdrplay_api_GetLastError_t$FUNC, session); + } + static sdrplay_api_GetLastError_t ofAddress(MemoryAddress addr, MemorySession session) { + MemorySegment symbol = MemorySegment.ofAddress(addr, 0, session); + return (java.lang.foreign.MemoryAddress _device) -> { + try { + return (java.lang.foreign.Addressable)(java.lang.foreign.MemoryAddress)constants$3.sdrplay_api_GetLastError_t$MH.invokeExact((Addressable)symbol, (java.lang.foreign.Addressable)_device); + } catch (Throwable ex$) { + throw new AssertionError("should not reach here", ex$); + } + }; + } +} + + diff --git a/sdrplay-api/src/main/java/com/github/dsheirer/sdrplay/api/v3_08/sdrplay_api_Init_t.java b/sdrplay-api/src/main/java/com/github/dsheirer/sdrplay/api/v3_08/sdrplay_api_Init_t.java new file mode 100644 index 000000000..b132623cb --- /dev/null +++ b/sdrplay-api/src/main/java/com/github/dsheirer/sdrplay/api/v3_08/sdrplay_api_Init_t.java @@ -0,0 +1,27 @@ +// Generated by jextract + +package com.github.dsheirer.sdrplay.api.v3_08; + +import java.lang.foreign.Addressable; +import java.lang.foreign.MemoryAddress; +import java.lang.foreign.MemorySegment; +import java.lang.foreign.MemorySession; +public interface sdrplay_api_Init_t { + + int apply(java.lang.foreign.MemoryAddress dev, java.lang.foreign.MemoryAddress callbackFns, java.lang.foreign.MemoryAddress cbContext); + static MemorySegment allocate(sdrplay_api_Init_t fi, MemorySession session) { + return RuntimeHelper.upcallStub(sdrplay_api_Init_t.class, fi, constants$5.sdrplay_api_Init_t$FUNC, session); + } + static sdrplay_api_Init_t ofAddress(MemoryAddress addr, MemorySession session) { + MemorySegment symbol = MemorySegment.ofAddress(addr, 0, session); + return (java.lang.foreign.MemoryAddress _dev, java.lang.foreign.MemoryAddress _callbackFns, java.lang.foreign.MemoryAddress _cbContext) -> { + try { + return (int)constants$5.sdrplay_api_Init_t$MH.invokeExact((Addressable)symbol, (java.lang.foreign.Addressable)_dev, (java.lang.foreign.Addressable)_callbackFns, (java.lang.foreign.Addressable)_cbContext); + } catch (Throwable ex$) { + throw new AssertionError("should not reach here", ex$); + } + }; + } +} + + diff --git a/sdrplay-api/src/main/java/com/github/dsheirer/sdrplay/api/v3_08/sdrplay_api_LockDeviceApi_t.java b/sdrplay-api/src/main/java/com/github/dsheirer/sdrplay/api/v3_08/sdrplay_api_LockDeviceApi_t.java new file mode 100644 index 000000000..024d7b996 --- /dev/null +++ b/sdrplay-api/src/main/java/com/github/dsheirer/sdrplay/api/v3_08/sdrplay_api_LockDeviceApi_t.java @@ -0,0 +1,27 @@ +// Generated by jextract + +package com.github.dsheirer.sdrplay.api.v3_08; + +import java.lang.foreign.Addressable; +import java.lang.foreign.MemoryAddress; +import java.lang.foreign.MemorySegment; +import java.lang.foreign.MemorySession; +public interface sdrplay_api_LockDeviceApi_t { + + int apply(); + static MemorySegment allocate(sdrplay_api_LockDeviceApi_t fi, MemorySession session) { + return RuntimeHelper.upcallStub(sdrplay_api_LockDeviceApi_t.class, fi, constants$1.sdrplay_api_LockDeviceApi_t$FUNC, session); + } + static sdrplay_api_LockDeviceApi_t ofAddress(MemoryAddress addr, MemorySession session) { + MemorySegment symbol = MemorySegment.ofAddress(addr, 0, session); + return () -> { + try { + return (int)constants$1.sdrplay_api_LockDeviceApi_t$MH.invokeExact((Addressable)symbol); + } catch (Throwable ex$) { + throw new AssertionError("should not reach here", ex$); + } + }; + } +} + + diff --git a/sdrplay-api/src/main/java/com/github/dsheirer/sdrplay/api/v3_08/sdrplay_api_Open_t.java b/sdrplay-api/src/main/java/com/github/dsheirer/sdrplay/api/v3_08/sdrplay_api_Open_t.java new file mode 100644 index 000000000..399da163c --- /dev/null +++ b/sdrplay-api/src/main/java/com/github/dsheirer/sdrplay/api/v3_08/sdrplay_api_Open_t.java @@ -0,0 +1,27 @@ +// Generated by jextract + +package com.github.dsheirer.sdrplay.api.v3_08; + +import java.lang.foreign.Addressable; +import java.lang.foreign.MemoryAddress; +import java.lang.foreign.MemorySegment; +import java.lang.foreign.MemorySession; +public interface sdrplay_api_Open_t { + + int apply(); + static MemorySegment allocate(sdrplay_api_Open_t fi, MemorySession session) { + return RuntimeHelper.upcallStub(sdrplay_api_Open_t.class, fi, constants$0.sdrplay_api_Open_t$FUNC, session); + } + static sdrplay_api_Open_t ofAddress(MemoryAddress addr, MemorySession session) { + MemorySegment symbol = MemorySegment.ofAddress(addr, 0, session); + return () -> { + try { + return (int)constants$0.sdrplay_api_Open_t$MH.invokeExact((Addressable)symbol); + } catch (Throwable ex$) { + throw new AssertionError("should not reach here", ex$); + } + }; + } +} + + diff --git a/sdrplay-api/src/main/java/com/github/dsheirer/sdrplay/api/v3_08/sdrplay_api_PowerOverloadCbParamT.java b/sdrplay-api/src/main/java/com/github/dsheirer/sdrplay/api/v3_08/sdrplay_api_PowerOverloadCbParamT.java new file mode 100644 index 000000000..0d0699496 --- /dev/null +++ b/sdrplay-api/src/main/java/com/github/dsheirer/sdrplay/api/v3_08/sdrplay_api_PowerOverloadCbParamT.java @@ -0,0 +1,44 @@ +// Generated by jextract + +package com.github.dsheirer.sdrplay.api.v3_08; + +import java.lang.foreign.GroupLayout; +import java.lang.foreign.MemoryAddress; +import java.lang.foreign.MemoryLayout; +import java.lang.foreign.MemorySegment; +import java.lang.foreign.MemorySession; +import java.lang.foreign.SegmentAllocator; +import java.lang.invoke.VarHandle; +public class sdrplay_api_PowerOverloadCbParamT { + + static final GroupLayout $struct$LAYOUT = MemoryLayout.structLayout( + Constants$root.C_LONG$LAYOUT.withName("powerOverloadChangeType") + ); + public static MemoryLayout $LAYOUT() { + return sdrplay_api_PowerOverloadCbParamT.$struct$LAYOUT; + } + static final VarHandle powerOverloadChangeType$VH = $struct$LAYOUT.varHandle(MemoryLayout.PathElement.groupElement("powerOverloadChangeType")); + public static VarHandle powerOverloadChangeType$VH() { + return sdrplay_api_PowerOverloadCbParamT.powerOverloadChangeType$VH; + } + public static int powerOverloadChangeType$get(MemorySegment seg) { + return (int)sdrplay_api_PowerOverloadCbParamT.powerOverloadChangeType$VH.get(seg); + } + public static void powerOverloadChangeType$set( MemorySegment seg, int x) { + sdrplay_api_PowerOverloadCbParamT.powerOverloadChangeType$VH.set(seg, x); + } + public static int powerOverloadChangeType$get(MemorySegment seg, long index) { + return (int)sdrplay_api_PowerOverloadCbParamT.powerOverloadChangeType$VH.get(seg.asSlice(index*sizeof())); + } + public static void powerOverloadChangeType$set(MemorySegment seg, long index, int x) { + sdrplay_api_PowerOverloadCbParamT.powerOverloadChangeType$VH.set(seg.asSlice(index*sizeof()), x); + } + public static long sizeof() { return $LAYOUT().byteSize(); } + public static MemorySegment allocate(SegmentAllocator allocator) { return allocator.allocate($LAYOUT()); } + public static MemorySegment allocateArray(int len, SegmentAllocator allocator) { + return allocator.allocate(MemoryLayout.sequenceLayout(len, $LAYOUT())); + } + public static MemorySegment ofAddress(MemoryAddress addr, MemorySession session) { return RuntimeHelper.asArray(addr, $LAYOUT(), 1, session); } +} + + diff --git a/sdrplay-api/src/main/java/com/github/dsheirer/sdrplay/api/v3_08/sdrplay_api_ReleaseDevice_t.java b/sdrplay-api/src/main/java/com/github/dsheirer/sdrplay/api/v3_08/sdrplay_api_ReleaseDevice_t.java new file mode 100644 index 000000000..f33acfa34 --- /dev/null +++ b/sdrplay-api/src/main/java/com/github/dsheirer/sdrplay/api/v3_08/sdrplay_api_ReleaseDevice_t.java @@ -0,0 +1,27 @@ +// Generated by jextract + +package com.github.dsheirer.sdrplay.api.v3_08; + +import java.lang.foreign.Addressable; +import java.lang.foreign.MemoryAddress; +import java.lang.foreign.MemorySegment; +import java.lang.foreign.MemorySession; +public interface sdrplay_api_ReleaseDevice_t { + + int apply(java.lang.foreign.MemoryAddress device); + static MemorySegment allocate(sdrplay_api_ReleaseDevice_t fi, MemorySession session) { + return RuntimeHelper.upcallStub(sdrplay_api_ReleaseDevice_t.class, fi, constants$3.sdrplay_api_ReleaseDevice_t$FUNC, session); + } + static sdrplay_api_ReleaseDevice_t ofAddress(MemoryAddress addr, MemorySession session) { + MemorySegment symbol = MemorySegment.ofAddress(addr, 0, session); + return (java.lang.foreign.MemoryAddress _device) -> { + try { + return (int)constants$3.sdrplay_api_ReleaseDevice_t$MH.invokeExact((Addressable)symbol, (java.lang.foreign.Addressable)_device); + } catch (Throwable ex$) { + throw new AssertionError("should not reach here", ex$); + } + }; + } +} + + diff --git a/sdrplay-api/src/main/java/com/github/dsheirer/sdrplay/api/v3_08/sdrplay_api_ResetFlagsT.java b/sdrplay-api/src/main/java/com/github/dsheirer/sdrplay/api/v3_08/sdrplay_api_ResetFlagsT.java new file mode 100644 index 000000000..1edb0819c --- /dev/null +++ b/sdrplay-api/src/main/java/com/github/dsheirer/sdrplay/api/v3_08/sdrplay_api_ResetFlagsT.java @@ -0,0 +1,78 @@ +// Generated by jextract + +package com.github.dsheirer.sdrplay.api.v3_08; + +import java.lang.foreign.GroupLayout; +import java.lang.foreign.MemoryAddress; +import java.lang.foreign.MemoryLayout; +import java.lang.foreign.MemorySegment; +import java.lang.foreign.MemorySession; +import java.lang.foreign.SegmentAllocator; +import java.lang.invoke.VarHandle; +public class sdrplay_api_ResetFlagsT { + + static final GroupLayout $struct$LAYOUT = MemoryLayout.structLayout( + Constants$root.C_CHAR$LAYOUT.withName("resetGainUpdate"), + Constants$root.C_CHAR$LAYOUT.withName("resetRfUpdate"), + Constants$root.C_CHAR$LAYOUT.withName("resetFsUpdate") + ); + public static MemoryLayout $LAYOUT() { + return sdrplay_api_ResetFlagsT.$struct$LAYOUT; + } + static final VarHandle resetGainUpdate$VH = $struct$LAYOUT.varHandle(MemoryLayout.PathElement.groupElement("resetGainUpdate")); + public static VarHandle resetGainUpdate$VH() { + return sdrplay_api_ResetFlagsT.resetGainUpdate$VH; + } + public static byte resetGainUpdate$get(MemorySegment seg) { + return (byte)sdrplay_api_ResetFlagsT.resetGainUpdate$VH.get(seg); + } + public static void resetGainUpdate$set( MemorySegment seg, byte x) { + sdrplay_api_ResetFlagsT.resetGainUpdate$VH.set(seg, x); + } + public static byte resetGainUpdate$get(MemorySegment seg, long index) { + return (byte)sdrplay_api_ResetFlagsT.resetGainUpdate$VH.get(seg.asSlice(index*sizeof())); + } + public static void resetGainUpdate$set(MemorySegment seg, long index, byte x) { + sdrplay_api_ResetFlagsT.resetGainUpdate$VH.set(seg.asSlice(index*sizeof()), x); + } + static final VarHandle resetRfUpdate$VH = $struct$LAYOUT.varHandle(MemoryLayout.PathElement.groupElement("resetRfUpdate")); + public static VarHandle resetRfUpdate$VH() { + return sdrplay_api_ResetFlagsT.resetRfUpdate$VH; + } + public static byte resetRfUpdate$get(MemorySegment seg) { + return (byte)sdrplay_api_ResetFlagsT.resetRfUpdate$VH.get(seg); + } + public static void resetRfUpdate$set( MemorySegment seg, byte x) { + sdrplay_api_ResetFlagsT.resetRfUpdate$VH.set(seg, x); + } + public static byte resetRfUpdate$get(MemorySegment seg, long index) { + return (byte)sdrplay_api_ResetFlagsT.resetRfUpdate$VH.get(seg.asSlice(index*sizeof())); + } + public static void resetRfUpdate$set(MemorySegment seg, long index, byte x) { + sdrplay_api_ResetFlagsT.resetRfUpdate$VH.set(seg.asSlice(index*sizeof()), x); + } + static final VarHandle resetFsUpdate$VH = $struct$LAYOUT.varHandle(MemoryLayout.PathElement.groupElement("resetFsUpdate")); + public static VarHandle resetFsUpdate$VH() { + return sdrplay_api_ResetFlagsT.resetFsUpdate$VH; + } + public static byte resetFsUpdate$get(MemorySegment seg) { + return (byte)sdrplay_api_ResetFlagsT.resetFsUpdate$VH.get(seg); + } + public static void resetFsUpdate$set( MemorySegment seg, byte x) { + sdrplay_api_ResetFlagsT.resetFsUpdate$VH.set(seg, x); + } + public static byte resetFsUpdate$get(MemorySegment seg, long index) { + return (byte)sdrplay_api_ResetFlagsT.resetFsUpdate$VH.get(seg.asSlice(index*sizeof())); + } + public static void resetFsUpdate$set(MemorySegment seg, long index, byte x) { + sdrplay_api_ResetFlagsT.resetFsUpdate$VH.set(seg.asSlice(index*sizeof()), x); + } + public static long sizeof() { return $LAYOUT().byteSize(); } + public static MemorySegment allocate(SegmentAllocator allocator) { return allocator.allocate($LAYOUT()); } + public static MemorySegment allocateArray(int len, SegmentAllocator allocator) { + return allocator.allocate(MemoryLayout.sequenceLayout(len, $LAYOUT())); + } + public static MemorySegment ofAddress(MemoryAddress addr, MemorySession session) { return RuntimeHelper.asArray(addr, $LAYOUT(), 1, session); } +} + + diff --git a/sdrplay-api/src/main/java/com/github/dsheirer/sdrplay/api/v3_08/sdrplay_api_RfFreqT.java b/sdrplay-api/src/main/java/com/github/dsheirer/sdrplay/api/v3_08/sdrplay_api_RfFreqT.java new file mode 100644 index 000000000..ed54aa0c1 --- /dev/null +++ b/sdrplay-api/src/main/java/com/github/dsheirer/sdrplay/api/v3_08/sdrplay_api_RfFreqT.java @@ -0,0 +1,62 @@ +// Generated by jextract + +package com.github.dsheirer.sdrplay.api.v3_08; + +import java.lang.foreign.GroupLayout; +import java.lang.foreign.MemoryAddress; +import java.lang.foreign.MemoryLayout; +import java.lang.foreign.MemorySegment; +import java.lang.foreign.MemorySession; +import java.lang.foreign.SegmentAllocator; +import java.lang.invoke.VarHandle; +public class sdrplay_api_RfFreqT { + + static final GroupLayout $struct$LAYOUT = MemoryLayout.structLayout( + Constants$root.C_DOUBLE$LAYOUT.withName("rfHz"), + Constants$root.C_CHAR$LAYOUT.withName("syncUpdate"), + MemoryLayout.paddingLayout(56) + ); + public static MemoryLayout $LAYOUT() { + return sdrplay_api_RfFreqT.$struct$LAYOUT; + } + static final VarHandle rfHz$VH = $struct$LAYOUT.varHandle(MemoryLayout.PathElement.groupElement("rfHz")); + public static VarHandle rfHz$VH() { + return sdrplay_api_RfFreqT.rfHz$VH; + } + public static double rfHz$get(MemorySegment seg) { + return (double)sdrplay_api_RfFreqT.rfHz$VH.get(seg); + } + public static void rfHz$set( MemorySegment seg, double x) { + sdrplay_api_RfFreqT.rfHz$VH.set(seg, x); + } + public static double rfHz$get(MemorySegment seg, long index) { + return (double)sdrplay_api_RfFreqT.rfHz$VH.get(seg.asSlice(index*sizeof())); + } + public static void rfHz$set(MemorySegment seg, long index, double x) { + sdrplay_api_RfFreqT.rfHz$VH.set(seg.asSlice(index*sizeof()), x); + } + static final VarHandle syncUpdate$VH = $struct$LAYOUT.varHandle(MemoryLayout.PathElement.groupElement("syncUpdate")); + public static VarHandle syncUpdate$VH() { + return sdrplay_api_RfFreqT.syncUpdate$VH; + } + public static byte syncUpdate$get(MemorySegment seg) { + return (byte)sdrplay_api_RfFreqT.syncUpdate$VH.get(seg); + } + public static void syncUpdate$set( MemorySegment seg, byte x) { + sdrplay_api_RfFreqT.syncUpdate$VH.set(seg, x); + } + public static byte syncUpdate$get(MemorySegment seg, long index) { + return (byte)sdrplay_api_RfFreqT.syncUpdate$VH.get(seg.asSlice(index*sizeof())); + } + public static void syncUpdate$set(MemorySegment seg, long index, byte x) { + sdrplay_api_RfFreqT.syncUpdate$VH.set(seg.asSlice(index*sizeof()), x); + } + public static long sizeof() { return $LAYOUT().byteSize(); } + public static MemorySegment allocate(SegmentAllocator allocator) { return allocator.allocate($LAYOUT()); } + public static MemorySegment allocateArray(int len, SegmentAllocator allocator) { + return allocator.allocate(MemoryLayout.sequenceLayout(len, $LAYOUT())); + } + public static MemorySegment ofAddress(MemoryAddress addr, MemorySession session) { return RuntimeHelper.asArray(addr, $LAYOUT(), 1, session); } +} + + diff --git a/sdrplay-api/src/main/java/com/github/dsheirer/sdrplay/api/v3_08/sdrplay_api_Rsp1aParamsT.java b/sdrplay-api/src/main/java/com/github/dsheirer/sdrplay/api/v3_08/sdrplay_api_Rsp1aParamsT.java new file mode 100644 index 000000000..d48d979e3 --- /dev/null +++ b/sdrplay-api/src/main/java/com/github/dsheirer/sdrplay/api/v3_08/sdrplay_api_Rsp1aParamsT.java @@ -0,0 +1,61 @@ +// Generated by jextract + +package com.github.dsheirer.sdrplay.api.v3_08; + +import java.lang.foreign.GroupLayout; +import java.lang.foreign.MemoryAddress; +import java.lang.foreign.MemoryLayout; +import java.lang.foreign.MemorySegment; +import java.lang.foreign.MemorySession; +import java.lang.foreign.SegmentAllocator; +import java.lang.invoke.VarHandle; +public class sdrplay_api_Rsp1aParamsT { + + static final GroupLayout $struct$LAYOUT = MemoryLayout.structLayout( + Constants$root.C_CHAR$LAYOUT.withName("rfNotchEnable"), + Constants$root.C_CHAR$LAYOUT.withName("rfDabNotchEnable") + ); + public static MemoryLayout $LAYOUT() { + return sdrplay_api_Rsp1aParamsT.$struct$LAYOUT; + } + static final VarHandle rfNotchEnable$VH = $struct$LAYOUT.varHandle(MemoryLayout.PathElement.groupElement("rfNotchEnable")); + public static VarHandle rfNotchEnable$VH() { + return sdrplay_api_Rsp1aParamsT.rfNotchEnable$VH; + } + public static byte rfNotchEnable$get(MemorySegment seg) { + return (byte)sdrplay_api_Rsp1aParamsT.rfNotchEnable$VH.get(seg); + } + public static void rfNotchEnable$set( MemorySegment seg, byte x) { + sdrplay_api_Rsp1aParamsT.rfNotchEnable$VH.set(seg, x); + } + public static byte rfNotchEnable$get(MemorySegment seg, long index) { + return (byte)sdrplay_api_Rsp1aParamsT.rfNotchEnable$VH.get(seg.asSlice(index*sizeof())); + } + public static void rfNotchEnable$set(MemorySegment seg, long index, byte x) { + sdrplay_api_Rsp1aParamsT.rfNotchEnable$VH.set(seg.asSlice(index*sizeof()), x); + } + static final VarHandle rfDabNotchEnable$VH = $struct$LAYOUT.varHandle(MemoryLayout.PathElement.groupElement("rfDabNotchEnable")); + public static VarHandle rfDabNotchEnable$VH() { + return sdrplay_api_Rsp1aParamsT.rfDabNotchEnable$VH; + } + public static byte rfDabNotchEnable$get(MemorySegment seg) { + return (byte)sdrplay_api_Rsp1aParamsT.rfDabNotchEnable$VH.get(seg); + } + public static void rfDabNotchEnable$set( MemorySegment seg, byte x) { + sdrplay_api_Rsp1aParamsT.rfDabNotchEnable$VH.set(seg, x); + } + public static byte rfDabNotchEnable$get(MemorySegment seg, long index) { + return (byte)sdrplay_api_Rsp1aParamsT.rfDabNotchEnable$VH.get(seg.asSlice(index*sizeof())); + } + public static void rfDabNotchEnable$set(MemorySegment seg, long index, byte x) { + sdrplay_api_Rsp1aParamsT.rfDabNotchEnable$VH.set(seg.asSlice(index*sizeof()), x); + } + public static long sizeof() { return $LAYOUT().byteSize(); } + public static MemorySegment allocate(SegmentAllocator allocator) { return allocator.allocate($LAYOUT()); } + public static MemorySegment allocateArray(int len, SegmentAllocator allocator) { + return allocator.allocate(MemoryLayout.sequenceLayout(len, $LAYOUT())); + } + public static MemorySegment ofAddress(MemoryAddress addr, MemorySession session) { return RuntimeHelper.asArray(addr, $LAYOUT(), 1, session); } +} + + diff --git a/sdrplay-api/src/main/java/com/github/dsheirer/sdrplay/api/v3_08/sdrplay_api_Rsp1aTunerParamsT.java b/sdrplay-api/src/main/java/com/github/dsheirer/sdrplay/api/v3_08/sdrplay_api_Rsp1aTunerParamsT.java new file mode 100644 index 000000000..afb62b2e8 --- /dev/null +++ b/sdrplay-api/src/main/java/com/github/dsheirer/sdrplay/api/v3_08/sdrplay_api_Rsp1aTunerParamsT.java @@ -0,0 +1,44 @@ +// Generated by jextract + +package com.github.dsheirer.sdrplay.api.v3_08; + +import java.lang.foreign.GroupLayout; +import java.lang.foreign.MemoryAddress; +import java.lang.foreign.MemoryLayout; +import java.lang.foreign.MemorySegment; +import java.lang.foreign.MemorySession; +import java.lang.foreign.SegmentAllocator; +import java.lang.invoke.VarHandle; +public class sdrplay_api_Rsp1aTunerParamsT { + + static final GroupLayout $struct$LAYOUT = MemoryLayout.structLayout( + Constants$root.C_CHAR$LAYOUT.withName("biasTEnable") + ); + public static MemoryLayout $LAYOUT() { + return sdrplay_api_Rsp1aTunerParamsT.$struct$LAYOUT; + } + static final VarHandle biasTEnable$VH = $struct$LAYOUT.varHandle(MemoryLayout.PathElement.groupElement("biasTEnable")); + public static VarHandle biasTEnable$VH() { + return sdrplay_api_Rsp1aTunerParamsT.biasTEnable$VH; + } + public static byte biasTEnable$get(MemorySegment seg) { + return (byte)sdrplay_api_Rsp1aTunerParamsT.biasTEnable$VH.get(seg); + } + public static void biasTEnable$set( MemorySegment seg, byte x) { + sdrplay_api_Rsp1aTunerParamsT.biasTEnable$VH.set(seg, x); + } + public static byte biasTEnable$get(MemorySegment seg, long index) { + return (byte)sdrplay_api_Rsp1aTunerParamsT.biasTEnable$VH.get(seg.asSlice(index*sizeof())); + } + public static void biasTEnable$set(MemorySegment seg, long index, byte x) { + sdrplay_api_Rsp1aTunerParamsT.biasTEnable$VH.set(seg.asSlice(index*sizeof()), x); + } + public static long sizeof() { return $LAYOUT().byteSize(); } + public static MemorySegment allocate(SegmentAllocator allocator) { return allocator.allocate($LAYOUT()); } + public static MemorySegment allocateArray(int len, SegmentAllocator allocator) { + return allocator.allocate(MemoryLayout.sequenceLayout(len, $LAYOUT())); + } + public static MemorySegment ofAddress(MemoryAddress addr, MemorySession session) { return RuntimeHelper.asArray(addr, $LAYOUT(), 1, session); } +} + + diff --git a/sdrplay-api/src/main/java/com/github/dsheirer/sdrplay/api/v3_08/sdrplay_api_Rsp2ParamsT.java b/sdrplay-api/src/main/java/com/github/dsheirer/sdrplay/api/v3_08/sdrplay_api_Rsp2ParamsT.java new file mode 100644 index 000000000..c668c179d --- /dev/null +++ b/sdrplay-api/src/main/java/com/github/dsheirer/sdrplay/api/v3_08/sdrplay_api_Rsp2ParamsT.java @@ -0,0 +1,44 @@ +// Generated by jextract + +package com.github.dsheirer.sdrplay.api.v3_08; + +import java.lang.foreign.GroupLayout; +import java.lang.foreign.MemoryAddress; +import java.lang.foreign.MemoryLayout; +import java.lang.foreign.MemorySegment; +import java.lang.foreign.MemorySession; +import java.lang.foreign.SegmentAllocator; +import java.lang.invoke.VarHandle; +public class sdrplay_api_Rsp2ParamsT { + + static final GroupLayout $struct$LAYOUT = MemoryLayout.structLayout( + Constants$root.C_CHAR$LAYOUT.withName("extRefOutputEn") + ); + public static MemoryLayout $LAYOUT() { + return sdrplay_api_Rsp2ParamsT.$struct$LAYOUT; + } + static final VarHandle extRefOutputEn$VH = $struct$LAYOUT.varHandle(MemoryLayout.PathElement.groupElement("extRefOutputEn")); + public static VarHandle extRefOutputEn$VH() { + return sdrplay_api_Rsp2ParamsT.extRefOutputEn$VH; + } + public static byte extRefOutputEn$get(MemorySegment seg) { + return (byte)sdrplay_api_Rsp2ParamsT.extRefOutputEn$VH.get(seg); + } + public static void extRefOutputEn$set( MemorySegment seg, byte x) { + sdrplay_api_Rsp2ParamsT.extRefOutputEn$VH.set(seg, x); + } + public static byte extRefOutputEn$get(MemorySegment seg, long index) { + return (byte)sdrplay_api_Rsp2ParamsT.extRefOutputEn$VH.get(seg.asSlice(index*sizeof())); + } + public static void extRefOutputEn$set(MemorySegment seg, long index, byte x) { + sdrplay_api_Rsp2ParamsT.extRefOutputEn$VH.set(seg.asSlice(index*sizeof()), x); + } + public static long sizeof() { return $LAYOUT().byteSize(); } + public static MemorySegment allocate(SegmentAllocator allocator) { return allocator.allocate($LAYOUT()); } + public static MemorySegment allocateArray(int len, SegmentAllocator allocator) { + return allocator.allocate(MemoryLayout.sequenceLayout(len, $LAYOUT())); + } + public static MemorySegment ofAddress(MemoryAddress addr, MemorySession session) { return RuntimeHelper.asArray(addr, $LAYOUT(), 1, session); } +} + + diff --git a/sdrplay-api/src/main/java/com/github/dsheirer/sdrplay/api/v3_08/sdrplay_api_Rsp2TunerParamsT.java b/sdrplay-api/src/main/java/com/github/dsheirer/sdrplay/api/v3_08/sdrplay_api_Rsp2TunerParamsT.java new file mode 100644 index 000000000..f814a873f --- /dev/null +++ b/sdrplay-api/src/main/java/com/github/dsheirer/sdrplay/api/v3_08/sdrplay_api_Rsp2TunerParamsT.java @@ -0,0 +1,97 @@ +// Generated by jextract + +package com.github.dsheirer.sdrplay.api.v3_08; + +import java.lang.foreign.GroupLayout; +import java.lang.foreign.MemoryAddress; +import java.lang.foreign.MemoryLayout; +import java.lang.foreign.MemorySegment; +import java.lang.foreign.MemorySession; +import java.lang.foreign.SegmentAllocator; +import java.lang.invoke.VarHandle; +public class sdrplay_api_Rsp2TunerParamsT { + + static final GroupLayout $struct$LAYOUT = MemoryLayout.structLayout( + Constants$root.C_CHAR$LAYOUT.withName("biasTEnable"), + MemoryLayout.paddingLayout(24), + Constants$root.C_LONG$LAYOUT.withName("amPortSel"), + Constants$root.C_LONG$LAYOUT.withName("antennaSel"), + Constants$root.C_CHAR$LAYOUT.withName("rfNotchEnable"), + MemoryLayout.paddingLayout(24) + ); + public static MemoryLayout $LAYOUT() { + return sdrplay_api_Rsp2TunerParamsT.$struct$LAYOUT; + } + static final VarHandle biasTEnable$VH = $struct$LAYOUT.varHandle(MemoryLayout.PathElement.groupElement("biasTEnable")); + public static VarHandle biasTEnable$VH() { + return sdrplay_api_Rsp2TunerParamsT.biasTEnable$VH; + } + public static byte biasTEnable$get(MemorySegment seg) { + return (byte)sdrplay_api_Rsp2TunerParamsT.biasTEnable$VH.get(seg); + } + public static void biasTEnable$set( MemorySegment seg, byte x) { + sdrplay_api_Rsp2TunerParamsT.biasTEnable$VH.set(seg, x); + } + public static byte biasTEnable$get(MemorySegment seg, long index) { + return (byte)sdrplay_api_Rsp2TunerParamsT.biasTEnable$VH.get(seg.asSlice(index*sizeof())); + } + public static void biasTEnable$set(MemorySegment seg, long index, byte x) { + sdrplay_api_Rsp2TunerParamsT.biasTEnable$VH.set(seg.asSlice(index*sizeof()), x); + } + static final VarHandle amPortSel$VH = $struct$LAYOUT.varHandle(MemoryLayout.PathElement.groupElement("amPortSel")); + public static VarHandle amPortSel$VH() { + return sdrplay_api_Rsp2TunerParamsT.amPortSel$VH; + } + public static int amPortSel$get(MemorySegment seg) { + return (int)sdrplay_api_Rsp2TunerParamsT.amPortSel$VH.get(seg); + } + public static void amPortSel$set( MemorySegment seg, int x) { + sdrplay_api_Rsp2TunerParamsT.amPortSel$VH.set(seg, x); + } + public static int amPortSel$get(MemorySegment seg, long index) { + return (int)sdrplay_api_Rsp2TunerParamsT.amPortSel$VH.get(seg.asSlice(index*sizeof())); + } + public static void amPortSel$set(MemorySegment seg, long index, int x) { + sdrplay_api_Rsp2TunerParamsT.amPortSel$VH.set(seg.asSlice(index*sizeof()), x); + } + static final VarHandle antennaSel$VH = $struct$LAYOUT.varHandle(MemoryLayout.PathElement.groupElement("antennaSel")); + public static VarHandle antennaSel$VH() { + return sdrplay_api_Rsp2TunerParamsT.antennaSel$VH; + } + public static int antennaSel$get(MemorySegment seg) { + return (int)sdrplay_api_Rsp2TunerParamsT.antennaSel$VH.get(seg); + } + public static void antennaSel$set( MemorySegment seg, int x) { + sdrplay_api_Rsp2TunerParamsT.antennaSel$VH.set(seg, x); + } + public static int antennaSel$get(MemorySegment seg, long index) { + return (int)sdrplay_api_Rsp2TunerParamsT.antennaSel$VH.get(seg.asSlice(index*sizeof())); + } + public static void antennaSel$set(MemorySegment seg, long index, int x) { + sdrplay_api_Rsp2TunerParamsT.antennaSel$VH.set(seg.asSlice(index*sizeof()), x); + } + static final VarHandle rfNotchEnable$VH = $struct$LAYOUT.varHandle(MemoryLayout.PathElement.groupElement("rfNotchEnable")); + public static VarHandle rfNotchEnable$VH() { + return sdrplay_api_Rsp2TunerParamsT.rfNotchEnable$VH; + } + public static byte rfNotchEnable$get(MemorySegment seg) { + return (byte)sdrplay_api_Rsp2TunerParamsT.rfNotchEnable$VH.get(seg); + } + public static void rfNotchEnable$set( MemorySegment seg, byte x) { + sdrplay_api_Rsp2TunerParamsT.rfNotchEnable$VH.set(seg, x); + } + public static byte rfNotchEnable$get(MemorySegment seg, long index) { + return (byte)sdrplay_api_Rsp2TunerParamsT.rfNotchEnable$VH.get(seg.asSlice(index*sizeof())); + } + public static void rfNotchEnable$set(MemorySegment seg, long index, byte x) { + sdrplay_api_Rsp2TunerParamsT.rfNotchEnable$VH.set(seg.asSlice(index*sizeof()), x); + } + public static long sizeof() { return $LAYOUT().byteSize(); } + public static MemorySegment allocate(SegmentAllocator allocator) { return allocator.allocate($LAYOUT()); } + public static MemorySegment allocateArray(int len, SegmentAllocator allocator) { + return allocator.allocate(MemoryLayout.sequenceLayout(len, $LAYOUT())); + } + public static MemorySegment ofAddress(MemoryAddress addr, MemorySession session) { return RuntimeHelper.asArray(addr, $LAYOUT(), 1, session); } +} + + diff --git a/sdrplay-api/src/main/java/com/github/dsheirer/sdrplay/api/v3_08/sdrplay_api_RspDuoModeCbParamT.java b/sdrplay-api/src/main/java/com/github/dsheirer/sdrplay/api/v3_08/sdrplay_api_RspDuoModeCbParamT.java new file mode 100644 index 000000000..f5f18e963 --- /dev/null +++ b/sdrplay-api/src/main/java/com/github/dsheirer/sdrplay/api/v3_08/sdrplay_api_RspDuoModeCbParamT.java @@ -0,0 +1,44 @@ +// Generated by jextract + +package com.github.dsheirer.sdrplay.api.v3_08; + +import java.lang.foreign.GroupLayout; +import java.lang.foreign.MemoryAddress; +import java.lang.foreign.MemoryLayout; +import java.lang.foreign.MemorySegment; +import java.lang.foreign.MemorySession; +import java.lang.foreign.SegmentAllocator; +import java.lang.invoke.VarHandle; +public class sdrplay_api_RspDuoModeCbParamT { + + static final GroupLayout $struct$LAYOUT = MemoryLayout.structLayout( + Constants$root.C_LONG$LAYOUT.withName("modeChangeType") + ); + public static MemoryLayout $LAYOUT() { + return sdrplay_api_RspDuoModeCbParamT.$struct$LAYOUT; + } + static final VarHandle modeChangeType$VH = $struct$LAYOUT.varHandle(MemoryLayout.PathElement.groupElement("modeChangeType")); + public static VarHandle modeChangeType$VH() { + return sdrplay_api_RspDuoModeCbParamT.modeChangeType$VH; + } + public static int modeChangeType$get(MemorySegment seg) { + return (int)sdrplay_api_RspDuoModeCbParamT.modeChangeType$VH.get(seg); + } + public static void modeChangeType$set( MemorySegment seg, int x) { + sdrplay_api_RspDuoModeCbParamT.modeChangeType$VH.set(seg, x); + } + public static int modeChangeType$get(MemorySegment seg, long index) { + return (int)sdrplay_api_RspDuoModeCbParamT.modeChangeType$VH.get(seg.asSlice(index*sizeof())); + } + public static void modeChangeType$set(MemorySegment seg, long index, int x) { + sdrplay_api_RspDuoModeCbParamT.modeChangeType$VH.set(seg.asSlice(index*sizeof()), x); + } + public static long sizeof() { return $LAYOUT().byteSize(); } + public static MemorySegment allocate(SegmentAllocator allocator) { return allocator.allocate($LAYOUT()); } + public static MemorySegment allocateArray(int len, SegmentAllocator allocator) { + return allocator.allocate(MemoryLayout.sequenceLayout(len, $LAYOUT())); + } + public static MemorySegment ofAddress(MemoryAddress addr, MemorySession session) { return RuntimeHelper.asArray(addr, $LAYOUT(), 1, session); } +} + + diff --git a/sdrplay-api/src/main/java/com/github/dsheirer/sdrplay/api/v3_08/sdrplay_api_RspDuoParamsT.java b/sdrplay-api/src/main/java/com/github/dsheirer/sdrplay/api/v3_08/sdrplay_api_RspDuoParamsT.java new file mode 100644 index 000000000..2b08a48e7 --- /dev/null +++ b/sdrplay-api/src/main/java/com/github/dsheirer/sdrplay/api/v3_08/sdrplay_api_RspDuoParamsT.java @@ -0,0 +1,44 @@ +// Generated by jextract + +package com.github.dsheirer.sdrplay.api.v3_08; + +import java.lang.foreign.GroupLayout; +import java.lang.foreign.MemoryAddress; +import java.lang.foreign.MemoryLayout; +import java.lang.foreign.MemorySegment; +import java.lang.foreign.MemorySession; +import java.lang.foreign.SegmentAllocator; +import java.lang.invoke.VarHandle; +public class sdrplay_api_RspDuoParamsT { + + static final GroupLayout $struct$LAYOUT = MemoryLayout.structLayout( + Constants$root.C_LONG$LAYOUT.withName("extRefOutputEn") + ); + public static MemoryLayout $LAYOUT() { + return sdrplay_api_RspDuoParamsT.$struct$LAYOUT; + } + static final VarHandle extRefOutputEn$VH = $struct$LAYOUT.varHandle(MemoryLayout.PathElement.groupElement("extRefOutputEn")); + public static VarHandle extRefOutputEn$VH() { + return sdrplay_api_RspDuoParamsT.extRefOutputEn$VH; + } + public static int extRefOutputEn$get(MemorySegment seg) { + return (int)sdrplay_api_RspDuoParamsT.extRefOutputEn$VH.get(seg); + } + public static void extRefOutputEn$set( MemorySegment seg, int x) { + sdrplay_api_RspDuoParamsT.extRefOutputEn$VH.set(seg, x); + } + public static int extRefOutputEn$get(MemorySegment seg, long index) { + return (int)sdrplay_api_RspDuoParamsT.extRefOutputEn$VH.get(seg.asSlice(index*sizeof())); + } + public static void extRefOutputEn$set(MemorySegment seg, long index, int x) { + sdrplay_api_RspDuoParamsT.extRefOutputEn$VH.set(seg.asSlice(index*sizeof()), x); + } + public static long sizeof() { return $LAYOUT().byteSize(); } + public static MemorySegment allocate(SegmentAllocator allocator) { return allocator.allocate($LAYOUT()); } + public static MemorySegment allocateArray(int len, SegmentAllocator allocator) { + return allocator.allocate(MemoryLayout.sequenceLayout(len, $LAYOUT())); + } + public static MemorySegment ofAddress(MemoryAddress addr, MemorySession session) { return RuntimeHelper.asArray(addr, $LAYOUT(), 1, session); } +} + + diff --git a/sdrplay-api/src/main/java/com/github/dsheirer/sdrplay/api/v3_08/sdrplay_api_RspDuoTunerParamsT.java b/sdrplay-api/src/main/java/com/github/dsheirer/sdrplay/api/v3_08/sdrplay_api_RspDuoTunerParamsT.java new file mode 100644 index 000000000..4daa64e29 --- /dev/null +++ b/sdrplay-api/src/main/java/com/github/dsheirer/sdrplay/api/v3_08/sdrplay_api_RspDuoTunerParamsT.java @@ -0,0 +1,114 @@ +// Generated by jextract + +package com.github.dsheirer.sdrplay.api.v3_08; + +import java.lang.foreign.GroupLayout; +import java.lang.foreign.MemoryAddress; +import java.lang.foreign.MemoryLayout; +import java.lang.foreign.MemorySegment; +import java.lang.foreign.MemorySession; +import java.lang.foreign.SegmentAllocator; +import java.lang.invoke.VarHandle; +public class sdrplay_api_RspDuoTunerParamsT { + + static final GroupLayout $struct$LAYOUT = MemoryLayout.structLayout( + Constants$root.C_CHAR$LAYOUT.withName("biasTEnable"), + MemoryLayout.paddingLayout(24), + Constants$root.C_LONG$LAYOUT.withName("tuner1AmPortSel"), + Constants$root.C_CHAR$LAYOUT.withName("tuner1AmNotchEnable"), + Constants$root.C_CHAR$LAYOUT.withName("rfNotchEnable"), + Constants$root.C_CHAR$LAYOUT.withName("rfDabNotchEnable"), + MemoryLayout.paddingLayout(8) + ); + public static MemoryLayout $LAYOUT() { + return sdrplay_api_RspDuoTunerParamsT.$struct$LAYOUT; + } + static final VarHandle biasTEnable$VH = $struct$LAYOUT.varHandle(MemoryLayout.PathElement.groupElement("biasTEnable")); + public static VarHandle biasTEnable$VH() { + return sdrplay_api_RspDuoTunerParamsT.biasTEnable$VH; + } + public static byte biasTEnable$get(MemorySegment seg) { + return (byte)sdrplay_api_RspDuoTunerParamsT.biasTEnable$VH.get(seg); + } + public static void biasTEnable$set( MemorySegment seg, byte x) { + sdrplay_api_RspDuoTunerParamsT.biasTEnable$VH.set(seg, x); + } + public static byte biasTEnable$get(MemorySegment seg, long index) { + return (byte)sdrplay_api_RspDuoTunerParamsT.biasTEnable$VH.get(seg.asSlice(index*sizeof())); + } + public static void biasTEnable$set(MemorySegment seg, long index, byte x) { + sdrplay_api_RspDuoTunerParamsT.biasTEnable$VH.set(seg.asSlice(index*sizeof()), x); + } + static final VarHandle tuner1AmPortSel$VH = $struct$LAYOUT.varHandle(MemoryLayout.PathElement.groupElement("tuner1AmPortSel")); + public static VarHandle tuner1AmPortSel$VH() { + return sdrplay_api_RspDuoTunerParamsT.tuner1AmPortSel$VH; + } + public static int tuner1AmPortSel$get(MemorySegment seg) { + return (int)sdrplay_api_RspDuoTunerParamsT.tuner1AmPortSel$VH.get(seg); + } + public static void tuner1AmPortSel$set( MemorySegment seg, int x) { + sdrplay_api_RspDuoTunerParamsT.tuner1AmPortSel$VH.set(seg, x); + } + public static int tuner1AmPortSel$get(MemorySegment seg, long index) { + return (int)sdrplay_api_RspDuoTunerParamsT.tuner1AmPortSel$VH.get(seg.asSlice(index*sizeof())); + } + public static void tuner1AmPortSel$set(MemorySegment seg, long index, int x) { + sdrplay_api_RspDuoTunerParamsT.tuner1AmPortSel$VH.set(seg.asSlice(index*sizeof()), x); + } + static final VarHandle tuner1AmNotchEnable$VH = $struct$LAYOUT.varHandle(MemoryLayout.PathElement.groupElement("tuner1AmNotchEnable")); + public static VarHandle tuner1AmNotchEnable$VH() { + return sdrplay_api_RspDuoTunerParamsT.tuner1AmNotchEnable$VH; + } + public static byte tuner1AmNotchEnable$get(MemorySegment seg) { + return (byte)sdrplay_api_RspDuoTunerParamsT.tuner1AmNotchEnable$VH.get(seg); + } + public static void tuner1AmNotchEnable$set( MemorySegment seg, byte x) { + sdrplay_api_RspDuoTunerParamsT.tuner1AmNotchEnable$VH.set(seg, x); + } + public static byte tuner1AmNotchEnable$get(MemorySegment seg, long index) { + return (byte)sdrplay_api_RspDuoTunerParamsT.tuner1AmNotchEnable$VH.get(seg.asSlice(index*sizeof())); + } + public static void tuner1AmNotchEnable$set(MemorySegment seg, long index, byte x) { + sdrplay_api_RspDuoTunerParamsT.tuner1AmNotchEnable$VH.set(seg.asSlice(index*sizeof()), x); + } + static final VarHandle rfNotchEnable$VH = $struct$LAYOUT.varHandle(MemoryLayout.PathElement.groupElement("rfNotchEnable")); + public static VarHandle rfNotchEnable$VH() { + return sdrplay_api_RspDuoTunerParamsT.rfNotchEnable$VH; + } + public static byte rfNotchEnable$get(MemorySegment seg) { + return (byte)sdrplay_api_RspDuoTunerParamsT.rfNotchEnable$VH.get(seg); + } + public static void rfNotchEnable$set( MemorySegment seg, byte x) { + sdrplay_api_RspDuoTunerParamsT.rfNotchEnable$VH.set(seg, x); + } + public static byte rfNotchEnable$get(MemorySegment seg, long index) { + return (byte)sdrplay_api_RspDuoTunerParamsT.rfNotchEnable$VH.get(seg.asSlice(index*sizeof())); + } + public static void rfNotchEnable$set(MemorySegment seg, long index, byte x) { + sdrplay_api_RspDuoTunerParamsT.rfNotchEnable$VH.set(seg.asSlice(index*sizeof()), x); + } + static final VarHandle rfDabNotchEnable$VH = $struct$LAYOUT.varHandle(MemoryLayout.PathElement.groupElement("rfDabNotchEnable")); + public static VarHandle rfDabNotchEnable$VH() { + return sdrplay_api_RspDuoTunerParamsT.rfDabNotchEnable$VH; + } + public static byte rfDabNotchEnable$get(MemorySegment seg) { + return (byte)sdrplay_api_RspDuoTunerParamsT.rfDabNotchEnable$VH.get(seg); + } + public static void rfDabNotchEnable$set( MemorySegment seg, byte x) { + sdrplay_api_RspDuoTunerParamsT.rfDabNotchEnable$VH.set(seg, x); + } + public static byte rfDabNotchEnable$get(MemorySegment seg, long index) { + return (byte)sdrplay_api_RspDuoTunerParamsT.rfDabNotchEnable$VH.get(seg.asSlice(index*sizeof())); + } + public static void rfDabNotchEnable$set(MemorySegment seg, long index, byte x) { + sdrplay_api_RspDuoTunerParamsT.rfDabNotchEnable$VH.set(seg.asSlice(index*sizeof()), x); + } + public static long sizeof() { return $LAYOUT().byteSize(); } + public static MemorySegment allocate(SegmentAllocator allocator) { return allocator.allocate($LAYOUT()); } + public static MemorySegment allocateArray(int len, SegmentAllocator allocator) { + return allocator.allocate(MemoryLayout.sequenceLayout(len, $LAYOUT())); + } + public static MemorySegment ofAddress(MemoryAddress addr, MemorySession session) { return RuntimeHelper.asArray(addr, $LAYOUT(), 1, session); } +} + + diff --git a/sdrplay-api/src/main/java/com/github/dsheirer/sdrplay/api/v3_08/sdrplay_api_RspDxParamsT.java b/sdrplay-api/src/main/java/com/github/dsheirer/sdrplay/api/v3_08/sdrplay_api_RspDxParamsT.java new file mode 100644 index 000000000..285357928 --- /dev/null +++ b/sdrplay-api/src/main/java/com/github/dsheirer/sdrplay/api/v3_08/sdrplay_api_RspDxParamsT.java @@ -0,0 +1,114 @@ +// Generated by jextract + +package com.github.dsheirer.sdrplay.api.v3_08; + +import java.lang.foreign.GroupLayout; +import java.lang.foreign.MemoryAddress; +import java.lang.foreign.MemoryLayout; +import java.lang.foreign.MemorySegment; +import java.lang.foreign.MemorySession; +import java.lang.foreign.SegmentAllocator; +import java.lang.invoke.VarHandle; +public class sdrplay_api_RspDxParamsT { + + static final GroupLayout $struct$LAYOUT = MemoryLayout.structLayout( + Constants$root.C_CHAR$LAYOUT.withName("hdrEnable"), + Constants$root.C_CHAR$LAYOUT.withName("biasTEnable"), + MemoryLayout.paddingLayout(16), + Constants$root.C_LONG$LAYOUT.withName("antennaSel"), + Constants$root.C_CHAR$LAYOUT.withName("rfNotchEnable"), + Constants$root.C_CHAR$LAYOUT.withName("rfDabNotchEnable"), + MemoryLayout.paddingLayout(16) + ); + public static MemoryLayout $LAYOUT() { + return sdrplay_api_RspDxParamsT.$struct$LAYOUT; + } + static final VarHandle hdrEnable$VH = $struct$LAYOUT.varHandle(MemoryLayout.PathElement.groupElement("hdrEnable")); + public static VarHandle hdrEnable$VH() { + return sdrplay_api_RspDxParamsT.hdrEnable$VH; + } + public static byte hdrEnable$get(MemorySegment seg) { + return (byte)sdrplay_api_RspDxParamsT.hdrEnable$VH.get(seg); + } + public static void hdrEnable$set( MemorySegment seg, byte x) { + sdrplay_api_RspDxParamsT.hdrEnable$VH.set(seg, x); + } + public static byte hdrEnable$get(MemorySegment seg, long index) { + return (byte)sdrplay_api_RspDxParamsT.hdrEnable$VH.get(seg.asSlice(index*sizeof())); + } + public static void hdrEnable$set(MemorySegment seg, long index, byte x) { + sdrplay_api_RspDxParamsT.hdrEnable$VH.set(seg.asSlice(index*sizeof()), x); + } + static final VarHandle biasTEnable$VH = $struct$LAYOUT.varHandle(MemoryLayout.PathElement.groupElement("biasTEnable")); + public static VarHandle biasTEnable$VH() { + return sdrplay_api_RspDxParamsT.biasTEnable$VH; + } + public static byte biasTEnable$get(MemorySegment seg) { + return (byte)sdrplay_api_RspDxParamsT.biasTEnable$VH.get(seg); + } + public static void biasTEnable$set( MemorySegment seg, byte x) { + sdrplay_api_RspDxParamsT.biasTEnable$VH.set(seg, x); + } + public static byte biasTEnable$get(MemorySegment seg, long index) { + return (byte)sdrplay_api_RspDxParamsT.biasTEnable$VH.get(seg.asSlice(index*sizeof())); + } + public static void biasTEnable$set(MemorySegment seg, long index, byte x) { + sdrplay_api_RspDxParamsT.biasTEnable$VH.set(seg.asSlice(index*sizeof()), x); + } + static final VarHandle antennaSel$VH = $struct$LAYOUT.varHandle(MemoryLayout.PathElement.groupElement("antennaSel")); + public static VarHandle antennaSel$VH() { + return sdrplay_api_RspDxParamsT.antennaSel$VH; + } + public static int antennaSel$get(MemorySegment seg) { + return (int)sdrplay_api_RspDxParamsT.antennaSel$VH.get(seg); + } + public static void antennaSel$set( MemorySegment seg, int x) { + sdrplay_api_RspDxParamsT.antennaSel$VH.set(seg, x); + } + public static int antennaSel$get(MemorySegment seg, long index) { + return (int)sdrplay_api_RspDxParamsT.antennaSel$VH.get(seg.asSlice(index*sizeof())); + } + public static void antennaSel$set(MemorySegment seg, long index, int x) { + sdrplay_api_RspDxParamsT.antennaSel$VH.set(seg.asSlice(index*sizeof()), x); + } + static final VarHandle rfNotchEnable$VH = $struct$LAYOUT.varHandle(MemoryLayout.PathElement.groupElement("rfNotchEnable")); + public static VarHandle rfNotchEnable$VH() { + return sdrplay_api_RspDxParamsT.rfNotchEnable$VH; + } + public static byte rfNotchEnable$get(MemorySegment seg) { + return (byte)sdrplay_api_RspDxParamsT.rfNotchEnable$VH.get(seg); + } + public static void rfNotchEnable$set( MemorySegment seg, byte x) { + sdrplay_api_RspDxParamsT.rfNotchEnable$VH.set(seg, x); + } + public static byte rfNotchEnable$get(MemorySegment seg, long index) { + return (byte)sdrplay_api_RspDxParamsT.rfNotchEnable$VH.get(seg.asSlice(index*sizeof())); + } + public static void rfNotchEnable$set(MemorySegment seg, long index, byte x) { + sdrplay_api_RspDxParamsT.rfNotchEnable$VH.set(seg.asSlice(index*sizeof()), x); + } + static final VarHandle rfDabNotchEnable$VH = $struct$LAYOUT.varHandle(MemoryLayout.PathElement.groupElement("rfDabNotchEnable")); + public static VarHandle rfDabNotchEnable$VH() { + return sdrplay_api_RspDxParamsT.rfDabNotchEnable$VH; + } + public static byte rfDabNotchEnable$get(MemorySegment seg) { + return (byte)sdrplay_api_RspDxParamsT.rfDabNotchEnable$VH.get(seg); + } + public static void rfDabNotchEnable$set( MemorySegment seg, byte x) { + sdrplay_api_RspDxParamsT.rfDabNotchEnable$VH.set(seg, x); + } + public static byte rfDabNotchEnable$get(MemorySegment seg, long index) { + return (byte)sdrplay_api_RspDxParamsT.rfDabNotchEnable$VH.get(seg.asSlice(index*sizeof())); + } + public static void rfDabNotchEnable$set(MemorySegment seg, long index, byte x) { + sdrplay_api_RspDxParamsT.rfDabNotchEnable$VH.set(seg.asSlice(index*sizeof()), x); + } + public static long sizeof() { return $LAYOUT().byteSize(); } + public static MemorySegment allocate(SegmentAllocator allocator) { return allocator.allocate($LAYOUT()); } + public static MemorySegment allocateArray(int len, SegmentAllocator allocator) { + return allocator.allocate(MemoryLayout.sequenceLayout(len, $LAYOUT())); + } + public static MemorySegment ofAddress(MemoryAddress addr, MemorySession session) { return RuntimeHelper.asArray(addr, $LAYOUT(), 1, session); } +} + + diff --git a/sdrplay-api/src/main/java/com/github/dsheirer/sdrplay/api/v3_08/sdrplay_api_RspDxTunerParamsT.java b/sdrplay-api/src/main/java/com/github/dsheirer/sdrplay/api/v3_08/sdrplay_api_RspDxTunerParamsT.java new file mode 100644 index 000000000..41325bc6c --- /dev/null +++ b/sdrplay-api/src/main/java/com/github/dsheirer/sdrplay/api/v3_08/sdrplay_api_RspDxTunerParamsT.java @@ -0,0 +1,44 @@ +// Generated by jextract + +package com.github.dsheirer.sdrplay.api.v3_08; + +import java.lang.foreign.GroupLayout; +import java.lang.foreign.MemoryAddress; +import java.lang.foreign.MemoryLayout; +import java.lang.foreign.MemorySegment; +import java.lang.foreign.MemorySession; +import java.lang.foreign.SegmentAllocator; +import java.lang.invoke.VarHandle; +public class sdrplay_api_RspDxTunerParamsT { + + static final GroupLayout $struct$LAYOUT = MemoryLayout.structLayout( + Constants$root.C_LONG$LAYOUT.withName("hdrBw") + ); + public static MemoryLayout $LAYOUT() { + return sdrplay_api_RspDxTunerParamsT.$struct$LAYOUT; + } + static final VarHandle hdrBw$VH = $struct$LAYOUT.varHandle(MemoryLayout.PathElement.groupElement("hdrBw")); + public static VarHandle hdrBw$VH() { + return sdrplay_api_RspDxTunerParamsT.hdrBw$VH; + } + public static int hdrBw$get(MemorySegment seg) { + return (int)sdrplay_api_RspDxTunerParamsT.hdrBw$VH.get(seg); + } + public static void hdrBw$set( MemorySegment seg, int x) { + sdrplay_api_RspDxTunerParamsT.hdrBw$VH.set(seg, x); + } + public static int hdrBw$get(MemorySegment seg, long index) { + return (int)sdrplay_api_RspDxTunerParamsT.hdrBw$VH.get(seg.asSlice(index*sizeof())); + } + public static void hdrBw$set(MemorySegment seg, long index, int x) { + sdrplay_api_RspDxTunerParamsT.hdrBw$VH.set(seg.asSlice(index*sizeof()), x); + } + public static long sizeof() { return $LAYOUT().byteSize(); } + public static MemorySegment allocate(SegmentAllocator allocator) { return allocator.allocate($LAYOUT()); } + public static MemorySegment allocateArray(int len, SegmentAllocator allocator) { + return allocator.allocate(MemoryLayout.sequenceLayout(len, $LAYOUT())); + } + public static MemorySegment ofAddress(MemoryAddress addr, MemorySession session) { return RuntimeHelper.asArray(addr, $LAYOUT(), 1, session); } +} + + diff --git a/sdrplay-api/src/main/java/com/github/dsheirer/sdrplay/api/v3_08/sdrplay_api_RxChannelParamsT.java b/sdrplay-api/src/main/java/com/github/dsheirer/sdrplay/api/v3_08/sdrplay_api_RxChannelParamsT.java new file mode 100644 index 000000000..db48f2649 --- /dev/null +++ b/sdrplay-api/src/main/java/com/github/dsheirer/sdrplay/api/v3_08/sdrplay_api_RxChannelParamsT.java @@ -0,0 +1,122 @@ +// Generated by jextract + +package com.github.dsheirer.sdrplay.api.v3_08; + +import java.lang.foreign.GroupLayout; +import java.lang.foreign.MemoryAddress; +import java.lang.foreign.MemoryLayout; +import java.lang.foreign.MemorySegment; +import java.lang.foreign.MemorySession; +import java.lang.foreign.SegmentAllocator; +public class sdrplay_api_RxChannelParamsT { + + static final GroupLayout $struct$LAYOUT = MemoryLayout.structLayout( + MemoryLayout.structLayout( + Constants$root.C_LONG$LAYOUT.withName("bwType"), + Constants$root.C_LONG$LAYOUT.withName("ifType"), + Constants$root.C_LONG$LAYOUT.withName("loMode"), + MemoryLayout.structLayout( + Constants$root.C_LONG$LAYOUT.withName("gRdB"), + Constants$root.C_CHAR$LAYOUT.withName("LNAstate"), + Constants$root.C_CHAR$LAYOUT.withName("syncUpdate"), + MemoryLayout.paddingLayout(16), + Constants$root.C_LONG$LAYOUT.withName("minGr"), + MemoryLayout.structLayout( + Constants$root.C_FLOAT$LAYOUT.withName("curr"), + Constants$root.C_FLOAT$LAYOUT.withName("max"), + Constants$root.C_FLOAT$LAYOUT.withName("min") + ).withName("gainVals") + ).withName("gain"), + MemoryLayout.paddingLayout(32), + MemoryLayout.structLayout( + Constants$root.C_DOUBLE$LAYOUT.withName("rfHz"), + Constants$root.C_CHAR$LAYOUT.withName("syncUpdate"), + MemoryLayout.paddingLayout(56) + ).withName("rfFreq"), + MemoryLayout.structLayout( + Constants$root.C_CHAR$LAYOUT.withName("dcCal"), + Constants$root.C_CHAR$LAYOUT.withName("speedUp"), + MemoryLayout.paddingLayout(16), + Constants$root.C_LONG$LAYOUT.withName("trackTime"), + Constants$root.C_LONG$LAYOUT.withName("refreshRateTime") + ).withName("dcOffsetTuner"), + MemoryLayout.paddingLayout(32) + ).withName("tunerParams"), + MemoryLayout.structLayout( + MemoryLayout.structLayout( + Constants$root.C_CHAR$LAYOUT.withName("DCenable"), + Constants$root.C_CHAR$LAYOUT.withName("IQenable") + ).withName("dcOffset"), + MemoryLayout.structLayout( + Constants$root.C_CHAR$LAYOUT.withName("enable"), + Constants$root.C_CHAR$LAYOUT.withName("decimationFactor"), + Constants$root.C_CHAR$LAYOUT.withName("wideBandSignal") + ).withName("decimation"), + MemoryLayout.paddingLayout(24), + MemoryLayout.structLayout( + Constants$root.C_LONG$LAYOUT.withName("enable"), + Constants$root.C_LONG$LAYOUT.withName("setPoint_dBfs"), + Constants$root.C_SHORT$LAYOUT.withName("attack_ms"), + Constants$root.C_SHORT$LAYOUT.withName("decay_ms"), + Constants$root.C_SHORT$LAYOUT.withName("decay_delay_ms"), + Constants$root.C_SHORT$LAYOUT.withName("decay_threshold_dB"), + Constants$root.C_LONG$LAYOUT.withName("syncUpdate") + ).withName("agc"), + Constants$root.C_LONG$LAYOUT.withName("adsbMode") + ).withName("ctrlParams"), + MemoryLayout.structLayout( + Constants$root.C_CHAR$LAYOUT.withName("biasTEnable") + ).withName("rsp1aTunerParams"), + MemoryLayout.paddingLayout(24), + MemoryLayout.structLayout( + Constants$root.C_CHAR$LAYOUT.withName("biasTEnable"), + MemoryLayout.paddingLayout(24), + Constants$root.C_LONG$LAYOUT.withName("amPortSel"), + Constants$root.C_LONG$LAYOUT.withName("antennaSel"), + Constants$root.C_CHAR$LAYOUT.withName("rfNotchEnable"), + MemoryLayout.paddingLayout(24) + ).withName("rsp2TunerParams"), + MemoryLayout.structLayout( + Constants$root.C_CHAR$LAYOUT.withName("biasTEnable"), + MemoryLayout.paddingLayout(24), + Constants$root.C_LONG$LAYOUT.withName("tuner1AmPortSel"), + Constants$root.C_CHAR$LAYOUT.withName("tuner1AmNotchEnable"), + Constants$root.C_CHAR$LAYOUT.withName("rfNotchEnable"), + Constants$root.C_CHAR$LAYOUT.withName("rfDabNotchEnable"), + MemoryLayout.paddingLayout(8) + ).withName("rspDuoTunerParams"), + MemoryLayout.structLayout( + Constants$root.C_LONG$LAYOUT.withName("hdrBw") + ).withName("rspDxTunerParams"), + MemoryLayout.paddingLayout(32) + ); + public static MemoryLayout $LAYOUT() { + return sdrplay_api_RxChannelParamsT.$struct$LAYOUT; + } + public static MemorySegment tunerParams$slice(MemorySegment seg) { + return seg.asSlice(0, 72); + } + public static MemorySegment ctrlParams$slice(MemorySegment seg) { + return seg.asSlice(72, 32); + } + public static MemorySegment rsp1aTunerParams$slice(MemorySegment seg) { + return seg.asSlice(104, 1); + } + public static MemorySegment rsp2TunerParams$slice(MemorySegment seg) { + return seg.asSlice(108, 16); + } + public static MemorySegment rspDuoTunerParams$slice(MemorySegment seg) { + return seg.asSlice(124, 12); + } + public static MemorySegment rspDxTunerParams$slice(MemorySegment seg) { + return seg.asSlice(136, 4); + } + public static long sizeof() { return $LAYOUT().byteSize(); } + public static MemorySegment allocate(SegmentAllocator allocator) { return allocator.allocate($LAYOUT()); } + public static MemorySegment allocateArray(int len, SegmentAllocator allocator) { + return allocator.allocate(MemoryLayout.sequenceLayout(len, $LAYOUT())); + } + public static MemorySegment ofAddress(MemoryAddress addr, MemorySession session) { return RuntimeHelper.asArray(addr, $LAYOUT(), 1, session); } +} + + diff --git a/sdrplay-api/src/main/java/com/github/dsheirer/sdrplay/api/v3_08/sdrplay_api_SelectDevice_t.java b/sdrplay-api/src/main/java/com/github/dsheirer/sdrplay/api/v3_08/sdrplay_api_SelectDevice_t.java new file mode 100644 index 000000000..f37ff9f9c --- /dev/null +++ b/sdrplay-api/src/main/java/com/github/dsheirer/sdrplay/api/v3_08/sdrplay_api_SelectDevice_t.java @@ -0,0 +1,27 @@ +// Generated by jextract + +package com.github.dsheirer.sdrplay.api.v3_08; + +import java.lang.foreign.Addressable; +import java.lang.foreign.MemoryAddress; +import java.lang.foreign.MemorySegment; +import java.lang.foreign.MemorySession; +public interface sdrplay_api_SelectDevice_t { + + int apply(java.lang.foreign.MemoryAddress device); + static MemorySegment allocate(sdrplay_api_SelectDevice_t fi, MemorySession session) { + return RuntimeHelper.upcallStub(sdrplay_api_SelectDevice_t.class, fi, constants$2.sdrplay_api_SelectDevice_t$FUNC, session); + } + static sdrplay_api_SelectDevice_t ofAddress(MemoryAddress addr, MemorySession session) { + MemorySegment symbol = MemorySegment.ofAddress(addr, 0, session); + return (java.lang.foreign.MemoryAddress _device) -> { + try { + return (int)constants$2.sdrplay_api_SelectDevice_t$MH.invokeExact((Addressable)symbol, (java.lang.foreign.Addressable)_device); + } catch (Throwable ex$) { + throw new AssertionError("should not reach here", ex$); + } + }; + } +} + + diff --git a/sdrplay-api/src/main/java/com/github/dsheirer/sdrplay/api/v3_08/sdrplay_api_StreamCallback_t.java b/sdrplay-api/src/main/java/com/github/dsheirer/sdrplay/api/v3_08/sdrplay_api_StreamCallback_t.java new file mode 100644 index 000000000..029027bd0 --- /dev/null +++ b/sdrplay-api/src/main/java/com/github/dsheirer/sdrplay/api/v3_08/sdrplay_api_StreamCallback_t.java @@ -0,0 +1,27 @@ +// Generated by jextract + +package com.github.dsheirer.sdrplay.api.v3_08; + +import java.lang.foreign.Addressable; +import java.lang.foreign.MemoryAddress; +import java.lang.foreign.MemorySegment; +import java.lang.foreign.MemorySession; +public interface sdrplay_api_StreamCallback_t { + + void apply(java.lang.foreign.MemoryAddress xi, java.lang.foreign.MemoryAddress xq, java.lang.foreign.MemoryAddress params, int numSamples, int reset, java.lang.foreign.MemoryAddress cbContext); + static MemorySegment allocate(sdrplay_api_StreamCallback_t fi, MemorySession session) { + return RuntimeHelper.upcallStub(sdrplay_api_StreamCallback_t.class, fi, constants$0.sdrplay_api_StreamCallback_t$FUNC, session); + } + static sdrplay_api_StreamCallback_t ofAddress(MemoryAddress addr, MemorySession session) { + MemorySegment symbol = MemorySegment.ofAddress(addr, 0, session); + return (java.lang.foreign.MemoryAddress _xi, java.lang.foreign.MemoryAddress _xq, java.lang.foreign.MemoryAddress _params, int _numSamples, int _reset, java.lang.foreign.MemoryAddress _cbContext) -> { + try { + constants$0.sdrplay_api_StreamCallback_t$MH.invokeExact((Addressable)symbol, (java.lang.foreign.Addressable)_xi, (java.lang.foreign.Addressable)_xq, (java.lang.foreign.Addressable)_params, _numSamples, _reset, (java.lang.foreign.Addressable)_cbContext); + } catch (Throwable ex$) { + throw new AssertionError("should not reach here", ex$); + } + }; + } +} + + diff --git a/sdrplay-api/src/main/java/com/github/dsheirer/sdrplay/api/v3_08/sdrplay_api_StreamCbParamsT.java b/sdrplay-api/src/main/java/com/github/dsheirer/sdrplay/api/v3_08/sdrplay_api_StreamCbParamsT.java new file mode 100644 index 000000000..d412615a5 --- /dev/null +++ b/sdrplay-api/src/main/java/com/github/dsheirer/sdrplay/api/v3_08/sdrplay_api_StreamCbParamsT.java @@ -0,0 +1,112 @@ +// Generated by jextract + +package com.github.dsheirer.sdrplay.api.v3_08; + +import java.lang.foreign.GroupLayout; +import java.lang.foreign.MemoryAddress; +import java.lang.foreign.MemoryLayout; +import java.lang.foreign.MemorySegment; +import java.lang.foreign.MemorySession; +import java.lang.foreign.SegmentAllocator; +import java.lang.invoke.VarHandle; +public class sdrplay_api_StreamCbParamsT { + + static final GroupLayout $struct$LAYOUT = MemoryLayout.structLayout( + Constants$root.C_LONG$LAYOUT.withName("firstSampleNum"), + Constants$root.C_LONG$LAYOUT.withName("grChanged"), + Constants$root.C_LONG$LAYOUT.withName("rfChanged"), + Constants$root.C_LONG$LAYOUT.withName("fsChanged"), + Constants$root.C_LONG$LAYOUT.withName("numSamples") + ); + public static MemoryLayout $LAYOUT() { + return sdrplay_api_StreamCbParamsT.$struct$LAYOUT; + } + static final VarHandle firstSampleNum$VH = $struct$LAYOUT.varHandle(MemoryLayout.PathElement.groupElement("firstSampleNum")); + public static VarHandle firstSampleNum$VH() { + return sdrplay_api_StreamCbParamsT.firstSampleNum$VH; + } + public static int firstSampleNum$get(MemorySegment seg) { + return (int)sdrplay_api_StreamCbParamsT.firstSampleNum$VH.get(seg); + } + public static void firstSampleNum$set( MemorySegment seg, int x) { + sdrplay_api_StreamCbParamsT.firstSampleNum$VH.set(seg, x); + } + public static int firstSampleNum$get(MemorySegment seg, long index) { + return (int)sdrplay_api_StreamCbParamsT.firstSampleNum$VH.get(seg.asSlice(index*sizeof())); + } + public static void firstSampleNum$set(MemorySegment seg, long index, int x) { + sdrplay_api_StreamCbParamsT.firstSampleNum$VH.set(seg.asSlice(index*sizeof()), x); + } + static final VarHandle grChanged$VH = $struct$LAYOUT.varHandle(MemoryLayout.PathElement.groupElement("grChanged")); + public static VarHandle grChanged$VH() { + return sdrplay_api_StreamCbParamsT.grChanged$VH; + } + public static int grChanged$get(MemorySegment seg) { + return (int)sdrplay_api_StreamCbParamsT.grChanged$VH.get(seg); + } + public static void grChanged$set( MemorySegment seg, int x) { + sdrplay_api_StreamCbParamsT.grChanged$VH.set(seg, x); + } + public static int grChanged$get(MemorySegment seg, long index) { + return (int)sdrplay_api_StreamCbParamsT.grChanged$VH.get(seg.asSlice(index*sizeof())); + } + public static void grChanged$set(MemorySegment seg, long index, int x) { + sdrplay_api_StreamCbParamsT.grChanged$VH.set(seg.asSlice(index*sizeof()), x); + } + static final VarHandle rfChanged$VH = $struct$LAYOUT.varHandle(MemoryLayout.PathElement.groupElement("rfChanged")); + public static VarHandle rfChanged$VH() { + return sdrplay_api_StreamCbParamsT.rfChanged$VH; + } + public static int rfChanged$get(MemorySegment seg) { + return (int)sdrplay_api_StreamCbParamsT.rfChanged$VH.get(seg); + } + public static void rfChanged$set( MemorySegment seg, int x) { + sdrplay_api_StreamCbParamsT.rfChanged$VH.set(seg, x); + } + public static int rfChanged$get(MemorySegment seg, long index) { + return (int)sdrplay_api_StreamCbParamsT.rfChanged$VH.get(seg.asSlice(index*sizeof())); + } + public static void rfChanged$set(MemorySegment seg, long index, int x) { + sdrplay_api_StreamCbParamsT.rfChanged$VH.set(seg.asSlice(index*sizeof()), x); + } + static final VarHandle fsChanged$VH = $struct$LAYOUT.varHandle(MemoryLayout.PathElement.groupElement("fsChanged")); + public static VarHandle fsChanged$VH() { + return sdrplay_api_StreamCbParamsT.fsChanged$VH; + } + public static int fsChanged$get(MemorySegment seg) { + return (int)sdrplay_api_StreamCbParamsT.fsChanged$VH.get(seg); + } + public static void fsChanged$set( MemorySegment seg, int x) { + sdrplay_api_StreamCbParamsT.fsChanged$VH.set(seg, x); + } + public static int fsChanged$get(MemorySegment seg, long index) { + return (int)sdrplay_api_StreamCbParamsT.fsChanged$VH.get(seg.asSlice(index*sizeof())); + } + public static void fsChanged$set(MemorySegment seg, long index, int x) { + sdrplay_api_StreamCbParamsT.fsChanged$VH.set(seg.asSlice(index*sizeof()), x); + } + static final VarHandle numSamples$VH = $struct$LAYOUT.varHandle(MemoryLayout.PathElement.groupElement("numSamples")); + public static VarHandle numSamples$VH() { + return sdrplay_api_StreamCbParamsT.numSamples$VH; + } + public static int numSamples$get(MemorySegment seg) { + return (int)sdrplay_api_StreamCbParamsT.numSamples$VH.get(seg); + } + public static void numSamples$set( MemorySegment seg, int x) { + sdrplay_api_StreamCbParamsT.numSamples$VH.set(seg, x); + } + public static int numSamples$get(MemorySegment seg, long index) { + return (int)sdrplay_api_StreamCbParamsT.numSamples$VH.get(seg.asSlice(index*sizeof())); + } + public static void numSamples$set(MemorySegment seg, long index, int x) { + sdrplay_api_StreamCbParamsT.numSamples$VH.set(seg.asSlice(index*sizeof()), x); + } + public static long sizeof() { return $LAYOUT().byteSize(); } + public static MemorySegment allocate(SegmentAllocator allocator) { return allocator.allocate($LAYOUT()); } + public static MemorySegment allocateArray(int len, SegmentAllocator allocator) { + return allocator.allocate(MemoryLayout.sequenceLayout(len, $LAYOUT())); + } + public static MemorySegment ofAddress(MemoryAddress addr, MemorySession session) { return RuntimeHelper.asArray(addr, $LAYOUT(), 1, session); } +} + + diff --git a/sdrplay-api/src/main/java/com/github/dsheirer/sdrplay/api/v3_08/sdrplay_api_SwapRspDuoActiveTuner_t.java b/sdrplay-api/src/main/java/com/github/dsheirer/sdrplay/api/v3_08/sdrplay_api_SwapRspDuoActiveTuner_t.java new file mode 100644 index 000000000..b28289d6a --- /dev/null +++ b/sdrplay-api/src/main/java/com/github/dsheirer/sdrplay/api/v3_08/sdrplay_api_SwapRspDuoActiveTuner_t.java @@ -0,0 +1,27 @@ +// Generated by jextract + +package com.github.dsheirer.sdrplay.api.v3_08; + +import java.lang.foreign.Addressable; +import java.lang.foreign.MemoryAddress; +import java.lang.foreign.MemorySegment; +import java.lang.foreign.MemorySession; +public interface sdrplay_api_SwapRspDuoActiveTuner_t { + + int apply(java.lang.foreign.MemoryAddress dev, java.lang.foreign.MemoryAddress tuner, int tuner1AmPortSel); + static MemorySegment allocate(sdrplay_api_SwapRspDuoActiveTuner_t fi, MemorySession session) { + return RuntimeHelper.upcallStub(sdrplay_api_SwapRspDuoActiveTuner_t.class, fi, constants$6.sdrplay_api_SwapRspDuoActiveTuner_t$FUNC, session); + } + static sdrplay_api_SwapRspDuoActiveTuner_t ofAddress(MemoryAddress addr, MemorySession session) { + MemorySegment symbol = MemorySegment.ofAddress(addr, 0, session); + return (java.lang.foreign.MemoryAddress _dev, java.lang.foreign.MemoryAddress _tuner, int _tuner1AmPortSel) -> { + try { + return (int)constants$6.sdrplay_api_SwapRspDuoActiveTuner_t$MH.invokeExact((Addressable)symbol, (java.lang.foreign.Addressable)_dev, (java.lang.foreign.Addressable)_tuner, _tuner1AmPortSel); + } catch (Throwable ex$) { + throw new AssertionError("should not reach here", ex$); + } + }; + } +} + + diff --git a/sdrplay-api/src/main/java/com/github/dsheirer/sdrplay/api/v3_08/sdrplay_api_SwapRspDuoDualTunerModeSampleRate_t.java b/sdrplay-api/src/main/java/com/github/dsheirer/sdrplay/api/v3_08/sdrplay_api_SwapRspDuoDualTunerModeSampleRate_t.java new file mode 100644 index 000000000..987f5747b --- /dev/null +++ b/sdrplay-api/src/main/java/com/github/dsheirer/sdrplay/api/v3_08/sdrplay_api_SwapRspDuoDualTunerModeSampleRate_t.java @@ -0,0 +1,27 @@ +// Generated by jextract + +package com.github.dsheirer.sdrplay.api.v3_08; + +import java.lang.foreign.Addressable; +import java.lang.foreign.MemoryAddress; +import java.lang.foreign.MemorySegment; +import java.lang.foreign.MemorySession; +public interface sdrplay_api_SwapRspDuoDualTunerModeSampleRate_t { + + int apply(java.lang.foreign.MemoryAddress currentSampleRate, double newSampleRate); + static MemorySegment allocate(sdrplay_api_SwapRspDuoDualTunerModeSampleRate_t fi, MemorySession session) { + return RuntimeHelper.upcallStub(sdrplay_api_SwapRspDuoDualTunerModeSampleRate_t.class, fi, constants$6.sdrplay_api_SwapRspDuoDualTunerModeSampleRate_t$FUNC, session); + } + static sdrplay_api_SwapRspDuoDualTunerModeSampleRate_t ofAddress(MemoryAddress addr, MemorySession session) { + MemorySegment symbol = MemorySegment.ofAddress(addr, 0, session); + return (java.lang.foreign.MemoryAddress _currentSampleRate, double _newSampleRate) -> { + try { + return (int)constants$6.sdrplay_api_SwapRspDuoDualTunerModeSampleRate_t$MH.invokeExact((Addressable)symbol, (java.lang.foreign.Addressable)_currentSampleRate, _newSampleRate); + } catch (Throwable ex$) { + throw new AssertionError("should not reach here", ex$); + } + }; + } +} + + diff --git a/sdrplay-api/src/main/java/com/github/dsheirer/sdrplay/api/v3_08/sdrplay_api_SwapRspDuoMode_t.java b/sdrplay-api/src/main/java/com/github/dsheirer/sdrplay/api/v3_08/sdrplay_api_SwapRspDuoMode_t.java new file mode 100644 index 000000000..7b13b348f --- /dev/null +++ b/sdrplay-api/src/main/java/com/github/dsheirer/sdrplay/api/v3_08/sdrplay_api_SwapRspDuoMode_t.java @@ -0,0 +1,27 @@ +// Generated by jextract + +package com.github.dsheirer.sdrplay.api.v3_08; + +import java.lang.foreign.Addressable; +import java.lang.foreign.MemoryAddress; +import java.lang.foreign.MemorySegment; +import java.lang.foreign.MemorySession; +public interface sdrplay_api_SwapRspDuoMode_t { + + int apply(java.lang.foreign.MemoryAddress currDevice, java.lang.foreign.MemoryAddress deviceParams, int rspDuoMode, double sampleRate, int tuner, int bwType, int ifType, int tuner1AmPortSel); + static MemorySegment allocate(sdrplay_api_SwapRspDuoMode_t fi, MemorySession session) { + return RuntimeHelper.upcallStub(sdrplay_api_SwapRspDuoMode_t.class, fi, constants$6.sdrplay_api_SwapRspDuoMode_t$FUNC, session); + } + static sdrplay_api_SwapRspDuoMode_t ofAddress(MemoryAddress addr, MemorySession session) { + MemorySegment symbol = MemorySegment.ofAddress(addr, 0, session); + return (java.lang.foreign.MemoryAddress _currDevice, java.lang.foreign.MemoryAddress _deviceParams, int _rspDuoMode, double _sampleRate, int _tuner, int _bwType, int _ifType, int _tuner1AmPortSel) -> { + try { + return (int)constants$6.sdrplay_api_SwapRspDuoMode_t$MH.invokeExact((Addressable)symbol, (java.lang.foreign.Addressable)_currDevice, (java.lang.foreign.Addressable)_deviceParams, _rspDuoMode, _sampleRate, _tuner, _bwType, _ifType, _tuner1AmPortSel); + } catch (Throwable ex$) { + throw new AssertionError("should not reach here", ex$); + } + }; + } +} + + diff --git a/sdrplay-api/src/main/java/com/github/dsheirer/sdrplay/api/v3_08/sdrplay_api_SyncUpdateT.java b/sdrplay-api/src/main/java/com/github/dsheirer/sdrplay/api/v3_08/sdrplay_api_SyncUpdateT.java new file mode 100644 index 000000000..9ea8d932d --- /dev/null +++ b/sdrplay-api/src/main/java/com/github/dsheirer/sdrplay/api/v3_08/sdrplay_api_SyncUpdateT.java @@ -0,0 +1,61 @@ +// Generated by jextract + +package com.github.dsheirer.sdrplay.api.v3_08; + +import java.lang.foreign.GroupLayout; +import java.lang.foreign.MemoryAddress; +import java.lang.foreign.MemoryLayout; +import java.lang.foreign.MemorySegment; +import java.lang.foreign.MemorySession; +import java.lang.foreign.SegmentAllocator; +import java.lang.invoke.VarHandle; +public class sdrplay_api_SyncUpdateT { + + static final GroupLayout $struct$LAYOUT = MemoryLayout.structLayout( + Constants$root.C_LONG$LAYOUT.withName("sampleNum"), + Constants$root.C_LONG$LAYOUT.withName("period") + ); + public static MemoryLayout $LAYOUT() { + return sdrplay_api_SyncUpdateT.$struct$LAYOUT; + } + static final VarHandle sampleNum$VH = $struct$LAYOUT.varHandle(MemoryLayout.PathElement.groupElement("sampleNum")); + public static VarHandle sampleNum$VH() { + return sdrplay_api_SyncUpdateT.sampleNum$VH; + } + public static int sampleNum$get(MemorySegment seg) { + return (int)sdrplay_api_SyncUpdateT.sampleNum$VH.get(seg); + } + public static void sampleNum$set( MemorySegment seg, int x) { + sdrplay_api_SyncUpdateT.sampleNum$VH.set(seg, x); + } + public static int sampleNum$get(MemorySegment seg, long index) { + return (int)sdrplay_api_SyncUpdateT.sampleNum$VH.get(seg.asSlice(index*sizeof())); + } + public static void sampleNum$set(MemorySegment seg, long index, int x) { + sdrplay_api_SyncUpdateT.sampleNum$VH.set(seg.asSlice(index*sizeof()), x); + } + static final VarHandle period$VH = $struct$LAYOUT.varHandle(MemoryLayout.PathElement.groupElement("period")); + public static VarHandle period$VH() { + return sdrplay_api_SyncUpdateT.period$VH; + } + public static int period$get(MemorySegment seg) { + return (int)sdrplay_api_SyncUpdateT.period$VH.get(seg); + } + public static void period$set( MemorySegment seg, int x) { + sdrplay_api_SyncUpdateT.period$VH.set(seg, x); + } + public static int period$get(MemorySegment seg, long index) { + return (int)sdrplay_api_SyncUpdateT.period$VH.get(seg.asSlice(index*sizeof())); + } + public static void period$set(MemorySegment seg, long index, int x) { + sdrplay_api_SyncUpdateT.period$VH.set(seg.asSlice(index*sizeof()), x); + } + public static long sizeof() { return $LAYOUT().byteSize(); } + public static MemorySegment allocate(SegmentAllocator allocator) { return allocator.allocate($LAYOUT()); } + public static MemorySegment allocateArray(int len, SegmentAllocator allocator) { + return allocator.allocate(MemoryLayout.sequenceLayout(len, $LAYOUT())); + } + public static MemorySegment ofAddress(MemoryAddress addr, MemorySession session) { return RuntimeHelper.asArray(addr, $LAYOUT(), 1, session); } +} + + diff --git a/sdrplay-api/src/main/java/com/github/dsheirer/sdrplay/api/v3_08/sdrplay_api_TunerParamsT.java b/sdrplay-api/src/main/java/com/github/dsheirer/sdrplay/api/v3_08/sdrplay_api_TunerParamsT.java new file mode 100644 index 000000000..8e34576ed --- /dev/null +++ b/sdrplay-api/src/main/java/com/github/dsheirer/sdrplay/api/v3_08/sdrplay_api_TunerParamsT.java @@ -0,0 +1,113 @@ +// Generated by jextract + +package com.github.dsheirer.sdrplay.api.v3_08; + +import java.lang.foreign.GroupLayout; +import java.lang.foreign.MemoryAddress; +import java.lang.foreign.MemoryLayout; +import java.lang.foreign.MemorySegment; +import java.lang.foreign.MemorySession; +import java.lang.foreign.SegmentAllocator; +import java.lang.invoke.VarHandle; +public class sdrplay_api_TunerParamsT { + + static final GroupLayout $struct$LAYOUT = MemoryLayout.structLayout( + Constants$root.C_LONG$LAYOUT.withName("bwType"), + Constants$root.C_LONG$LAYOUT.withName("ifType"), + Constants$root.C_LONG$LAYOUT.withName("loMode"), + MemoryLayout.structLayout( + Constants$root.C_LONG$LAYOUT.withName("gRdB"), + Constants$root.C_CHAR$LAYOUT.withName("LNAstate"), + Constants$root.C_CHAR$LAYOUT.withName("syncUpdate"), + MemoryLayout.paddingLayout(16), + Constants$root.C_LONG$LAYOUT.withName("minGr"), + MemoryLayout.structLayout( + Constants$root.C_FLOAT$LAYOUT.withName("curr"), + Constants$root.C_FLOAT$LAYOUT.withName("max"), + Constants$root.C_FLOAT$LAYOUT.withName("min") + ).withName("gainVals") + ).withName("gain"), + MemoryLayout.paddingLayout(32), + MemoryLayout.structLayout( + Constants$root.C_DOUBLE$LAYOUT.withName("rfHz"), + Constants$root.C_CHAR$LAYOUT.withName("syncUpdate"), + MemoryLayout.paddingLayout(56) + ).withName("rfFreq"), + MemoryLayout.structLayout( + Constants$root.C_CHAR$LAYOUT.withName("dcCal"), + Constants$root.C_CHAR$LAYOUT.withName("speedUp"), + MemoryLayout.paddingLayout(16), + Constants$root.C_LONG$LAYOUT.withName("trackTime"), + Constants$root.C_LONG$LAYOUT.withName("refreshRateTime") + ).withName("dcOffsetTuner"), + MemoryLayout.paddingLayout(32) + ); + public static MemoryLayout $LAYOUT() { + return sdrplay_api_TunerParamsT.$struct$LAYOUT; + } + static final VarHandle bwType$VH = $struct$LAYOUT.varHandle(MemoryLayout.PathElement.groupElement("bwType")); + public static VarHandle bwType$VH() { + return sdrplay_api_TunerParamsT.bwType$VH; + } + public static int bwType$get(MemorySegment seg) { + return (int)sdrplay_api_TunerParamsT.bwType$VH.get(seg); + } + public static void bwType$set( MemorySegment seg, int x) { + sdrplay_api_TunerParamsT.bwType$VH.set(seg, x); + } + public static int bwType$get(MemorySegment seg, long index) { + return (int)sdrplay_api_TunerParamsT.bwType$VH.get(seg.asSlice(index*sizeof())); + } + public static void bwType$set(MemorySegment seg, long index, int x) { + sdrplay_api_TunerParamsT.bwType$VH.set(seg.asSlice(index*sizeof()), x); + } + static final VarHandle ifType$VH = $struct$LAYOUT.varHandle(MemoryLayout.PathElement.groupElement("ifType")); + public static VarHandle ifType$VH() { + return sdrplay_api_TunerParamsT.ifType$VH; + } + public static int ifType$get(MemorySegment seg) { + return (int)sdrplay_api_TunerParamsT.ifType$VH.get(seg); + } + public static void ifType$set( MemorySegment seg, int x) { + sdrplay_api_TunerParamsT.ifType$VH.set(seg, x); + } + public static int ifType$get(MemorySegment seg, long index) { + return (int)sdrplay_api_TunerParamsT.ifType$VH.get(seg.asSlice(index*sizeof())); + } + public static void ifType$set(MemorySegment seg, long index, int x) { + sdrplay_api_TunerParamsT.ifType$VH.set(seg.asSlice(index*sizeof()), x); + } + static final VarHandle loMode$VH = $struct$LAYOUT.varHandle(MemoryLayout.PathElement.groupElement("loMode")); + public static VarHandle loMode$VH() { + return sdrplay_api_TunerParamsT.loMode$VH; + } + public static int loMode$get(MemorySegment seg) { + return (int)sdrplay_api_TunerParamsT.loMode$VH.get(seg); + } + public static void loMode$set( MemorySegment seg, int x) { + sdrplay_api_TunerParamsT.loMode$VH.set(seg, x); + } + public static int loMode$get(MemorySegment seg, long index) { + return (int)sdrplay_api_TunerParamsT.loMode$VH.get(seg.asSlice(index*sizeof())); + } + public static void loMode$set(MemorySegment seg, long index, int x) { + sdrplay_api_TunerParamsT.loMode$VH.set(seg.asSlice(index*sizeof()), x); + } + public static MemorySegment gain$slice(MemorySegment seg) { + return seg.asSlice(12, 24); + } + public static MemorySegment rfFreq$slice(MemorySegment seg) { + return seg.asSlice(40, 16); + } + public static MemorySegment dcOffsetTuner$slice(MemorySegment seg) { + return seg.asSlice(56, 12); + } + public static long sizeof() { return $LAYOUT().byteSize(); } + public static MemorySegment allocate(SegmentAllocator allocator) { return allocator.allocate($LAYOUT()); } + public static MemorySegment allocateArray(int len, SegmentAllocator allocator) { + return allocator.allocate(MemoryLayout.sequenceLayout(len, $LAYOUT())); + } + public static MemorySegment ofAddress(MemoryAddress addr, MemorySession session) { return RuntimeHelper.asArray(addr, $LAYOUT(), 1, session); } +} + + diff --git a/sdrplay-api/src/main/java/com/github/dsheirer/sdrplay/api/v3_08/sdrplay_api_Uninit_t.java b/sdrplay-api/src/main/java/com/github/dsheirer/sdrplay/api/v3_08/sdrplay_api_Uninit_t.java new file mode 100644 index 000000000..0dc19bbae --- /dev/null +++ b/sdrplay-api/src/main/java/com/github/dsheirer/sdrplay/api/v3_08/sdrplay_api_Uninit_t.java @@ -0,0 +1,27 @@ +// Generated by jextract + +package com.github.dsheirer.sdrplay.api.v3_08; + +import java.lang.foreign.Addressable; +import java.lang.foreign.MemoryAddress; +import java.lang.foreign.MemorySegment; +import java.lang.foreign.MemorySession; +public interface sdrplay_api_Uninit_t { + + int apply(java.lang.foreign.MemoryAddress dev); + static MemorySegment allocate(sdrplay_api_Uninit_t fi, MemorySession session) { + return RuntimeHelper.upcallStub(sdrplay_api_Uninit_t.class, fi, constants$5.sdrplay_api_Uninit_t$FUNC, session); + } + static sdrplay_api_Uninit_t ofAddress(MemoryAddress addr, MemorySession session) { + MemorySegment symbol = MemorySegment.ofAddress(addr, 0, session); + return (java.lang.foreign.MemoryAddress _dev) -> { + try { + return (int)constants$5.sdrplay_api_Uninit_t$MH.invokeExact((Addressable)symbol, (java.lang.foreign.Addressable)_dev); + } catch (Throwable ex$) { + throw new AssertionError("should not reach here", ex$); + } + }; + } +} + + diff --git a/sdrplay-api/src/main/java/com/github/dsheirer/sdrplay/api/v3_08/sdrplay_api_UnlockDeviceApi_t.java b/sdrplay-api/src/main/java/com/github/dsheirer/sdrplay/api/v3_08/sdrplay_api_UnlockDeviceApi_t.java new file mode 100644 index 000000000..d7aa1f639 --- /dev/null +++ b/sdrplay-api/src/main/java/com/github/dsheirer/sdrplay/api/v3_08/sdrplay_api_UnlockDeviceApi_t.java @@ -0,0 +1,27 @@ +// Generated by jextract + +package com.github.dsheirer.sdrplay.api.v3_08; + +import java.lang.foreign.Addressable; +import java.lang.foreign.MemoryAddress; +import java.lang.foreign.MemorySegment; +import java.lang.foreign.MemorySession; +public interface sdrplay_api_UnlockDeviceApi_t { + + int apply(); + static MemorySegment allocate(sdrplay_api_UnlockDeviceApi_t fi, MemorySession session) { + return RuntimeHelper.upcallStub(sdrplay_api_UnlockDeviceApi_t.class, fi, constants$2.sdrplay_api_UnlockDeviceApi_t$FUNC, session); + } + static sdrplay_api_UnlockDeviceApi_t ofAddress(MemoryAddress addr, MemorySession session) { + MemorySegment symbol = MemorySegment.ofAddress(addr, 0, session); + return () -> { + try { + return (int)constants$2.sdrplay_api_UnlockDeviceApi_t$MH.invokeExact((Addressable)symbol); + } catch (Throwable ex$) { + throw new AssertionError("should not reach here", ex$); + } + }; + } +} + + diff --git a/sdrplay-api/src/main/java/com/github/dsheirer/sdrplay/api/v3_08/sdrplay_api_Update_t.java b/sdrplay-api/src/main/java/com/github/dsheirer/sdrplay/api/v3_08/sdrplay_api_Update_t.java new file mode 100644 index 000000000..2caca357f --- /dev/null +++ b/sdrplay-api/src/main/java/com/github/dsheirer/sdrplay/api/v3_08/sdrplay_api_Update_t.java @@ -0,0 +1,27 @@ +// Generated by jextract + +package com.github.dsheirer.sdrplay.api.v3_08; + +import java.lang.foreign.Addressable; +import java.lang.foreign.MemoryAddress; +import java.lang.foreign.MemorySegment; +import java.lang.foreign.MemorySession; +public interface sdrplay_api_Update_t { + + int apply(java.lang.foreign.MemoryAddress dev, int tuner, int reasonForUpdate, int reasonForUpdateExt1); + static MemorySegment allocate(sdrplay_api_Update_t fi, MemorySession session) { + return RuntimeHelper.upcallStub(sdrplay_api_Update_t.class, fi, constants$5.sdrplay_api_Update_t$FUNC, session); + } + static sdrplay_api_Update_t ofAddress(MemoryAddress addr, MemorySession session) { + MemorySegment symbol = MemorySegment.ofAddress(addr, 0, session); + return (java.lang.foreign.MemoryAddress _dev, int _tuner, int _reasonForUpdate, int _reasonForUpdateExt1) -> { + try { + return (int)constants$5.sdrplay_api_Update_t$MH.invokeExact((Addressable)symbol, (java.lang.foreign.Addressable)_dev, _tuner, _reasonForUpdate, _reasonForUpdateExt1); + } catch (Throwable ex$) { + throw new AssertionError("should not reach here", ex$); + } + }; + } +} + + diff --git a/sdrplay-api/src/main/java/com/github/dsheirer/sdrplay/api/v3_08/sdrplay_api_h.java b/sdrplay-api/src/main/java/com/github/dsheirer/sdrplay/api/v3_08/sdrplay_api_h.java new file mode 100644 index 000000000..067e97ebe --- /dev/null +++ b/sdrplay-api/src/main/java/com/github/dsheirer/sdrplay/api/v3_08/sdrplay_api_h.java @@ -0,0 +1,740 @@ +// Generated by jextract + +package com.github.dsheirer.sdrplay.api.v3_08; + +import java.lang.foreign.Addressable; +import java.lang.foreign.MemoryAddress; +import java.lang.invoke.MethodHandle; + +import static java.lang.foreign.ValueLayout.OfAddress; +import static java.lang.foreign.ValueLayout.OfByte; +import static java.lang.foreign.ValueLayout.OfDouble; +import static java.lang.foreign.ValueLayout.OfFloat; +import static java.lang.foreign.ValueLayout.OfInt; +import static java.lang.foreign.ValueLayout.OfLong; +import static java.lang.foreign.ValueLayout.OfShort; +public class sdrplay_api_h { + + /* package-private */ sdrplay_api_h() {} + public static OfByte C_CHAR = Constants$root.C_CHAR$LAYOUT; + public static OfShort C_SHORT = Constants$root.C_SHORT$LAYOUT; + public static OfInt C_INT = Constants$root.C_LONG$LAYOUT; + public static OfInt C_LONG = Constants$root.C_LONG$LAYOUT; + public static OfLong C_LONG_LONG = Constants$root.C_LONG_LONG$LAYOUT; + public static OfFloat C_FLOAT = Constants$root.C_FLOAT$LAYOUT; + public static OfDouble C_DOUBLE = Constants$root.C_DOUBLE$LAYOUT; + public static OfAddress C_POINTER = Constants$root.C_POINTER$LAYOUT; + public static int RSPIA_NUM_LNA_STATES() { + return (int)10L; + } + public static int RSPIA_NUM_LNA_STATES_AM() { + return (int)7L; + } + public static int RSPIA_NUM_LNA_STATES_LBAND() { + return (int)9L; + } + public static int RSPII_NUM_LNA_STATES() { + return (int)9L; + } + public static int RSPII_NUM_LNA_STATES_AMPORT() { + return (int)5L; + } + public static int RSPII_NUM_LNA_STATES_420MHZ() { + return (int)6L; + } + public static int RSPDUO_NUM_LNA_STATES() { + return (int)10L; + } + public static int RSPDUO_NUM_LNA_STATES_AMPORT() { + return (int)5L; + } + public static int RSPDUO_NUM_LNA_STATES_AM() { + return (int)7L; + } + public static int RSPDUO_NUM_LNA_STATES_LBAND() { + return (int)9L; + } + public static int RSPDX_NUM_LNA_STATES() { + return (int)28L; + } + public static int RSPDX_NUM_LNA_STATES_AMPORT2_0_12() { + return (int)19L; + } + public static int RSPDX_NUM_LNA_STATES_AMPORT2_12_50() { + return (int)20L; + } + public static int RSPDX_NUM_LNA_STATES_AMPORT2_50_60() { + return (int)25L; + } + public static int RSPDX_NUM_LNA_STATES_VHF_BAND3() { + return (int)27L; + } + public static int RSPDX_NUM_LNA_STATES_420MHZ() { + return (int)21L; + } + public static int RSPDX_NUM_LNA_STATES_LBAND() { + return (int)19L; + } + public static int RSPDX_NUM_LNA_STATES_DX() { + return (int)22L; + } + public static int sdrplay_api_Rsp2_ANTENNA_A() { + return (int)5L; + } + public static int sdrplay_api_Rsp2_ANTENNA_B() { + return (int)6L; + } + public static int sdrplay_api_Rsp2_AMPORT_1() { + return (int)1L; + } + public static int sdrplay_api_Rsp2_AMPORT_2() { + return (int)0L; + } + public static int sdrplay_api_RspDuoMode_Unknown() { + return (int)0L; + } + public static int sdrplay_api_RspDuoMode_Single_Tuner() { + return (int)1L; + } + public static int sdrplay_api_RspDuoMode_Dual_Tuner() { + return (int)2L; + } + public static int sdrplay_api_RspDuoMode_Master() { + return (int)4L; + } + public static int sdrplay_api_RspDuoMode_Slave() { + return (int)8L; + } + public static int sdrplay_api_RspDuo_AMPORT_1() { + return (int)1L; + } + public static int sdrplay_api_RspDuo_AMPORT_2() { + return (int)0L; + } + public static int sdrplay_api_BW_Undefined() { + return (int)0L; + } + public static int sdrplay_api_BW_0_200() { + return (int)200L; + } + public static int sdrplay_api_BW_0_300() { + return (int)300L; + } + public static int sdrplay_api_BW_0_600() { + return (int)600L; + } + public static int sdrplay_api_BW_1_536() { + return (int)1536L; + } + public static int sdrplay_api_BW_5_000() { + return (int)5000L; + } + public static int sdrplay_api_BW_6_000() { + return (int)6000L; + } + public static int sdrplay_api_BW_7_000() { + return (int)7000L; + } + public static int sdrplay_api_BW_8_000() { + return (int)8000L; + } + public static int sdrplay_api_IF_Undefined() { + return (int)-1L; + } + public static int sdrplay_api_IF_Zero() { + return (int)0L; + } + public static int sdrplay_api_IF_0_450() { + return (int)450L; + } + public static int sdrplay_api_IF_1_620() { + return (int)1620L; + } + public static int sdrplay_api_IF_2_048() { + return (int)2048L; + } + public static int sdrplay_api_LO_Undefined() { + return (int)0L; + } + public static int sdrplay_api_LO_Auto() { + return (int)1L; + } + public static int sdrplay_api_LO_120MHz() { + return (int)2L; + } + public static int sdrplay_api_LO_144MHz() { + return (int)3L; + } + public static int sdrplay_api_LO_168MHz() { + return (int)4L; + } + public static int sdrplay_api_EXTENDED_MIN_GR() { + return (int)0L; + } + public static int sdrplay_api_NORMAL_MIN_GR() { + return (int)20L; + } + public static int sdrplay_api_Tuner_Neither() { + return (int)0L; + } + public static int sdrplay_api_Tuner_A() { + return (int)1L; + } + public static int sdrplay_api_Tuner_B() { + return (int)2L; + } + public static int sdrplay_api_Tuner_Both() { + return (int)3L; + } + public static int sdrplay_api_RspDx_ANTENNA_A() { + return (int)0L; + } + public static int sdrplay_api_RspDx_ANTENNA_B() { + return (int)1L; + } + public static int sdrplay_api_RspDx_ANTENNA_C() { + return (int)2L; + } + public static int sdrplay_api_RspDx_HDRMODE_BW_0_200() { + return (int)0L; + } + public static int sdrplay_api_RspDx_HDRMODE_BW_0_500() { + return (int)1L; + } + public static int sdrplay_api_RspDx_HDRMODE_BW_1_200() { + return (int)2L; + } + public static int sdrplay_api_RspDx_HDRMODE_BW_1_700() { + return (int)3L; + } + public static int sdrplay_api_ISOCH() { + return (int)0L; + } + public static int sdrplay_api_BULK() { + return (int)1L; + } + public static int sdrplay_api_AGC_DISABLE() { + return (int)0L; + } + public static int sdrplay_api_AGC_100HZ() { + return (int)1L; + } + public static int sdrplay_api_AGC_50HZ() { + return (int)2L; + } + public static int sdrplay_api_AGC_5HZ() { + return (int)3L; + } + public static int sdrplay_api_AGC_CTRL_EN() { + return (int)4L; + } + public static int sdrplay_api_ADSB_DECIMATION() { + return (int)0L; + } + public static int sdrplay_api_ADSB_NO_DECIMATION_LOWPASS() { + return (int)1L; + } + public static int sdrplay_api_ADSB_NO_DECIMATION_BANDPASS_2MHZ() { + return (int)2L; + } + public static int sdrplay_api_ADSB_NO_DECIMATION_BANDPASS_3MHZ() { + return (int)3L; + } + public static int sdrplay_api_Overload_Detected() { + return (int)0L; + } + public static int sdrplay_api_Overload_Corrected() { + return (int)1L; + } + public static int sdrplay_api_MasterInitialised() { + return (int)0L; + } + public static int sdrplay_api_SlaveAttached() { + return (int)1L; + } + public static int sdrplay_api_SlaveDetached() { + return (int)2L; + } + public static int sdrplay_api_SlaveInitialised() { + return (int)3L; + } + public static int sdrplay_api_SlaveUninitialised() { + return (int)4L; + } + public static int sdrplay_api_MasterDllDisappeared() { + return (int)5L; + } + public static int sdrplay_api_SlaveDllDisappeared() { + return (int)6L; + } + public static int sdrplay_api_GainChange() { + return (int)0L; + } + public static int sdrplay_api_PowerOverloadChange() { + return (int)1L; + } + public static int sdrplay_api_DeviceRemoved() { + return (int)2L; + } + public static int sdrplay_api_RspDuoModeChange() { + return (int)3L; + } + public static int sdrplay_api_DeviceFailure() { + return (int)4L; + } + public static OfAddress HANDLE = Constants$root.C_POINTER$LAYOUT; + public static int sdrplay_api_Success() { + return (int)0L; + } + public static int sdrplay_api_Fail() { + return (int)1L; + } + public static int sdrplay_api_InvalidParam() { + return (int)2L; + } + public static int sdrplay_api_OutOfRange() { + return (int)3L; + } + public static int sdrplay_api_GainUpdateError() { + return (int)4L; + } + public static int sdrplay_api_RfUpdateError() { + return (int)5L; + } + public static int sdrplay_api_FsUpdateError() { + return (int)6L; + } + public static int sdrplay_api_HwError() { + return (int)7L; + } + public static int sdrplay_api_AliasingError() { + return (int)8L; + } + public static int sdrplay_api_AlreadyInitialised() { + return (int)9L; + } + public static int sdrplay_api_NotInitialised() { + return (int)10L; + } + public static int sdrplay_api_NotEnabled() { + return (int)11L; + } + public static int sdrplay_api_HwVerError() { + return (int)12L; + } + public static int sdrplay_api_OutOfMemError() { + return (int)13L; + } + public static int sdrplay_api_ServiceNotResponding() { + return (int)14L; + } + public static int sdrplay_api_StartPending() { + return (int)15L; + } + public static int sdrplay_api_StopPending() { + return (int)16L; + } + public static int sdrplay_api_InvalidMode() { + return (int)17L; + } + public static int sdrplay_api_FailedVerification1() { + return (int)18L; + } + public static int sdrplay_api_FailedVerification2() { + return (int)19L; + } + public static int sdrplay_api_FailedVerification3() { + return (int)20L; + } + public static int sdrplay_api_FailedVerification4() { + return (int)21L; + } + public static int sdrplay_api_FailedVerification5() { + return (int)22L; + } + public static int sdrplay_api_FailedVerification6() { + return (int)23L; + } + public static int sdrplay_api_InvalidServiceVersion() { + return (int)24L; + } + public static int sdrplay_api_Update_None() { + return (int)0L; + } + public static int sdrplay_api_Update_Dev_Fs() { + return (int)1L; + } + public static int sdrplay_api_Update_Dev_Ppm() { + return (int)2L; + } + public static int sdrplay_api_Update_Dev_SyncUpdate() { + return (int)4L; + } + public static int sdrplay_api_Update_Dev_ResetFlags() { + return (int)8L; + } + public static int sdrplay_api_Update_Rsp1a_BiasTControl() { + return (int)16L; + } + public static int sdrplay_api_Update_Rsp1a_RfNotchControl() { + return (int)32L; + } + public static int sdrplay_api_Update_Rsp1a_RfDabNotchControl() { + return (int)64L; + } + public static int sdrplay_api_Update_Rsp2_BiasTControl() { + return (int)128L; + } + public static int sdrplay_api_Update_Rsp2_AmPortSelect() { + return (int)256L; + } + public static int sdrplay_api_Update_Rsp2_AntennaControl() { + return (int)512L; + } + public static int sdrplay_api_Update_Rsp2_RfNotchControl() { + return (int)1024L; + } + public static int sdrplay_api_Update_Rsp2_ExtRefControl() { + return (int)2048L; + } + public static int sdrplay_api_Update_RspDuo_ExtRefControl() { + return (int)4096L; + } + public static int sdrplay_api_Update_Master_Spare_1() { + return (int)8192L; + } + public static int sdrplay_api_Update_Master_Spare_2() { + return (int)16384L; + } + public static int sdrplay_api_Update_Tuner_Gr() { + return (int)32768L; + } + public static int sdrplay_api_Update_Tuner_GrLimits() { + return (int)65536L; + } + public static int sdrplay_api_Update_Tuner_Frf() { + return (int)131072L; + } + public static int sdrplay_api_Update_Tuner_BwType() { + return (int)262144L; + } + public static int sdrplay_api_Update_Tuner_IfType() { + return (int)524288L; + } + public static int sdrplay_api_Update_Tuner_DcOffset() { + return (int)1048576L; + } + public static int sdrplay_api_Update_Tuner_LoMode() { + return (int)2097152L; + } + public static int sdrplay_api_Update_Ctrl_DCoffsetIQimbalance() { + return (int)4194304L; + } + public static int sdrplay_api_Update_Ctrl_Decimation() { + return (int)8388608L; + } + public static int sdrplay_api_Update_Ctrl_Agc() { + return (int)16777216L; + } + public static int sdrplay_api_Update_Ctrl_AdsbMode() { + return (int)33554432L; + } + public static int sdrplay_api_Update_Ctrl_OverloadMsgAck() { + return (int)67108864L; + } + public static int sdrplay_api_Update_RspDuo_BiasTControl() { + return (int)134217728L; + } + public static int sdrplay_api_Update_RspDuo_AmPortSelect() { + return (int)268435456L; + } + public static int sdrplay_api_Update_RspDuo_Tuner1AmNotchControl() { + return (int)536870912L; + } + public static int sdrplay_api_Update_RspDuo_RfNotchControl() { + return (int)1073741824L; + } + public static int sdrplay_api_Update_RspDuo_RfDabNotchControl() { + return (int)-2147483648L; + } + public static int sdrplay_api_Update_Ext1_None() { + return (int)0L; + } + public static int sdrplay_api_Update_RspDx_HdrEnable() { + return (int)1L; + } + public static int sdrplay_api_Update_RspDx_BiasTControl() { + return (int)2L; + } + public static int sdrplay_api_Update_RspDx_AntennaControl() { + return (int)4L; + } + public static int sdrplay_api_Update_RspDx_RfNotchControl() { + return (int)8L; + } + public static int sdrplay_api_Update_RspDx_RfDabNotchControl() { + return (int)16L; + } + public static int sdrplay_api_Update_RspDx_HdrBw() { + return (int)32L; + } + public static int sdrplay_api_DbgLvl_Disable() { + return (int)0L; + } + public static int sdrplay_api_DbgLvl_Verbose() { + return (int)1L; + } + public static int sdrplay_api_DbgLvl_Warning() { + return (int)2L; + } + public static int sdrplay_api_DbgLvl_Error() { + return (int)3L; + } + public static int sdrplay_api_DbgLvl_Message() { + return (int)4L; + } + public static MethodHandle sdrplay_api_Open$MH() { + return RuntimeHelper.requireNonNull(constants$7.sdrplay_api_Open$MH,"sdrplay_api_Open"); + } + public static int sdrplay_api_Open () { + var mh$ = sdrplay_api_Open$MH(); + try { + return (int)mh$.invokeExact(); + } catch (Throwable ex$) { + throw new AssertionError("should not reach here", ex$); + } + } + public static MethodHandle sdrplay_api_Close$MH() { + return RuntimeHelper.requireNonNull(constants$7.sdrplay_api_Close$MH,"sdrplay_api_Close"); + } + public static int sdrplay_api_Close () { + var mh$ = sdrplay_api_Close$MH(); + try { + return (int)mh$.invokeExact(); + } catch (Throwable ex$) { + throw new AssertionError("should not reach here", ex$); + } + } + public static MethodHandle sdrplay_api_ApiVersion$MH() { + return RuntimeHelper.requireNonNull(constants$7.sdrplay_api_ApiVersion$MH,"sdrplay_api_ApiVersion"); + } + public static int sdrplay_api_ApiVersion ( Addressable apiVer) { + var mh$ = sdrplay_api_ApiVersion$MH(); + try { + return (int)mh$.invokeExact(apiVer); + } catch (Throwable ex$) { + throw new AssertionError("should not reach here", ex$); + } + } + public static MethodHandle sdrplay_api_LockDeviceApi$MH() { + return RuntimeHelper.requireNonNull(constants$7.sdrplay_api_LockDeviceApi$MH,"sdrplay_api_LockDeviceApi"); + } + public static int sdrplay_api_LockDeviceApi () { + var mh$ = sdrplay_api_LockDeviceApi$MH(); + try { + return (int)mh$.invokeExact(); + } catch (Throwable ex$) { + throw new AssertionError("should not reach here", ex$); + } + } + public static MethodHandle sdrplay_api_UnlockDeviceApi$MH() { + return RuntimeHelper.requireNonNull(constants$7.sdrplay_api_UnlockDeviceApi$MH,"sdrplay_api_UnlockDeviceApi"); + } + public static int sdrplay_api_UnlockDeviceApi () { + var mh$ = sdrplay_api_UnlockDeviceApi$MH(); + try { + return (int)mh$.invokeExact(); + } catch (Throwable ex$) { + throw new AssertionError("should not reach here", ex$); + } + } + public static MethodHandle sdrplay_api_GetDevices$MH() { + return RuntimeHelper.requireNonNull(constants$7.sdrplay_api_GetDevices$MH,"sdrplay_api_GetDevices"); + } + public static int sdrplay_api_GetDevices ( Addressable devices, Addressable numDevs, int maxDevs) { + var mh$ = sdrplay_api_GetDevices$MH(); + try { + return (int)mh$.invokeExact(devices, numDevs, maxDevs); + } catch (Throwable ex$) { + throw new AssertionError("should not reach here", ex$); + } + } + public static MethodHandle sdrplay_api_SelectDevice$MH() { + return RuntimeHelper.requireNonNull(constants$8.sdrplay_api_SelectDevice$MH,"sdrplay_api_SelectDevice"); + } + public static int sdrplay_api_SelectDevice ( Addressable device) { + var mh$ = sdrplay_api_SelectDevice$MH(); + try { + return (int)mh$.invokeExact(device); + } catch (Throwable ex$) { + throw new AssertionError("should not reach here", ex$); + } + } + public static MethodHandle sdrplay_api_ReleaseDevice$MH() { + return RuntimeHelper.requireNonNull(constants$8.sdrplay_api_ReleaseDevice$MH,"sdrplay_api_ReleaseDevice"); + } + public static int sdrplay_api_ReleaseDevice ( Addressable device) { + var mh$ = sdrplay_api_ReleaseDevice$MH(); + try { + return (int)mh$.invokeExact(device); + } catch (Throwable ex$) { + throw new AssertionError("should not reach here", ex$); + } + } + public static MethodHandle sdrplay_api_GetErrorString$MH() { + return RuntimeHelper.requireNonNull(constants$8.sdrplay_api_GetErrorString$MH,"sdrplay_api_GetErrorString"); + } + public static MemoryAddress sdrplay_api_GetErrorString ( int err) { + var mh$ = sdrplay_api_GetErrorString$MH(); + try { + return (java.lang.foreign.MemoryAddress)mh$.invokeExact(err); + } catch (Throwable ex$) { + throw new AssertionError("should not reach here", ex$); + } + } + public static MethodHandle sdrplay_api_GetLastError$MH() { + return RuntimeHelper.requireNonNull(constants$8.sdrplay_api_GetLastError$MH,"sdrplay_api_GetLastError"); + } + public static MemoryAddress sdrplay_api_GetLastError ( Addressable device) { + var mh$ = sdrplay_api_GetLastError$MH(); + try { + return (java.lang.foreign.MemoryAddress)mh$.invokeExact(device); + } catch (Throwable ex$) { + throw new AssertionError("should not reach here", ex$); + } + } + public static MethodHandle sdrplay_api_DisableHeartbeat$MH() { + return RuntimeHelper.requireNonNull(constants$8.sdrplay_api_DisableHeartbeat$MH,"sdrplay_api_DisableHeartbeat"); + } + public static int sdrplay_api_DisableHeartbeat () { + var mh$ = sdrplay_api_DisableHeartbeat$MH(); + try { + return (int)mh$.invokeExact(); + } catch (Throwable ex$) { + throw new AssertionError("should not reach here", ex$); + } + } + public static MethodHandle sdrplay_api_DebugEnable$MH() { + return RuntimeHelper.requireNonNull(constants$8.sdrplay_api_DebugEnable$MH,"sdrplay_api_DebugEnable"); + } + public static int sdrplay_api_DebugEnable ( Addressable dev, int enable) { + var mh$ = sdrplay_api_DebugEnable$MH(); + try { + return (int)mh$.invokeExact(dev, enable); + } catch (Throwable ex$) { + throw new AssertionError("should not reach here", ex$); + } + } + public static MethodHandle sdrplay_api_GetDeviceParams$MH() { + return RuntimeHelper.requireNonNull(constants$9.sdrplay_api_GetDeviceParams$MH,"sdrplay_api_GetDeviceParams"); + } + public static int sdrplay_api_GetDeviceParams ( Addressable dev, Addressable deviceParams) { + var mh$ = sdrplay_api_GetDeviceParams$MH(); + try { + return (int)mh$.invokeExact(dev, deviceParams); + } catch (Throwable ex$) { + throw new AssertionError("should not reach here", ex$); + } + } + public static MethodHandle sdrplay_api_Init$MH() { + return RuntimeHelper.requireNonNull(constants$9.sdrplay_api_Init$MH,"sdrplay_api_Init"); + } + public static int sdrplay_api_Init ( Addressable dev, Addressable callbackFns, Addressable cbContext) { + var mh$ = sdrplay_api_Init$MH(); + try { + return (int)mh$.invokeExact(dev, callbackFns, cbContext); + } catch (Throwable ex$) { + throw new AssertionError("should not reach here", ex$); + } + } + public static MethodHandle sdrplay_api_Uninit$MH() { + return RuntimeHelper.requireNonNull(constants$9.sdrplay_api_Uninit$MH,"sdrplay_api_Uninit"); + } + public static int sdrplay_api_Uninit ( Addressable dev) { + var mh$ = sdrplay_api_Uninit$MH(); + try { + return (int)mh$.invokeExact(dev); + } catch (Throwable ex$) { + throw new AssertionError("should not reach here", ex$); + } + } + public static MethodHandle sdrplay_api_Update$MH() { + return RuntimeHelper.requireNonNull(constants$9.sdrplay_api_Update$MH,"sdrplay_api_Update"); + } + public static int sdrplay_api_Update ( Addressable dev, int tuner, int reasonForUpdate, int reasonForUpdateExt1) { + var mh$ = sdrplay_api_Update$MH(); + try { + return (int)mh$.invokeExact(dev, tuner, reasonForUpdate, reasonForUpdateExt1); + } catch (Throwable ex$) { + throw new AssertionError("should not reach here", ex$); + } + } + public static MethodHandle sdrplay_api_SwapRspDuoActiveTuner$MH() { + return RuntimeHelper.requireNonNull(constants$9.sdrplay_api_SwapRspDuoActiveTuner$MH,"sdrplay_api_SwapRspDuoActiveTuner"); + } + public static int sdrplay_api_SwapRspDuoActiveTuner ( Addressable dev, Addressable currentTuner, int tuner1AmPortSel) { + var mh$ = sdrplay_api_SwapRspDuoActiveTuner$MH(); + try { + return (int)mh$.invokeExact(dev, currentTuner, tuner1AmPortSel); + } catch (Throwable ex$) { + throw new AssertionError("should not reach here", ex$); + } + } + public static MethodHandle sdrplay_api_SwapRspDuoDualTunerModeSampleRate$MH() { + return RuntimeHelper.requireNonNull(constants$9.sdrplay_api_SwapRspDuoDualTunerModeSampleRate$MH,"sdrplay_api_SwapRspDuoDualTunerModeSampleRate"); + } + public static int sdrplay_api_SwapRspDuoDualTunerModeSampleRate ( Addressable dev, Addressable currentSampleRate, double newSampleRate) { + var mh$ = sdrplay_api_SwapRspDuoDualTunerModeSampleRate$MH(); + try { + return (int)mh$.invokeExact(dev, currentSampleRate, newSampleRate); + } catch (Throwable ex$) { + throw new AssertionError("should not reach here", ex$); + } + } + public static MethodHandle sdrplay_api_SwapRspDuoMode$MH() { + return RuntimeHelper.requireNonNull(constants$10.sdrplay_api_SwapRspDuoMode$MH,"sdrplay_api_SwapRspDuoMode"); + } + public static int sdrplay_api_SwapRspDuoMode ( Addressable currDevice, Addressable deviceParams, int rspDuoMode, double sampleRate, int tuner, int bwType, int ifType, int tuner1AmPortSel) { + var mh$ = sdrplay_api_SwapRspDuoMode$MH(); + try { + return (int)mh$.invokeExact(currDevice, deviceParams, rspDuoMode, sampleRate, tuner, bwType, ifType, tuner1AmPortSel); + } catch (Throwable ex$) { + throw new AssertionError("should not reach here", ex$); + } + } + public static int MAX_BB_GR() { + return (int)59L; + } + public static float SDRPLAY_API_VERSION() { + return 3.08f; + } + public static int SDRPLAY_MAX_DEVICES() { + return (int)16L; + } + public static int SDRPLAY_MAX_TUNERS_PER_DEVICE() { + return (int)2L; + } + public static int SDRPLAY_MAX_SER_NO_LEN() { + return (int)64L; + } + public static int SDRPLAY_MAX_ROOT_NM_LEN() { + return (int)32L; + } + public static int SDRPLAY_RSP1_ID() { + return (int)1L; + } + public static int SDRPLAY_RSP1A_ID() { + return (int)255L; + } + public static int SDRPLAY_RSP2_ID() { + return (int)2L; + } + public static int SDRPLAY_RSPduo_ID() { + return (int)3L; + } + public static int SDRPLAY_RSPdx_ID() { + return (int)4L; + } +} + + diff --git a/sdrplay-api/src/main/java/module-info.java b/sdrplay-api/src/main/java/module-info.java new file mode 100644 index 000000000..f9c0992be --- /dev/null +++ b/sdrplay-api/src/main/java/module-info.java @@ -0,0 +1,4 @@ +module sdrplay.api { + exports com.github.dsheirer.sdrplay.api.v3_07; + exports com.github.dsheirer.sdrplay.api.v3_08; +} \ No newline at end of file diff --git a/sdrplay-api/src/main/resources/README b/sdrplay-api/src/main/resources/README new file mode 100644 index 000000000..5d61b3ad3 --- /dev/null +++ b/sdrplay-api/src/main/resources/README @@ -0,0 +1,15 @@ +SDRplay API 3.07 +Auto-created from sdrplay api header files using JDK 17 jextract tool: + +1. Install the sdrplay api +2. On Linux, headers are located here: /usr/local/include/*.h +3. cd into the (project)/jSDRplay/sdrplay-api/src/main/java/ directory +4. Run: jextract -t io.github.dsheirer.sdrplay.api /usr/local/include/sdrplay_api.h -l libsdrplay_api --source + +IntelliJ setup +1. Run configuration +2. JVM Option: --enable-native-access=ALL-UNNAMED +3. Add library location to the java.library.path: + Linux: /usr/local/lib + Windows: ?? + MacOS: ?? diff --git a/settings.gradle b/settings.gradle index e592e50ed..ea97b6db6 100644 --- a/settings.gradle +++ b/settings.gradle @@ -1 +1,4 @@ -rootProject.name = 'sdr-trunk' \ No newline at end of file +rootProject.name = 'sdr-trunk' + +include 'jsdrplay' +include 'sdrplay-api' diff --git a/src/main/java/io/github/dsheirer/gui/SDRTrunk.java b/src/main/java/io/github/dsheirer/gui/SDRTrunk.java index 70c5a1146..6a4df9715 100644 --- a/src/main/java/io/github/dsheirer/gui/SDRTrunk.java +++ b/src/main/java/io/github/dsheirer/gui/SDRTrunk.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 @@ -59,6 +59,26 @@ import io.github.dsheirer.util.ThreadPool; import io.github.dsheirer.util.TimeStamp; import io.github.dsheirer.vector.calibrate.CalibrationManager; +import java.awt.AWTException; +import java.awt.Desktop; +import java.awt.Dimension; +import java.awt.EventQueue; +import java.awt.GraphicsEnvironment; +import java.awt.Point; +import java.awt.Robot; +import java.awt.event.ActionEvent; +import java.awt.event.ActionListener; +import java.awt.event.KeyEvent; +import java.awt.event.WindowAdapter; +import java.awt.event.WindowEvent; +import java.awt.image.BufferedImage; +import java.io.IOException; +import java.nio.file.FileSystems; +import java.nio.file.Files; +import java.nio.file.Path; +import java.util.List; +import java.util.Locale; +import java.util.Optional; import javafx.application.Platform; import javafx.scene.control.ButtonType; import jiconfont.icons.font_awesome.FontAwesome; @@ -80,26 +100,6 @@ import javax.swing.event.MenuEvent; import javax.swing.event.MenuListener; import javax.swing.plaf.metal.MetalLookAndFeel; -import java.awt.AWTException; -import java.awt.Desktop; -import java.awt.Dimension; -import java.awt.EventQueue; -import java.awt.GraphicsEnvironment; -import java.awt.Point; -import java.awt.Robot; -import java.awt.event.ActionEvent; -import java.awt.event.ActionListener; -import java.awt.event.KeyEvent; -import java.awt.event.WindowAdapter; -import java.awt.event.WindowEvent; -import java.awt.image.BufferedImage; -import java.io.IOException; -import java.nio.file.FileSystems; -import java.nio.file.Files; -import java.nio.file.Path; -import java.util.List; -import java.util.Locale; -import java.util.Optional; public class SDRTrunk implements Listener { @@ -247,7 +247,11 @@ public SDRTrunk() { mMainGui.setVisible(true); Tuner tuner = tunerSpectralDisplayManager.showFirstTuner(); - updateTitle(tuner); + + if(tuner != null) + { + updateTitle(tuner.getPreferredName()); + } } if(calibrating && !GraphicsEnvironment.isHeadless()) @@ -623,21 +627,34 @@ private Path getHomePath() @Override public void receive(TunerEvent event) { - if(event.getEvent() == TunerEvent.Event.REQUEST_MAIN_SPECTRAL_DISPLAY) + switch(event.getEvent()) { - updateTitle(event.getTuner()); + case REQUEST_MAIN_SPECTRAL_DISPLAY: + updateTitle(event.getTuner().getPreferredName()); + break; + case REQUEST_CLEAR_MAIN_SPECTRAL_DISPLAY: + updateTitle(null); + break; + case NOTIFICATION_SHUTTING_DOWN: + Tuner currentTuner = mSpectralPanel.getTuner(); + + if(event.hasTuner() && event.getTuner().equals(currentTuner) || currentTuner == null) + { + updateTitle(null); + } + break; } } /** * Updates the title bar with the tuner name - * @param tuner optional + * @param tunerName optional */ - private void updateTitle(Tuner tuner) + private void updateTitle(String tunerName) { - if(tuner != null) + if(tunerName != null) { - mMainGui.setTitle(mTitle + " - " + tuner.getPreferredName()); + mMainGui.setTitle(mTitle + " - " + tunerName); } else { diff --git a/src/main/java/io/github/dsheirer/gui/preference/PreferenceEditorFactory.java b/src/main/java/io/github/dsheirer/gui/preference/PreferenceEditorFactory.java index 5ec247de2..b2dd2ec8f 100644 --- a/src/main/java/io/github/dsheirer/gui/preference/PreferenceEditorFactory.java +++ b/src/main/java/io/github/dsheirer/gui/preference/PreferenceEditorFactory.java @@ -53,7 +53,7 @@ public static Node getEditor(PreferenceEditorType preferenceEditorType, UserPref return new DirectoryPreferenceEditor(userPreferences); case JMBE_LIBRARY: return new JmbeLibraryPreferenceEditor(userPreferences); - case SOURCE_TUNER_CHANNELIZER: + case SOURCE_TUNERS: return new TunerPreferenceEditor(userPreferences); case TALKGROUP_FORMAT: return new TalkgroupFormatPreferenceEditor(userPreferences); diff --git a/src/main/java/io/github/dsheirer/gui/preference/PreferenceEditorType.java b/src/main/java/io/github/dsheirer/gui/preference/PreferenceEditorType.java index 7c8d87618..22b268ef8 100644 --- a/src/main/java/io/github/dsheirer/gui/preference/PreferenceEditorType.java +++ b/src/main/java/io/github/dsheirer/gui/preference/PreferenceEditorType.java @@ -31,7 +31,7 @@ public enum PreferenceEditorType AUDIO_RECORD("Record"), AUDIO_OUTPUT("Output/Tones"), AUDIO_DUPLICATE_CALL_DETECTION("Duplicate Calls"), - SOURCE_TUNER_CHANNELIZER("Tuner Channelizer"), + SOURCE_TUNERS("Tuners"), TALKGROUP_FORMAT("Talkgroup & Radio ID"), VECTOR_CALIBRATION("Vector Calibration"), DEFAULT("Default"); diff --git a/src/main/java/io/github/dsheirer/gui/preference/UserPreferencesEditor.java b/src/main/java/io/github/dsheirer/gui/preference/UserPreferencesEditor.java index 240621136..37add324c 100644 --- a/src/main/java/io/github/dsheirer/gui/preference/UserPreferencesEditor.java +++ b/src/main/java/io/github/dsheirer/gui/preference/UserPreferencesEditor.java @@ -22,6 +22,8 @@ import io.github.dsheirer.eventbus.MyEventBus; import io.github.dsheirer.gui.playlist.ViewPlaylistRequest; import io.github.dsheirer.preference.UserPreferences; +import java.util.EnumMap; +import java.util.Map; import javafx.beans.value.ChangeListener; import javafx.beans.value.ObservableValue; import javafx.geometry.Insets; @@ -44,9 +46,6 @@ import org.slf4j.Logger; import org.slf4j.LoggerFactory; -import java.util.EnumMap; -import java.util.Map; - /** * Preferences editor dialog */ @@ -196,7 +195,7 @@ private TreeView getEditorSelectionTreeView() storageItem.setExpanded(true); TreeItem sourceItem = new TreeItem<>("Source"); - sourceItem.getChildren().add(new TreeItem(PreferenceEditorType.SOURCE_TUNER_CHANNELIZER)); + sourceItem.getChildren().add(new TreeItem(PreferenceEditorType.SOURCE_TUNERS)); treeRoot.getChildren().add(sourceItem); sourceItem.setExpanded(true); diff --git a/src/main/java/io/github/dsheirer/gui/preference/tuner/RspDuoSelectionMode.java b/src/main/java/io/github/dsheirer/gui/preference/tuner/RspDuoSelectionMode.java new file mode 100644 index 000000000..d726acbb5 --- /dev/null +++ b/src/main/java/io/github/dsheirer/gui/preference/tuner/RspDuoSelectionMode.java @@ -0,0 +1,62 @@ +/* + * ***************************************************************************** + * 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 io.github.dsheirer.gui.preference.tuner; + +/** + * RSPduo tuner select mode preferences. + */ +public enum RspDuoSelectionMode +{ + DUAL("Dual Tuner"), + SINGLE_1("Single Tuner 1"), + SINGLE_2("Single Tuner 2"); + + private String mLabel; + + RspDuoSelectionMode(String label) + { + mLabel = label; + } + + @Override + public String toString() + { + return mLabel; + } + + /** + * Lookup the enum entry from the value. + * @param value to match + * @return matched value or (default) DUAL if the value couldn't be matched. + */ + public static RspDuoSelectionMode fromValue(String value) + { + try + { + return RspDuoSelectionMode.valueOf(value); + } + catch(Exception e) + { + //Do nothing + } + + return DUAL; + } +} diff --git a/src/main/java/io/github/dsheirer/gui/preference/tuner/TunerPreferenceEditor.java b/src/main/java/io/github/dsheirer/gui/preference/tuner/TunerPreferenceEditor.java index 25a68d99c..d633c93c7 100644 --- a/src/main/java/io/github/dsheirer/gui/preference/tuner/TunerPreferenceEditor.java +++ b/src/main/java/io/github/dsheirer/gui/preference/tuner/TunerPreferenceEditor.java @@ -1,23 +1,20 @@ /* + * ***************************************************************************** + * Copyright (C) 2014-2022 Dennis Sheirer * - * * ****************************************************************************** - * * Copyright (C) 2014-2020 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 - * * ***************************************************************************** + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see + * **************************************************************************** */ package io.github.dsheirer.gui.preference.tuner; @@ -55,6 +52,8 @@ public class TunerPreferenceEditor extends HBox private Label mHelpTextPolyphaseLabel; private Label mHeterodyneLabel; private Label mHelpTextHeterodyneLabel; + private ChoiceBox mRspDuoTunerModeChoiceBox; + private Label mRspDuoModeLabel; public TunerPreferenceEditor(UserPreferences userPreferences) { @@ -66,19 +65,24 @@ private GridPane getEditorPane() { if(mEditorPane == null) { + int row = 0; mEditorPane = new GridPane(); mEditorPane.setVgap(10); mEditorPane.setHgap(10); mEditorPane.setPadding(new Insets(10, 10, 10, 10)); - GridPane.setHalignment(getChannelizerLabel(), HPos.LEFT); - mEditorPane.add(getChannelizerLabel(), 0, 0); - mEditorPane.add(getChannelizerTypeChoiceBox(), 1, 0); - mEditorPane.add(new Separator(Orientation.HORIZONTAL), 0, 1, 2, 1); - mEditorPane.add(getPolyphaseLabel(), 0, 2, 2, 1); - mEditorPane.add(getHelpTextPolyphaseLabel(), 0, 3, 2, 3); - mEditorPane.add(new Label(" "), 0, 6); - mEditorPane.add(getHeterodyneLabel(), 0, 7, 2, 1); - mEditorPane.add(getHelpTextHeterodyneLabel(), 0, 8, 2, 3); + GridPane.setHalignment(getChannelizerLabel(), HPos.RIGHT); + mEditorPane.add(getChannelizerLabel(), 0, row); + mEditorPane.add(getChannelizerTypeChoiceBox(), 1, row); + mEditorPane.add(getPolyphaseLabel(), 0, ++row, 2, 1); + mEditorPane.add(getHelpTextPolyphaseLabel(), 0, ++row, 2, 3); + row += 3; + mEditorPane.add(new Label(" "), 0, row); + mEditorPane.add(getHeterodyneLabel(), 0, ++row, 2, 1); + mEditorPane.add(getHelpTextHeterodyneLabel(), 0, ++row, 2, 3); + row += 3; + mEditorPane.add(new Separator(Orientation.HORIZONTAL), 0, row, 2, 1); + mEditorPane.add(getRspDuoModeLabel(), 0, ++row); + mEditorPane.add(getRspDuoTunerModeChoiceBox(), 1, row); } return mEditorPane; @@ -161,4 +165,40 @@ private Label getHelpTextHeterodyneLabel() return mHelpTextHeterodyneLabel; } + + private ChoiceBox getRspDuoTunerModeChoiceBox() + { + if(mRspDuoTunerModeChoiceBox == null) + { + mRspDuoTunerModeChoiceBox = new ChoiceBox<>(); + mRspDuoTunerModeChoiceBox.getItems().addAll(RspDuoSelectionMode.values()); + + RspDuoSelectionMode current = mTunerPreference.getRspDuoTunerMode(); + mRspDuoTunerModeChoiceBox.getSelectionModel().select(current); + + mRspDuoTunerModeChoiceBox.setOnAction(event -> { + RspDuoSelectionMode selected = mRspDuoTunerModeChoiceBox.getSelectionModel().getSelectedItem(); + mTunerPreference.setRspDuoTunerMode(selected); + + Label label = new Label("Please restart the application for this change to take effect"); + label.setWrapText(true); + Alert alert = new Alert(Alert.AlertType.WARNING); + alert.getDialogPane().setContent(label); + alert.initOwner(((Node)getRspDuoTunerModeChoiceBox()).getScene().getWindow()); + alert.show(); + }); + } + + return mRspDuoTunerModeChoiceBox; + } + + private Label getRspDuoModeLabel() + { + if(mRspDuoModeLabel == null) + { + mRspDuoModeLabel = new Label("SDRPlay RSPduo Selection Mode"); + } + + return mRspDuoModeLabel; + } } diff --git a/src/main/java/io/github/dsheirer/preference/source/TunerPreference.java b/src/main/java/io/github/dsheirer/preference/source/TunerPreference.java index 94d40e4c7..ebfb84776 100644 --- a/src/main/java/io/github/dsheirer/preference/source/TunerPreference.java +++ b/src/main/java/io/github/dsheirer/preference/source/TunerPreference.java @@ -19,14 +19,14 @@ package io.github.dsheirer.preference.source; +import io.github.dsheirer.gui.preference.tuner.RspDuoSelectionMode; import io.github.dsheirer.preference.Preference; import io.github.dsheirer.preference.PreferenceType; import io.github.dsheirer.sample.Listener; +import java.util.prefs.Preferences; import org.slf4j.Logger; import org.slf4j.LoggerFactory; -import java.util.prefs.Preferences; - /** * Tuner preferences */ @@ -35,8 +35,10 @@ public class TunerPreference extends Preference private final static Logger mLog = LoggerFactory.getLogger(TunerPreference.class); private Preferences mPreferences = Preferences.userNodeForPackage(TunerPreference.class); private static final String PREFERENCE_KEY_CHANNELIZER_TYPE = "channelizer.type"; + private static final String PREFERENCE_KEY_RSP_DUO_TUNER_MODE = "rsp.duo.tuner.mode"; private ChannelizerType mChannelizerType; + private RspDuoSelectionMode mRspDuoSelectionMode; /** * Constructs a tuner preference with the update listener @@ -94,4 +96,30 @@ public void setChannelizerType(ChannelizerType type) mPreferences.put(PREFERENCE_KEY_CHANNELIZER_TYPE, mChannelizerType.name()); notifyPreferenceUpdated(); } + + /** + * RSPduo tuner select mode. + * @return mode or a default value of DUAL + */ + public RspDuoSelectionMode getRspDuoTunerMode() + { + if(mRspDuoSelectionMode == null) + { + String mode = mPreferences.get(PREFERENCE_KEY_RSP_DUO_TUNER_MODE, RspDuoSelectionMode.DUAL.name()); + mRspDuoSelectionMode = RspDuoSelectionMode.fromValue(mode); + } + + return mRspDuoSelectionMode; + } + + /** + * Sets the RSPduo tuner select mode + * @param mode to use + */ + public void setRspDuoTunerMode(RspDuoSelectionMode mode) + { + mRspDuoSelectionMode = mode; + mPreferences.put(PREFERENCE_KEY_RSP_DUO_TUNER_MODE, mRspDuoSelectionMode.name()); + notifyPreferenceUpdated(); + } } diff --git a/src/main/java/io/github/dsheirer/sample/Broadcaster.java b/src/main/java/io/github/dsheirer/sample/Broadcaster.java index 494b289f6..703e9cf33 100644 --- a/src/main/java/io/github/dsheirer/sample/Broadcaster.java +++ b/src/main/java/io/github/dsheirer/sample/Broadcaster.java @@ -18,12 +18,13 @@ */ package io.github.dsheirer.sample; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + import java.util.ArrayList; import java.util.Collections; import java.util.List; import java.util.concurrent.locks.ReentrantLock; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; /** * Broadcasts an item to multiple listeners @@ -100,6 +101,10 @@ public void addListener(Listener listener) mListeners.add(listener); } } + catch(Exception e) + { + mLog.error("Unexpected error while adding listener", e); + } finally { mLock.unlock(); @@ -120,6 +125,10 @@ public void removeListener(Listener listener) { mListeners.remove(listener); } + catch(Exception e) + { + mLog.error("Unexpected error while removing listener", e); + } finally { mLock.unlock(); @@ -151,6 +160,10 @@ public void broadcast(T t) listener.receive(t); } } + catch(Exception e) + { + mLog.error("Unexpected error while broadcasting to listeners", e); + } finally { mLock.unlock(); diff --git a/src/main/java/io/github/dsheirer/source/tuner/ITunerErrorListener.java b/src/main/java/io/github/dsheirer/source/tuner/ITunerErrorListener.java index 4332783e2..4d8446fc3 100644 --- a/src/main/java/io/github/dsheirer/source/tuner/ITunerErrorListener.java +++ b/src/main/java/io/github/dsheirer/source/tuner/ITunerErrorListener.java @@ -1,23 +1,20 @@ /* + * ***************************************************************************** + * Copyright (C) 2014-2023 Dennis Sheirer * - * * ****************************************************************************** - * * Copyright (C) 2014-2020 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 - * * ***************************************************************************** + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see + * **************************************************************************** */ package io.github.dsheirer.source.tuner; @@ -29,4 +26,9 @@ public interface ITunerErrorListener * @param errorMessage to set */ void setErrorMessage(String errorMessage); + + /** + * Indicates that the tuner has been removed from the system. + */ + void tunerRemoved(); } diff --git a/src/main/java/io/github/dsheirer/source/tuner/LoggingTunerErrorListener.java b/src/main/java/io/github/dsheirer/source/tuner/LoggingTunerErrorListener.java index 785b4a0f4..676e93f49 100644 --- a/src/main/java/io/github/dsheirer/source/tuner/LoggingTunerErrorListener.java +++ b/src/main/java/io/github/dsheirer/source/tuner/LoggingTunerErrorListener.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 @@ -34,4 +34,10 @@ public void setErrorMessage(String errorMessage) { mLog.error("Tuner Error: " + errorMessage); } + + @Override + public void tunerRemoved() + { + mLog.warn("Tuner removal detected"); + } } diff --git a/src/main/java/io/github/dsheirer/source/tuner/Tuner.java b/src/main/java/io/github/dsheirer/source/tuner/Tuner.java index aa86e1742..ea4142f01 100644 --- a/src/main/java/io/github/dsheirer/source/tuner/Tuner.java +++ b/src/main/java/io/github/dsheirer/source/tuner/Tuner.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 @@ -149,6 +149,22 @@ public void setErrorMessage(String errorMessage) } } + /** + * Process tuner removal error from tuner controller and propagate to an external listener. + */ + @Override + public void tunerRemoved() + { + mLog.info("Tuner processing tuner removal. Stopping ..."); + stop(); + + mLog.info("Tuner pushing tuner removal event to external listener (tuner model)"); + if(mTunerErrorListener != null) + { + mTunerErrorListener.tunerRemoved(); + } + } + /** * Sets the channel source manager * @param manager to use diff --git a/src/main/java/io/github/dsheirer/source/tuner/TunerClass.java b/src/main/java/io/github/dsheirer/source/tuner/TunerClass.java index 3d8823f20..51906891e 100644 --- a/src/main/java/io/github/dsheirer/source/tuner/TunerClass.java +++ b/src/main/java/io/github/dsheirer/source/tuner/TunerClass.java @@ -30,6 +30,7 @@ public enum TunerClass FUNCUBE_DONGLE_PRO_PLUS("Funcube Dongle Pro+" ), HACKRF("HackRF" ), RTL2832("RTL-2832"), + RSP("RSP"), TEST_TUNER("Test"), RECORDING_TUNER("Recording"), UNKNOWN("Unknown" ); diff --git a/src/main/java/io/github/dsheirer/source/tuner/TunerController.java b/src/main/java/io/github/dsheirer/source/tuner/TunerController.java index cede08c06..581258f20 100644 --- a/src/main/java/io/github/dsheirer/source/tuner/TunerController.java +++ b/src/main/java/io/github/dsheirer/source/tuner/TunerController.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 @@ -46,7 +46,11 @@ public abstract class TunerController implements Tunable, ISourceEventProcessor, INativeBufferProvider, Listener, ITunerErrorListener { private final static Logger mLog = LoggerFactory.getLogger(TunerController.class); + + //Protects access to the native buffer broadcaster for adding, removing or checking for listener count. + protected ReentrantLock mBufferListenerLock = new ReentrantLock(); protected Broadcaster mNativeBufferBroadcaster = new Broadcaster(); + protected FrequencyController mFrequencyController; private int mMiddleUnusableHalfBandwidth; private int mMeasuredFrequencyError; @@ -129,6 +133,19 @@ public void setErrorMessage(String errorMessage) } } + /** + * Indicates that the tuner has been removed from the system and requests the listener to process the cleanup. + */ + @Override + public void tunerRemoved() + { + //Request parent tuner process the shutdown and cleanup + if(mTunerErrorListener != null) + { + mTunerErrorListener.tunerRemoved(); + } + } + /** * Number of samples contained in each complex buffer provided by this tuner. * @@ -572,7 +589,16 @@ public void removeListener( ISourceEventProcessor processor ) @Override public void addBufferListener(Listener listener) { - mNativeBufferBroadcaster.addListener(listener); + mBufferListenerLock.lock(); + + try + { + mNativeBufferBroadcaster.addListener(listener); + } + finally + { + mBufferListenerLock.unlock(); + } } /** @@ -581,7 +607,16 @@ public void addBufferListener(Listener listener) @Override public void removeBufferListener(Listener listener) { - mNativeBufferBroadcaster.removeListener(listener); + mBufferListenerLock.lock(); + + try + { + mNativeBufferBroadcaster.removeListener(listener); + } + finally + { + mBufferListenerLock.unlock(); + } } /** @@ -590,7 +625,20 @@ public void removeBufferListener(Listener listener) @Override public boolean hasBufferListeners() { - return mNativeBufferBroadcaster.hasListeners(); + boolean hasListeners; + + mBufferListenerLock.lock(); + + try + { + hasListeners = mNativeBufferBroadcaster.hasListeners(); + } + finally + { + mBufferListenerLock.unlock(); + } + + return hasListeners; } /** @@ -598,6 +646,7 @@ public boolean hasBufferListeners() */ protected void broadcast(INativeBuffer complexSamples) { + //Note: unprotected access to the broadcaster ... the broadcaster uses thread-save internal list mNativeBufferBroadcaster.broadcast(complexSamples); } diff --git a/src/main/java/io/github/dsheirer/source/tuner/TunerEvent.java b/src/main/java/io/github/dsheirer/source/tuner/TunerEvent.java index 887ec2ded..02c8eb2b8 100644 --- a/src/main/java/io/github/dsheirer/source/tuner/TunerEvent.java +++ b/src/main/java/io/github/dsheirer/source/tuner/TunerEvent.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 @@ -54,6 +54,24 @@ public boolean hasTuner() return mTuner != null; } + @Override + public String toString() + { + StringBuilder sb = new StringBuilder(); + sb.append("Tuner Event [").append(getEvent().name()).append("] for tuner ["); + if(hasTuner()) + { + sb.append(getTuner()); + } + else + { + sb.append("No Tuner"); + } + + sb.append("]"); + return sb.toString(); + } + /** * Event type */ @@ -75,6 +93,7 @@ public enum Event NOTIFICATION_SHUTTING_DOWN, REQUEST_CLEAR_MAIN_SPECTRAL_DISPLAY, + REQUEST_ENABLE_RSP_SLAVE_DEVICE, REQUEST_MAIN_SPECTRAL_DISPLAY, REQUEST_NEW_SPECTRAL_DISPLAY; } 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 7b3010a84..039cb81c1 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,6 +19,17 @@ package io.github.dsheirer.source.tuner; +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.Rsp1Device; +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; @@ -53,7 +64,50 @@ import io.github.dsheirer.source.tuner.rtl.r820t.R820TEmbeddedTuner; 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.ControlRsp1; +import io.github.dsheirer.source.tuner.sdrplay.rsp1.DiscoveredRsp1Tuner; +import io.github.dsheirer.source.tuner.sdrplay.rsp1.IControlRsp1; +import io.github.dsheirer.source.tuner.sdrplay.rsp1.Rsp1TunerConfiguration; +import io.github.dsheirer.source.tuner.sdrplay.rsp1.Rsp1TunerController; +import io.github.dsheirer.source.tuner.sdrplay.rsp1.Rsp1TunerEditor; +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; +import io.github.dsheirer.source.tuner.sdrplay.rspDuo.ControlRspDuoTuner2Single; +import io.github.dsheirer.source.tuner.sdrplay.rspDuo.ControlRspDuoTuner2Slave; +import io.github.dsheirer.source.tuner.sdrplay.rspDuo.DiscoveredRspDuoTuner1; +import io.github.dsheirer.source.tuner.sdrplay.rspDuo.DiscoveredRspDuoTuner2; +import io.github.dsheirer.source.tuner.sdrplay.rspDuo.IControlRspDuoTuner1; +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; @@ -66,6 +120,182 @@ public class TunerFactory { private static final Logger mLog = LoggerFactory.getLogger(TunerFactory.class); + /** + * 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 List getRspTuners(DeviceInfo deviceInfo, ChannelizerType channelizerType, RspDuoSelectionMode selectionMode) + { + List tuners = new ArrayList<>(); + + switch(deviceInfo.getDeviceType()) + { + case RSP1: + tuners.add(new DiscoveredRsp1Tuner(deviceInfo, channelizerType)); + break; + case RSP1A: + tuners.add(new DiscoveredRsp1aTuner(deviceInfo, channelizerType)); + break; + case RSP2: + tuners.add(new DiscoveredRsp2Tuner(deviceInfo, channelizerType)); + break; + case RSPdx: + tuners.add(new DiscoveredRspDxTuner(deviceInfo, channelizerType)); + break; + case RSPduo: + 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 RSP1: + if(device instanceof Rsp1Device rsp1Device) + { + IControlRsp1 controlRsp1 = new ControlRsp1(rsp1Device); + Rsp1TunerController rsp1TunerController = new Rsp1TunerController(controlRsp1, tunerErrorListener); + return new RspTuner(rsp1TunerController, tunerErrorListener, channelizerType); + } + break; + case RSP1A: + if(device instanceof Rsp1aDevice rsp1aDevice) + { + 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()) + { + 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"); + } + } + break; + case default: + mLog.warn("Unrecognized SDRplay RSP Device Type: " + device.getDeviceType() + " SER#: " + device.getSerialNumber()); + 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()) + { + 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"); + } + } + break; + } + } + + throw new SDRPlayException("Unable to obtain RSPduo tuner"); + } + /** * Create a USB tuner * @param tunerClass to instantiate @@ -148,6 +378,18 @@ public static TunerConfiguration getTunerConfiguration(TunerType type, String un return new R820TTunerConfiguration(uniqueID); case RECORDING: return RecordingTunerConfiguration.create(); + case RSP_1: + return new Rsp1TunerConfiguration(uniqueID); + case RSP_1A: + return new Rsp1aTunerConfiguration(uniqueID); + case RSP_2: + return new Rsp2TunerConfiguration(uniqueID); + case RSP_DUO_1: + return new RspDuoTuner1Configuration(uniqueID); + case RSP_DUO_2: + return new RspDuoTuner2Configuration(uniqueID); + case RSP_DX: + return new RspDxTunerConfiguration(uniqueID); default: throw new IllegalArgumentException("Unrecognized tuner type [" + type.name() + "]"); } @@ -169,6 +411,42 @@ public static TunerEditor getEditor(UserPreferences userPreferences, DiscoveredT return new FCD2TunerEditor(userPreferences, tunerManager, discoveredTuner); case HACKRF: return new HackRFTunerEditor(userPreferences, tunerManager, discoveredTuner); + case RSP: + if(discoveredTuner instanceof DiscoveredRspTuner discoveredRspTuner) + { + switch(discoveredRspTuner.getDeviceType()) + { + case RSP1: + return new Rsp1TunerEditor(userPreferences, tunerManager, discoveredRspTuner); + case RSP1A: + return new Rsp1aTunerEditor(userPreferences, tunerManager, discoveredRspTuner); + case RSP2: + return new Rsp2TunerEditor(userPreferences, tunerManager, discoveredRspTuner); + case RSPdx: + return new RspDxTunerEditor(userPreferences, tunerManager, discoveredRspTuner); + case RSPduo: + if(discoveredRspTuner instanceof DiscoveredRspDuoTuner1 duoTuner1) + { + return new RspDuoTuner1Editor(userPreferences, tunerManager, duoTuner1); + } + else if(discoveredRspTuner instanceof DiscoveredRspDuoTuner2 duoTuner2) + { + return new RspDuoTuner2Editor(userPreferences, tunerManager, duoTuner2); + } + else + { + throw new IllegalArgumentException("Unrecognized RSPduo device type:" + + discoveredRspTuner.getClass()); + } + case UNKNOWN: + throw new IllegalArgumentException("Unrecognized RSP device type: " + + discoveredRspTuner.getDeviceType()); + } + } + throw new IllegalArgumentException("Unrecognized discovered RSP tuner class: " + + discoveredTuner.getClass()); + case RECORDING_TUNER: + return new RecordingTunerEditor(userPreferences, tunerManager, discoveredTuner); case RTL2832: if(discoveredTuner.hasTuner()) { @@ -181,8 +459,6 @@ public static TunerEditor getEditor(UserPreferences userPreferences, DiscoveredT } } return new RTL2832UnknownTunerEditor(userPreferences, tunerManager, discoveredTuner); - case RECORDING_TUNER: - return new RecordingTunerEditor(userPreferences, tunerManager, discoveredTuner); case TEST_TUNER: case UNKNOWN: default: diff --git a/src/main/java/io/github/dsheirer/source/tuner/TunerType.java b/src/main/java/io/github/dsheirer/source/tuner/TunerType.java index c8686e084..de36198eb 100644 --- a/src/main/java/io/github/dsheirer/source/tuner/TunerType.java +++ b/src/main/java/io/github/dsheirer/source/tuner/TunerType.java @@ -37,6 +37,13 @@ public enum TunerType HACKRF_RAD1O("RAD1O"), RAFAELMICRO_R820T("R820T"), RAFAELMICRO_R828D("R828D"), + RSP_1("RSP1"), + RSP_1A("RSP1A"), + RSP_2("RSP2"), + RSP_DUO_1("RSPduo Tuner 1"), + RSP_DUO_2("RSPduo Tuner 2"), + RSP_DX("RSPdx"), + TEST("Test"), RECORDING("Recording"), UNKNOWN("Unknown"); diff --git a/src/main/java/io/github/dsheirer/source/tuner/configuration/TunerConfiguration.java b/src/main/java/io/github/dsheirer/source/tuner/configuration/TunerConfiguration.java index 1b8c55688..2827ea7da 100644 --- a/src/main/java/io/github/dsheirer/source/tuner/configuration/TunerConfiguration.java +++ b/src/main/java/io/github/dsheirer/source/tuner/configuration/TunerConfiguration.java @@ -31,6 +31,7 @@ import io.github.dsheirer.source.tuner.recording.RecordingTunerConfiguration; import io.github.dsheirer.source.tuner.rtl.e4k.E4KTunerConfiguration; import io.github.dsheirer.source.tuner.rtl.r820t.R820TTunerConfiguration; +import io.github.dsheirer.source.tuner.sdrplay.RspTunerConfiguration; /** * Abstract class to hold a configuration for a specific type of tuner @@ -44,6 +45,7 @@ @JsonSubTypes.Type(value = HackRFTunerConfiguration.class, name = "hackRFTunerConfiguration"), @JsonSubTypes.Type(value = RecordingTunerConfiguration.class, name = "recordingTunerConfiguration"), @JsonSubTypes.Type(value = R820TTunerConfiguration.class, name = "r820TTunerConfiguration"), + @JsonSubTypes.Type(value = RspTunerConfiguration.class, name = "rspTunerConfiguration"), }) @JacksonXmlRootElement(localName = "tuner_configuration") public abstract class TunerConfiguration diff --git a/src/main/java/io/github/dsheirer/source/tuner/configuration/TunerConfigurationManager.java b/src/main/java/io/github/dsheirer/source/tuner/configuration/TunerConfigurationManager.java index cd61a9fa9..069d60c0c 100644 --- a/src/main/java/io/github/dsheirer/source/tuner/configuration/TunerConfigurationManager.java +++ b/src/main/java/io/github/dsheirer/source/tuner/configuration/TunerConfigurationManager.java @@ -147,6 +147,12 @@ public void saveConfigurations() } } + /** + * Monitors discovered tuner enabled status and applies configurations or updates disable state of tuners. + * @param discoveredTuner that has a status change. + * @param previous tuner status + * @param current tuner status + */ @Override public void tunerStatusUpdated(DiscoveredTuner discoveredTuner, TunerStatus previous, TunerStatus current) { @@ -157,6 +163,23 @@ public void tunerStatusUpdated(DiscoveredTuner discoveredTuner, TunerStatus prev else if(current == TunerStatus.ENABLED) { removeDisabledTuner(discoveredTuner); + + if(discoveredTuner.hasTuner()) + { + TunerType tunerType = discoveredTuner.getTuner().getTunerType(); + + if(tunerType != TunerType.RECORDING) + { + TunerConfiguration tunerConfiguration = getTunerConfiguration(tunerType, discoveredTuner.getId()); + + if(tunerConfiguration != null) + { + discoveredTuner.setTunerConfiguration(tunerConfiguration); + saveConfigurations(); + } + } + } + } } diff --git a/src/main/java/io/github/dsheirer/source/tuner/manager/DiscoveredTuner.java b/src/main/java/io/github/dsheirer/source/tuner/manager/DiscoveredTuner.java index bd8fd3dbd..42eb2df18 100644 --- a/src/main/java/io/github/dsheirer/source/tuner/manager/DiscoveredTuner.java +++ b/src/main/java/io/github/dsheirer/source/tuner/manager/DiscoveredTuner.java @@ -219,7 +219,10 @@ public boolean hasTunerConfiguration() */ public void addTunerStatusListener(IDiscoveredTunerStatusListener listener) { - mListeners.add(listener); + if(!mListeners.contains(listener)) + { + mListeners.add(listener); + } } /** @@ -257,6 +260,12 @@ public void setErrorMessage(String errorMessage) setTunerStatus(TunerStatus.ERROR); } + @Override + public void tunerRemoved() + { + setTunerStatus(TunerStatus.REMOVED); + } + /** * Indicates if this tuner has an error message. */ 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 2441ef7b6..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,6 +19,10 @@ package io.github.dsheirer.source.tuner.manager; +import com.github.dsheirer.sdrplay.SDRPlayException; +import com.github.dsheirer.sdrplay.SDRplay; +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; import io.github.dsheirer.source.Source; @@ -28,6 +32,7 @@ import io.github.dsheirer.source.config.SourceConfiguration; import io.github.dsheirer.source.mixer.MixerManager; import io.github.dsheirer.source.tuner.TunerClass; +import io.github.dsheirer.source.tuner.TunerFactory; import io.github.dsheirer.source.tuner.TunerType; import io.github.dsheirer.source.tuner.channel.ChannelSpecification; import io.github.dsheirer.source.tuner.channel.MultiFrequencyTunerChannelSource; @@ -36,6 +41,8 @@ import io.github.dsheirer.source.tuner.configuration.TunerConfiguration; 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.DiscoveredRspDuoTuner1; import io.github.dsheirer.source.tuner.ui.DiscoveredTunerModel; import io.github.dsheirer.util.ThreadPool; import java.nio.ByteBuffer; @@ -63,14 +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 boolean mLibUsbInitialized = false; + private SDRplay mSDRplay; /** * Constructs an instance @@ -142,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) { @@ -238,37 +251,7 @@ private void addUsbTuner(DiscoveredUSBTuner discoveredUSBTuner) { if(!mDiscoveredTunerModel.hasUsbTuner(discoveredUSBTuner.getBus(), discoveredUSBTuner.getPortAddress())) { - discoveredUSBTuner.addTunerStatusListener(this); - - //Set the tuner to disabled if the user has previously blacklisted the tuner - if(mTunerConfigurationManager.isDisabled(discoveredUSBTuner)) - { - discoveredUSBTuner.setEnabled(false); - mLog.info("Tuner: " + discoveredUSBTuner + " - Added / Disabled"); - } - else - { - mLog.info("Tuner: " + discoveredUSBTuner + " - Added / Starting ..."); - //Attempt to start the discovered tuner and determine the tuner type - discoveredUSBTuner.start(); - - if(discoveredUSBTuner.hasTuner()) - { - TunerType tunerType = discoveredUSBTuner.getTuner().getTunerType(); - - TunerConfiguration tunerConfiguration = mTunerConfigurationManager - .getTunerConfiguration(tunerType, discoveredUSBTuner.getId()); - - if(tunerConfiguration != null) - { - mLog.info("Tuner: " + discoveredUSBTuner + " - Applying Tuner Configuration"); - discoveredUSBTuner.setTunerConfiguration(tunerConfiguration); - mTunerConfigurationManager.saveConfigurations(); - } - } - } - - mDiscoveredTunerModel.addDiscoveredTuner(discoveredUSBTuner); + startAndConfigureTuner(discoveredUSBTuner); } } @@ -282,12 +265,77 @@ private DiscoveredTuner removeUsbTuner(int bus, String portAddress) return mDiscoveredTunerModel.removeUsbTuner(bus, portAddress); } + /** + * Starts, configures and adds the tuner to the tuner model. + * @param discoveredTuner to add and configure + */ + private void startAndConfigureTuner(DiscoveredTuner discoveredTuner) + { + discoveredTuner.addTunerStatusListener(this); + + //Set the tuner to disabled if the user has previously blacklisted the tuner + if(mTunerConfigurationManager.isDisabled(discoveredTuner)) + { + discoveredTuner.setEnabled(false); + mLog.info("Tuner: " + discoveredTuner + " - Added / Disabled"); + } + else + { + mLog.info("Tuner: " + discoveredTuner + " - Added / Starting ..."); + //Attempt to start the discovered tuner and determine the tuner type + tunerStatusUpdated(discoveredTuner, TunerStatus.DISABLED, TunerStatus.ENABLED); + } + + mDiscoveredTunerModel.addDiscoveredTuner(discoveredTuner); + } + /** * Discover SDRPlay RSP tuners */ private void discoverSdrPlayTuners() { - //placeholder ... + ChannelizerType channelizerType = mUserPreferences.getTunerPreference().getChannelizerType(); + RspDuoSelectionMode duoSelectionMode = 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(mSDRplay.isAvailable()) + { + try + { + List deviceInfos = mSDRplay.getDeviceInfos(); + + mLog.info("Discovered [" + deviceInfos.size() + "] RSP devices from SDRplay API"); + + if(deviceInfos.isEmpty()) + { + mSDRplay.close(); + mSDRplay = null; + return; + } + + for(DeviceInfo deviceInfo: deviceInfos) + { + 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"); + } + } + else + { + mSDRplay.close(); + mSDRplay = null; + } } /** @@ -329,30 +377,44 @@ private void discoverRecordingTuners() @Override public void tunerStatusUpdated(DiscoveredTuner discoveredTuner, TunerStatus previous, TunerStatus current) { - mTunerConfigurationManager.tunerStatusUpdated(discoveredTuner, previous, current); - - if(previous != TunerStatus.ENABLED && current == TunerStatus.ENABLED) + if(current == TunerStatus.ENABLED) { discoveredTuner.start(); + } - if(discoveredTuner.hasTuner()) - { - TunerType tunerType = discoveredTuner.getTuner().getTunerType(); + //Special handling for RSPduo to auto-update enabled state for slave device when configured for master/slave operation + 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"); + DiscoveredTuner rspDuoTuner2 = getDiscoveredTunerModel().getDiscoveredTuner(id); - //Don't fetch or create a configuration for recording tuners - if(tunerType != TunerType.RECORDING) + if(rspDuoTuner2 != null) + { + if(previous == TunerStatus.ENABLED && current == TunerStatus.DISABLED) { - TunerConfiguration tunerConfiguration = mTunerConfigurationManager - .getTunerConfiguration(tunerType, discoveredTuner.getId()); - - if(tunerConfiguration != null) - { - discoveredTuner.setTunerConfiguration(tunerConfiguration); - mTunerConfigurationManager.saveConfigurations(); - } + rspDuoTuner2.setEnabled(false); } + else if(previous == TunerStatus.DISABLED && current == TunerStatus.ENABLED) + { + rspDuoTuner2.setEnabled(true); + rspDuoTuner2.start(); + } + } + + //Notify tuner configuration manager to apply tuner configurations & update disabled tuner states + mTunerConfigurationManager.tunerStatusUpdated(rspDuoTuner1, previous, current); + + if(rspDuoTuner2 != null) + { + mTunerConfigurationManager.tunerStatusUpdated(rspDuoTuner2, previous, current); } } + else + { + //Notify tuner configuration manager to apply tuner configuration + mTunerConfigurationManager.tunerStatusUpdated(discoveredTuner, previous, current); + } } /** diff --git a/src/main/java/io/github/dsheirer/source/tuner/manager/TunerStatus.java b/src/main/java/io/github/dsheirer/source/tuner/manager/TunerStatus.java index d32cb001a..04ab2d5b6 100644 --- a/src/main/java/io/github/dsheirer/source/tuner/manager/TunerStatus.java +++ b/src/main/java/io/github/dsheirer/source/tuner/manager/TunerStatus.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 @@ -34,6 +34,12 @@ public enum TunerStatus */ DISABLED("Disabled"), + + /** + * Indicates that the tuner has been removed from the system. + */ + REMOVED("Removed"), + /** * A tuner that has an error state and is unusable */ 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 new file mode 100644 index 000000000..4194b7239 --- /dev/null +++ b/src/main/java/io/github/dsheirer/source/tuner/sdrplay/ControlRsp.java @@ -0,0 +1,371 @@ +/* + * ***************************************************************************** + * Copyright (C) 2014-2023 Dennis Sheirer + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see + * **************************************************************************** + */ + +package io.github.dsheirer.source.tuner.sdrplay; + +import com.github.dsheirer.sdrplay.DeviceSelectionMode; +import com.github.dsheirer.sdrplay.SDRPlayException; +import com.github.dsheirer.sdrplay.Status; +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 +{ + 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; + private IStreamListener mStreamListener; + + //Streaming control lock and boolean status indicator. Access to the boolean indicator is protected by the lock. + protected ReentrantLock mStreamingLock = new ReentrantLock(); + protected boolean mStreaming = false; + + /** + * Constructs an instance + * @param device for the device, obtained from the API + */ + 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 RSP device sample stream - device not started"); + } + } + catch(SDRPlayException se) + { + if(se.getStatus() == Status.FAIL) + { + mLog.error("Unable to start RSP streaming - device may have been unplugged - removing."); + if(mDeviceEventListener != null) + { + mDeviceEventListener.processDeviceRemoval(getTunerSelect()); + } + } + else + { + mLog.error("Unable to initialize/start streaming for RSP device", se); + } + } + finally + { + mStreamingLock.unlock(); + } + } + + @Override + public void stopStream() + { + mStreamingLock.lock(); + + try + { + if(hasDevice() && mStreaming) + { + getDevice().uninitialize(); + } + } + catch(SDRPlayException se) + { + mLog.error("Unable to uninitialize/stop streaming for RSP device"); + } + finally + { + mStreaming = false; + mStreamingLock.unlock(); + } + } + + @Override + public DeviceSelectionMode getDeviceSelectionMode() + { + //Default device selection mode for all tuners except the RSPduo + return DeviceSelectionMode.SINGLE_TUNER_1; + } + + /** + * Device descriptor for this device + */ + public T getDevice() + { + return mDevice; + } + + /** + * RSP device was unplugged from USB bus. Clear the device and do not attempt any further interaction with the + * device via the API. + */ + @Override + public void deviceRemoved() + { + clearDevice(); + + mStreamingLock.lock(); + + try + { + mStreaming = false; + } + finally + { + mStreamingLock.unlock(); + } + } + + /** + * Clears/nullifies the device. This should be invoked after stopping the device to prevent reuse. + */ + public void clearDevice() + { + 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()) + { + 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("RSP tuner has not been started - can't apply sample rate"); + } + } + + /** + * 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"); + } + } + + /** + * Current sample rate setting + */ + @Override + public RspSampleRate getSampleRateEnumeration() + { + return mSampleRate; + } + + /** + * Current sample rate + */ + @Override + public double getCurrentSampleRate() + { + return getSampleRateEnumeration().getEffectiveSampleRate(); + } + + /** + * Current gain index + * @return gain index + */ + @Override + public int getGain() + { + return mGain; + } + + /** + * Verifies that the requested gain index setting is within the range of valid gain values. + * @param gain to validate + * @throws SDRPlayException if the gain index value is outside the range of valid values. + */ + protected void validateGain(int gain) throws SDRPlayException + { + if(gain < GainReduction.MIN_GAIN_INDEX || gain > GainReduction.MAX_GAIN_INDEX) + { + throw new SDRPlayException("Invalid gain index value [" + gain + "]. Valid range is " + + GainReduction.MIN_GAIN_INDEX + " - " + GainReduction.MAX_GAIN_INDEX); + } + } + + /** + * Registers listeners to receive device events and sample streams. + * @param deviceEventListener to receive device events + * @param streamListener to receive sample stream and related parameters. + */ + @Override + public void resister(IDeviceEventListener deviceEventListener, IStreamListener streamListener) + { + mDeviceEventListener = deviceEventListener; + mStreamListener = streamListener; + } + + /** + * Registered device event listener + * @return device event listener or null if a listener has not been registered. + */ + protected IDeviceEventListener getDeviceEventListener() + { + return mDeviceEventListener; + } + + /** + * Registered stream listener + * @return stream listener or null if a listener has not been registered. + */ + protected IStreamListener getStreamListener() + { + return mStreamListener; + } +} 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 new file mode 100644 index 000000000..af990cfe9 --- /dev/null +++ b/src/main/java/io/github/dsheirer/source/tuner/sdrplay/DiscoveredRspTuner.java @@ -0,0 +1,122 @@ +/* + * ***************************************************************************** + * Copyright (C) 2014-2023 Dennis Sheirer + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see + * **************************************************************************** + */ + +package io.github.dsheirer.source.tuner.sdrplay; + +import 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; + +/** + * Discovered SDRplay RSP tuner + */ +public abstract class DiscoveredRspTuner extends DiscoveredTuner +{ + private final DeviceInfo mDeviceInfo; + private final ChannelizerType mChannelizerType; + + /** + * Constructs an instance + * @param deviceInfo to select the device from the API + */ + public DiscoveredRspTuner(DeviceInfo deviceInfo, ChannelizerType channelizerType) + { + mDeviceInfo = deviceInfo; + mChannelizerType = channelizerType; + } + + /** + * Information about the discovered RSP device + * @return device info + */ + public DeviceInfo getDeviceInfo() + { + return mDeviceInfo; + } + + /** + * Channelizer type to use for the tuner + */ + protected ChannelizerType getChannelizerType() + { + return mChannelizerType; + } + + @Override + public TunerClass getTunerClass() + { + return TunerClass.RSP; + } + + /** + * Type of RSP tuner device + */ + public DeviceType 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 + public String toString() + { + return getId(); + } +} 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 new file mode 100644 index 000000000..031a801f5 --- /dev/null +++ b/src/main/java/io/github/dsheirer/source/tuner/sdrplay/IControlRsp.java @@ -0,0 +1,128 @@ +/* + * ***************************************************************************** + * Copyright (C) 2014-2023 Dennis Sheirer + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see + * **************************************************************************** + */ + +package io.github.dsheirer.source.tuner.sdrplay; + +import 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; + +/** + * Control interface for base RSP device + */ +public interface IControlRsp +{ + DeviceSelectionMode getDeviceSelectionMode(); + + /** + * Device descriptor for this RSP + * @return device descriptor + */ + Device getDevice(); + + /** + * Process an RSP device removal. Device memory resources should be nullified and the software should not attempt + * any further interaction with the device via the API. + */ + void deviceRemoved(); + + /** + * Selected tuner for this RSP. + * @return selected tuner. + */ + TunerSelect getTunerSelect(); + + /** + * Starts the device + */ + void start() throws SDRPlayException; + + /** + * Stops the device + */ + void stop() throws SDRPlayException; + + /** + * Registers listeners to receive device events and streaming samples when startStream() is invoked. + * @param deviceEventListener to receive device events + * @param streamListener to receive sample stream and related parameters. + */ + void resister(IDeviceEventListener deviceEventListener, IStreamListener streamListener); + + /** + * Starts the sample stream and delivers the samples to the registered listener. + */ + void startStream(); + + /** + * Stops the sample stream. + */ + void stopStream(); + + /** + * Callback to acknowledge a power overload event. + * @param tunerSelect identifies the tuner where the power overload is happening. + */ + void acknowledgePowerOverload(TunerSelect tunerSelect) throws SDRPlayException; + + /** + * Current center tune frequency + * @return frequency in Hertz + */ + long getTunedFrequency() throws SDRPlayException; + + /** + * Sets the center tune frequency + * @param frequency in Hertz + */ + void setTunedFrequency(long frequency) throws SDRPlayException; + + /** + * Current sample rate enumeration value + * @return sample rate enumeration. + */ + RspSampleRate getSampleRateEnumeration(); + + /** + * Sets the sample rate. + * @param rspSampleRate enumeration value. + */ + void setSampleRate(RspSampleRate rspSampleRate) throws SDRPlayException; + + /** + * Current sample rate value. + * @return sample rate in Hertz + */ + double getCurrentSampleRate(); + + /** + * Sets the gain index value. + * @param gain index value (0 - 28) + */ + void setGain(int gain) throws SDRPlayException; + + /** + * Current gain index value + * @return gain index value (0 - 28) + */ + int getGain(); +} diff --git a/src/main/java/io/github/dsheirer/source/tuner/sdrplay/RspNativeBuffer.java b/src/main/java/io/github/dsheirer/source/tuner/sdrplay/RspNativeBuffer.java new file mode 100644 index 000000000..e8cb792b8 --- /dev/null +++ b/src/main/java/io/github/dsheirer/source/tuner/sdrplay/RspNativeBuffer.java @@ -0,0 +1,141 @@ +/* + * ***************************************************************************** + * 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 io.github.dsheirer.source.tuner.sdrplay; + +import io.github.dsheirer.buffer.AbstractNativeBuffer; +import io.github.dsheirer.sample.complex.ComplexSamples; +import io.github.dsheirer.sample.complex.InterleavedComplexSamples; +import java.util.Iterator; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +/** + * Native buffer implementation for RSP tuner I/Q sample buffers. + * + * Note: in testing with API v3.07, the daemon returns 2016 samples in each of the I and Q arrays. + */ +public class RspNativeBuffer extends AbstractNativeBuffer +{ + private static final Logger mLog = LoggerFactory.getLogger(RspNativeBuffer.class); + private static final float SAMPLE_TO_FLOAT = 1.0f / 32768.0f; + private short[] mISamples; + private short[] mQSamples; + + /** + * Constructs an instance + * @param i samples array + * @param q samples array + * @param timestamp for the first sample + * @param samplesPerMillisecond used to calculate sub-buffer fragment timestamp offsets from the start of this buffer. + */ + public RspNativeBuffer(short[] i, short[] q, long timestamp, float samplesPerMillisecond) + { + super(timestamp, samplesPerMillisecond); + mISamples = i; + mQSamples = q; + } + + /** + * Iterator over samples that produces complex sample buffers. + */ + @Override + public Iterator iterator() + { + return new SampleIterator(); + } + + /** + * Iterator over samples that produces interleaved complex sample buffers + */ + @Override + public Iterator iteratorInterleaved() + { + return new InterleavedSampleIterator(); + } + + @Override + public int sampleCount() + { + return mISamples.length * 2; + } + + /** + * Iterator providing (non-interleaved) complex sample buffers + */ + private class SampleIterator implements Iterator + { + private int mSamplePointer; + + @Override + public boolean hasNext() + { + return mSamplePointer < mISamples.length; + } + + @Override + public ComplexSamples next() + { + float[] i = new float[mISamples.length]; + float[] q = new float[mISamples.length]; + + for(int x = 0; x < mISamples.length; x++) + { + i[x] = mISamples[x] * SAMPLE_TO_FLOAT; + q[x] = mQSamples[x] * SAMPLE_TO_FLOAT; + } + + mSamplePointer += mISamples.length; + + return new ComplexSamples(i, q, getTimestamp()); + } + } + + /** + * Interator providing interleaved sample buffers. + */ + private class InterleavedSampleIterator implements Iterator + { + private int mSamplePointer; + + @Override + public boolean hasNext() + { + return mSamplePointer < mISamples.length; + } + + @Override + public InterleavedComplexSamples next() + { + float[] samples = new float[mISamples.length * 2]; + + int index = 0; + + for(int x = 0; x < mISamples.length; x++) + { + samples[index++] = mISamples[x] * SAMPLE_TO_FLOAT; + samples[index++] = mQSamples[x] * SAMPLE_TO_FLOAT; + } + + mSamplePointer += mISamples.length; + + return new InterleavedComplexSamples(samples, getTimestamp()); + } + } +} diff --git a/src/main/java/io/github/dsheirer/source/tuner/sdrplay/RspSampleRate.java b/src/main/java/io/github/dsheirer/source/tuner/sdrplay/RspSampleRate.java new file mode 100644 index 000000000..7bd243310 --- /dev/null +++ b/src/main/java/io/github/dsheirer/source/tuner/sdrplay/RspSampleRate.java @@ -0,0 +1,185 @@ +/* + * ***************************************************************************** + * 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 io.github.dsheirer.source.tuner.sdrplay; + +import com.github.dsheirer.sdrplay.device.Decimate; +import com.github.dsheirer.sdrplay.parameter.tuner.Bandwidth; + +import java.util.EnumSet; + +/** + * RSP device Sample Rate, Bandwidth and Decimation enumeration + * + * Note: final effective sample rate must be greater than IF bandwidth setting to avoid aliasing. The available IF + * bandwidth values effectively dictate the available sample rates + */ +public enum RspSampleRate +{ + RATE_0_250(8_000_000, 016_000, Bandwidth.BW_0_300, Decimate.X32, "0.250 MHz (0.234 usable)"), + RATE_0_500(8_000_000, 024_000, Bandwidth.BW_0_600, Decimate.X16, "0.500 MHz (0.476 usable)"), + RATE_1_000(8_000_000, 100_000, Bandwidth.BW_1_536, Decimate.X8, "1.000 MHz (0.900 usable)"), + RATE_1_500(6_000_000, 140_000, Bandwidth.BW_1_536, Decimate.X4, "1.500 MHz (1.360 usable)"), + RATE_3_000(6_000_000, 300_000, Bandwidth.BW_5_000, Decimate.X2, "3.000 MHz (2.700 usable)"), + RATE_4_000(8_000_000, 340_000, Bandwidth.BW_5_000, Decimate.X2, "4.000 MHz (3.560 usable)"), + RATE_5_000(5_000_000, 880_000, Bandwidth.BW_5_000, Decimate.X1, "5.000 MHz (4.120 usable)"), + RATE_6_000(6_000_000, 800_000, Bandwidth.BW_6_000, Decimate.X1, "6.000 MHz (5.200 usable)"), + RATE_7_000(7_000_000, 1_040_000, Bandwidth.BW_7_000, Decimate.X1, "7.000 MHz (5.960 usable)"), + RATE_8_000(8_000_000, 1_060_000, Bandwidth.BW_8_000, Decimate.X1, "8.000 MHz (6.940 usable)"), + RATE_9_000(9_000_000, 1_620_000, Bandwidth.BW_8_000, Decimate.X1, "9.000 MHz (7.380 usable)"), + RATE_10_000(10_000_000, 1_500_000, Bandwidth.BW_8_000, Decimate.X1, "10.000 MHz (8.500 usable)"), + + /** + * Note: in dual tuner mode, available sample rates are 6 or 8 MHz with an effective output rate of + * 2 MHz. Decimation is applied against the final 2 MHz rate, not the original 6/8 sampling rate. + */ + DUO_RATE_0_500(8_000_000, 50_000, Bandwidth.BW_8_000, Decimate.X4, "0.500 MHz (0.450 usable)"), + DUO_RATE_1_000(8_000_000, 50_000, Bandwidth.BW_8_000, Decimate.X2, "1.000 MHz (0.950 usable)"), + DUO_RATE_1_500(6_000_000, 0, Bandwidth.BW_6_000, Decimate.X1, "1.500 MHz (1.500 usable)"), + DUO_RATE_2_000(8_000_000, 0, Bandwidth.BW_8_000, Decimate.X1, "2.000 MHz (2.000 usable)"), + + UNDEFINED(0, 0, Bandwidth.UNDEFINED, Decimate.X1, "UNDEFINED"); + + private long mSampleRate; + private long mUnusable; + private Bandwidth mBandwidth; + private Decimate mDecimation; + private String mDescription; + + /** + * Constructs an instance + * @param sampleRate in hertz + * @param unusable bandwidth (total) in Hertz due to IF or decimation filter roll-off at spectrum edges + * @param bandwidth of the frequency spectrum + * @param decimation to be applied to the original sample rate to achieve the effective sample rate + * @param description for UI display + */ + RspSampleRate(long sampleRate, long unusable, Bandwidth bandwidth, Decimate decimation, String description) + { + mSampleRate = sampleRate; + mUnusable = unusable; + mBandwidth = bandwidth; + mDecimation = decimation; + mDescription = description; + } + + /** + * Single tuner sample rates for all devices operating in single tuner mode + */ + public static EnumSet SINGLE_TUNER_SAMPLE_RATES = EnumSet.range(RATE_0_250, RATE_10_000); + + /** + * RSPduo dual-tuner mode sample rates + */ + public static EnumSet DUAL_TUNER_SAMPLE_RATES = EnumSet.range(DUO_RATE_0_500, DUO_RATE_2_000); + + /** + * Sample Rate + * @return sample rate (Hz) + */ + public long getSampleRate() + { + return mSampleRate; + } + + /** + * Usable bandwidth in range 0.0 to 1.0, where 1.0 is 100% usable bandwidth + */ + public double getUsableBandwidth() + { + if(getSampleRate() != 0) + { + return 1.0 - ((double)mUnusable / (double)getEffectiveSampleRate()); + } + + return 0.0; + } + + /** + * Indicates if this is a sample rate supported by the RSPduo operating in dual-tuner mode. + * @return true if this is a dual-tuner sample rate. + */ + public boolean isDualTunerSampleRate() + { + return DUAL_TUNER_SAMPLE_RATES.contains(this); + } + + /** + * Sample size in bits. Can be used to adjust spectral display for effective dynamic range. + * @return sample size in bits. + */ + public int getSampleSize() + { + return mDecimation.getSampleSize(); + } + + /** + * Decimation rate to be applied against sample rate. + * @return decimation value + */ + public Decimate getDecimation() + { + return mDecimation; + } + + /** + * Indicates if this sample rate specifies decimation + */ + public boolean hasDecimation() + { + return getDecimation().isEnabled(); + } + + /** + * Effective Sample Rate (sample rate / decimation). Note: for RSPduo operating in dual-tuner mode, an + * inherent x4 decimation is applied in the hardware. + * @return effective sample rate (Hz) + */ + public long getEffectiveSampleRate() + { + if(isDualTunerSampleRate()) + { + //Dual tuner sample rate is specified at 8 MHz, but there is an inherent x4 decimation to 2 MHz + //on top of the user specified decimation rate. + return getSampleRate() / getDecimation().getValue() / 4; + } + else + { + return getSampleRate() / getDecimation().getValue(); + } + } + + /** + * Bandwidth entry + */ + public Bandwidth getBandwidth() + { + return mBandwidth; + } + + /** + * Overrides the default string representation to use the UI description/label. + * @return string representation of the entry + */ + @Override + public String toString() + { + return mDescription; + } +} 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 new file mode 100644 index 000000000..8e339a441 --- /dev/null +++ b/src/main/java/io/github/dsheirer/source/tuner/sdrplay/RspTuner.java @@ -0,0 +1,104 @@ +/* + * ***************************************************************************** + * Copyright (C) 2014-2023 Dennis Sheirer + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see + * **************************************************************************** + */ + +package io.github.dsheirer.source.tuner.sdrplay; + +import io.github.dsheirer.preference.source.ChannelizerType; +import io.github.dsheirer.source.tuner.ITunerErrorListener; +import io.github.dsheirer.source.tuner.Tuner; +import io.github.dsheirer.source.tuner.TunerClass; +import io.github.dsheirer.source.tuner.sdrplay.rspDuo.IControlRspDuoTuner1; +import io.github.dsheirer.source.tuner.sdrplay.rspDuo.IControlRspDuoTuner2; + +/** + * Generic RSP tuner with a device specific tuner controller implementation. + */ +public class RspTuner extends Tuner +{ + /** + * Constructs an instance + * @param tunerController for controlling the tuner + * @param tunerErrorListener to process errors from this tuner + * @param channelizerType to use with this tuner + */ + public RspTuner(RspTunerController tunerController, ITunerErrorListener tunerErrorListener, ChannelizerType channelizerType) + { + super(tunerController, tunerErrorListener, channelizerType); + } + + @Override + public int getMaximumUSBBitsPerSecond() + { + //12-bits per sample, 2 samples per frame, 10 MHz sample rate + return 320_000_000; + } + + @Override + public String getUniqueID() + { + return getRspTunerController().getControlRsp().getDevice().getSerialNumber(); + } + + @Override + public TunerClass getTunerClass() + { + return TunerClass.RSP; + } + + /** + * RSP Tuner controller for this tuner + */ + public RspTunerController getRspTunerController() + { + return (RspTunerController)getTunerController(); + } + + @Override + public String getPreferredName() + { + if(getRspTunerController().getControlRsp() instanceof IControlRspDuoTuner1 && + getRspTunerController().getControlRsp().getDevice() != null) + { + return getRspTunerController().getControlRsp().getDevice().getDeviceType() + + " SER:" + getRspTunerController().getControlRsp().getDevice().getSerialNumber() + " Tuner 1"; + } + else if(getRspTunerController().getControlRsp() instanceof IControlRspDuoTuner2 && + getRspTunerController().getControlRsp().getDevice() != null) + { + return getRspTunerController().getControlRsp().getDevice().getDeviceType() + + " SER:" + getRspTunerController().getControlRsp().getDevice().getSerialNumber() + " Tuner 2"; + } + else if(getRspTunerController().getControlRsp() instanceof IControlRsp && + getRspTunerController().getControlRsp().getDevice() != null) + { + return getRspTunerController().getControlRsp().getDevice().getDeviceType() + + " SER:" + getRspTunerController().getControlRsp().getDevice().getSerialNumber(); + } + else + { + return "RSP Tuner - Device Not Available"; + } + } + + @Override + public double getSampleSize() + { + return getRspTunerController().getControlRsp().getSampleRateEnumeration().getSampleSize(); + } +} diff --git a/src/main/java/io/github/dsheirer/source/tuner/sdrplay/RspTunerConfiguration.java b/src/main/java/io/github/dsheirer/source/tuner/sdrplay/RspTunerConfiguration.java new file mode 100644 index 000000000..6e14bf167 --- /dev/null +++ b/src/main/java/io/github/dsheirer/source/tuner/sdrplay/RspTunerConfiguration.java @@ -0,0 +1,106 @@ +/* + * ***************************************************************************** + * 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 io.github.dsheirer.source.tuner.sdrplay; + +import com.fasterxml.jackson.annotation.JsonSubTypes; +import com.fasterxml.jackson.annotation.JsonTypeInfo; +import com.fasterxml.jackson.dataformat.xml.annotation.JacksonXmlProperty; +import com.github.dsheirer.sdrplay.parameter.tuner.GainReduction; +import io.github.dsheirer.source.tuner.configuration.TunerConfiguration; +import io.github.dsheirer.source.tuner.sdrplay.rsp1a.Rsp1aTunerConfiguration; +import io.github.dsheirer.source.tuner.sdrplay.rsp2.Rsp2TunerConfiguration; +import io.github.dsheirer.source.tuner.sdrplay.rspDuo.RspDuoTuner1Configuration; +import io.github.dsheirer.source.tuner.sdrplay.rspDuo.RspDuoTuner2Configuration; +import io.github.dsheirer.source.tuner.sdrplay.rspDx.RspDxTunerConfiguration; + +/** + * Abstract RSP tuner configuration + */ +@JsonTypeInfo(use = JsonTypeInfo.Id.NAME, include = JsonTypeInfo.As.PROPERTY, property = "type") +@JsonSubTypes({ + @JsonSubTypes.Type(value = Rsp1aTunerConfiguration.class, name = "rsp1aTunerConfiguration"), + @JsonSubTypes.Type(value = Rsp2TunerConfiguration.class, name = "rsp2TunerConfiguration"), + @JsonSubTypes.Type(value = RspDuoTuner1Configuration.class, name = "rspDuoTuner1Configuration"), + @JsonSubTypes.Type(value = RspDuoTuner2Configuration.class, name = "rspDuoTuner2Configuration"), + @JsonSubTypes.Type(value = RspDxTunerConfiguration.class, name = "rspDxTunerConfiguration"), +}) +public abstract class RspTunerConfiguration extends TunerConfiguration +{ + public static final RspSampleRate DEFAULT_SINGLE_TUNER_SAMPLE_RATE = RspSampleRate.RATE_8_000; + public static final RspSampleRate DEFAULT_DUAL_TUNER_SAMPLE_RATE = RspSampleRate.DUO_RATE_2_000; + + private RspSampleRate mRspSampleRate = DEFAULT_SINGLE_TUNER_SAMPLE_RATE; + private int mGain = 14; + + /** + * JAXB Constructor + */ + public RspTunerConfiguration() + { + } + + /** + * Constructs an instance with the specified unique id + * @param uniqueId for the tuner + */ + public RspTunerConfiguration(String uniqueId) + { + super(uniqueId); + } + + /** + * Sample rate for the tuner + */ + @JacksonXmlProperty(isAttribute = true, localName = "sampleRate") + public RspSampleRate getSampleRate() + { + return mRspSampleRate; + } + + /** + * Sets the sample rate for the tuner + */ + public void setSampleRate(RspSampleRate rspSampleRate) + { + mRspSampleRate = rspSampleRate; + } + + /** + * Gain index to use + * @return gain index, 0 - 28 + */ + @JacksonXmlProperty(isAttribute = true, localName = "gain") + public int getGain() + { + return mGain; + } + + /** + * Sets the gain index + * @param gain index, 0 - 28 + */ + public void setGain(int gain) + { + if(GainReduction.MIN_GAIN_INDEX <= gain && gain <= GainReduction.MAX_GAIN_INDEX) + { + mGain = gain; + } + } +} 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 new file mode 100644 index 000000000..d4e813fdf --- /dev/null +++ b/src/main/java/io/github/dsheirer/source/tuner/sdrplay/RspTunerController.java @@ -0,0 +1,325 @@ +/* + * ***************************************************************************** + * Copyright (C) 2014-2023 Dennis Sheirer + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see + * **************************************************************************** + */ + +package io.github.dsheirer.source.tuner.sdrplay; + +import com.github.dsheirer.sdrplay.SDRPlayException; +import com.github.dsheirer.sdrplay.callback.IDeviceEventListener; +import com.github.dsheirer.sdrplay.callback.IStreamListener; +import com.github.dsheirer.sdrplay.callback.StreamCallbackParameters; +import com.github.dsheirer.sdrplay.device.TunerSelect; +import com.github.dsheirer.sdrplay.parameter.event.EventType; +import com.github.dsheirer.sdrplay.parameter.event.GainCallbackParameters; +import com.github.dsheirer.sdrplay.parameter.event.PowerOverloadCallbackParameters; +import com.github.dsheirer.sdrplay.parameter.event.RspDuoModeCallbackParameters; +import io.github.dsheirer.buffer.INativeBuffer; +import io.github.dsheirer.sample.Listener; +import io.github.dsheirer.source.SourceException; +import io.github.dsheirer.source.tuner.ITunerErrorListener; +import io.github.dsheirer.source.tuner.TunerController; +import io.github.dsheirer.source.tuner.configuration.TunerConfiguration; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +/** + * Abstract/Base RSP tuner controller + */ +public abstract class RspTunerController extends TunerController + implements IDeviceEventListener, IStreamListener +{ + private static final Logger mLog = LoggerFactory.getLogger(RspTunerController.class); + protected static final long MINIMUM_FREQUENCY = 100_000; + protected static final long MAXIMUM_FREQUENCY = 2_000_000_000; + protected static final int MIDDLE_UNUSABLE_BANDWIDTH = 0; + private I mControlRsp; + + /** + * Abstract tuner controller class. The tuner controller manages frequency bandwidth and currently tuned channels + * that are being fed samples from the tuner. + * + * @param controlRsp that is the RSP tuner + * @param tunerErrorListener to monitor errors produced from this tuner controller + */ + public RspTunerController(I controlRsp, ITunerErrorListener tunerErrorListener) + { + super(tunerErrorListener); + mControlRsp = controlRsp; + + //Register this controller to receive device events and sample streams when startStream() is invoked. + mControlRsp.resister(this, this); + + setMinimumFrequency(MINIMUM_FREQUENCY); + setMaximumFrequency(MAXIMUM_FREQUENCY); + setMiddleUnusableHalfBandwidth(MIDDLE_UNUSABLE_BANDWIDTH); + setUsableBandwidthPercentage(1.0); //Initial value + } + + @Override + public void apply(TunerConfiguration config) throws SourceException + { + if(config instanceof RspTunerConfiguration rtc) + { + //This sets the frequency and software PPM + super.apply(config); + + try + { + setSampleRate(rtc.getSampleRate()); + } + catch(SDRPlayException se) + { + mLog.error("Error setting RSP sample rate to " + rtc.getSampleRate(), se); + } + + try + { + getControlRsp().setGain(rtc.getGain()); + } + catch(SDRPlayException se) + { + mLog.error("Error setting RSP gain index to " + rtc.getGain()); + } + } + } + + /** + * The RSP control for this tuner controller + */ + public I getControlRsp() + { + return mControlRsp; + } + + @Override + public TunerSelect getTunerSelect() + { + return mControlRsp.getTunerSelect(); + } + + @Override + public void processStream(short[] inphase, short[] quadrature, + StreamCallbackParameters parameters, boolean reset) + { + //RSP I/Q sample buffers are small and don't currently get fragmented by the RspNativeBuffer, so we don't + //calculate the sub-buffer samples per millisecond value -- just use a constant value of 0. + mNativeBufferBroadcaster.broadcast(new RspNativeBuffer(inphase, quadrature, System.currentTimeMillis(), 0.0f)); + + if(reset) + { +// mLog.info(getControlRsp().getDeviceDescriptor().getDeviceType() + " - sample stream was reset"); + } + if(parameters.isGainReductionChanged()) + { +// mLog.info("^^^ Got a gain reduction change"); + } + if(parameters.isRfFrequencyChanged()) + { +// mLog.info("^^^ Got a frequency changed"); + } + if(parameters.isSampleRateChanged()) + { +// mLog.info("^^^ Got a sample rate changed"); + } + } + + /** + * Starts this RSP tuner and attempts to claim the device via the API + * @throws SourceException + */ + @Override + public void start() throws SourceException + { + try + { + mControlRsp.start(); + } + catch(SDRPlayException se) + { + throw new SourceException("Unable to select tuner - in use"); + } + } + + @Override + public void stop() + { + try + { + mControlRsp.stop(); + } + catch(SDRPlayException se) + { + mLog.error("Error releasing RSP tuner device", se); + } + } + + /** + * Adds the listener to receive native buffers and starts the sample stream when this is the first listener. + * @param listener to add + */ + @Override + public void addBufferListener(Listener listener) + { + mBufferListenerLock.lock(); + + try + { + if(!hasBufferListeners()) + { + mControlRsp.startStream(); + } + + super.addBufferListener(listener); + } + finally + { + mBufferListenerLock.unlock(); + } + } + + /** + * Removes the listener from receiving native buffers and stops the sample stream when this is the last listener. + * @param listener to remove + */ + @Override + public void removeBufferListener(Listener listener) + { + mBufferListenerLock.lock(); + + try + { + super.removeBufferListener(listener); + + if(!hasBufferListeners()) + { + mControlRsp.stopStream(); + } + } + finally + { + mBufferListenerLock.unlock(); + } + } + + /** + * Currently tuned frequency + * @return frequency in Hertz + * @throws SourceException if there is an error + */ + @Override + public long getTunedFrequency() throws SourceException + { + try + { + return getControlRsp().getTunedFrequency(); + } + catch(SDRPlayException se) + { + throw new SourceException("Error setting tuned frequency", se); + } + } + + /** + * Sets the center tuned frequency. + * @param frequency in Hertz + * @throws SourceException if there is an error + */ + @Override + public void setTunedFrequency(long frequency) throws SourceException + { + try + { + getControlRsp().setTunedFrequency(frequency); + } + catch(SDRPlayException se) + { + throw new SourceException("Unable to set center frequency [" + frequency + "]", se); + } + } + + /** + * Sets the sample rate + * @param rspSampleRate to apply + * @throws SDRPlayException if there is an error + */ + public void setSampleRate(RspSampleRate rspSampleRate) throws SDRPlayException + { + getControlRsp().setSampleRate(rspSampleRate); + + try + { + mFrequencyController.setSampleRate((int) rspSampleRate.getEffectiveSampleRate()); + } + catch(SourceException se) + { + mLog.error("Error setting sample rate in frequency controller"); + } + + //Update the usable bandwidth based on the sample rate and filtered bandwidth + setUsableBandwidthPercentage(rspSampleRate.getUsableBandwidth()); + } + + @Override + public double getCurrentSampleRate() throws SourceException + { + return getControlRsp().getCurrentSampleRate(); + } + + @Override + public int getBufferSampleCount() + { + return 128; + } + + //Device Event Listener interface methods ... + @Override + public void processEvent(EventType eventType, TunerSelect tunerSelect) {} + @Override + public void processGainChange(TunerSelect tunerSelect, GainCallbackParameters parameters) {} + @Override + public void processRspDuoModeChange(TunerSelect tunerSelect, RspDuoModeCallbackParameters parameters) {} + @Override + public void processPowerOverload(TunerSelect tunerSelect, PowerOverloadCallbackParameters parameters) + { + if(getControlRsp() != null) + { + try + { + getControlRsp().acknowledgePowerOverload(tunerSelect); + } + catch(SDRPlayException se) + { + mLog.error("Unable to acknowledge power overload for [" + tunerSelect + "]", se); + } + } + } + + @Override + public void processDeviceRemoval(TunerSelect tunerSelect) + { + mLog.info("Processing device removal for tuner [" + tunerSelect + "] controller class [" + getClass().getSimpleName() + "]"); + //Command the control RSP to nullify the device so that we cease all attempts to control the device via the API + if(getControlRsp() != null) + { + getControlRsp().deviceRemoved(); + } + + //Signal that tuner is removed so parent tuner and discovered tuner wrapper can do graceful removal/cleanup + tunerRemoved(); + } +} diff --git a/src/main/java/io/github/dsheirer/source/tuner/sdrplay/RspTunerEditor.java b/src/main/java/io/github/dsheirer/source/tuner/sdrplay/RspTunerEditor.java new file mode 100644 index 000000000..60b729957 --- /dev/null +++ b/src/main/java/io/github/dsheirer/source/tuner/sdrplay/RspTunerEditor.java @@ -0,0 +1,108 @@ +/* + * ***************************************************************************** + * 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 io.github.dsheirer.source.tuner.sdrplay; + +import com.github.dsheirer.sdrplay.parameter.tuner.GainReduction; +import io.github.dsheirer.preference.UserPreferences; +import io.github.dsheirer.source.tuner.manager.TunerManager; +import io.github.dsheirer.source.tuner.ui.TunerEditor; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import javax.swing.JLabel; +import javax.swing.JOptionPane; +import javax.swing.JSlider; + +/** + * Abstract RSP tuner editor + */ +public abstract class RspTunerEditor extends TunerEditor +{ + private Logger mLog = LoggerFactory.getLogger(RspTunerEditor.class); + private JSlider mGainSlider; + private JLabel mGainValueLabel; + + /** + * Constructs an instance + * @param userPreferences for preference settings + * @param tunerManager to notify for state changes + * @param discoveredTuner to be edited. + */ + public RspTunerEditor(UserPreferences userPreferences, TunerManager tunerManager, DiscoveredRspTuner discoveredTuner) + { + super(userPreferences, tunerManager, discoveredTuner); + } + + private RspTunerController getTunerController() + { + return (RspTunerController) getTuner().getTunerController(); + } + + /** + * Gain reduction slider control + */ + protected JSlider getGainSlider() + { + if(mGainSlider == null) + { + mGainSlider = new JSlider(JSlider.HORIZONTAL, GainReduction.MIN_GAIN_INDEX, + GainReduction.MAX_GAIN_INDEX, GainReduction.MIN_GAIN_INDEX); + mGainSlider.setEnabled(false); + mGainSlider.setMajorTickSpacing(1); + mGainSlider.setPaintTicks(true); + mGainSlider.addChangeListener(event -> + { + int gain = mGainSlider.getValue(); + + if(hasTuner() && !isLoading()) + { + try + { + getTunerController().getControlRsp().setGain(gain); + save(); + } + catch(Exception e) + { + mLog.error("Couldn't set RSP gain to:" + gain, e); + JOptionPane.showMessageDialog(mGainSlider, "Couldn't set RSP gain value to " + gain); + } + } + + getGainValueLabel().setText(String.valueOf(gain)); + }); + } + + return mGainSlider; + } + + /** + * Label for displaying current gain index value + */ + protected JLabel getGainValueLabel() + { + if(mGainValueLabel == null) + { + mGainValueLabel = new JLabel("0"); + mGainValueLabel.setEnabled(false); + } + + return mGainValueLabel; + } +} diff --git a/src/main/java/io/github/dsheirer/source/tuner/sdrplay/rsp1/ControlRsp1.java b/src/main/java/io/github/dsheirer/source/tuner/sdrplay/rsp1/ControlRsp1.java new file mode 100644 index 000000000..754d565b5 --- /dev/null +++ b/src/main/java/io/github/dsheirer/source/tuner/sdrplay/rsp1/ControlRsp1.java @@ -0,0 +1,42 @@ +/* + * ***************************************************************************** + * Copyright (C) 2014-2023 Dennis Sheirer + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see + * **************************************************************************** + */ + +package io.github.dsheirer.source.tuner.sdrplay.rsp1; + +import com.github.dsheirer.sdrplay.device.Rsp1Device; +import io.github.dsheirer.source.tuner.sdrplay.ControlRsp; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +/** + * Control wrapper for an RSP1 Device + */ +public class ControlRsp1 extends ControlRsp implements IControlRsp1 +{ + private Logger mLog = LoggerFactory.getLogger(ControlRsp1.class); + + /** + * Constructs an instance + * @param device for the device + */ + public ControlRsp1(Rsp1Device device) + { + super(device); + } +} diff --git a/src/main/java/io/github/dsheirer/source/tuner/sdrplay/rsp1/DiscoveredRsp1Tuner.java b/src/main/java/io/github/dsheirer/source/tuner/sdrplay/rsp1/DiscoveredRsp1Tuner.java new file mode 100644 index 000000000..4a6144ac8 --- /dev/null +++ b/src/main/java/io/github/dsheirer/source/tuner/sdrplay/rsp1/DiscoveredRsp1Tuner.java @@ -0,0 +1,40 @@ +/* + * ***************************************************************************** + * Copyright (C) 2014-2023 Dennis Sheirer + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see + * **************************************************************************** + */ + +package io.github.dsheirer.source.tuner.sdrplay.rsp1; + +import com.github.dsheirer.sdrplay.device.DeviceInfo; +import io.github.dsheirer.preference.source.ChannelizerType; +import io.github.dsheirer.source.tuner.sdrplay.DiscoveredRspTuner; + +/** + * RSP1 discovered tuner. + */ +public class DiscoveredRsp1Tuner extends DiscoveredRspTuner +{ + /** + * Constructs an instance + * @param deviceInfo for controlling the RSP1A after it's been started + * @param channelizerType to use for the tuner once started + */ + public DiscoveredRsp1Tuner(DeviceInfo deviceInfo, ChannelizerType channelizerType) + { + super(deviceInfo, channelizerType); + } +} diff --git a/src/main/java/io/github/dsheirer/source/tuner/sdrplay/rsp1/IControlRsp1.java b/src/main/java/io/github/dsheirer/source/tuner/sdrplay/rsp1/IControlRsp1.java new file mode 100644 index 000000000..424097066 --- /dev/null +++ b/src/main/java/io/github/dsheirer/source/tuner/sdrplay/rsp1/IControlRsp1.java @@ -0,0 +1,30 @@ +/* + * ***************************************************************************** + * Copyright (C) 2014-2023 Dennis Sheirer + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see + * **************************************************************************** + */ + +package io.github.dsheirer.source.tuner.sdrplay.rsp1; + +import io.github.dsheirer.source.tuner.sdrplay.IControlRsp; + +/** + * Control interface for RSP1A device + */ +public interface IControlRsp1 extends IControlRsp +{ + //No additional features beyond the base control. +} diff --git a/src/main/java/io/github/dsheirer/source/tuner/sdrplay/rsp1/Rsp1TunerConfiguration.java b/src/main/java/io/github/dsheirer/source/tuner/sdrplay/rsp1/Rsp1TunerConfiguration.java new file mode 100644 index 000000000..08660965d --- /dev/null +++ b/src/main/java/io/github/dsheirer/source/tuner/sdrplay/rsp1/Rsp1TunerConfiguration.java @@ -0,0 +1,51 @@ +/* + * ***************************************************************************** + * 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 io.github.dsheirer.source.tuner.sdrplay.rsp1; + +import io.github.dsheirer.source.tuner.TunerType; +import io.github.dsheirer.source.tuner.sdrplay.RspTunerConfiguration; + +/** + * RSP1 tuner configuration + */ +public class Rsp1TunerConfiguration extends RspTunerConfiguration +{ + /** + * Constructs an instance + * @param uniqueId for the tuner + */ + public Rsp1TunerConfiguration(String uniqueId) + { + super(uniqueId); + } + + /** + * JAXB constructor + */ + public Rsp1TunerConfiguration() + { + } + + @Override + public TunerType getTunerType() + { + return TunerType.RSP_1; + } +} diff --git a/src/main/java/io/github/dsheirer/source/tuner/sdrplay/rsp1/Rsp1TunerController.java b/src/main/java/io/github/dsheirer/source/tuner/sdrplay/rsp1/Rsp1TunerController.java new file mode 100644 index 000000000..68c174273 --- /dev/null +++ b/src/main/java/io/github/dsheirer/source/tuner/sdrplay/rsp1/Rsp1TunerController.java @@ -0,0 +1,66 @@ +/* + * ***************************************************************************** + * Copyright (C) 2014-2023 Dennis Sheirer + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see + * **************************************************************************** + */ + +package io.github.dsheirer.source.tuner.sdrplay.rsp1; + +import io.github.dsheirer.source.SourceException; +import io.github.dsheirer.source.tuner.ITunerErrorListener; +import io.github.dsheirer.source.tuner.TunerType; +import io.github.dsheirer.source.tuner.configuration.TunerConfiguration; +import io.github.dsheirer.source.tuner.sdrplay.RspTunerController; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +/** + * Tuner controller for RSP1 + */ +public class Rsp1TunerController extends RspTunerController +{ + private Logger mLog = LoggerFactory.getLogger(Rsp1TunerController.class); + + /** + * Constructs an instance + * + * @param control interface for the RSP1 tuner + * @param tunerErrorListener to monitor errors produced from this tuner controller + */ + public Rsp1TunerController(IControlRsp1 control, ITunerErrorListener tunerErrorListener) + { + super(control, tunerErrorListener); + } + + @Override + public TunerType getTunerType() + { + return TunerType.RSP_1; + } + + @Override + public void apply(TunerConfiguration config) throws SourceException + { + if(config instanceof Rsp1TunerConfiguration) + { + super.apply(config); + } + else + { + mLog.error("Invalid RSP1 tuner configuration type: " + config.getClass()); + } + } +} diff --git a/src/main/java/io/github/dsheirer/source/tuner/sdrplay/rsp1/Rsp1TunerEditor.java b/src/main/java/io/github/dsheirer/source/tuner/sdrplay/rsp1/Rsp1TunerEditor.java new file mode 100644 index 000000000..590b4039a --- /dev/null +++ b/src/main/java/io/github/dsheirer/source/tuner/sdrplay/rsp1/Rsp1TunerEditor.java @@ -0,0 +1,172 @@ +/* + * ***************************************************************************** + * Copyright (C) 2014-2023 Dennis Sheirer + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see + * **************************************************************************** + */ + +package io.github.dsheirer.source.tuner.sdrplay.rsp1; + +import com.github.dsheirer.sdrplay.SDRPlayException; +import io.github.dsheirer.preference.UserPreferences; +import io.github.dsheirer.source.tuner.manager.TunerManager; +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 net.miginfocom.swing.MigLayout; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import javax.swing.JComboBox; +import javax.swing.JLabel; +import javax.swing.JSeparator; +import javax.swing.SpinnerNumberModel; + +/** + * RSP1 Tuner Editor + */ +public class Rsp1TunerEditor extends RspTunerEditor +{ + private static final Logger mLog = LoggerFactory.getLogger(Rsp1TunerEditor.class); + + private JComboBox mSampleRateCombo; + + /** + * Constructs an instance + * @param userPreferences for settings + * @param tunerManager for state updates + * @param discoveredTuner to edit or control. + */ + public Rsp1TunerEditor(UserPreferences userPreferences, TunerManager tunerManager, DiscoveredRspTuner discoveredTuner) + { + super(userPreferences, tunerManager, discoveredTuner); + init(); + tunerStatusUpdated(); + } + + private void init() + { + setLayout(new MigLayout("fill,wrap 3", "[right][grow,fill][fill]", + "[][][][][][][][][][][][grow]")); + + add(new JLabel("Tuner:")); + add(getTunerIdLabel(), "wrap"); + + add(new JLabel("Status:")); + add(getTunerStatusLabel(), "wrap"); + + add(getButtonPanel(), "span,align left"); + + add(new JSeparator(), "span,growx,push"); + + add(new JLabel("Frequency (MHz):")); + add(getFrequencyPanel(), "wrap"); + + add(new JLabel("Sample Rate:")); + add(getSampleRateCombo(), "wrap"); + + add(new JLabel("Gain:")); + add(getGainSlider()); + add(getGainValueLabel()); + + add(new JSeparator(), "span,growx,push"); + } + + /** + * Access tuner controller + */ + private Rsp1TunerController getTunerController() + { + if(hasTuner()) + { + return (Rsp1TunerController)getTuner().getTunerController(); + } + + return null; + } + + @Override + protected void tunerStatusUpdated() + { + setLoading(true); + + getTunerIdLabel().setText(getDiscoveredTuner().getId()); + + String status = getDiscoveredTuner().getTunerStatus().toString(); + if(getDiscoveredTuner().hasErrorMessage()) + { + status += " - " + getDiscoveredTuner().getErrorMessage(); + } + getTunerStatusLabel().setText(status); + getButtonPanel().updateControls(); + getFrequencyPanel().updateControls(); + + getSampleRateCombo().setEnabled(hasTuner() && !getTuner().getTunerController().isLockedSampleRate()); + getSampleRateCombo().setSelectedItem(hasTuner() ? getTunerController().getControlRsp().getSampleRateEnumeration() : null); + + getGainSlider().setEnabled(hasTuner()); + getGainValueLabel().setEnabled(hasTuner()); + getGainSlider().setValue(hasTuner() ? getTunerController().getControlRsp().getGain() : 0); + + setLoading(false); + } + + @Override + public void save() + { + if(hasConfiguration() && !isLoading()) + { + getConfiguration().setFrequency(getFrequencyControl().getFrequency()); + double value = ((SpinnerNumberModel) getFrequencyCorrectionSpinner().getModel()).getNumber().doubleValue(); + getConfiguration().setFrequencyCorrection(value); + getConfiguration().setAutoPPMCorrectionEnabled(getAutoPPMCheckBox().isSelected()); + getConfiguration().setSampleRate((RspSampleRate)getSampleRateCombo().getSelectedItem()); + getConfiguration().setGain(getGainSlider().getValue()); + + saveConfiguration(); + } + } + + /** + * Sample rate selection combobox control + */ + private JComboBox getSampleRateCombo() + { + if(mSampleRateCombo == null) + { + RspSampleRate[] rspSampleRates = RspSampleRate.SINGLE_TUNER_SAMPLE_RATES.toArray(new RspSampleRate[RspSampleRate.SINGLE_TUNER_SAMPLE_RATES.size()]); + mSampleRateCombo = new JComboBox<>(rspSampleRates); + mSampleRateCombo.setEnabled(false); + mSampleRateCombo.addActionListener(e -> { + if(hasTuner() && !isLoading()) + { + RspSampleRate selected = (RspSampleRate)mSampleRateCombo.getSelectedItem(); + + try + { + getTunerController().setSampleRate(selected); + save(); + } + catch(SDRPlayException se) + { + mLog.error("Error setting sample rate for RSP1A tuner", se); + } + } + }); + } + + return mSampleRateCombo; + } +} 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 new file mode 100644 index 000000000..af1dd02c3 --- /dev/null +++ b/src/main/java/io/github/dsheirer/source/tuner/sdrplay/rsp1a/ControlRsp1a.java @@ -0,0 +1,121 @@ +/* + * ***************************************************************************** + * Copyright (C) 2014-2023 Dennis Sheirer + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see + * **************************************************************************** + */ + +package io.github.dsheirer.source.tuner.sdrplay.rsp1a; + +import com.github.dsheirer.sdrplay.SDRPlayException; +import com.github.dsheirer.sdrplay.device.Rsp1aDevice; +import io.github.dsheirer.source.tuner.sdrplay.ControlRsp; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +/** + * Control wrapper for an RSP1A Device + */ +public class ControlRsp1a extends ControlRsp implements IControlRsp1a +{ + private Logger mLog = LoggerFactory.getLogger(ControlRsp1a.class); + + /** + * Constructs an instance + * @param device for the device + */ + public ControlRsp1a(Rsp1aDevice device) + { + super(device); + } + + @Override + public boolean isBiasT() throws SDRPlayException + { + if(hasDevice()) + { + return getDevice().getTuner().isBiasT(); + } + else + { + throw new SDRPlayException("Device is not initialized"); + } + } + + @Override + public void setBiasT(boolean enabled) throws SDRPlayException + { + if(hasDevice()) + { + getDevice().getTuner().setBiasT(enabled); + } + else + { + throw new SDRPlayException("Device is not initialized"); + } + } + + @Override + public boolean isRfDabNotch() throws SDRPlayException + { + if(hasDevice()) + { + return getDevice().getTuner().isRfDabNotch(); + } + else + { + throw new SDRPlayException("Device is not initialized"); + } + } + + @Override + public void setRfDabNotch(boolean enabled) throws SDRPlayException + { + if(hasDevice()) + { + getDevice().getTuner().setRfDabNotch(enabled); + } + else + { + throw new SDRPlayException("Device is not initialized"); + } + } + + @Override + public boolean isRfNotch() throws SDRPlayException + { + if(hasDevice()) + { + return getDevice().getTuner().isRfNotch(); + } + else + { + throw new SDRPlayException("Device is not initialized"); + } + } + + @Override + public void setRfNotch(boolean enabled) throws SDRPlayException + { + if(hasDevice()) + { + getDevice().getTuner().setRfNotch(enabled); + } + else + { + throw new SDRPlayException("Device is not initialized"); + } + } +} 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 new file mode 100644 index 000000000..c2994f0ab --- /dev/null +++ b/src/main/java/io/github/dsheirer/source/tuner/sdrplay/rsp1a/DiscoveredRsp1aTuner.java @@ -0,0 +1,40 @@ +/* + * ***************************************************************************** + * Copyright (C) 2014-2023 Dennis Sheirer + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see + * **************************************************************************** + */ + +package io.github.dsheirer.source.tuner.sdrplay.rsp1a; + +import com.github.dsheirer.sdrplay.device.DeviceInfo; +import io.github.dsheirer.preference.source.ChannelizerType; +import io.github.dsheirer.source.tuner.sdrplay.DiscoveredRspTuner; + +/** + * RSP1A discovered tuner. + */ +public class DiscoveredRsp1aTuner extends DiscoveredRspTuner +{ + /** + * Constructs an instance + * @param deviceInfo for controlling the RSP1A after it's been started + * @param channelizerType to use for the tuner once started + */ + public DiscoveredRsp1aTuner(DeviceInfo deviceInfo, ChannelizerType channelizerType) + { + super(deviceInfo, channelizerType); + } +} diff --git a/src/main/java/io/github/dsheirer/source/tuner/sdrplay/rsp1a/IControlRsp1a.java b/src/main/java/io/github/dsheirer/source/tuner/sdrplay/rsp1a/IControlRsp1a.java new file mode 100644 index 000000000..4da745f35 --- /dev/null +++ b/src/main/java/io/github/dsheirer/source/tuner/sdrplay/rsp1a/IControlRsp1a.java @@ -0,0 +1,71 @@ +/* + * ***************************************************************************** + * 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 io.github.dsheirer.source.tuner.sdrplay.rsp1a; + +import com.github.dsheirer.sdrplay.SDRPlayException; +import io.github.dsheirer.source.tuner.sdrplay.IControlRsp; + +/** + * Control interface for RSP1A device + */ +public interface IControlRsp1a extends IControlRsp +{ + /** + * Indicates if the Bias-T power is enabled. + * @return true if enabled. + * @throws exception if the device is no started/selected + */ + boolean isBiasT() throws SDRPlayException; + + /** + * Sets the enabled state of the Bias-T power. + * @param enabled true to power on the Bias-T + * @throws exception if the device is no started/selected + */ + void setBiasT(boolean enabled) throws SDRPlayException; + + /** + * Indicates if the RF DAB notch is enabled (DAB broadcast band filter). + * @return true if enabled. + * @throws exception if the device is no started/selected + */ + boolean isRfDabNotch() throws SDRPlayException; + + /** + * Sets the enabled state of the RF DAB notch. + * @param enabled true to filter the DAB broadcast band frequency range. + * @throws exception if the device is no started/selected + */ + void setRfDabNotch(boolean enabled) throws SDRPlayException; + + /** + * Indicates if the RF notch is enabled (FM broadcast band filter). + * @return true if enabled. + * @throws exception if the device is no started/selected + */ + boolean isRfNotch() throws SDRPlayException; + + /** + * Sets the enabled state of the RF notch + * @param enabled true to filter the FM broadcast band frequency range. + * @throws exception if the device is no started/selected + */ + void setRfNotch(boolean enabled) throws SDRPlayException; +} diff --git a/src/main/java/io/github/dsheirer/source/tuner/sdrplay/rsp1a/Rsp1aTunerConfiguration.java b/src/main/java/io/github/dsheirer/source/tuner/sdrplay/rsp1a/Rsp1aTunerConfiguration.java new file mode 100644 index 000000000..d2915b3a2 --- /dev/null +++ b/src/main/java/io/github/dsheirer/source/tuner/sdrplay/rsp1a/Rsp1aTunerConfiguration.java @@ -0,0 +1,109 @@ +/* + * ***************************************************************************** + * 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 io.github.dsheirer.source.tuner.sdrplay.rsp1a; + +import com.fasterxml.jackson.dataformat.xml.annotation.JacksonXmlProperty; +import io.github.dsheirer.source.tuner.TunerType; +import io.github.dsheirer.source.tuner.sdrplay.RspTunerConfiguration; + +/** + * RSP1A tuner configuration + */ +public class Rsp1aTunerConfiguration extends RspTunerConfiguration +{ + private boolean mRfNotch; + private boolean mRfDabNotch; + private boolean mBiasT; + + /** + * Constructs an instance + * @param uniqueId for the tuner + */ + public Rsp1aTunerConfiguration(String uniqueId) + { + super(uniqueId); + } + + /** + * JAXB constructor + */ + public Rsp1aTunerConfiguration() + { + } + + @Override + public TunerType getTunerType() + { + return TunerType.RSP_1A; + } + + /** + * Indicates if the RF notch is enabled. + */ + @JacksonXmlProperty(isAttribute = true, localName = "rf_notch") + public boolean isRfNotch() + { + return mRfNotch; + } + + /** + * Sets the enabled state of the RF notch + * @param enabled + */ + public void setRfNotch(boolean enabled) + { + mRfNotch = enabled; + } + + /** + * Indicates if the RF Digital Audio Broadcast (DAB) notch is enabled. + */ + @JacksonXmlProperty(isAttribute = true, localName = "dab_notch") + public boolean isRfDabNotch() + { + return mRfDabNotch; + } + + /** + * Sets the enabled state of the RF DAB notch + * @param enabled + */ + public void setRfDabNotch(boolean enabled) + { + mRfDabNotch = enabled; + } + + /** + * Indicates if the Bias-T is enabled. + */ + @JacksonXmlProperty(isAttribute = true, localName = "bias_t") + public boolean isBiasT() + { + return mBiasT; + } + + /** + * Sets the enabled state of the Bias-T + */ + public void setBiasT(boolean enabled) + { + mBiasT = enabled; + } +} diff --git a/src/main/java/io/github/dsheirer/source/tuner/sdrplay/rsp1a/Rsp1aTunerController.java b/src/main/java/io/github/dsheirer/source/tuner/sdrplay/rsp1a/Rsp1aTunerController.java new file mode 100644 index 000000000..0933dc940 --- /dev/null +++ b/src/main/java/io/github/dsheirer/source/tuner/sdrplay/rsp1a/Rsp1aTunerController.java @@ -0,0 +1,94 @@ +/* + * ***************************************************************************** + * 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 io.github.dsheirer.source.tuner.sdrplay.rsp1a; + +import com.github.dsheirer.sdrplay.SDRPlayException; +import io.github.dsheirer.source.SourceException; +import io.github.dsheirer.source.tuner.ITunerErrorListener; +import io.github.dsheirer.source.tuner.TunerType; +import io.github.dsheirer.source.tuner.configuration.TunerConfiguration; +import io.github.dsheirer.source.tuner.sdrplay.RspTunerController; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +/** + * Tuner controller for RSP1a + */ +public class Rsp1aTunerController extends RspTunerController +{ + private Logger mLog = LoggerFactory.getLogger(Rsp1aTunerController.class); + + /** + * Constructs an instance + * + * @param control interface for the RSP1A tuner + * @param tunerErrorListener to monitor errors produced from this tuner controller + */ + public Rsp1aTunerController(IControlRsp1a control, ITunerErrorListener tunerErrorListener) + { + super(control, tunerErrorListener); + } + + @Override + public TunerType getTunerType() + { + return TunerType.RSP_1A; + } + + @Override + public void apply(TunerConfiguration config) throws SourceException + { + if(config instanceof Rsp1aTunerConfiguration rtc) + { + super.apply(config); + + try + { + getControlRsp().setBiasT(rtc.isBiasT()); + } + catch(SDRPlayException se) + { + mLog.error("Error setting RSP1A bias-T enabled to " + rtc.isBiasT()); + } + + try + { + getControlRsp().setRfNotch(rtc.isRfNotch()); + } + catch(SDRPlayException se) + { + mLog.error("Error setting RSP1A RF Notch enabled to " + rtc.isRfNotch()); + } + + try + { + getControlRsp().setRfDabNotch(rtc.isRfDabNotch()); + } + catch(SDRPlayException se) + { + mLog.error("Error setting RSP1A RF DAB Notch enabled to " + rtc.isRfDabNotch()); + } + } + else + { + mLog.error("Invalid RSP1A tuner configuration type: " + config.getClass()); + } + } +} diff --git a/src/main/java/io/github/dsheirer/source/tuner/sdrplay/rsp1a/Rsp1aTunerEditor.java b/src/main/java/io/github/dsheirer/source/tuner/sdrplay/rsp1a/Rsp1aTunerEditor.java new file mode 100644 index 000000000..687bc3ec4 --- /dev/null +++ b/src/main/java/io/github/dsheirer/source/tuner/sdrplay/rsp1a/Rsp1aTunerEditor.java @@ -0,0 +1,300 @@ +/* + * ***************************************************************************** + * 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 io.github.dsheirer.source.tuner.sdrplay.rsp1a; + +import com.github.dsheirer.sdrplay.SDRPlayException; +import io.github.dsheirer.preference.UserPreferences; +import io.github.dsheirer.source.tuner.manager.TunerManager; +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 net.miginfocom.swing.MigLayout; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import javax.swing.JCheckBox; +import javax.swing.JComboBox; +import javax.swing.JLabel; +import javax.swing.JSeparator; +import javax.swing.SpinnerNumberModel; + +/** + * RSP1A Tuner Editor + */ +public class Rsp1aTunerEditor extends RspTunerEditor +{ + private static final Logger mLog = LoggerFactory.getLogger(Rsp1aTunerEditor.class); + + private JComboBox mSampleRateCombo; + private JCheckBox mBiasTCheckBox; + private JCheckBox mRfDabNotchCheckBox; + private JCheckBox mRfNotchCheckBox; + + /** + * Constructs an instance + * @param userPreferences for settings + * @param tunerManager for state updates + * @param discoveredTuner to edit or control. + */ + public Rsp1aTunerEditor(UserPreferences userPreferences, TunerManager tunerManager, DiscoveredRspTuner discoveredTuner) + { + super(userPreferences, tunerManager, discoveredTuner); + init(); + tunerStatusUpdated(); + } + + private void init() + { + setLayout(new MigLayout("fill,wrap 3", "[right][grow,fill][fill]", + "[][][][][][][][][][][][grow]")); + + add(new JLabel("Tuner:")); + add(getTunerIdLabel(), "wrap"); + + add(new JLabel("Status:")); + add(getTunerStatusLabel(), "wrap"); + + add(getButtonPanel(), "span,align left"); + + add(new JSeparator(), "span,growx,push"); + + add(new JLabel("Frequency (MHz):")); + add(getFrequencyPanel(), "wrap"); + + add(new JLabel("Sample Rate:")); + add(getSampleRateCombo(), "wrap"); + + add(new JLabel("Gain:")); + add(getGainSlider()); + add(getGainValueLabel()); + + add(new JSeparator(), "span,growx,push"); + + add(new JLabel()); + add(getBiasTCheckBox(), "wrap"); + add(new JLabel()); + add(getRfNotchCheckBox(), "wrap"); + add(new JLabel()); + add(getRfDabNotchCheckBox(), "wrap"); + } + + /** + * Access tuner controller + */ + private Rsp1aTunerController getTunerController() + { + if(hasTuner()) + { + return (Rsp1aTunerController)getTuner().getTunerController(); + } + + return null; + } + + @Override + protected void tunerStatusUpdated() + { + setLoading(true); + + getTunerIdLabel().setText(getDiscoveredTuner().getId()); + + String status = getDiscoveredTuner().getTunerStatus().toString(); + if(getDiscoveredTuner().hasErrorMessage()) + { + status += " - " + getDiscoveredTuner().getErrorMessage(); + } + getTunerStatusLabel().setText(status); + getButtonPanel().updateControls(); + getFrequencyPanel().updateControls(); + + getSampleRateCombo().setEnabled(hasTuner() && !getTuner().getTunerController().isLockedSampleRate()); + getSampleRateCombo().setSelectedItem(hasTuner() ? getTunerController().getControlRsp().getSampleRateEnumeration() : null); + + getGainSlider().setEnabled(hasTuner()); + getGainValueLabel().setEnabled(hasTuner()); + getGainSlider().setValue(hasTuner() ? getTunerController().getControlRsp().getGain() : 0); + + getBiasTCheckBox().setEnabled(hasTuner()); + try + { + getBiasTCheckBox().setSelected(hasTuner() && getTunerController().getControlRsp().isBiasT()); + } + catch(SDRPlayException se) + { + mLog.error("Error setting Bias-T enabled state in editor"); + } + + getRfDabNotchCheckBox().setEnabled(hasTuner()); + try + { + getRfDabNotchCheckBox().setSelected(hasTuner() && getTunerController().getControlRsp().isRfDabNotch()); + } + catch(SDRPlayException se) + { + mLog.error("Error setting RF DAB Notch enabled state in editor"); + } + + getRfNotchCheckBox().setEnabled(hasTuner()); + try + { + getRfNotchCheckBox().setSelected(hasTuner() ? getTunerController().getControlRsp().isRfNotch() : false); + } + catch(SDRPlayException se) + { + mLog.error("Error setting RF Notch enabled state in editor"); + } + + setLoading(false); + } + + @Override + public void save() + { + if(hasConfiguration() && !isLoading()) + { + getConfiguration().setFrequency(getFrequencyControl().getFrequency()); + double value = ((SpinnerNumberModel) getFrequencyCorrectionSpinner().getModel()).getNumber().doubleValue(); + getConfiguration().setFrequencyCorrection(value); + getConfiguration().setAutoPPMCorrectionEnabled(getAutoPPMCheckBox().isSelected()); + getConfiguration().setSampleRate((RspSampleRate)getSampleRateCombo().getSelectedItem()); + getConfiguration().setBiasT(getBiasTCheckBox().isSelected()); + getConfiguration().setRfNotch(getRfNotchCheckBox().isSelected()); + getConfiguration().setRfDabNotch(getRfDabNotchCheckBox().isSelected()); + getConfiguration().setGain(getGainSlider().getValue()); + + saveConfiguration(); + } + } + + /** + * Sample rate selection combobox control + */ + private JComboBox getSampleRateCombo() + { + if(mSampleRateCombo == null) + { + RspSampleRate[] rspSampleRates = RspSampleRate.SINGLE_TUNER_SAMPLE_RATES.toArray(new RspSampleRate[RspSampleRate.SINGLE_TUNER_SAMPLE_RATES.size()]); + mSampleRateCombo = new JComboBox<>(rspSampleRates); + mSampleRateCombo.setEnabled(false); + mSampleRateCombo.addActionListener(e -> { + if(hasTuner() && !isLoading()) + { + RspSampleRate selected = (RspSampleRate)mSampleRateCombo.getSelectedItem(); + + try + { + getTunerController().setSampleRate(selected); + save(); + } + catch(SDRPlayException se) + { + mLog.error("Error setting sample rate for RSP1A tuner", se); + } + } + }); + } + + return mSampleRateCombo; + } + + /** + * Checkbox control for Bias-T + */ + private JCheckBox getBiasTCheckBox() + { + if(mBiasTCheckBox == null) + { + mBiasTCheckBox = new JCheckBox("Bias-T Power"); + mBiasTCheckBox.setEnabled(false); + mBiasTCheckBox.addActionListener(e -> { + if(hasTuner() && !isLoading()) + { + try + { + getTunerController().getControlRsp().setBiasT(mBiasTCheckBox.isSelected()); + save(); + } + catch(SDRPlayException se) + { + mLog.error("Unable to set RSP1A Bias-T enabled to " + mBiasTCheckBox.isSelected(), se); + } + } + }); + } + + return mBiasTCheckBox; + } + + /** + * Checkbox control for RF DAB notch + */ + private JCheckBox getRfDabNotchCheckBox() + { + if(mRfDabNotchCheckBox == null) + { + mRfDabNotchCheckBox = new JCheckBox("DAB Broadcast Band Filter (160-235 MHz)"); + mRfDabNotchCheckBox.setEnabled(false); + mRfDabNotchCheckBox.addActionListener(e -> { + if(hasTuner() && !isLoading()) + { + try + { + getTunerController().getControlRsp().setRfDabNotch(mRfDabNotchCheckBox.isSelected()); + save(); + } + catch(SDRPlayException se) + { + mLog.error("Unable to set RSP1A RF DAB notch enabled to " + mRfDabNotchCheckBox.isSelected(), se); + } + } + }); + } + + return mRfDabNotchCheckBox; + } + + /** + * Checkbox control for RF notch + */ + private JCheckBox getRfNotchCheckBox() + { + if(mRfNotchCheckBox == null) + { + mRfNotchCheckBox = new JCheckBox("FM Broadcast Band Filter (77-115 MHz)"); + mRfNotchCheckBox.setEnabled(false); + mRfNotchCheckBox.addActionListener(e -> { + if(hasTuner() && !isLoading()) + { + try + { + getTunerController().getControlRsp().setRfNotch(mRfNotchCheckBox.isSelected()); + save(); + } + catch(SDRPlayException se) + { + mLog.error("Unable to set RSP1A RF notch enabled to " + mRfNotchCheckBox.isSelected(), se); + } + } + }); + } + + return mRfNotchCheckBox; + } +} 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 new file mode 100644 index 000000000..33b6dd7da --- /dev/null +++ b/src/main/java/io/github/dsheirer/source/tuner/sdrplay/rsp2/ControlRsp2.java @@ -0,0 +1,144 @@ +/* + * ***************************************************************************** + * Copyright (C) 2014-2023 Dennis Sheirer + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see + * **************************************************************************** + */ + +package io.github.dsheirer.source.tuner.sdrplay.rsp2; + +import com.github.dsheirer.sdrplay.SDRPlayException; +import com.github.dsheirer.sdrplay.device.Rsp2Device; +import com.github.dsheirer.sdrplay.parameter.tuner.Rsp2AntennaSelection; +import io.github.dsheirer.source.tuner.sdrplay.ControlRsp; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +/** + * Control wrapper for an RSP2 Device + */ +public class ControlRsp2 extends ControlRsp implements IControlRsp2 +{ + private Logger mLog = LoggerFactory.getLogger(ControlRsp2.class); + private Rsp2AntennaSelection mAntennaSelection = Rsp2AntennaSelection.ANT_A; + + /** + * Constructs an instance + * @param sdrplayApi to control the device + * @param device to control + */ + public ControlRsp2(Rsp2Device device) + { + super(device); + } + + @Override + public boolean isBiasT() throws SDRPlayException + { + if(hasDevice()) + { + return getDevice().getTuner().isBiasT(); + } + else + { + throw new SDRPlayException("Device is not initialized"); + } + } + + @Override + public void setBiasT(boolean enabled) throws SDRPlayException + { + if(hasDevice()) + { + getDevice().getTuner().setBiasT(enabled); + } + else + { + throw new SDRPlayException("Device is not initialized"); + } + } + + @Override + public boolean isExternalReferenceOutput() throws SDRPlayException + { + if(hasDevice()) + { + return getDevice().getTuner().isExternalReferenceOutput(); + } + else + { + throw new SDRPlayException("Device is not initialized"); + } + } + + @Override + public void setExternalReferenceOutput(boolean enabled) throws SDRPlayException + { + if(hasDevice()) + { + getDevice().getTuner().setExternalReferenceOutput(enabled); + } + else + { + throw new SDRPlayException("Device is not initialized"); + } + } + + @Override + public boolean isRfNotch() throws SDRPlayException + { + if(hasDevice()) + { + return getDevice().getTuner().isRfNotch(); + } + else + { + throw new SDRPlayException("Device is not initialized"); + } + } + + @Override + public void setRfNotch(boolean enabled) throws SDRPlayException + { + if(hasDevice()) + { + getDevice().getTuner().setRfNotch(enabled); + } + else + { + throw new SDRPlayException("Device is not initialized"); + } + } + + @Override + public Rsp2AntennaSelection getAntennaSelection() throws SDRPlayException + { + return mAntennaSelection; + } + + @Override + public void setAntennaSelection(Rsp2AntennaSelection selection) throws SDRPlayException + { + if(hasDevice()) + { + getDevice().getTuner().setAmPort(selection.getAmPort()); + getDevice().getTuner().setAntenna(selection.getAntenna()); + } + else + { + throw new SDRPlayException("Device is not initialized"); + } + } +} 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 new file mode 100644 index 000000000..9032a87d3 --- /dev/null +++ b/src/main/java/io/github/dsheirer/source/tuner/sdrplay/rsp2/DiscoveredRsp2Tuner.java @@ -0,0 +1,40 @@ +/* + * ***************************************************************************** + * Copyright (C) 2014-2023 Dennis Sheirer + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see + * **************************************************************************** + */ + +package io.github.dsheirer.source.tuner.sdrplay.rsp2; + +import com.github.dsheirer.sdrplay.device.DeviceInfo; +import io.github.dsheirer.preference.source.ChannelizerType; +import io.github.dsheirer.source.tuner.sdrplay.DiscoveredRspTuner; + +/** + * RSP2 discovered tuner. + */ +public class DiscoveredRsp2Tuner extends DiscoveredRspTuner +{ + /** + * Constructs an instance + * @param deviceInfo for the tuner + * @param channelizerType to use for the tuner once started + */ + public DiscoveredRsp2Tuner(DeviceInfo deviceInfo, ChannelizerType channelizerType) + { + super(deviceInfo, channelizerType); + } +} diff --git a/src/main/java/io/github/dsheirer/source/tuner/sdrplay/rsp2/IControlRsp2.java b/src/main/java/io/github/dsheirer/source/tuner/sdrplay/rsp2/IControlRsp2.java new file mode 100644 index 000000000..9e8eed542 --- /dev/null +++ b/src/main/java/io/github/dsheirer/source/tuner/sdrplay/rsp2/IControlRsp2.java @@ -0,0 +1,86 @@ +/* + * ***************************************************************************** + * 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 io.github.dsheirer.source.tuner.sdrplay.rsp2; + +import com.github.dsheirer.sdrplay.SDRPlayException; +import com.github.dsheirer.sdrplay.parameter.tuner.Rsp2AntennaSelection; +import io.github.dsheirer.source.tuner.sdrplay.IControlRsp; + +/** + * Control interface for RSP2 device + */ +public interface IControlRsp2 extends IControlRsp +{ + /** + * Indicates if the Bias-T power is enabled. + * @return true if enabled. + * @throws SDRPlayException if the device is no started/selected + */ + boolean isBiasT() throws SDRPlayException; + + /** + * Sets the enabled state of the Bias-T power. + * @param enabled true to power on the Bias-T + * @throws SDRPlayException if the device is not started (selected). + */ + void setBiasT(boolean enabled) throws SDRPlayException; + + /** + * Indicates the enabled state of the external reference output. + * @return true if enabled. + * @throws SDRPlayException if the device is not started (selected). + */ + boolean isExternalReferenceOutput() throws SDRPlayException; + + /** + * Sets the enabled state of the external reference output. + * @param enabled true to enable. + * @throws SDRPlayException if the device is not started (selected). + */ + void setExternalReferenceOutput(boolean enabled) throws SDRPlayException; + + /** + * Indicates if the RF notch is enabled (FM broadcast band filter). + * @return true if enabled. + * @throws SDRPlayException if the device is not started (selected). + */ + boolean isRfNotch() throws SDRPlayException; + + /** + * Sets the enabled state of the RF notch + * @param enabled true to filter the FM broadcast band frequency range. + * @throws SDRPlayException if the device is not started (selected). + */ + void setRfNotch(boolean enabled) throws SDRPlayException; + + /** + * Antenna currently being used. + * @return antenna being used. + * @throws SDRPlayException if the device is not started (selected). + */ + Rsp2AntennaSelection getAntennaSelection() throws SDRPlayException; + + /** + * Sets the antenna selection + * @param antenna to use + * @throws SDRPlayException if the device is not started (selected). + */ + void setAntennaSelection(Rsp2AntennaSelection antenna) throws SDRPlayException; +} diff --git a/src/main/java/io/github/dsheirer/source/tuner/sdrplay/rsp2/Rsp2TunerConfiguration.java b/src/main/java/io/github/dsheirer/source/tuner/sdrplay/rsp2/Rsp2TunerConfiguration.java new file mode 100644 index 000000000..e136d897c --- /dev/null +++ b/src/main/java/io/github/dsheirer/source/tuner/sdrplay/rsp2/Rsp2TunerConfiguration.java @@ -0,0 +1,126 @@ +/* + * ***************************************************************************** + * 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 io.github.dsheirer.source.tuner.sdrplay.rsp2; + +import com.fasterxml.jackson.dataformat.xml.annotation.JacksonXmlProperty; +import com.github.dsheirer.sdrplay.parameter.tuner.Rsp2AntennaSelection; +import io.github.dsheirer.source.tuner.TunerType; +import io.github.dsheirer.source.tuner.sdrplay.RspTunerConfiguration; + +/** + * RSP2 tuner configuration + */ +public class Rsp2TunerConfiguration extends RspTunerConfiguration +{ + private boolean mBiasT; + private boolean mExternalReferenceOutput; + private boolean mRfNotch; + private Rsp2AntennaSelection mAntennaSelection = Rsp2AntennaSelection.ANT_A; + + /** + * Constructs an instance + * @param uniqueId for the tuner + */ + public Rsp2TunerConfiguration(String uniqueId) + { + super(uniqueId); + } + + /** + * JAXB constructor + */ + public Rsp2TunerConfiguration() + { + } + + @Override + public TunerType getTunerType() + { + return TunerType.RSP_2; + } + + /** + * Indicates if the external reference output is enabled. + */ + @JacksonXmlProperty(isAttribute = true, localName = "external_reference_output") + public boolean isExternalReferenceOutput() + { + return mExternalReferenceOutput; + } + + /** + * Sets the enabled state of the external reference output. + */ + public void setExternalReferenceOutput(boolean enabled) + { + mExternalReferenceOutput = enabled; + } + + /** + * Indicates if the Bias-T is enabled + */ + @JacksonXmlProperty(isAttribute = true, localName = "bias_t") + public boolean isBiasT() + { + return mBiasT; + } + + /** + * Sets the enabled state of the Bias-T + */ + public void setBiasT(boolean enabled) + { + mBiasT = enabled; + } + + /** + * Indicates if the RF Notch is enabled + */ + @JacksonXmlProperty(isAttribute = true, localName = "rf_notch") + public boolean isRfNotch() + { + return mRfNotch; + } + + /** + * Sets the enabled state of the RF Notch. + */ + public void setRfNotch(boolean rfNotch) + { + mRfNotch = rfNotch; + } + + /** + * Antenna selection + */ + @JacksonXmlProperty(isAttribute = true, localName = "antenna") + public Rsp2AntennaSelection getAntennaSelection() + { + return mAntennaSelection; + } + + /** + * Sets the antenna selection + */ + public void setAntennaSelection(Rsp2AntennaSelection selection) + { + mAntennaSelection = selection; + } +} diff --git a/src/main/java/io/github/dsheirer/source/tuner/sdrplay/rsp2/Rsp2TunerController.java b/src/main/java/io/github/dsheirer/source/tuner/sdrplay/rsp2/Rsp2TunerController.java new file mode 100644 index 000000000..9ebbecea0 --- /dev/null +++ b/src/main/java/io/github/dsheirer/source/tuner/sdrplay/rsp2/Rsp2TunerController.java @@ -0,0 +1,103 @@ +/* + * ***************************************************************************** + * 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 io.github.dsheirer.source.tuner.sdrplay.rsp2; + +import com.github.dsheirer.sdrplay.SDRPlayException; +import io.github.dsheirer.source.SourceException; +import io.github.dsheirer.source.tuner.ITunerErrorListener; +import io.github.dsheirer.source.tuner.TunerType; +import io.github.dsheirer.source.tuner.configuration.TunerConfiguration; +import io.github.dsheirer.source.tuner.sdrplay.RspTunerController; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +/** + * Tuner controller for RSP2 + */ +public class Rsp2TunerController extends RspTunerController +{ + private Logger mLog = LoggerFactory.getLogger(Rsp2TunerController.class); + + /** + * Constructs an instance + * + * @param control interface for the RSP2 tuner + * @param tunerErrorListener to monitor errors produced from this tuner controller + */ + public Rsp2TunerController(IControlRsp2 control, ITunerErrorListener tunerErrorListener) + { + super(control, tunerErrorListener); + } + + @Override + public TunerType getTunerType() + { + return TunerType.RSP_2; + } + + @Override + public void apply(TunerConfiguration config) throws SourceException + { + if(config instanceof Rsp2TunerConfiguration rtc) + { + super.apply(config); + + try + { + getControlRsp().setBiasT(rtc.isBiasT()); + } + catch(SDRPlayException se) + { + mLog.error("Error setting RSP2 bias-T enabled to " + rtc.isBiasT()); + } + + try + { + getControlRsp().setExternalReferenceOutput(rtc.isExternalReferenceOutput()); + } + catch(SDRPlayException se) + { + mLog.error("Error setting RSP2 external reference output enabled to " + rtc.isExternalReferenceOutput()); + } + + try + { + getControlRsp().setRfNotch(rtc.isRfNotch()); + } + catch(SDRPlayException se) + { + mLog.error("Error setting RSP2 RF Notch enabled to " + rtc.isRfNotch()); + } + + try + { + getControlRsp().setAntennaSelection(rtc.getAntennaSelection()); + } + catch(SDRPlayException se) + { + mLog.error("Error setting RSP2 antenna selection to " + rtc.getAntennaSelection()); + } + } + else + { + mLog.error("Invalid RSP2 tuner configuration type: " + config.getClass()); + } + } +} diff --git a/src/main/java/io/github/dsheirer/source/tuner/sdrplay/rsp2/Rsp2TunerEditor.java b/src/main/java/io/github/dsheirer/source/tuner/sdrplay/rsp2/Rsp2TunerEditor.java new file mode 100644 index 000000000..cc7e83742 --- /dev/null +++ b/src/main/java/io/github/dsheirer/source/tuner/sdrplay/rsp2/Rsp2TunerEditor.java @@ -0,0 +1,345 @@ +/* + * ***************************************************************************** + * 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 io.github.dsheirer.source.tuner.sdrplay.rsp2; + +import com.github.dsheirer.sdrplay.SDRPlayException; +import com.github.dsheirer.sdrplay.parameter.tuner.Rsp2AntennaSelection; +import io.github.dsheirer.preference.UserPreferences; +import io.github.dsheirer.source.tuner.manager.TunerManager; +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 net.miginfocom.swing.MigLayout; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import javax.swing.JCheckBox; +import javax.swing.JComboBox; +import javax.swing.JLabel; +import javax.swing.JSeparator; +import javax.swing.SpinnerNumberModel; + +/** + * RSP2 Tuner Editor + */ +public class Rsp2TunerEditor extends RspTunerEditor +{ + private static final Logger mLog = LoggerFactory.getLogger(Rsp2TunerEditor.class); + + private JComboBox mSampleRateCombo; + private JCheckBox mBiasTCheckBox; + private JCheckBox mExternalReferenceOutputCheckBox; + private JCheckBox mRfNotchCheckBox; + private JComboBox mAntennaSelectionCombo; + + /** + * Constructs an instance + * @param userPreferences for settings + * @param tunerManager for state updates + * @param discoveredTuner to edit or control. + */ + public Rsp2TunerEditor(UserPreferences userPreferences, TunerManager tunerManager, DiscoveredRspTuner discoveredTuner) + { + super(userPreferences, tunerManager, discoveredTuner); + init(); + tunerStatusUpdated(); + } + + private void init() + { + setLayout(new MigLayout("fill,wrap 3", "[right][grow,fill][fill]", + "[][][][][][][][][][][][grow]")); + + add(new JLabel("Tuner:")); + add(getTunerIdLabel(), "wrap"); + + add(new JLabel("Status:")); + add(getTunerStatusLabel(), "wrap"); + + add(getButtonPanel(), "span,align left"); + + add(new JSeparator(), "span,growx,push"); + + add(new JLabel("Frequency (MHz):")); + add(getFrequencyPanel(), "wrap"); + + add(new JLabel("Sample Rate:")); + add(getSampleRateCombo(), "wrap"); + + add(new JLabel("Gain:")); + add(getGainSlider()); + add(getGainValueLabel()); + + add(new JSeparator(), "span,growx,push"); + + add(new JLabel()); + add(getBiasTCheckBox(), "wrap"); + add(new JLabel()); + add(getExternalReferenceOutputCheckBox(), "wrap"); + add(new JLabel()); + add(getRfNotchCheckBox(), "wrap"); + add(new JLabel()); + add(getAntennaSelectionCombo(), "wrap"); + } + + /** + * Access tuner controller + */ + private Rsp2TunerController getTunerController() + { + if(hasTuner()) + { + return (Rsp2TunerController) getTuner().getTunerController(); + } + + return null; + } + + @Override + protected void tunerStatusUpdated() + { + setLoading(true); + + getTunerIdLabel().setText(getDiscoveredTuner().getId()); + + String status = getDiscoveredTuner().getTunerStatus().toString(); + if(getDiscoveredTuner().hasErrorMessage()) + { + status += " - " + getDiscoveredTuner().getErrorMessage(); + } + getTunerStatusLabel().setText(status); + getButtonPanel().updateControls(); + getFrequencyPanel().updateControls(); + + getSampleRateCombo().setEnabled(hasTuner() && !getTuner().getTunerController().isLockedSampleRate()); + getSampleRateCombo().setSelectedItem(hasTuner() ? getTunerController().getControlRsp().getSampleRateEnumeration() : null); + + getGainSlider().setEnabled(hasTuner()); + getGainValueLabel().setEnabled(hasTuner()); + getGainSlider().setValue(hasTuner() ? getTunerController().getControlRsp().getGain() : 0); + + getBiasTCheckBox().setEnabled(hasTuner()); + try + { + getBiasTCheckBox().setSelected(hasTuner() && getTunerController().getControlRsp().isBiasT()); + } + catch(SDRPlayException se) + { + mLog.error("Error setting Bias-T enabled state in editor"); + } + + getExternalReferenceOutputCheckBox().setEnabled(hasTuner()); + try + { + getExternalReferenceOutputCheckBox().setSelected(hasTuner() && getTunerController().getControlRsp().isExternalReferenceOutput()); + } + catch(SDRPlayException se) + { + mLog.error("Error setting RF DAB Notch enabled state in editor"); + } + + getRfNotchCheckBox().setEnabled(hasTuner()); + try + { + getRfNotchCheckBox().setSelected(hasTuner() && getTunerController().getControlRsp().isRfNotch()); + } + catch(SDRPlayException se) + { + mLog.error("Error setting RF Notch enabled state in editor"); + } + + getAntennaSelectionCombo().setEnabled(hasTuner()); + try + { + getAntennaSelectionCombo().setSelectedItem(hasTuner() ? getTunerController().getControlRsp().getAntennaSelection() : null); + } + catch(SDRPlayException se) + { + mLog.error("Error setting antenna selection in editor"); + } + + setLoading(false); + } + + @Override + public void save() + { + if(hasConfiguration() && !isLoading()) + { + getConfiguration().setFrequency(getFrequencyControl().getFrequency()); + double value = ((SpinnerNumberModel) getFrequencyCorrectionSpinner().getModel()).getNumber().doubleValue(); + getConfiguration().setFrequencyCorrection(value); + getConfiguration().setAutoPPMCorrectionEnabled(getAutoPPMCheckBox().isSelected()); + getConfiguration().setSampleRate((RspSampleRate)getSampleRateCombo().getSelectedItem()); + getConfiguration().setBiasT(getBiasTCheckBox().isSelected()); + getConfiguration().setRfNotch(getRfNotchCheckBox().isSelected()); + getConfiguration().setAntennaSelection((Rsp2AntennaSelection)getAntennaSelectionCombo().getSelectedItem()); + getConfiguration().setGain(getGainSlider().getValue()); + + saveConfiguration(); + } + } + + /** + * Sample rate selection combobox control + */ + private JComboBox getSampleRateCombo() + { + if(mSampleRateCombo == null) + { + RspSampleRate[] rspSampleRates = RspSampleRate.SINGLE_TUNER_SAMPLE_RATES.toArray(new RspSampleRate[RspSampleRate.SINGLE_TUNER_SAMPLE_RATES.size()]); + mSampleRateCombo = new JComboBox<>(rspSampleRates); + mSampleRateCombo.setEnabled(false); + mSampleRateCombo.addActionListener(e -> { + if(hasTuner() && !isLoading()) + { + RspSampleRate selected = (RspSampleRate)mSampleRateCombo.getSelectedItem(); + + try + { + getTunerController().setSampleRate(selected); + save(); + } + catch(SDRPlayException se) + { + mLog.error("Error setting sample rate for RSP2 tuner", se); + } + } + }); + } + + return mSampleRateCombo; + } + + /** + * Checkbox control for Bias-T + */ + private JCheckBox getBiasTCheckBox() + { + if(mBiasTCheckBox == null) + { + mBiasTCheckBox = new JCheckBox("ANT B Bias-T Power"); + mBiasTCheckBox.setEnabled(false); + mBiasTCheckBox.addActionListener(e -> { + if(hasTuner() && !isLoading()) + { + try + { + getTunerController().getControlRsp().setBiasT(mBiasTCheckBox.isSelected()); + save(); + } + catch(SDRPlayException se) + { + mLog.error("Unable to set RSP2 Bias-T enabled to " + mBiasTCheckBox.isSelected(), se); + } + } + }); + } + + return mBiasTCheckBox; + } + + /** + * Checkbox control for RF notch + */ + private JCheckBox getRfNotchCheckBox() + { + if(mRfNotchCheckBox == null) + { + mRfNotchCheckBox = new JCheckBox("FM Broadcast Band Filter (77-115 MHz)"); + mRfNotchCheckBox.setEnabled(false); + mRfNotchCheckBox.addActionListener(e -> { + if(hasTuner() && !isLoading()) + { + try + { + getTunerController().getControlRsp().setRfNotch(mRfNotchCheckBox.isSelected()); + save(); + } + catch(SDRPlayException se) + { + mLog.error("Unable to set RSP2 RF notch enabled to " + mRfNotchCheckBox.isSelected(), se); + } + } + }); + } + + return mRfNotchCheckBox; + } + + /** + * Checkbox control for External Reference Output + */ + private JCheckBox getExternalReferenceOutputCheckBox() + { + if(mExternalReferenceOutputCheckBox == null) + { + mExternalReferenceOutputCheckBox = new JCheckBox("External Reference Output"); + mExternalReferenceOutputCheckBox.setEnabled(false); + mExternalReferenceOutputCheckBox.addActionListener(e -> { + if(hasTuner() && !isLoading()) + { + try + { + getTunerController().getControlRsp().setExternalReferenceOutput(mExternalReferenceOutputCheckBox.isSelected()); + save(); + } + catch(SDRPlayException se) + { + mLog.error("Unable to set RSP2 external reference output notch enabled to " + + mExternalReferenceOutputCheckBox.isSelected(), se); + } + } + }); + } + + return mExternalReferenceOutputCheckBox; + } + + /** + * Antenna selection combobox control + */ + private JComboBox getAntennaSelectionCombo() + { + if(mAntennaSelectionCombo == null) + { + mAntennaSelectionCombo = new JComboBox<>(Rsp2AntennaSelection.values()); + mAntennaSelectionCombo.setEnabled(false); + mAntennaSelectionCombo.addActionListener(e -> { + if(hasTuner() && !isLoading()) + { + Rsp2AntennaSelection selected = (Rsp2AntennaSelection)mAntennaSelectionCombo.getSelectedItem(); + + try + { + getTunerController().getControlRsp().setAntennaSelection(selected); + save(); + } + catch(SDRPlayException se) + { + mLog.error("Error setting Antenna selection for RSP2", se); + } + } + }); + } + + return mAntennaSelectionCombo; + } +} 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 new file mode 100644 index 000000000..8f95293c8 --- /dev/null +++ b/src/main/java/io/github/dsheirer/source/tuner/sdrplay/rspDuo/ControlRspDuo.java @@ -0,0 +1,347 @@ +/* + * ***************************************************************************** + * Copyright (C) 2014-2023 Dennis Sheirer + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see + * **************************************************************************** + */ + +package io.github.dsheirer.source.tuner.sdrplay.rspDuo; + +import com.github.dsheirer.sdrplay.DeviceSelectionMode; +import com.github.dsheirer.sdrplay.SDRPlayException; +import com.github.dsheirer.sdrplay.Status; +import com.github.dsheirer.sdrplay.UpdateReason; +import com.github.dsheirer.sdrplay.device.RspDuoDevice; +import com.github.dsheirer.sdrplay.device.RspDuoTuner; +import com.github.dsheirer.sdrplay.device.TunerSelect; +import com.github.dsheirer.sdrplay.parameter.control.AgcMode; +import com.github.dsheirer.sdrplay.parameter.control.ControlParameters; +import com.github.dsheirer.sdrplay.parameter.tuner.IfMode; +import com.github.dsheirer.sdrplay.parameter.tuner.LoMode; +import com.github.dsheirer.sdrplay.parameter.tuner.TunerParameters; +import io.github.dsheirer.source.tuner.sdrplay.ControlRsp; +import io.github.dsheirer.source.tuner.sdrplay.RspSampleRate; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +/** + * Base control wrapper for an RSPduo operating in either single-tuner or master or slave mode. + */ +public abstract class ControlRspDuo extends ControlRsp implements IControlRspDuo +{ + private final Logger mLog = LoggerFactory.getLogger(ControlRspDuo.class); + + /** + * Constructs an instance + * + * @param device for the device, obtained from the API + */ + public ControlRspDuo(RspDuoDevice device) + { + super(device); + } + + /** + * Access the tuner + * @return tuner + * @throws SDRPlayException if the device is not started/selected + */ + protected abstract T getTuner() throws SDRPlayException; + + /** + * Device selection mode - tuner 1 or tuner 2 + * @return mode + */ + public abstract DeviceSelectionMode getDeviceSelectionMode(); + + /** + * Control parameters for either tuner 1 or tuner 2 + * @return control parameters + */ + protected abstract ControlParameters getControlParameters(); + + /** + * Tuner parameters for either tuner 1 or tuner 2 + */ + protected abstract TunerParameters getTunerParameters(); + + @Override + public void start() throws SDRPlayException + { + if(hasDevice()) + { + 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 + getControlParameters().getDcOffset().setDC(true); + getControlParameters().getDcOffset().setIQ(true); + + //Setup LO and AGC Mode + getControlParameters().getAgc().setAgcMode(AgcMode.DISABLE); + getTunerParameters().setLoMode(LoMode.AUTO); + + //Setup IF mode. In master/slave dual-tuner mode use IF_2048, otherwise use IF_ZERO + if(getDeviceSelectionMode().isSingleTunerMode()) + { + getTunerParameters().setIfMode(IfMode.IF_ZERO); + } + else + { + getTunerParameters().setIfMode(IfMode.IF_2048); + } + } + else + { + throw new SDRPlayException("Unable to start - no device"); + } + } + + @Override + public void startStream() + { + mStreamingLock.lock(); + + try + { + if(hasDevice() && !mStreaming) + { + if(getDeviceSelectionMode().isSlaveMode()) + { + getDevice().initStreamB(getDeviceEventListener(), getStreamListener()); + } + else + { + getDevice().initStreamA(getDeviceEventListener(), getStreamListener()); + } + + mStreaming = true; + } + } + catch(SDRPlayException se) + { + if(se.getStatus() == Status.FAIL) + { + if(getDeviceEventListener() != null) + { + getDeviceEventListener().processDeviceRemoval(getTunerSelect()); + } + } + else + { + mLog.error("Unable to initialize/start streaming for RSPduo", se); + } + } + finally + { + mStreamingLock.unlock(); + } + } + + @Override + public void stopStream() + { + mStreamingLock.lock(); + + try + { + if(hasDevice() && mStreaming) + { + getDevice().uninitialize(); + mStreaming = false; + } + } + catch(Exception e) + { + mLog.error("Error while stopping RSPduo stream", e); + } + finally + { + mStreamingLock.unlock(); + } + } + + /** + * Sets the sample rate + * @param sampleRate enumeration value. + * @throws SDRPlayException if the device is not started/initialized + */ + @Override + public void setSampleRate(RspSampleRate sampleRate) throws SDRPlayException + { + if(hasDevice()) + { + mSampleRate = sampleRate; + + getDevice().getTuner().setBandwidth(sampleRate.getBandwidth()); + 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) + { + getDevice().update(getTunerSelect(), UpdateReason.DEVICE_SAMPLE_RATE); + } + + getControlParameters().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 for errors setting gain value. + */ + @Override + public void setGain(int gain) throws SDRPlayException + { + validateGain(gain); + + if(gain != mGain) + { + mGain = gain; + 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 getTuner().getFrequency(); + } + else + { + throw new SDRPlayException("Device is not initialized"); + } + } + + @Override + public void setTunedFrequency(long frequency) throws SDRPlayException + { + if(hasDevice()) + { + getTuner().setFrequency(frequency); + } + else + { + throw new SDRPlayException("Device is not initialized"); + } + } + + @Override + public boolean isRfDabNotch() throws SDRPlayException + { + if(hasDevice()) + { + return getTuner().isRfDabNotch(); + } + else + { + throw new SDRPlayException("Device is not initialized"); + } + } + + @Override + public void setRfDabNotch(boolean enabled) throws SDRPlayException + { + if(hasDevice()) + { + getTuner().setRfDabNotch(enabled); + } + else + { + throw new SDRPlayException("Device is not initialized"); + } + } + + @Override + public boolean isRfNotch() throws SDRPlayException + { + if(hasDevice()) + { + return getTuner().isRFNotch(); + } + else + { + throw new SDRPlayException("Device is not initialized"); + } + } + + @Override + public void setRfNotch(boolean enabled) throws SDRPlayException + { + if(hasDevice()) + { + getTuner().setRfNotch(enabled); + } + else + { + throw new SDRPlayException("Device is not initialized"); + } + } + + @Override + public boolean isExternalReferenceOutput() throws SDRPlayException + { + if(hasDevice()) + { + return getTuner().isExternalReferenceOutput(); + } + else + { + throw new SDRPlayException("Device is not initialized"); + } + } + + @Override + public void setExternalReferenceOutput(boolean enabled) throws SDRPlayException + { + if(hasDevice()) + { + getTuner().setExternalReferenceOutput(enabled); + } + else + { + throw new SDRPlayException("Device is not initialized"); + } + } +} 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 new file mode 100644 index 000000000..4e05307eb --- /dev/null +++ b/src/main/java/io/github/dsheirer/source/tuner/sdrplay/rspDuo/ControlRspDuoTuner1.java @@ -0,0 +1,133 @@ +/* + * ***************************************************************************** + * Copyright (C) 2014-2023 Dennis Sheirer + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see + * **************************************************************************** + */ + +package io.github.dsheirer.source.tuner.sdrplay.rspDuo; + +import com.github.dsheirer.sdrplay.SDRPlayException; +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; +import com.github.dsheirer.sdrplay.parameter.tuner.RspDuoAmPort; +import com.github.dsheirer.sdrplay.parameter.tuner.TunerParameters; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +/** + * Base control wrapper for an RSPduo Tuner 1 + */ +public abstract class ControlRspDuoTuner1 extends ControlRspDuo implements IControlRspDuoTuner1 +{ + private Logger mLog = LoggerFactory.getLogger(ControlRspDuoTuner1.class); + + /** + * Constructs an instance + * + * @param device to control + */ + public ControlRspDuoTuner1(RspDuoDevice device) + { + super(device); + } + + /** + * Access tuner 1. + * @return tuner + * @throws SDRPlayException if the device is not started. + */ + protected RspDuoTuner1 getTuner() throws SDRPlayException + { + if(hasDevice()) + { + return (RspDuoTuner1) getDevice().getTuner(); + } + + throw new SDRPlayException("RSPduo device is not started"); + } + + @Override + public TunerSelect getTunerSelect() + { + return TunerSelect.TUNER_1; + } + + @Override + protected ControlParameters getControlParameters() + { + return getDevice().getCompositeParameters().getControlAParameters(); + } + + @Override + protected TunerParameters getTunerParameters() + { + return getDevice().getCompositeParameters().getTunerAParameters(); + } + + @Override + public boolean isAmNotch() throws SDRPlayException + { + if(hasDevice()) + { + return getTuner().isAmNotch(); + } + else + { + throw new SDRPlayException("Device is not initialized"); + } + } + + @Override + public void setAmNotch(boolean enabled) throws SDRPlayException + { + if(hasDevice()) + { + getTuner().setAmNotch(enabled); + } + else + { + throw new SDRPlayException("Device is not initialized"); + } + } + + @Override + public RspDuoAmPort getAmPort() throws SDRPlayException + { + if(hasDevice()) + { + return getTuner().getAmPort(); + } + else + { + throw new SDRPlayException("Device is not initialized"); + } + } + + @Override + public void setAmPort(RspDuoAmPort port) throws SDRPlayException + { + if(hasDevice()) + { + getTuner().setAmPort(port); + } + else + { + throw new SDRPlayException("Device is not initialized"); + } + } +} 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 new file mode 100644 index 000000000..641921df0 --- /dev/null +++ b/src/main/java/io/github/dsheirer/source/tuner/sdrplay/rspDuo/ControlRspDuoTuner1Master.java @@ -0,0 +1,157 @@ +/* + * ***************************************************************************** + * Copyright (C) 2014-2023 Dennis Sheirer + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see + * **************************************************************************** + */ + +package io.github.dsheirer.source.tuner.sdrplay.rspDuo; + +import com.github.dsheirer.sdrplay.DeviceSelectionMode; +import com.github.dsheirer.sdrplay.SDRPlayException; +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; + +/** + * RSPduo operating in dual-tuner mode with tuner 1 configured as master. + */ +public class ControlRspDuoTuner1Master extends ControlRspDuoTuner1 +{ + private static final Logger mLog = LoggerFactory.getLogger(ControlRspDuoTuner1Master.class); + + /** + * Bridge to tuner 2 slave device. + */ + private MasterSlaveBridge mMasterSlaveBridge; + + /** + * Flag to indicate that continuous streaming is required because the slave device is streaming. + */ + private boolean mContinuousStream = false; + + /** + * Constructs an instance + * + * @param device to control + */ + public ControlRspDuoTuner1Master(RspDuoDevice device, MasterSlaveBridge bridge) + { + super(device); + mMasterSlaveBridge = bridge; + } + + @Override + public DeviceSelectionMode getDeviceSelectionMode() + { + return DeviceSelectionMode.MASTER_TUNER_1; + } + + @Override + public EnumSet getSupportedSampleRates() + { + return RspSampleRate.DUAL_TUNER_SAMPLE_RATES; + } + + @Override + public void setSampleRate(RspSampleRate sampleRate) throws SDRPlayException + { + if(!sampleRate.isDualTunerSampleRate()) + { + throw new SDRPlayException("Use dual-tuner sample rates only"); + } + + super.setSampleRate(sampleRate); + + //Notify tuner 2 slave device to configure for this sample rate + if(mMasterSlaveBridge != null) + { + mMasterSlaveBridge.notifySampleRate(sampleRate); + } + } + + /** + * Overrides parent stop method to disable continous streaming flag before stopping this device so that the + * stream can be stopped. + * @throws SDRPlayException if there is an error + */ + @Override + public void stop() throws SDRPlayException + { + mStreamingLock.lock(); + + try + { + if(mMasterSlaveBridge != null) + { + mMasterSlaveBridge.stopSlave(); + } + } + catch(Exception e) + { + mLog.error("Error stopping slave device while preparing to stop the master device."); + } + + try + { + mContinuousStream = false; + super.stop(); + } + finally + { + mStreamingLock.unlock(); + } + } + + @Override + public void stopStream() + { + mStreamingLock.lock(); + + try + { + if(!mContinuousStream) + { + super.stopStream(); + } + } + finally + { + mStreamingLock.unlock(); + } + } + + /** + * Starts this tuner streaming continuously. Streaming will only stop once stop() is invoked. This method is + * invoked by a tuner 2 slave device to ensure that this master tuner 1 device is streaming continously while the + * slave is streaming. + */ + public void startStreamContinuously() + { + mStreamingLock.lock(); + + try + { + mContinuousStream = true; + startStream(); + } + finally + { + mStreamingLock.unlock(); + } + } +} 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 new file mode 100644 index 000000000..022707dfc --- /dev/null +++ b/src/main/java/io/github/dsheirer/source/tuner/sdrplay/rspDuo/ControlRspDuoTuner1Single.java @@ -0,0 +1,65 @@ +/* + * ***************************************************************************** + * Copyright (C) 2014-2023 Dennis Sheirer + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see + * **************************************************************************** + */ + +package io.github.dsheirer.source.tuner.sdrplay.rspDuo; + +import com.github.dsheirer.sdrplay.DeviceSelectionMode; +import com.github.dsheirer.sdrplay.SDRPlayException; +import com.github.dsheirer.sdrplay.device.RspDuoDevice; +import io.github.dsheirer.source.tuner.sdrplay.RspSampleRate; +import java.util.EnumSet; + +/** + * RSPduo with tuner 1 configured as single tuner. + */ +public class ControlRspDuoTuner1Single extends ControlRspDuoTuner1 +{ + /** + * Constructs an instance + * + * @param device to control + */ + public ControlRspDuoTuner1Single(RspDuoDevice device) + { + super(device); + } + + @Override + public DeviceSelectionMode getDeviceSelectionMode() + { + return DeviceSelectionMode.SINGLE_TUNER_1; + } + + @Override + public EnumSet getSupportedSampleRates() + { + return RspSampleRate.SINGLE_TUNER_SAMPLE_RATES; + } + + @Override + public void setSampleRate(RspSampleRate sampleRate) throws SDRPlayException + { + if(sampleRate.isDualTunerSampleRate()) + { + throw new SDRPlayException("Use single-tuner sample rates only"); + } + + super.setSampleRate(sampleRate); + } +} 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 new file mode 100644 index 000000000..d054436af --- /dev/null +++ b/src/main/java/io/github/dsheirer/source/tuner/sdrplay/rspDuo/ControlRspDuoTuner2.java @@ -0,0 +1,106 @@ +/* + * ***************************************************************************** + * Copyright (C) 2014-2023 Dennis Sheirer + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see + * **************************************************************************** + */ + +package io.github.dsheirer.source.tuner.sdrplay.rspDuo; + +import com.github.dsheirer.sdrplay.SDRPlayException; +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; +import com.github.dsheirer.sdrplay.parameter.tuner.TunerParameters; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +/** + * Base control wrapper for an RSPduo Tuner 2 + */ +public abstract class ControlRspDuoTuner2 extends ControlRspDuo implements IControlRspDuoTuner2 +{ + private Logger mLog = LoggerFactory.getLogger(ControlRspDuoTuner2.class); + + /** + * Constructs an instance + * + * @param device for the device, obtained from the API + */ + public ControlRspDuoTuner2(RspDuoDevice device) + { + super(device); + } + + /** + * Access tuner 2. + * @return tuner + * @throws SDRPlayException if the device is not started. + */ + protected RspDuoTuner2 getTuner() throws SDRPlayException + { + if(hasDevice()) + { + return (RspDuoTuner2) getDevice().getTuner(); + } + + throw new SDRPlayException("RSPduo device is not started"); + } + + @Override + public TunerSelect getTunerSelect() + { + return TunerSelect.TUNER_2; + } + + @Override + protected ControlParameters getControlParameters() + { + return getDevice().getCompositeParameters().getControlBParameters(); + } + + @Override + protected TunerParameters getTunerParameters() + { + return getDevice().getCompositeParameters().getTunerBParameters(); + } + + @Override + public boolean isBiasT() throws SDRPlayException + { + if(hasDevice()) + { + return getTuner().isBiasT(); + } + else + { + throw new SDRPlayException("Device is not initialized"); + } + } + + @Override + public void setBiasT(boolean enabled) throws SDRPlayException + { + if(hasDevice()) + { + getTuner().setBiasT(enabled); + } + else + { + throw new SDRPlayException("Device is not initialized"); + } + } +} 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 new file mode 100644 index 000000000..64bf8ccfe --- /dev/null +++ b/src/main/java/io/github/dsheirer/source/tuner/sdrplay/rspDuo/ControlRspDuoTuner2Single.java @@ -0,0 +1,75 @@ +/* + * ***************************************************************************** + * Copyright (C) 2014-2023 Dennis Sheirer + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see + * **************************************************************************** + */ + +package io.github.dsheirer.source.tuner.sdrplay.rspDuo; + +import com.github.dsheirer.sdrplay.DeviceSelectionMode; +import com.github.dsheirer.sdrplay.SDRPlayException; +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; + +/** + * Control wrapper for an RSPduo Tuner 2 operating in single-tuner mode. + */ +public class ControlRspDuoTuner2Single extends ControlRspDuoTuner2 +{ + private Logger mLog = LoggerFactory.getLogger(ControlRspDuoTuner2Single.class); + + /** + * Constructs an instance + * + * @param device to control + */ + public ControlRspDuoTuner2Single(RspDuoDevice device) + { + super(device); + } + + @Override + public DeviceSelectionMode getDeviceSelectionMode() + { + return DeviceSelectionMode.SINGLE_TUNER_2; + } + + @Override + public boolean isSlaveMode() + { + return false; + } + + @Override + public EnumSet getSupportedSampleRates() + { + return RspSampleRate.SINGLE_TUNER_SAMPLE_RATES; + } + + @Override + public void setSampleRate(RspSampleRate sampleRate) throws SDRPlayException + { + if(sampleRate.isDualTunerSampleRate()) + { + throw new SDRPlayException("Use single-tuner sample rates only"); + } + + super.setSampleRate(sampleRate); + } +} 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 new file mode 100644 index 000000000..f31cc2c6c --- /dev/null +++ b/src/main/java/io/github/dsheirer/source/tuner/sdrplay/rspDuo/ControlRspDuoTuner2Slave.java @@ -0,0 +1,102 @@ +/* + * ***************************************************************************** + * Copyright (C) 2014-2023 Dennis Sheirer + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see + * **************************************************************************** + */ + +package io.github.dsheirer.source.tuner.sdrplay.rspDuo; + +import com.github.dsheirer.sdrplay.DeviceSelectionMode; +import com.github.dsheirer.sdrplay.SDRPlayException; +import com.github.dsheirer.sdrplay.device.RspDuoDevice; +import io.github.dsheirer.source.tuner.sdrplay.RspSampleRate; +import java.util.EnumSet; + +/** + * Control wrapper for an RSPduo Tuner 2 operating in dual-tuner mode as the slave device + */ +public class ControlRspDuoTuner2Slave extends ControlRspDuoTuner2 +{ + private MasterSlaveBridge mMasterSlaveBridge; + + /** + * Constructs an instance + * + * @param device to control + */ + public ControlRspDuoTuner2Slave(RspDuoDevice device, MasterSlaveBridge bridge) + { + super(device); + mMasterSlaveBridge = bridge; + } + + /** + * Overrides the default method to request that master starts streaming so that this slave can also + * start streaming. Uses the bridge to put master in a continuous streaming mode where master is + * started and a flag is set to prevent master from stopping streaming. + */ + @Override + public void startStream() + { + if(mMasterSlaveBridge != null) + { + mMasterSlaveBridge.startMasterStreamContinuously(); + } + + super.startStream(); + } + + @Override + public boolean isSlaveMode() + { + return true; + } + + @Override + public DeviceSelectionMode getDeviceSelectionMode() + { + return DeviceSelectionMode.SLAVE_TUNER_2; + } + + @Override + public EnumSet getSupportedSampleRates() + { + //In dual-tuner mode only the master device can set the sample rate + return EnumSet.noneOf(RspSampleRate.class); + } + + @Override + public void setSampleRate(RspSampleRate sampleRate) throws SDRPlayException + { + if(hasDevice()) + { + mSampleRate = sampleRate; + getDevice().getTuner().setBandwidth(sampleRate.getBandwidth()); + getControlParameters().getDecimation().setWideBandSignal(true); + getDevice().setDecimation(sampleRate.getDecimation()); + } + else + { + throw new SDRPlayException("Device is not initialized"); + } + } + + @Override + public void setExternalReferenceOutput(boolean enabled) throws SDRPlayException + { + //Ignore ... tuner 2 configured for slave mode does not control the external reference output + } +} 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 new file mode 100644 index 000000000..cb8f79ca1 --- /dev/null +++ b/src/main/java/io/github/dsheirer/source/tuner/sdrplay/rspDuo/DiscoveredRspDuoTuner1.java @@ -0,0 +1,125 @@ +/* + * ***************************************************************************** + * Copyright (C) 2014-2023 Dennis Sheirer + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see + * **************************************************************************** + */ + +package io.github.dsheirer.source.tuner.sdrplay.rspDuo; + +import com.github.dsheirer.sdrplay.device.DeviceInfo; +import io.github.dsheirer.preference.source.ChannelizerType; +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 configured for a single-tuner + * @param deviceInfo describing the tuner + * @param channelizerType to use for the tuner once started + */ + public DiscoveredRspDuoTuner1(DeviceInfo deviceInfo, ChannelizerType 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; + } + + /** + * Constructs and starts the tuner + */ + @Override + public void start() + { + if(isAvailable() && !hasTuner()) + { + try + { + 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(Exception se) + { + 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#" + getDeviceInfo().getSerialNumber(); + } + + /** + * ID for the slave tuner device, if one is present in the system. + * @return slave tuner ID + */ + public String getSlaveId() + { + return RSP_DUO_ID_PREFIX + "2 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 new file mode 100644 index 000000000..054eec9b5 --- /dev/null +++ b/src/main/java/io/github/dsheirer/source/tuner/sdrplay/rspDuo/DiscoveredRspDuoTuner2.java @@ -0,0 +1,121 @@ +/* + * ***************************************************************************** + * Copyright (C) 2014-2023 Dennis Sheirer + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see + * **************************************************************************** + */ + +package io.github.dsheirer.source.tuner.sdrplay.rspDuo; + +import com.github.dsheirer.sdrplay.device.DeviceInfo; +import io.github.dsheirer.preference.source.ChannelizerType; +import io.github.dsheirer.source.tuner.TunerFactory; +import io.github.dsheirer.source.tuner.sdrplay.DiscoveredRspTuner; + +/** + * 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 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(DeviceInfo deviceInfo, ChannelizerType channelizerType, MasterSlaveBridge bridge) + { + super(deviceInfo, channelizerType); + mMasterSlaveBridge = bridge; + } + + /** + * Constructs and starts the tuner + */ + @Override + public void start() + { + if(isAvailable() && !hasTuner()) + { + try + { + if(mMasterSlaveBridge != null) + { + mTuner = TunerFactory.getRspDuoTuner(getDeviceInfo(), getChannelizerType(), this, mMasterSlaveBridge); + } + else + { + mTuner = TunerFactory.getRspTuner(getDeviceInfo(), getChannelizerType(), this); + } + } + catch(Exception se) + { + 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#" + getDeviceInfo().getSerialNumber(); + } + + /** + * ID for the slave tuner device, if one is present in the system. + * @return slave tuner ID + */ + public String getMasterId() + { + return DiscoveredRspDuoTuner1.RSP_DUO_ID_PREFIX + "1 SER#" + getDeviceInfo().getSerialNumber(); + } +} diff --git a/src/main/java/io/github/dsheirer/source/tuner/sdrplay/rspDuo/IControlRspDuo.java b/src/main/java/io/github/dsheirer/source/tuner/sdrplay/rspDuo/IControlRspDuo.java new file mode 100644 index 000000000..2719548d0 --- /dev/null +++ b/src/main/java/io/github/dsheirer/source/tuner/sdrplay/rspDuo/IControlRspDuo.java @@ -0,0 +1,80 @@ +/* + * ***************************************************************************** + * 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 io.github.dsheirer.source.tuner.sdrplay.rspDuo; + +import com.github.dsheirer.sdrplay.SDRPlayException; +import io.github.dsheirer.source.tuner.sdrplay.IControlRsp; +import io.github.dsheirer.source.tuner.sdrplay.RspSampleRate; + +import java.util.EnumSet; + +/** + * Control interface for RSPduo device (tuner 1 or 2) + */ +public interface IControlRspDuo extends IControlRsp +{ + /** + * Set of valid sample rates to use with the RSPduo in the current operating mode + * @return supported sample rates or an empty set if you cannot set the sample rate on this tuner. + */ + EnumSet getSupportedSampleRates(); + + /** + * Indicates if the RF DAB notch is enabled (DAB broadcast band filter). + * @return true if enabled. + * @throws exception if the device is not started (selected). + */ + boolean isRfDabNotch() throws SDRPlayException; + + /** + * Sets the enabled state of the RF DAB notch. + * @param enabled true to filter the DAB broadcast band frequency range. + * @throws exception if the device is not started (selected). + */ + void setRfDabNotch(boolean enabled) throws SDRPlayException; + + /** + * Indicates if the RF notch is enabled (FM broadcast band filter). + * @return true if enabled. + * @throws exception if the device is not started (selected). + */ + boolean isRfNotch() throws SDRPlayException; + + /** + * Sets the enabled state of the RF notch + * @param enabled true to filter the FM broadcast band frequency range. + * @throws exception if the device is not started (selected). + */ + void setRfNotch(boolean enabled) throws SDRPlayException; + + /** + * Indicates the enabled state of the external reference output. + * @return true if enabled. + * @throws exception if the device is not started (selected). + */ + boolean isExternalReferenceOutput() throws SDRPlayException; + + /** + * Sets the enabled state of the external reference output. + * @param enabled true to enable. + * @throws exception if the device is not started (selected). + */ + void setExternalReferenceOutput(boolean enabled) throws SDRPlayException; +} diff --git a/src/main/java/io/github/dsheirer/source/tuner/sdrplay/rspDuo/IControlRspDuoTuner1.java b/src/main/java/io/github/dsheirer/source/tuner/sdrplay/rspDuo/IControlRspDuoTuner1.java new file mode 100644 index 000000000..cb38d0203 --- /dev/null +++ b/src/main/java/io/github/dsheirer/source/tuner/sdrplay/rspDuo/IControlRspDuoTuner1.java @@ -0,0 +1,57 @@ +/* + * ***************************************************************************** + * 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 io.github.dsheirer.source.tuner.sdrplay.rspDuo; + +import com.github.dsheirer.sdrplay.SDRPlayException; +import com.github.dsheirer.sdrplay.parameter.tuner.RspDuoAmPort; + +/** + * Control interface for RSPduo Tuner 1 device + */ +public interface IControlRspDuoTuner1 extends IControlRspDuo +{ + /** + * Indicates if the AM notch is enabled (AM broadcast band filter) + * @return true if enabled. + * @throws exception if the device is not started (selected). + */ + boolean isAmNotch() throws SDRPlayException; + + /** + * Sets the enabled state of the AM notch filter. + * @param enabled true to enable + * @throws exception if the device is not started (selected). + */ + void setAmNotch(boolean enabled) throws SDRPlayException; + + /** + * Current port selection setting for the AM port. + * @return selected AM port + * @throws exception if the device is not started (selected). + */ + RspDuoAmPort getAmPort() throws SDRPlayException; + + /** + * Sets the AM port. + * @param amPort to use. + * @throws exception if the device is not started (selected). + */ + void setAmPort(RspDuoAmPort amPort) throws SDRPlayException; +} diff --git a/src/main/java/io/github/dsheirer/source/tuner/sdrplay/rspDuo/IControlRspDuoTuner2.java b/src/main/java/io/github/dsheirer/source/tuner/sdrplay/rspDuo/IControlRspDuoTuner2.java new file mode 100644 index 000000000..bfeccfec7 --- /dev/null +++ b/src/main/java/io/github/dsheirer/source/tuner/sdrplay/rspDuo/IControlRspDuoTuner2.java @@ -0,0 +1,48 @@ +/* + * ***************************************************************************** + * 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 io.github.dsheirer.source.tuner.sdrplay.rspDuo; + +import com.github.dsheirer.sdrplay.SDRPlayException; + +/** + * Control interface for RSPduo Tuner 2 device + */ +public interface IControlRspDuoTuner2 extends IControlRspDuo +{ + /** + * Indicates if the Bias-T power is enabled. + * @return true if enabled. + * @throws SDRPlayException if the device is no started/selected + */ + boolean isBiasT() throws SDRPlayException; + + /** + * Sets the enabled state of the Bias-T power. + * @param enabled true to power on the Bias-T + * @throws SDRPlayException if the device is no started/selected + */ + void setBiasT(boolean enabled) throws SDRPlayException; + + /** + * Indicates if this tuner is configured for dual-tuner slave mode. + * @return true if slave mode. + */ + boolean isSlaveMode(); +} 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 new file mode 100644 index 000000000..b4b21817f --- /dev/null +++ b/src/main/java/io/github/dsheirer/source/tuner/sdrplay/rspDuo/MasterSlaveBridge.java @@ -0,0 +1,134 @@ +/* + * ***************************************************************************** + * Copyright (C) 2014-2023 Dennis Sheirer + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see + * **************************************************************************** + */ + +package io.github.dsheirer.source.tuner.sdrplay.rspDuo; + +import com.github.dsheirer.sdrplay.SDRPlayException; +import io.github.dsheirer.source.tuner.sdrplay.RspSampleRate; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +/** + * Bridge providing streaming control synchronization between master and slave devices. Additionally, this bridge + * allows the master device to notify the slave device of sample rate changes so that the slave can apply appropriate + * sample rate settings such as bandwidth and decimation. The RSPduo's two tuners do not operate independently. + * Streaming on the slave does not start until streaming on the master starts. The master cannot be shutdown until the + * slave is shutdown. This class provides the bridging to ensure that these sequencing requirements are met. + */ +public class MasterSlaveBridge +{ + private static final Logger mLog = LoggerFactory.getLogger(MasterSlaveBridge.class); + private RspDuoTuner1Controller mMaster; + private RspDuoTuner2Controller mSlave; + + public MasterSlaveBridge() + { + } + + /** + * Sets the master tuner controller + * @param master to set + */ + public void setMaster(RspDuoTuner1Controller master) + { + mMaster = master; + } + + /** + * Sets the slave tuner controller and transfers the sample rate setting from the master. + * @param slave to set + */ + public void setSlave(RspDuoTuner2Controller slave) + { + mSlave = slave; + + if(hasMasterControl()) + { + //Transfer master sample rate setting to slave + notifySampleRate(getMasterControl().getSampleRateEnumeration()); + } + } + + /** + * Access to the tuner 1 master controller + */ + private ControlRspDuoTuner1Master getMasterControl() + { + if(mMaster != null && mMaster.getControlRsp() instanceof ControlRspDuoTuner1Master masterControl) + { + return masterControl; + } + + return null; + } + + /** + * Indicates if we have access to a non-null master control + * @return true if non-null. + */ + private boolean hasMasterControl() + { + return getMasterControl() != null; + } + + /** + * A blocking call that ensures that the master device is streaming before returning. This method is intended to + * be called by the slave to ensure that the master is streaming before the slave initiates streaming. Once the + * slave invokes this method, the master will stream continuously until stop() is invoked on the master. + */ + public void startMasterStreamContinuously() + { + if(hasMasterControl()) + { + getMasterControl().startStreamContinuously(); + } + } + + /** + * A blocking call that ensures that the slave device stops streaming before returning. This method is intended + * to be invoked by the master device, just prior to stopping the master. + */ + public void stopSlave() + { + if(mSlave != null) + { + mSlave.stop(); + mSlave = null; + } + } + + /** + * Notifies the slave of sample rate changes in the master. + * @param sampleRate being applied by the master device. + */ + public void notifySampleRate(RspSampleRate sampleRate) + { + if(mSlave != null) + { + try + { + mSlave.setSampleRate(sampleRate); + } + catch(SDRPlayException se) + { + mLog.error("Error setting sample rate on RSPduo tuner 2 slave", se); + } + } + } +} diff --git a/src/main/java/io/github/dsheirer/source/tuner/sdrplay/rspDuo/RspDuoTuner1Configuration.java b/src/main/java/io/github/dsheirer/source/tuner/sdrplay/rspDuo/RspDuoTuner1Configuration.java new file mode 100644 index 000000000..46eb9ca8c --- /dev/null +++ b/src/main/java/io/github/dsheirer/source/tuner/sdrplay/rspDuo/RspDuoTuner1Configuration.java @@ -0,0 +1,144 @@ +/* + * ***************************************************************************** + * 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 io.github.dsheirer.source.tuner.sdrplay.rspDuo; + +import com.fasterxml.jackson.dataformat.xml.annotation.JacksonXmlProperty; +import com.github.dsheirer.sdrplay.parameter.tuner.RspDuoAmPort; +import io.github.dsheirer.source.tuner.TunerType; +import io.github.dsheirer.source.tuner.sdrplay.RspTunerConfiguration; + +/** + * RSPduo tuner 1 configuration + */ +public class RspDuoTuner1Configuration extends RspTunerConfiguration +{ + private RspDuoAmPort mAmPort = RspDuoAmPort.PORT_2; //50-ohm port is default. + private boolean mAmNotch; + private boolean mExternalReferenceOutput; + private boolean mRfDabNotch; + private boolean mRfNotch; + + /** + * Constructs an instance + * @param uniqueId for the tuner + */ + public RspDuoTuner1Configuration(String uniqueId) + { + super(uniqueId); + } + + /** + * JAXB constructor + */ + public RspDuoTuner1Configuration() + { + } + + @Override + public TunerType getTunerType() + { + return TunerType.RSP_DUO_1; + } + + /** + * Indicates if the RF Notch is enabled + */ + @JacksonXmlProperty(isAttribute = true, localName = "rf_notch") + public boolean isRfNotch() + { + return mRfNotch; + } + + /** + * Sets the enabled state of the RF Notch + */ + public void setRfNotch(boolean enabled) + { + mRfNotch = enabled; + } + + /** + * Indicates if the RF Digital Audio Broadcast (DAB) notch is enabled + */ + @JacksonXmlProperty(isAttribute = true, localName = "dab_notch") + public boolean isRfDabNotch() + { + return mRfDabNotch; + } + + /** + * Sets the enabled state of the RF Notch. + */ + public void setRfDabNotch(boolean enabled) + { + mRfDabNotch = enabled; + } + + /** + * Indicates if the external reference output is enabled + */ + @JacksonXmlProperty(isAttribute = true, localName = "external_reference_output") + public boolean isExternalReferenceOutput() + { + return mExternalReferenceOutput; + } + + /** + * Sets the enabled state of the external reference output + */ + public void setExternalReferenceOutput(boolean enabled) + { + mExternalReferenceOutput = enabled; + } + + /** + * Indicates if the AM Notch is enabled + */ + @JacksonXmlProperty(isAttribute = true, localName = "am_notch") + public boolean isAmNotch() + { + return mAmNotch; + } + + /** + * Sets the enabled state of the AM notch + */ + public void setAmNotch(boolean amNotch) + { + mAmNotch = amNotch; + } + + /** + * AM port setting + */ + @JacksonXmlProperty(isAttribute = true, localName = "am_port") + public RspDuoAmPort getAmPort() + { + return mAmPort; + } + + /** + * Sets the AM port + */ + public void setAmPort(RspDuoAmPort amPort) + { + mAmPort = amPort; + } +} diff --git a/src/main/java/io/github/dsheirer/source/tuner/sdrplay/rspDuo/RspDuoTuner1Controller.java b/src/main/java/io/github/dsheirer/source/tuner/sdrplay/rspDuo/RspDuoTuner1Controller.java new file mode 100644 index 000000000..c08a98af2 --- /dev/null +++ b/src/main/java/io/github/dsheirer/source/tuner/sdrplay/rspDuo/RspDuoTuner1Controller.java @@ -0,0 +1,147 @@ +/* + * ***************************************************************************** + * 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 io.github.dsheirer.source.tuner.sdrplay.rspDuo; + +import com.github.dsheirer.sdrplay.SDRPlayException; +import io.github.dsheirer.source.SourceException; +import io.github.dsheirer.source.tuner.ITunerErrorListener; +import io.github.dsheirer.source.tuner.TunerType; +import io.github.dsheirer.source.tuner.configuration.TunerConfiguration; +import io.github.dsheirer.source.tuner.sdrplay.RspSampleRate; +import io.github.dsheirer.source.tuner.sdrplay.RspTunerConfiguration; +import io.github.dsheirer.source.tuner.sdrplay.RspTunerController; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +/** + * Tuner controller for RSPduo tuner 1 + */ +public class RspDuoTuner1Controller extends RspTunerController +{ + private Logger mLog = LoggerFactory.getLogger(RspDuoTuner1Controller.class); + + /** + * Constructs an instance + * + * @param device that is the RSP tuner + * @param tunerErrorListener to monitor errors produced from this tuner controller + */ + public RspDuoTuner1Controller(IControlRspDuoTuner1 device, ITunerErrorListener tunerErrorListener) + { + super(device, tunerErrorListener); + } + + @Override + public TunerType getTunerType() + { + return TunerType.RSP_DUO_1; + } + + @Override + public void apply(TunerConfiguration config) throws SourceException + { + if(config instanceof RspDuoTuner1Configuration duo1) + { + super.apply(config); + + try + { + getControlRsp().setRfNotch(duo1.isRfNotch()); + } + catch(SDRPlayException se) + { + mLog.error("Error setting RSPduo tuner 1 RF notch enabled to " + duo1.isRfNotch()); + } + + try + { + getControlRsp().setRfDabNotch(duo1.isRfDabNotch()); + } + catch(SDRPlayException se) + { + mLog.error("Error setting RSPduo tuner 1 RF DAB notch enabled to " + duo1.isRfDabNotch()); + } + + try + { + getControlRsp().setAmNotch(duo1.isAmNotch()); + } + catch(SDRPlayException se) + { + mLog.error("Error setting RSPduo tuner 1 AM notch enabled to " + duo1.isAmNotch()); + } + + try + { + getControlRsp().setAmPort(duo1.getAmPort()); + } + catch(SDRPlayException se) + { + mLog.error("Error setting RSPduo tuner 1 AM port to " + duo1.getAmPort()); + } + + try + { + getControlRsp().setExternalReferenceOutput(duo1.isExternalReferenceOutput()); + } + catch(SDRPlayException se) + { + mLog.error("Error setting RSPduo tuner 1 external reference output enabled to " + duo1.isExternalReferenceOutput()); + } + } + else + { + mLog.error("Invalid RSPduo tuner configuration type: " + config.getClass()); + } + } + + /** + * Overrides the default RSP controller to ensure the sample rate is compatible with the + * configuration of the RSP duo. + * @param rspSampleRate to apply + * @throws SDRPlayException + */ + @Override + public void setSampleRate(RspSampleRate rspSampleRate) throws SDRPlayException + { + if(getControlRsp().getDeviceSelectionMode().isSingleTunerMode()) + { + if(rspSampleRate.isDualTunerSampleRate()) + { + super.setSampleRate(RspTunerConfiguration.DEFAULT_SINGLE_TUNER_SAMPLE_RATE); + } + else + { + super.setSampleRate(rspSampleRate); + } + } + else + { + if(rspSampleRate.isDualTunerSampleRate()) + { + super.setSampleRate(rspSampleRate); + } + else + { + super.setSampleRate(RspTunerConfiguration.DEFAULT_DUAL_TUNER_SAMPLE_RATE); + } + } + } +} diff --git a/src/main/java/io/github/dsheirer/source/tuner/sdrplay/rspDuo/RspDuoTuner1Editor.java b/src/main/java/io/github/dsheirer/source/tuner/sdrplay/rspDuo/RspDuoTuner1Editor.java new file mode 100644 index 000000000..7e4d2cf6d --- /dev/null +++ b/src/main/java/io/github/dsheirer/source/tuner/sdrplay/rspDuo/RspDuoTuner1Editor.java @@ -0,0 +1,441 @@ +/* + * ***************************************************************************** + * 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 io.github.dsheirer.source.tuner.sdrplay.rspDuo; + +import com.github.dsheirer.sdrplay.SDRPlayException; +import com.github.dsheirer.sdrplay.parameter.tuner.RspDuoAmPort; +import io.github.dsheirer.eventbus.MyEventBus; +import io.github.dsheirer.gui.preference.PreferenceEditorType; +import io.github.dsheirer.gui.preference.ViewUserPreferenceEditorRequest; +import io.github.dsheirer.preference.UserPreferences; +import io.github.dsheirer.source.tuner.manager.TunerManager; +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 net.miginfocom.swing.MigLayout; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import javax.swing.JButton; +import javax.swing.JCheckBox; +import javax.swing.JComboBox; +import javax.swing.JLabel; +import javax.swing.JPanel; +import javax.swing.JSeparator; +import javax.swing.SpinnerNumberModel; +import java.util.EnumSet; + +/** + * RSPduo Tuner 1 Editor + */ +public class RspDuoTuner1Editor extends RspTunerEditor +{ + private static final Logger mLog = LoggerFactory.getLogger(RspDuoTuner1Editor.class); + + private JComboBox mSampleRateCombo; + private JCheckBox mRfDabNotchCheckBox; + private JCheckBox mRfNotchCheckBox; + private JCheckBox mAmNotchCheckBox; + private JCheckBox mExternalReferenceOutputCheckBox; + private JComboBox mAmPortCombo; + private JButton mTunerPreferencesButton; + + /** + * Constructs an instance + * @param userPreferences for settings + * @param tunerManager for state updates + * @param discoveredTuner to edit or control. + */ + public RspDuoTuner1Editor(UserPreferences userPreferences, TunerManager tunerManager, DiscoveredRspTuner discoveredTuner) + { + super(userPreferences, tunerManager, discoveredTuner); + init(); + tunerStatusUpdated(); + } + + private void init() + { + setLayout(new MigLayout("fill,wrap 3", "[right][grow,fill][fill]", + "[][][][][][][][][][][][][][][grow]")); + + add(new JLabel("Tuner:")); + JPanel labelAndButtonPanel = new JPanel(); + labelAndButtonPanel.setLayout(new MigLayout("insets 0")); + labelAndButtonPanel.add(getTunerIdLabel()); + labelAndButtonPanel.add(getTunerPreferencesButton()); + add(labelAndButtonPanel, "wrap"); + add(new JLabel("Status:")); + add(getTunerStatusLabel(), "wrap"); + add(getButtonPanel(), "span,align left"); + + add(new JSeparator(), "span,growx,push"); + + add(new JLabel("Frequency (MHz):")); + add(getFrequencyPanel(), "wrap"); + + add(new JLabel("Sample Rate:")); + add(getSampleRateCombo(), "wrap"); + + add(new JLabel("Gain:")); + add(getGainSlider()); + add(getGainValueLabel()); + + add(new JSeparator(), "span,growx,push"); + + add(new JLabel()); + add(getExternalReferenceOutputCheckBox(), "wrap"); + add(new JLabel()); + add(getAmNotchCheckBox(), "wrap"); + add(new JLabel()); + add(getRfDabNotchCheckBox(), "wrap"); + add(new JLabel()); + add(getRfNotchCheckBox(), "wrap"); + add(new JLabel("AM Port:")); + add(getAmPortCombo(), "wrap"); + } + + /** + * Access tuner controller + */ + private RspDuoTuner1Controller getTunerController() + { + if(hasTuner()) + { + return (RspDuoTuner1Controller) getTuner().getTunerController(); + } + + return null; + } + + @Override + protected void tunerStatusUpdated() + { + setLoading(true); + + getTunerIdLabel().setText(getDiscoveredTuner().getId()); + + String status = getDiscoveredTuner().getTunerStatus().toString(); + if(getDiscoveredTuner().hasErrorMessage()) + { + status += " - " + getDiscoveredTuner().getErrorMessage(); + } + getTunerStatusLabel().setText(status); + getButtonPanel().updateControls(); + getFrequencyPanel().updateControls(); + + clearSampleRates(); + if(hasTuner()) + { + setSampleRates(getTunerController().getControlRsp().getSupportedSampleRates()); + } + getSampleRateCombo().setEnabled(hasTuner() && !getTuner().getTunerController().isLockedSampleRate()); + getSampleRateCombo().setSelectedItem(hasTuner() ? getTunerController().getControlRsp().getSampleRateEnumeration() : null); + + getGainSlider().setEnabled(hasTuner()); + getGainValueLabel().setEnabled(hasTuner()); + getGainSlider().setValue(hasTuner() ? getTunerController().getControlRsp().getGain() : 0); + + getAmPortCombo().setEnabled(hasTuner() && !getTuner().getTunerController().isLockedSampleRate()); + try + { + getAmPortCombo().setSelectedItem(hasTuner() ? getTunerController().getControlRsp().getAmPort() : null); + } + catch(SDRPlayException se) + { + mLog.error("Error setting RSPduo tuner 1 AM Port in editor"); + } + + getRfDabNotchCheckBox().setEnabled(hasTuner()); + try + { + getRfDabNotchCheckBox().setSelected(hasTuner() && getTunerController().getControlRsp().isRfDabNotch()); + } + catch(SDRPlayException se) + { + mLog.error("Error setting RSPduo tuner 1 RF DAB Notch enabled state in editor"); + } + + getRfNotchCheckBox().setEnabled(hasTuner()); + try + { + getRfNotchCheckBox().setSelected(hasTuner() && getTunerController().getControlRsp().isRfNotch()); + } + catch(SDRPlayException se) + { + mLog.error("Error setting RSPduo tuner 1 RF Notch enabled state in editor"); + } + + getAmNotchCheckBox().setEnabled(hasTuner()); + try + { + getAmNotchCheckBox().setSelected(hasTuner() && getTunerController().getControlRsp().isAmNotch()); + } + catch(SDRPlayException se) + { + mLog.error("Error setting RSPduo tuner 1 AM Notch enabled state in editor"); + } + + getExternalReferenceOutputCheckBox().setEnabled(hasTuner()); + try + { + getExternalReferenceOutputCheckBox() + .setSelected(hasTuner() && getTunerController().getControlRsp().isExternalReferenceOutput()); + } + catch(SDRPlayException se) + { + mLog.error("Error setting RSPduo tuner 1 external reference output enabled state in editor"); + } + + setLoading(false); + } + + @Override + public void save() + { + if(hasConfiguration() && !isLoading()) + { + getConfiguration().setFrequency(getFrequencyControl().getFrequency()); + double value = ((SpinnerNumberModel) getFrequencyCorrectionSpinner().getModel()).getNumber().doubleValue(); + getConfiguration().setFrequencyCorrection(value); + getConfiguration().setAutoPPMCorrectionEnabled(getAutoPPMCheckBox().isSelected()); + getConfiguration().setSampleRate((RspSampleRate)getSampleRateCombo().getSelectedItem()); + getConfiguration().setAmNotch(getAmNotchCheckBox().isSelected()); + getConfiguration().setAmPort(getAmPortCombo().getSelectedItem() != null ? (RspDuoAmPort)getAmPortCombo().getSelectedItem() : null); + getConfiguration().setExternalReferenceOutput(getExternalReferenceOutputCheckBox().isSelected()); + getConfiguration().setRfDabNotch(getRfDabNotchCheckBox().isSelected()); + getConfiguration().setRfNotch(getRfNotchCheckBox().isSelected()); + getConfiguration().setGain(getGainSlider().getValue()); + + saveConfiguration(); + } + } + + /** + * Updates the sample rates listed in the combobox. + * @param sampleRates to use. + */ + private void setSampleRates(EnumSet sampleRates) + { + if(!sampleRates.isEmpty()) + { + for(RspSampleRate sampleRate: sampleRates) + { + getSampleRateCombo().addItem(sampleRate); + } + } + } + + /** + * Removes all sample rate options from the combo box. + */ + private void clearSampleRates() + { + getSampleRateCombo().removeAllItems(); + } + + /** + * Sample rate selection combobox control + */ + private JComboBox getSampleRateCombo() + { + if(mSampleRateCombo == null) + { + mSampleRateCombo = new JComboBox<>(); + mSampleRateCombo.setEnabled(false); + mSampleRateCombo.addActionListener(e -> { + if(hasTuner() && !isLoading()) + { + RspSampleRate selected = (RspSampleRate)mSampleRateCombo.getSelectedItem(); + + try + { + getTunerController().setSampleRate(selected); + save(); + } + catch(SDRPlayException se) + { + mLog.error("Error setting sample rate for RSPduo tuner 1", se); + } + } + }); + } + + return mSampleRateCombo; + } + + /** + * AM port selection combobox control + */ + private JComboBox getAmPortCombo() + { + if(mAmPortCombo == null) + { + mAmPortCombo = new JComboBox<>(RspDuoAmPort.values()); + mAmPortCombo.setEnabled(false); + mAmPortCombo.addActionListener(e -> { + if(hasTuner() && !isLoading()) + { + RspDuoAmPort selected = (RspDuoAmPort)mAmPortCombo.getSelectedItem(); + + try + { + getTunerController().getControlRsp().setAmPort(selected); + save(); + } + catch(SDRPlayException se) + { + mLog.error("Error setting AM port for RSPduo tuner 1", se); + } + } + }); + } + + return mAmPortCombo; + } + + /** + * Checkbox control for RF DAB notch + */ + private JCheckBox getRfDabNotchCheckBox() + { + if(mRfDabNotchCheckBox == null) + { + mRfDabNotchCheckBox = new JCheckBox("DAB Broadcast Band Filter (157-235 MHz)"); + mRfDabNotchCheckBox.setEnabled(false); + mRfDabNotchCheckBox.addActionListener(e -> { + if(hasTuner() && !isLoading()) + { + try + { + getTunerController().getControlRsp().setRfDabNotch(mRfDabNotchCheckBox.isSelected()); + save(); + } + catch(SDRPlayException se) + { + mLog.error("Unable to set RSPduo tuner 1 RF DAB notch enabled to " + mRfDabNotchCheckBox.isSelected(), se); + } + } + }); + } + + return mRfDabNotchCheckBox; + } + + /** + * Checkbox control for RF notch + */ + private JCheckBox getRfNotchCheckBox() + { + if(mRfNotchCheckBox == null) + { + mRfNotchCheckBox = new JCheckBox("FM Broadcast Band Filter (78-114 MHz)"); + mRfNotchCheckBox.setEnabled(false); + mRfNotchCheckBox.addActionListener(e -> { + if(hasTuner() && !isLoading()) + { + try + { + getTunerController().getControlRsp().setRfNotch(mRfNotchCheckBox.isSelected()); + save(); + } + catch(SDRPlayException se) + { + mLog.error("Unable to set RSPduo tuner 1 RF notch enabled to " + mRfNotchCheckBox.isSelected(), se); + } + } + }); + } + + return mRfNotchCheckBox; + } + + /** + * Checkbox control for AM notch + */ + private JCheckBox getAmNotchCheckBox() + { + if(mAmNotchCheckBox == null) + { + mAmNotchCheckBox = new JCheckBox("AM Broadcast Band Filter (415-1640 kHz)"); + mAmNotchCheckBox.setEnabled(false); + mAmNotchCheckBox.addActionListener(e -> { + if(hasTuner() && !isLoading()) + { + try + { + getTunerController().getControlRsp().setAmNotch(mAmNotchCheckBox.isSelected()); + save(); + } + catch(SDRPlayException se) + { + mLog.error("Unable to set RSPduo tuner 1 AM notch enabled to " + mAmNotchCheckBox.isSelected(), se); + } + } + }); + } + + return mAmNotchCheckBox; + } + + /** + * Checkbox control for External Reference Output + */ + private JCheckBox getExternalReferenceOutputCheckBox() + { + if(mExternalReferenceOutputCheckBox == null) + { + mExternalReferenceOutputCheckBox = new JCheckBox("External Reference Output"); + mExternalReferenceOutputCheckBox.setEnabled(false); + mExternalReferenceOutputCheckBox.addActionListener(e -> { + if(hasTuner() && !isLoading()) + { + try + { + getTunerController().getControlRsp().setExternalReferenceOutput(mExternalReferenceOutputCheckBox.isSelected()); + save(); + } + catch(SDRPlayException se) + { + mLog.error("Unable to set RSPduo tuner 1 external reference output notch enabled to " + + mExternalReferenceOutputCheckBox.isSelected(), se); + } + } + }); + } + + return mExternalReferenceOutputCheckBox; + } + + /** + * Button to launch the User Preferences editor to show the RSPduo tuner preference selection. + * @return constructed button. + */ + private JButton getTunerPreferencesButton() + { + if(mTunerPreferencesButton == null) + { + mTunerPreferencesButton = new JButton("RSPduo Preferences"); + mTunerPreferencesButton.addActionListener(e -> MyEventBus.getGlobalEventBus() + .post(new ViewUserPreferenceEditorRequest(PreferenceEditorType.SOURCE_TUNERS))); + } + + return mTunerPreferencesButton; + } +} diff --git a/src/main/java/io/github/dsheirer/source/tuner/sdrplay/rspDuo/RspDuoTuner2Configuration.java b/src/main/java/io/github/dsheirer/source/tuner/sdrplay/rspDuo/RspDuoTuner2Configuration.java new file mode 100644 index 000000000..7417ed61f --- /dev/null +++ b/src/main/java/io/github/dsheirer/source/tuner/sdrplay/rspDuo/RspDuoTuner2Configuration.java @@ -0,0 +1,126 @@ +/* + * ***************************************************************************** + * 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 io.github.dsheirer.source.tuner.sdrplay.rspDuo; + +import com.fasterxml.jackson.dataformat.xml.annotation.JacksonXmlProperty; +import io.github.dsheirer.source.tuner.TunerType; +import io.github.dsheirer.source.tuner.sdrplay.RspTunerConfiguration; + +/** + * RSPduo tuner 1 configuration + */ +public class RspDuoTuner2Configuration extends RspTunerConfiguration +{ + private boolean mBiasT; + private boolean mExternalReferenceOutput; + private boolean mRfDabNotch; + private boolean mRfNotch; + + /** + * Constructs an instance + * @param uniqueId for the tuner + */ + public RspDuoTuner2Configuration(String uniqueId) + { + super(uniqueId); + } + + /** + * JAXB constructor + */ + public RspDuoTuner2Configuration() + { + } + + + @Override + public TunerType getTunerType() + { + return TunerType.RSP_DUO_2; + } + + /** + * Indicates if the RF Notch is enabled + */ + @JacksonXmlProperty(isAttribute = true, localName = "rf_notch") + public boolean isRfNotch() + { + return mRfNotch; + } + + /** + * Sets the enabled state of the RF Notch + */ + public void setRfNotch(boolean enabled) + { + mRfNotch = enabled; + } + + /** + * Indicates if the RF Digital Audio Broadcast (DAB) notch is enabled + */ + @JacksonXmlProperty(isAttribute = true, localName = "dab_notch") + public boolean isRfDabNotch() + { + return mRfDabNotch; + } + + /** + * Sets the enabled state of the RF Notch. + */ + public void setRfDabNotch(boolean enabled) + { + mRfDabNotch = enabled; + } + + /** + * Indicates if the external reference output is enabled + */ + @JacksonXmlProperty(isAttribute = true, localName = "external_reference_output") + public boolean isExternalReferenceOutput() + { + return mExternalReferenceOutput; + } + + /** + * Sets the enabled state of the external reference output + */ + public void setExternalReferenceOutput(boolean enabled) + { + mExternalReferenceOutput = enabled; + } + + /** + * Indicates if the Bias-T is enabled + */ + @JacksonXmlProperty(isAttribute = true, localName = "bias_t") + public boolean isBiasT() + { + return mBiasT; + } + + /** + * Sets the enabled state of the Bias-T + */ + public void setBiasT(boolean enabled) + { + mBiasT = enabled; + } +} diff --git a/src/main/java/io/github/dsheirer/source/tuner/sdrplay/rspDuo/RspDuoTuner2Controller.java b/src/main/java/io/github/dsheirer/source/tuner/sdrplay/rspDuo/RspDuoTuner2Controller.java new file mode 100644 index 000000000..ef98d07d8 --- /dev/null +++ b/src/main/java/io/github/dsheirer/source/tuner/sdrplay/rspDuo/RspDuoTuner2Controller.java @@ -0,0 +1,138 @@ +/* + * ***************************************************************************** + * 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 io.github.dsheirer.source.tuner.sdrplay.rspDuo; + +import com.github.dsheirer.sdrplay.SDRPlayException; +import io.github.dsheirer.source.SourceException; +import io.github.dsheirer.source.tuner.ITunerErrorListener; +import io.github.dsheirer.source.tuner.TunerType; +import io.github.dsheirer.source.tuner.configuration.TunerConfiguration; +import io.github.dsheirer.source.tuner.sdrplay.RspSampleRate; +import io.github.dsheirer.source.tuner.sdrplay.RspTunerConfiguration; +import io.github.dsheirer.source.tuner.sdrplay.RspTunerController; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +/** + * Tuner controller for RSPduo tuner 2 + */ +public class RspDuoTuner2Controller extends RspTunerController +{ + private Logger mLog = LoggerFactory.getLogger(RspDuoTuner2Controller.class); + + /** + * Constructs an instance + * + * @param device that is the RSP tuner + * @param tunerErrorListener to monitor errors produced from this tuner controller + */ + public RspDuoTuner2Controller(IControlRspDuoTuner2 device, ITunerErrorListener tunerErrorListener) + { + super(device, tunerErrorListener); + } + + @Override + public TunerType getTunerType() + { + return TunerType.RSP_DUO_2; + } + + @Override + public void apply(TunerConfiguration config) throws SourceException + { + if(config instanceof RspDuoTuner2Configuration duo2) + { + super.apply(config); + + try + { + getControlRsp().setRfNotch(duo2.isRfNotch()); + } + catch(SDRPlayException se) + { + mLog.error("Error setting RSPduo tuner 2 RF notch enabled to " + duo2.isRfNotch()); + } + + try + { + getControlRsp().setRfDabNotch(duo2.isRfDabNotch()); + } + catch(SDRPlayException se) + { + mLog.error("Error setting RSPduo tuner 2 RF DAB notch enabled to " + duo2.isRfDabNotch()); + } + + try + { + getControlRsp().setBiasT(duo2.isBiasT()); + } + catch(SDRPlayException se) + { + mLog.error("Error setting RSPduo tuner 2 Bias-T enabled to " + duo2.isBiasT()); + } + + try + { + getControlRsp().setExternalReferenceOutput(duo2.isExternalReferenceOutput()); + } + catch(SDRPlayException se) + { + mLog.error("Error setting RSPduo tuner 2 external reference output enabled to " + duo2.isExternalReferenceOutput()); + } + } + else + { + mLog.error("Invalid RSPduo tuner configuration type: " + config.getClass()); + } + } + + /** + * Overrides the default RSP controller to ensure the sample rate is compatible with the + * configuration of the RSP duo. + * @param rspSampleRate to apply + * @throws SDRPlayException + */ + @Override + public void setSampleRate(RspSampleRate rspSampleRate) throws SDRPlayException + { + if(getControlRsp().getDeviceSelectionMode().isSingleTunerMode()) + { + if(rspSampleRate.isDualTunerSampleRate()) + { + super.setSampleRate(RspTunerConfiguration.DEFAULT_SINGLE_TUNER_SAMPLE_RATE); + } + else + { + super.setSampleRate(rspSampleRate); + } + } + else + { + if(rspSampleRate.isDualTunerSampleRate()) + { + super.setSampleRate(rspSampleRate); + } + else + { + super.setSampleRate(RspTunerConfiguration.DEFAULT_DUAL_TUNER_SAMPLE_RATE); + } + } + } +} 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 new file mode 100644 index 000000000..5d691727c --- /dev/null +++ b/src/main/java/io/github/dsheirer/source/tuner/sdrplay/rspDuo/RspDuoTuner2Editor.java @@ -0,0 +1,423 @@ +/* + * ***************************************************************************** + * Copyright (C) 2014-2023 Dennis Sheirer + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see + * **************************************************************************** + */ + +package io.github.dsheirer.source.tuner.sdrplay.rspDuo; + +import com.github.dsheirer.sdrplay.SDRPlayException; +import io.github.dsheirer.eventbus.MyEventBus; +import io.github.dsheirer.gui.preference.PreferenceEditorType; +import io.github.dsheirer.gui.preference.ViewUserPreferenceEditorRequest; +import io.github.dsheirer.preference.UserPreferences; +import io.github.dsheirer.source.tuner.manager.TunerManager; +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; + +import javax.swing.JButton; +import javax.swing.JCheckBox; +import javax.swing.JComboBox; +import javax.swing.JLabel; +import javax.swing.JPanel; +import javax.swing.JSeparator; +import javax.swing.SpinnerNumberModel; + +/** + * RSPduo Tuner 2 Editor + */ +public class RspDuoTuner2Editor extends RspTunerEditor +{ + private static final Logger mLog = LoggerFactory.getLogger(RspDuoTuner2Editor.class); + + private JComboBox mSampleRateCombo; + private JCheckBox mBiasTCheckBox; + private JCheckBox mExternalReferenceOutputCheckBox; + private JCheckBox mRfDabNotchCheckBox; + private JCheckBox mRfNotchCheckBox; + private JButton mTunerPreferencesButton; + + /** + * Constructs an instance + * @param userPreferences for settings + * @param tunerManager for state updates + * @param discoveredTuner to edit or control. + */ + public RspDuoTuner2Editor(UserPreferences userPreferences, TunerManager tunerManager, DiscoveredRspTuner discoveredTuner) + { + super(userPreferences, tunerManager, discoveredTuner); + init(); + tunerStatusUpdated(); + } + + private void init() + { + setLayout(new MigLayout("fill,wrap 3", "[right][grow,fill][fill]", + "[][][][][][][][][][][][][][][grow]")); + + add(new JLabel("Tuner:")); + JPanel labelAndButtonPanel = new JPanel(); + labelAndButtonPanel.setLayout(new MigLayout("insets 0")); + labelAndButtonPanel.add(getTunerIdLabel()); + labelAndButtonPanel.add(getTunerPreferencesButton()); + add(labelAndButtonPanel, "wrap"); + add(new JLabel("Status:")); + add(getTunerStatusLabel(), "wrap"); + add(getButtonPanel(), "span,align left"); + + add(new JSeparator(), "span,growx,push"); + + add(new JLabel("Frequency (MHz):")); + add(getFrequencyPanel(), "wrap"); + + add(new JLabel("Sample Rate:")); + add(getSampleRateCombo(), "wrap"); + + add(new JLabel("Gain:")); + add(getGainSlider()); + add(getGainValueLabel()); + + add(new JSeparator(), "span,growx,push"); + + add(new JLabel()); + add(getExternalReferenceOutputCheckBox(), "wrap"); + add(new JLabel()); + add(getBiasTCheckBox(), "wrap"); + add(new JLabel()); + add(getRfDabNotchCheckBox(), "wrap"); + add(new JLabel()); + add(getRfNotchCheckBox(), "wrap"); + } + + private DiscoveredRspTuner getDiscoveredRspTuner() + { + return (DiscoveredRspTuner)getDiscoveredTuner(); + } + + /** + * Access tuner controller + */ + private RspDuoTuner2Controller getTunerController() + { + if(hasTuner()) + { + return (RspDuoTuner2Controller) getTuner().getTunerController(); + } + + return null; + } + + /** + * Indicates if this editor has a tuner and the tuner is configured for slave mode. + */ + private boolean isSlaveMode() + { + return getDiscoveredRspTuner().getDeviceInfo().getDeviceSelectionMode().isSlaveMode(); + } + + @Override + protected void tunerStatusUpdated() + { + setLoading(true); + + getTunerIdLabel().setText(getDiscoveredTuner().getId()); + + String status = getDiscoveredTuner().getTunerStatus().toString(); + if(getDiscoveredTuner().hasErrorMessage()) + { + status += " - " + getDiscoveredTuner().getErrorMessage(); + } + getTunerStatusLabel().setText(status); + getButtonPanel().updateControls(); + + //If master/slave configuration, disable the slave's enable/disable button - user can disable + //the tuner via the master device. + if(isSlaveMode()) + { + getEnabledButton().setEnabled(false); + } + + getFrequencyPanel().updateControls(); + + clearSampleRates(); + if(hasTuner()) + { + setSampleRates(getTunerController().getControlRsp().getSupportedSampleRates()); + } + getSampleRateCombo().setEnabled(hasTuner() && !isSlaveMode() && !getTuner().getTunerController().isLockedSampleRate()); + getSampleRateCombo().setSelectedItem(hasTuner() ? getTunerController().getControlRsp().getSampleRateEnumeration() : null); + + getGainSlider().setEnabled(hasTuner()); + getGainValueLabel().setEnabled(hasTuner()); + getGainSlider().setValue(hasTuner() ? getTunerController().getControlRsp().getGain() : 0); + + getRfDabNotchCheckBox().setEnabled(hasTuner()); + try + { + getRfDabNotchCheckBox().setSelected(hasTuner() && getTunerController().getControlRsp().isRfDabNotch()); + } + catch(SDRPlayException se) + { + mLog.error("Error setting RSPduo tuner 2 RF DAB Notch enabled state in editor"); + } + + getRfNotchCheckBox().setEnabled(hasTuner()); + try + { + getRfNotchCheckBox().setSelected(hasTuner() && getTunerController().getControlRsp().isRfNotch()); + } + catch(SDRPlayException se) + { + mLog.error("Error setting RSPduo tuner 2 RF Notch enabled state in editor"); + } + + getBiasTCheckBox().setEnabled(hasTuner()); + try + { + getBiasTCheckBox().setSelected(hasTuner() && getTunerController().getControlRsp().isBiasT()); + } + catch(SDRPlayException se) + { + mLog.error("Error setting RSPduo tuner 2 Bias-T enabled state in editor"); + } + + getExternalReferenceOutputCheckBox().setEnabled(hasTuner() && !isSlaveMode()); + try + { + getExternalReferenceOutputCheckBox() + .setSelected(hasTuner() && !isSlaveMode() && getTunerController().getControlRsp().isExternalReferenceOutput()); + } + catch(SDRPlayException se) + { + mLog.error("Error setting RSPduo tuner 2 external reference output enabled state in editor"); + } + + setLoading(false); + } + + @Override + public void save() + { + if(hasConfiguration() && !isLoading()) + { + getConfiguration().setFrequency(getFrequencyControl().getFrequency()); + double value = ((SpinnerNumberModel) getFrequencyCorrectionSpinner().getModel()).getNumber().doubleValue(); + getConfiguration().setFrequencyCorrection(value); + getConfiguration().setAutoPPMCorrectionEnabled(getAutoPPMCheckBox().isSelected()); + if(getSampleRateCombo().getSelectedItem() != null) + { + getConfiguration().setSampleRate((RspSampleRate)getSampleRateCombo().getSelectedItem()); + } + getConfiguration().setBiasT(getBiasTCheckBox().isSelected()); + if(hasTuner() && !isSlaveMode()) + { + getConfiguration().setExternalReferenceOutput(getExternalReferenceOutputCheckBox().isSelected()); + } + getConfiguration().setRfDabNotch(getRfDabNotchCheckBox().isSelected()); + getConfiguration().setRfNotch(getRfNotchCheckBox().isSelected()); + getConfiguration().setGain(getGainSlider().getValue()); + + saveConfiguration(); + } + } + + /** + * Updates the sample rates listed in the combobox. + * @param sampleRates to use. + */ + private void setSampleRates(EnumSet sampleRates) + { + if(!sampleRates.isEmpty()) + { + for(RspSampleRate sampleRate: sampleRates) + { + getSampleRateCombo().addItem(sampleRate); + } + } + } + + /** + * Removes all sample rate options from the combo box. + */ + private void clearSampleRates() + { + getSampleRateCombo().removeAllItems(); + } + + /** + * Sample rate selection combobox control + */ + private JComboBox getSampleRateCombo() + { + if(mSampleRateCombo == null) + { + mSampleRateCombo = new JComboBox<>(); + mSampleRateCombo.setEnabled(false); + mSampleRateCombo.addActionListener(e -> { + if(hasTuner() && !isLoading()) + { + RspSampleRate selected = (RspSampleRate)mSampleRateCombo.getSelectedItem(); + + try + { + getTunerController().setSampleRate(selected); + save(); + } + catch(SDRPlayException se) + { + mLog.error("Error setting sample rate for RSPduo tuner 2", se); + } + } + }); + } + + return mSampleRateCombo; + } + + /** + * Checkbox control for RF DAB notch + */ + private JCheckBox getRfDabNotchCheckBox() + { + if(mRfDabNotchCheckBox == null) + { + mRfDabNotchCheckBox = new JCheckBox("DAB Broadcast Band Filter (157-235 MHz)"); + mRfDabNotchCheckBox.setEnabled(false); + mRfDabNotchCheckBox.addActionListener(e -> { + if(hasTuner() && !isLoading()) + { + try + { + getTunerController().getControlRsp().setRfDabNotch(mRfDabNotchCheckBox.isSelected()); + save(); + } + catch(SDRPlayException se) + { + mLog.error("Unable to set RSPduo tuner 2 RF DAB notch enabled to " + mRfDabNotchCheckBox.isSelected(), se); + } + } + }); + } + + return mRfDabNotchCheckBox; + } + + /** + * Checkbox control for RF notch + */ + private JCheckBox getRfNotchCheckBox() + { + if(mRfNotchCheckBox == null) + { + mRfNotchCheckBox = new JCheckBox("FM Broadcast Band Filter (78-114 MHz)"); + mRfNotchCheckBox.setEnabled(false); + mRfNotchCheckBox.addActionListener(e -> { + if(hasTuner() && !isLoading()) + { + try + { + getTunerController().getControlRsp().setRfNotch(mRfNotchCheckBox.isSelected()); + save(); + } + catch(SDRPlayException se) + { + mLog.error("Unable to set RSPduo tuner 2 RF notch enabled to " + mRfNotchCheckBox.isSelected(), se); + } + } + }); + } + + return mRfNotchCheckBox; + } + + /** + * Checkbox control for Bias-T + */ + private JCheckBox getBiasTCheckBox() + { + if(mBiasTCheckBox == null) + { + mBiasTCheckBox = new JCheckBox("Bias-T Power"); + mBiasTCheckBox.setEnabled(false); + mBiasTCheckBox.addActionListener(e -> { + if(hasTuner() && !isLoading()) + { + try + { + getTunerController().getControlRsp().setBiasT(mBiasTCheckBox.isSelected()); + save(); + } + catch(SDRPlayException se) + { + mLog.error("Unable to set RSPduo tuner 2 AM notch enabled to " + mBiasTCheckBox.isSelected(), se); + } + } + }); + } + + return mBiasTCheckBox; + } + + /** + * Checkbox control for External Reference Output + */ + private JCheckBox getExternalReferenceOutputCheckBox() + { + if(mExternalReferenceOutputCheckBox == null) + { + mExternalReferenceOutputCheckBox = new JCheckBox("External Reference Output"); + mExternalReferenceOutputCheckBox.setEnabled(false); + mExternalReferenceOutputCheckBox.addActionListener(e -> { + if(hasTuner() && !isLoading()) + { + try + { + getTunerController().getControlRsp().setExternalReferenceOutput(mExternalReferenceOutputCheckBox.isSelected()); + save(); + } + catch(SDRPlayException se) + { + mLog.error("Unable to set RSPduo tuner 2 external reference output notch enabled to " + + mExternalReferenceOutputCheckBox.isSelected(), se); + } + } + }); + } + + return mExternalReferenceOutputCheckBox; + } + + /** + * Button to launch the User Preferences editor to show the RSPduo tuner preference selection. + * @return constructed button. + */ + private JButton getTunerPreferencesButton() + { + if(mTunerPreferencesButton == null) + { + mTunerPreferencesButton = new JButton("RSPduo Preferences"); + mTunerPreferencesButton.addActionListener(e -> MyEventBus.getGlobalEventBus() + .post(new ViewUserPreferenceEditorRequest(PreferenceEditorType.SOURCE_TUNERS))); + } + + return mTunerPreferencesButton; + } +} 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 new file mode 100644 index 000000000..8c3c9ffbc --- /dev/null +++ b/src/main/java/io/github/dsheirer/source/tuner/sdrplay/rspDx/ControlRspDx.java @@ -0,0 +1,201 @@ +/* + * ***************************************************************************** + * Copyright (C) 2014-2023 Dennis Sheirer + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see + * **************************************************************************** + */ + +package io.github.dsheirer.source.tuner.sdrplay.rspDx; + +import com.github.dsheirer.sdrplay.SDRPlayException; +import com.github.dsheirer.sdrplay.device.RspDxDevice; +import com.github.dsheirer.sdrplay.parameter.tuner.HdrModeBandwidth; +import com.github.dsheirer.sdrplay.parameter.tuner.RspDxAntenna; +import io.github.dsheirer.source.tuner.sdrplay.ControlRsp; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +/** + * Control wrapper for an RSPdx Device + */ +public class ControlRspDx extends ControlRsp implements IControlRspDx +{ + private Logger mLog = LoggerFactory.getLogger(ControlRspDx.class); + + /** + * Constructs an instance + * @param device for the device + */ + public ControlRspDx(RspDxDevice device) + { + super(device); + } + + @Override + public boolean isBiasT() throws SDRPlayException + { + if(hasDevice()) + { + return getDevice().getTuner().isBiasT(); + } + else + { + throw new SDRPlayException("Device is not initialized"); + } + } + + @Override + public void setBiasT(boolean enabled) throws SDRPlayException + { + if(hasDevice()) + { + getDevice().getTuner().setBiasT(enabled); + } + else + { + throw new SDRPlayException("Device is not initialized"); + } + } + + @Override + public boolean isRfNotch() throws SDRPlayException + { + if(hasDevice()) + { + return getDevice().getTuner().isRfNotch(); + } + else + { + throw new SDRPlayException("Device is not initialized"); + } + } + + @Override + public void setRfNotch(boolean enabled) throws SDRPlayException + { + if(hasDevice()) + { + getDevice().getTuner().setRfNotch(enabled); + } + else + { + throw new SDRPlayException("Device is not initialized"); + } + } + + @Override + public boolean isRfDabNotch() throws SDRPlayException + { + if(hasDevice()) + { + return getDevice().getTuner().isRfDabNotch(); + } + else + { + throw new SDRPlayException("Device is not initialized"); + } + } + + @Override + public void setRfDabNotch(boolean enabled) throws SDRPlayException + { + if(hasDevice()) + { + getDevice().getTuner().setRfDabNotch(enabled); + } + else + { + throw new SDRPlayException("Device is not initialized"); + } + } + + @Override + public boolean isHighDynamicRange() throws SDRPlayException + { + if(hasDevice()) + { + return getDevice().getTuner().isHdrMode(); + } + else + { + throw new SDRPlayException("Device is not initialized"); + } + } + + @Override + public void setHighDynamicRange(boolean enabled) throws SDRPlayException + { + if(hasDevice()) + { + getDevice().getTuner().setHdrMode(enabled); + } + else + { + throw new SDRPlayException("Device is not initialized"); + } + } + + @Override + public RspDxAntenna getAntenna() throws SDRPlayException + { + if(hasDevice()) + { + return getDevice().getTuner().getAntenna(); + } + else + { + throw new SDRPlayException("Device is not initialized"); + } + } + + @Override + public void setAntenna(RspDxAntenna antenna) throws SDRPlayException + { + if(hasDevice()) + { + getDevice().getTuner().setAntenna(antenna); + } + else + { + throw new SDRPlayException("Device is not initialized"); + } + } + + @Override + public void setHdrModeBandwidth(HdrModeBandwidth bandwidth) throws SDRPlayException + { + if(hasDevice()) + { + getDevice().getTuner().setHdrModeBandwidth(bandwidth); + } + else + { + throw new SDRPlayException("Device is not initialized"); + } + } + + @Override + public HdrModeBandwidth getHdrModeBandwidth() throws SDRPlayException + { + if(hasDevice()) + { + return getDevice().getTuner().getHdrModeBandwidth(); + } + else + { + throw new SDRPlayException("Device is not initialized"); + } + } +} 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 new file mode 100644 index 000000000..0f8d927db --- /dev/null +++ b/src/main/java/io/github/dsheirer/source/tuner/sdrplay/rspDx/DiscoveredRspDxTuner.java @@ -0,0 +1,40 @@ +/* + * ***************************************************************************** + * Copyright (C) 2014-2023 Dennis Sheirer + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see + * **************************************************************************** + */ + +package io.github.dsheirer.source.tuner.sdrplay.rspDx; + +import com.github.dsheirer.sdrplay.device.DeviceInfo; +import io.github.dsheirer.preference.source.ChannelizerType; +import io.github.dsheirer.source.tuner.sdrplay.DiscoveredRspTuner; + +/** + * RSPdx discovered tuner. + */ +public class DiscoveredRspDxTuner extends DiscoveredRspTuner +{ + /** + * Constructs an instance + * @param deviceInfo for the tuner + * @param channelizerType to use for the tuner once started + */ + public DiscoveredRspDxTuner(DeviceInfo deviceInfo, ChannelizerType channelizerType) + { + super(deviceInfo, channelizerType); + } +} diff --git a/src/main/java/io/github/dsheirer/source/tuner/sdrplay/rspDx/IControlRspDx.java b/src/main/java/io/github/dsheirer/source/tuner/sdrplay/rspDx/IControlRspDx.java new file mode 100644 index 000000000..038e7bd0f --- /dev/null +++ b/src/main/java/io/github/dsheirer/source/tuner/sdrplay/rspDx/IControlRspDx.java @@ -0,0 +1,115 @@ +/* + * ***************************************************************************** + * 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 io.github.dsheirer.source.tuner.sdrplay.rspDx; + +import com.github.dsheirer.sdrplay.SDRPlayException; +import com.github.dsheirer.sdrplay.parameter.tuner.HdrModeBandwidth; +import com.github.dsheirer.sdrplay.parameter.tuner.RspDxAntenna; +import io.github.dsheirer.source.tuner.sdrplay.IControlRsp; + +/** + * Control interface for RSPdx device + */ +public interface IControlRspDx extends IControlRsp +{ + /** + * Indicates if the Bias-T power is enabled. + * @return true if enabled. + * @throws SDRPlayException if the device is no started/selected + */ + boolean isBiasT() throws SDRPlayException; + + /** + * Sets the enabled state of the Bias-T power. + * @param enabled true to power on the Bias-T + * @throws SDRPlayException if the device is not started (selected). + */ + void setBiasT(boolean enabled) throws SDRPlayException; + + /** + * Indicates the enabled state of high dynamic range mode + * @return true if enabled. + * @throws SDRPlayException if the device is not started (selected). + */ + boolean isHighDynamicRange() throws SDRPlayException; + + /** + * Sets the enabled state of the high dynamic range mode + * @param enabled true to enable. + * @throws SDRPlayException if the device is not started (selected). + */ + void setHighDynamicRange(boolean enabled) throws SDRPlayException; + + /** + * Indicates if the RF notch is enabled (FM broadcast band filter). + * @return true if enabled. + * @throws SDRPlayException if the device is not started (selected). + */ + boolean isRfNotch() throws SDRPlayException; + + /** + * Sets the enabled state of the RF notch + * @param enabled true to filter the FM broadcast band frequency range. + * @throws SDRPlayException if the device is not started (selected). + */ + void setRfNotch(boolean enabled) throws SDRPlayException; + + /** + * Indicates if the RF DAB notch is enabled (DAB broadcast band filter). + * @return true if enabled. + * @throws SDRPlayException if the device is not started (selected). + */ + boolean isRfDabNotch() throws SDRPlayException; + + /** + * Sets the enabled state of the RF DAB notch. + * @param enabled true to filter the DAB broadcast band frequency range. + * @throws SDRPlayException if the device is not started (selected). + */ + void setRfDabNotch(boolean enabled) throws SDRPlayException; + + /** + * Antenna selection + * @return currently selected antenna + * @throws SDRPlayException if the device is not started (selected) + */ + RspDxAntenna getAntenna() throws SDRPlayException; + + /** + * Sets the antenna selection + * @param antenna to select + * @throws SDRPlayException if the device is not started (selected) + */ + void setAntenna(RspDxAntenna antenna) throws SDRPlayException; + + /** + * Sets High Dynamic Range mode bandwidth + * @param bandwidth to apply + * @throws SDRPlayException if the device is not started (selected) + */ + void setHdrModeBandwidth(HdrModeBandwidth bandwidth) throws SDRPlayException; + + /** + * High Dynamic Range mode bandwidth + * @return bandwidth + * @throws SDRPlayException if the device is not started (selected) + */ + HdrModeBandwidth getHdrModeBandwidth() throws SDRPlayException; +} diff --git a/src/main/java/io/github/dsheirer/source/tuner/sdrplay/rspDx/RspDxTunerConfiguration.java b/src/main/java/io/github/dsheirer/source/tuner/sdrplay/rspDx/RspDxTunerConfiguration.java new file mode 100644 index 000000000..c4775ca19 --- /dev/null +++ b/src/main/java/io/github/dsheirer/source/tuner/sdrplay/rspDx/RspDxTunerConfiguration.java @@ -0,0 +1,164 @@ +/* + * ***************************************************************************** + * 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 io.github.dsheirer.source.tuner.sdrplay.rspDx; + +import com.fasterxml.jackson.dataformat.xml.annotation.JacksonXmlProperty; +import com.github.dsheirer.sdrplay.parameter.tuner.HdrModeBandwidth; +import com.github.dsheirer.sdrplay.parameter.tuner.RspDxAntenna; +import io.github.dsheirer.source.tuner.TunerType; +import io.github.dsheirer.source.tuner.sdrplay.RspTunerConfiguration; + +/** + * RSPdx tuner configuration + */ +public class RspDxTunerConfiguration extends RspTunerConfiguration +{ + private boolean mBiasT; + private boolean mHdrMode = false; + private boolean mRfNotch; + private boolean mRfDabNotch; + private RspDxAntenna mAntenna = RspDxAntenna.ANTENNA_A; + private HdrModeBandwidth mHdrModeBandwidth = HdrModeBandwidth.BANDWIDTH_1_700; + + /** + * Constructs an instance + * @param uniqueId for the tuner + */ + public RspDxTunerConfiguration(String uniqueId) + { + super(uniqueId); + } + + /** + * JAXB constructor + */ + public RspDxTunerConfiguration() + { + } + + + @Override + public TunerType getTunerType() + { + return TunerType.RSP_DX; + } + + /** + * Indicates if HDR mode is enabled + */ + @JacksonXmlProperty(isAttribute = true, localName = "hdr_mode") + public boolean isHdrMode() + { + return mHdrMode; + } + + /** + * Sets enabled state of HDR mode + */ + public void setHdrMode(boolean enabled) + { + mHdrMode = enabled; + } + + /** + * Indicates if RF notch is enabled + */ + @JacksonXmlProperty(isAttribute = true, localName = "rf_notch") + public boolean isRfNotch() + { + return mRfNotch; + } + + /** + * Sets enabled state of RF notch + */ + public void setRfNotch(boolean enabled) + { + mRfNotch = enabled; + } + + /** + * Indicates if RF Digital Audio Broadcast (DAB) notch is enabled + */ + @JacksonXmlProperty(isAttribute = true, localName = "dab_notch") + public boolean isRfDabNotch() + { + return mRfDabNotch; + } + + /** + * Sets enabled state of DAB notch + */ + public void setRfDabNotch(boolean enabled) + { + mRfDabNotch = enabled; + } + + /** + * Indicates if Bias-T is enabled + */ + @JacksonXmlProperty(isAttribute = true, localName = "bias_t") + public boolean isBiasT() + { + return mBiasT; + } + + /** + * Sets enabled state of Bias-T + */ + public void setBiasT(boolean enabled) + { + mBiasT = enabled; + } + + /** + * Antenna setting + */ + @JacksonXmlProperty(isAttribute = true, localName = "antenna") + public RspDxAntenna getAntenna() + { + return mAntenna; + } + + /** + * Sets the antenna. + */ + public void setAntenna(RspDxAntenna antenna) + { + mAntenna = antenna; + } + + /** + * HDR mode bandwidth setting. + */ + @JacksonXmlProperty(isAttribute = true, localName = "hdr_mode_bandwidth") + public HdrModeBandwidth getHdrModeBandwidth() + { + return mHdrModeBandwidth; + } + + /** + * Sets HDR mode bandwidth + */ + public void setHdrModeBandwidth(HdrModeBandwidth hdrModeBandwidth) + { + mHdrModeBandwidth = hdrModeBandwidth; + } +} diff --git a/src/main/java/io/github/dsheirer/source/tuner/sdrplay/rspDx/RspDxTunerController.java b/src/main/java/io/github/dsheirer/source/tuner/sdrplay/rspDx/RspDxTunerController.java new file mode 100644 index 000000000..c0c9bc0c3 --- /dev/null +++ b/src/main/java/io/github/dsheirer/source/tuner/sdrplay/rspDx/RspDxTunerController.java @@ -0,0 +1,121 @@ +/* + * ***************************************************************************** + * 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 io.github.dsheirer.source.tuner.sdrplay.rspDx; + +import com.github.dsheirer.sdrplay.SDRPlayException; +import io.github.dsheirer.source.SourceException; +import io.github.dsheirer.source.tuner.ITunerErrorListener; +import io.github.dsheirer.source.tuner.TunerType; +import io.github.dsheirer.source.tuner.configuration.TunerConfiguration; +import io.github.dsheirer.source.tuner.sdrplay.RspTunerController; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +/** + * Tuner controller for RSPdx + */ +public class RspDxTunerController extends RspTunerController +{ + private Logger mLog = LoggerFactory.getLogger(RspDxTunerController.class); + + /** + * Constructs an instance + * + * @param control interface for the RSPdx tuner + * @param tunerErrorListener to monitor errors produced from this tuner controller + */ + public RspDxTunerController(IControlRspDx control, ITunerErrorListener tunerErrorListener) + { + super(control, tunerErrorListener); + } + + @Override + public TunerType getTunerType() + { + return TunerType.RSP_DX; + } + + @Override + public void apply(TunerConfiguration config) throws SourceException + { + if(config instanceof RspDxTunerConfiguration rtc) + { + super.apply(config); + + try + { + getControlRsp().setAntenna(rtc.getAntenna()); + } + catch(SDRPlayException se) + { + mLog.error("Error setting RSPdx antenna to " + rtc.getAntenna()); + } + + try + { + getControlRsp().setBiasT(rtc.isBiasT()); + } + catch(SDRPlayException se) + { + mLog.error("Error setting RSPdx bias-T enabled to " + rtc.isBiasT()); + } + + try + { + getControlRsp().setHighDynamicRange(rtc.isHdrMode()); + } + catch(SDRPlayException se) + { + mLog.error("Error setting RSPdx high dynamic range mode enabled to " + rtc.isHdrMode()); + } + + try + { + getControlRsp().setRfNotch(rtc.isRfNotch()); + } + catch(SDRPlayException se) + { + mLog.error("Error setting RSPdx RF Notch enabled to " + rtc.isRfNotch()); + } + + try + { + getControlRsp().setRfDabNotch(rtc.isRfDabNotch()); + } + catch(SDRPlayException se) + { + mLog.error("Error setting RSPdx RF DAB Notch enabled to " + rtc.isRfDabNotch()); + } + + try + { + getControlRsp().setHdrModeBandwidth(rtc.getHdrModeBandwidth()); + } + catch(SDRPlayException se) + { + mLog.error("Error setting RSPdx HDR mode bandwdidth to " + rtc.getHdrModeBandwidth()); + } + } + else + { + mLog.error("Invalid RSPdx tuner configuration type: " + config.getClass()); + } + } +} diff --git a/src/main/java/io/github/dsheirer/source/tuner/sdrplay/rspDx/RspDxTunerEditor.java b/src/main/java/io/github/dsheirer/source/tuner/sdrplay/rspDx/RspDxTunerEditor.java new file mode 100644 index 000000000..848991b64 --- /dev/null +++ b/src/main/java/io/github/dsheirer/source/tuner/sdrplay/rspDx/RspDxTunerEditor.java @@ -0,0 +1,423 @@ +/* + * ***************************************************************************** + * 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 io.github.dsheirer.source.tuner.sdrplay.rspDx; + +import com.github.dsheirer.sdrplay.SDRPlayException; +import com.github.dsheirer.sdrplay.parameter.tuner.HdrModeBandwidth; +import com.github.dsheirer.sdrplay.parameter.tuner.RspDxAntenna; +import io.github.dsheirer.preference.UserPreferences; +import io.github.dsheirer.source.tuner.manager.TunerManager; +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 net.miginfocom.swing.MigLayout; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import javax.swing.JCheckBox; +import javax.swing.JComboBox; +import javax.swing.JLabel; +import javax.swing.JSeparator; +import javax.swing.SpinnerNumberModel; + +/** + * RSPdx Tuner Editor + */ +public class RspDxTunerEditor extends RspTunerEditor +{ + private static final Logger mLog = LoggerFactory.getLogger(RspDxTunerEditor.class); + + private JComboBox mSampleRateCombo; + private JCheckBox mBiasTCheckBox; + private JCheckBox mRfDabNotchCheckBox; + private JCheckBox mRfNotchCheckBox; + private JComboBox mAntennaCombo; + private JCheckBox mHdrModeCheckBox; + private JComboBox mHdrModeBandwidthCombo; + + /** + * Constructs an instance + * @param userPreferences for settings + * @param tunerManager for state updates + * @param discoveredTuner to edit or control. + */ + public RspDxTunerEditor(UserPreferences userPreferences, TunerManager tunerManager, DiscoveredRspTuner discoveredTuner) + { + super(userPreferences, tunerManager, discoveredTuner); + init(); + tunerStatusUpdated(); + } + + private void init() + { + setLayout(new MigLayout("fill,wrap 3", "[right][grow,fill][fill]", + "[][][][][][][][][][][][grow]")); + + add(new JLabel("Tuner:")); + add(getTunerIdLabel(), "wrap"); + + add(new JLabel("Status:")); + add(getTunerStatusLabel(), "wrap"); + + add(getButtonPanel(), "span,align left"); + + add(new JSeparator(), "span,growx,push"); + + add(new JLabel("Frequency (MHz):")); + add(getFrequencyPanel(), "wrap"); + + add(new JLabel("Sample Rate:")); + add(getSampleRateCombo(), "wrap"); + + add(new JLabel("Gain:")); + add(getGainSlider()); + add(getGainValueLabel()); + + add(new JSeparator(), "span,growx,push"); + + add(new JLabel()); + add(getAntennaCombo(), "wrap"); + add(new JLabel()); + add(getBiasTCheckBox(), "wrap"); + add(new JLabel()); + add(getRfDabNotchCheckBox(), "wrap"); + add(new JLabel()); + add(getRfNotchCheckBox(), "wrap"); + + add(new JSeparator(), "span,growx,push"); + add(new JLabel()); + add(getHdrModeCheckBox(), "wrap"); + add(new JLabel("HDR Mode Bandwidth")); + add(getHdrModeBandwidthCombo(), "wrap"); + } + + /** + * Access tuner controller + */ + private RspDxTunerController getTunerController() + { + if(hasTuner()) + { + return (RspDxTunerController) getTuner().getTunerController(); + } + + return null; + } + + @Override + protected void tunerStatusUpdated() + { + setLoading(true); + + getTunerIdLabel().setText(getDiscoveredTuner().getId()); + + String status = getDiscoveredTuner().getTunerStatus().toString(); + if(getDiscoveredTuner().hasErrorMessage()) + { + status += " - " + getDiscoveredTuner().getErrorMessage(); + } + getTunerStatusLabel().setText(status); + getButtonPanel().updateControls(); + getFrequencyPanel().updateControls(); + + getSampleRateCombo().setEnabled(hasTuner() && !getTuner().getTunerController().isLockedSampleRate()); + getSampleRateCombo().setSelectedItem(hasTuner() ? getTunerController().getControlRsp().getSampleRateEnumeration() : null); + + getGainSlider().setEnabled(hasTuner()); + getGainValueLabel().setEnabled(hasTuner()); + getGainSlider().setValue(hasTuner() ? getTunerController().getControlRsp().getGain() : 0); + + getBiasTCheckBox().setEnabled(hasTuner()); + try + { + getBiasTCheckBox().setSelected(hasTuner() && getTunerController().getControlRsp().isBiasT()); + } + catch(SDRPlayException se) + { + mLog.error("Error setting Bias-T enabled state in editor"); + } + + getHdrModeCheckBox().setEnabled(hasTuner()); + try + { + getHdrModeCheckBox().setSelected(hasTuner() && getTunerController().getControlRsp().isHighDynamicRange()); + } + catch(SDRPlayException se) + { + mLog.error("Error setting HDR mode enabled state in editor"); + } + + getRfNotchCheckBox().setEnabled(hasTuner()); + try + { + getRfNotchCheckBox().setSelected(hasTuner() && getTunerController().getControlRsp().isRfNotch()); + } + catch(SDRPlayException se) + { + mLog.error("Error setting RF Notch enabled state in editor"); + } + + getRfDabNotchCheckBox().setEnabled(hasTuner()); + try + { + getRfDabNotchCheckBox().setSelected(hasTuner() && getTunerController().getControlRsp().isRfDabNotch()); + } + catch(SDRPlayException se) + { + mLog.error("Error setting RF DAB Notch enabled state in editor"); + } + + getAntennaCombo().setEnabled(hasTuner()); + try + { + getAntennaCombo().setSelectedItem(hasTuner() ? getTunerController().getControlRsp().getAntenna() : null); + } + catch(SDRPlayException se) + { + mLog.error("Error setting antenna selection in editor"); + } + + setLoading(false); + } + + @Override + public void save() + { + if(hasConfiguration() && !isLoading()) + { + getConfiguration().setFrequency(getFrequencyControl().getFrequency()); + double value = ((SpinnerNumberModel) getFrequencyCorrectionSpinner().getModel()).getNumber().doubleValue(); + getConfiguration().setFrequencyCorrection(value); + getConfiguration().setAutoPPMCorrectionEnabled(getAutoPPMCheckBox().isSelected()); + getConfiguration().setSampleRate((RspSampleRate)getSampleRateCombo().getSelectedItem()); + getConfiguration().setBiasT(getBiasTCheckBox().isSelected()); + getConfiguration().setHdrMode(getHdrModeCheckBox().isSelected()); + getConfiguration().setRfDabNotch(getRfNotchCheckBox().isSelected()); + getConfiguration().setRfNotch(getRfNotchCheckBox().isSelected()); + getConfiguration().setAntenna((RspDxAntenna) getAntennaCombo().getSelectedItem()); + getConfiguration().setGain(getGainSlider().getValue()); + + saveConfiguration(); + } + } + + /** + * Sample rate selection combobox control + */ + private JComboBox getSampleRateCombo() + { + if(mSampleRateCombo == null) + { + RspSampleRate[] rspSampleRates = RspSampleRate.SINGLE_TUNER_SAMPLE_RATES.toArray(new RspSampleRate[RspSampleRate.SINGLE_TUNER_SAMPLE_RATES.size()]); + mSampleRateCombo = new JComboBox<>(rspSampleRates); + mSampleRateCombo.setEnabled(false); + mSampleRateCombo.addActionListener(e -> { + if(hasTuner() && !isLoading()) + { + RspSampleRate selected = (RspSampleRate)mSampleRateCombo.getSelectedItem(); + + try + { + getTunerController().setSampleRate(selected); + save(); + } + catch(SDRPlayException se) + { + mLog.error("Error setting sample rate for RSP2 tuner", se); + } + } + }); + } + + return mSampleRateCombo; + } + + /** + * Checkbox control for Bias-T + */ + private JCheckBox getBiasTCheckBox() + { + if(mBiasTCheckBox == null) + { + mBiasTCheckBox = new JCheckBox("ANT B Bias-T Power"); + mBiasTCheckBox.setEnabled(false); + mBiasTCheckBox.addActionListener(e -> { + if(hasTuner() && !isLoading()) + { + try + { + getTunerController().getControlRsp().setBiasT(mBiasTCheckBox.isSelected()); + save(); + } + catch(SDRPlayException se) + { + mLog.error("Unable to set RSP2 Bias-T enabled to " + mBiasTCheckBox.isSelected(), se); + } + } + }); + } + + return mBiasTCheckBox; + } + + /** + * Checkbox control for HDR mode + */ + private JCheckBox getHdrModeCheckBox() + { + if(mHdrModeCheckBox == null) + { + mHdrModeCheckBox = new JCheckBox("HDR Mode (1 kHz - 2 MHz)"); + mHdrModeCheckBox.setEnabled(false); + mHdrModeCheckBox.addActionListener(e -> { + if(hasTuner() && !isLoading()) + { + try + { + getTunerController().getControlRsp().setHighDynamicRange(mHdrModeCheckBox.isSelected()); + save(); + } + catch(SDRPlayException se) + { + mLog.error("Unable to set RSPd HDR mode enabled to " + mHdrModeCheckBox.isSelected(), se); + } + } + }); + } + + return mHdrModeCheckBox; + } + + /** + * Checkbox control for RF notch + */ + private JCheckBox getRfNotchCheckBox() + { + if(mRfNotchCheckBox == null) + { + mRfNotchCheckBox = new JCheckBox("FM Broadcast Band Filter (77-115 MHz)"); + mRfNotchCheckBox.setEnabled(false); + mRfNotchCheckBox.addActionListener(e -> { + if(hasTuner() && !isLoading()) + { + try + { + getTunerController().getControlRsp().setRfNotch(mRfNotchCheckBox.isSelected()); + save(); + } + catch(SDRPlayException se) + { + mLog.error("Unable to set RSP2 RF notch enabled to " + mRfNotchCheckBox.isSelected(), se); + } + } + }); + } + + return mRfNotchCheckBox; + } + + /** + * Checkbox control for RF DAB notch + */ + private JCheckBox getRfDabNotchCheckBox() + { + if(mRfDabNotchCheckBox == null) + { + mRfDabNotchCheckBox = new JCheckBox("DAB Broadcast Band Filter (155-235 MHz)"); + mRfDabNotchCheckBox.setEnabled(false); + mRfDabNotchCheckBox.addActionListener(e -> { + if(hasTuner() && !isLoading()) + { + try + { + getTunerController().getControlRsp().setRfDabNotch(mRfDabNotchCheckBox.isSelected()); + save(); + } + catch(SDRPlayException se) + { + mLog.error("Unable to set RSPdx RF DAB notch enabled to " + mRfDabNotchCheckBox.isSelected(), se); + } + } + }); + } + + return mRfDabNotchCheckBox; + } + + /** + * Antenna selection combobox control + */ + private JComboBox getAntennaCombo() + { + if(mAntennaCombo == null) + { + mAntennaCombo = new JComboBox<>(RspDxAntenna.values()); + mAntennaCombo.setEnabled(false); + mAntennaCombo.addActionListener(e -> { + if(hasTuner() && !isLoading()) + { + RspDxAntenna selected = (RspDxAntenna) mAntennaCombo.getSelectedItem(); + + try + { + getTunerController().getControlRsp().setAntenna(selected); + save(); + } + catch(SDRPlayException se) + { + mLog.error("Error setting Antenna selection for RSPdx", se); + } + } + }); + } + + return mAntennaCombo; + } + + /** + * HDR mode bandwidth selection combobox control + */ + private JComboBox getHdrModeBandwidthCombo() + { + if(mHdrModeBandwidthCombo == null) + { + mHdrModeBandwidthCombo = new JComboBox<>(HdrModeBandwidth.values()); + mHdrModeBandwidthCombo.setEnabled(false); + mHdrModeBandwidthCombo.addActionListener(e -> { + if(hasTuner() && !isLoading()) + { + HdrModeBandwidth selected = (HdrModeBandwidth) mHdrModeBandwidthCombo.getSelectedItem(); + + try + { + getTunerController().getControlRsp().setHdrModeBandwidth(selected); + save(); + } + catch(SDRPlayException se) + { + mLog.error("Error setting HDR mode bandwidth for RSPdx", se); + } + } + }); + } + + return mHdrModeBandwidthCombo; + } +} diff --git a/src/main/java/io/github/dsheirer/source/tuner/ui/DiscoveredTunerEditor.java b/src/main/java/io/github/dsheirer/source/tuner/ui/DiscoveredTunerEditor.java index 8bf71c9f2..0c43db36b 100644 --- a/src/main/java/io/github/dsheirer/source/tuner/ui/DiscoveredTunerEditor.java +++ b/src/main/java/io/github/dsheirer/source/tuner/ui/DiscoveredTunerEditor.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 @@ -124,7 +124,14 @@ public void tunerStatusUpdated(DiscoveredTuner discoveredTuner, TunerStatus prev //If this is the currently displayed tuner, set it again to re-render the editor if(hasItem() && getItem().equals(discoveredTuner)) { - setItem(discoveredTuner); + if(current == TunerStatus.REMOVED) + { + setItem(null); + } + else + { + setItem(discoveredTuner); + } } } } \ No newline at end of file diff --git a/src/main/java/io/github/dsheirer/source/tuner/ui/DiscoveredTunerModel.java b/src/main/java/io/github/dsheirer/source/tuner/ui/DiscoveredTunerModel.java index b8159f904..a809483cf 100644 --- a/src/main/java/io/github/dsheirer/source/tuner/ui/DiscoveredTunerModel.java +++ b/src/main/java/io/github/dsheirer/source/tuner/ui/DiscoveredTunerModel.java @@ -25,10 +25,13 @@ import io.github.dsheirer.source.tuner.manager.DiscoveredUSBTuner; import io.github.dsheirer.source.tuner.manager.IDiscoveredTunerStatusListener; import io.github.dsheirer.source.tuner.manager.TunerStatus; +import io.github.dsheirer.source.tuner.sdrplay.rspDuo.DiscoveredRspDuoTuner1; +import io.github.dsheirer.source.tuner.sdrplay.rspDuo.DiscoveredRspDuoTuner2; import java.awt.EventQueue; import java.text.DecimalFormat; import java.util.ArrayList; import java.util.List; +import java.util.Optional; import java.util.concurrent.CopyOnWriteArrayList; import java.util.concurrent.locks.Lock; import java.util.concurrent.locks.ReentrantLock; @@ -130,6 +133,35 @@ public DiscoveredTuner getDiscoveredTuner(int index) return null; } + /** + * Find a discovered tuner by ID + * @param id of the tuner to search for + * @return discovered tuner with matching ID or null. + */ + public DiscoveredTuner getDiscoveredTuner(String id) + { + DiscoveredTuner discoveredTuner = null; + + mLock.lock(); + + try + { + Optional result = mDiscoveredTuners.stream().filter(tuner -> tuner.getId().equals(id)).findFirst(); + + if(result.isPresent()) + { + discoveredTuner = result.get(); + } + } + finally + { + mLock.unlock(); + } + + return discoveredTuner; + } + + /** * Adds the Tuner to this model */ @@ -164,24 +196,23 @@ public void releaseDiscoveredTuners() { mLock.lock(); + List discoveredTuners = new ArrayList<>(mDiscoveredTuners); + try { - List discoveredTuners = new ArrayList<>(mDiscoveredTuners); - - for(DiscoveredTuner discoveredTuner: discoveredTuners) - { - if(discoveredTuner.hasTuner()) - { - discoveredTuner.getTuner().removeTunerEventListener(this); - } - - removeDiscoveredTuner(discoveredTuner); - } + mDiscoveredTuners.clear(); + fireTableDataChanged(); } finally { mLock.unlock(); } + + for(DiscoveredTuner discoveredTuner: discoveredTuners) + { + discoveredTuner.stop(); + discoveredTuner.removeTunerStatusListener(this); + } } /** @@ -198,10 +229,39 @@ public void removeDiscoveredTuner(DiscoveredTuner discoveredTuner) { int index = mDiscoveredTuners.indexOf(discoveredTuner); mDiscoveredTuners.remove(discoveredTuner); - EventQueue.invokeLater(() -> fireTableRowsDeleted(index, index)); + + if(EventQueue.isDispatchThread()) + { + try + { + fireTableRowsDeleted(index, index); + } + catch(Exception e) + { + mLog.info("Exception firing table rows deleted for index [" + index + "] on calling event dispatch thread", e); + } + } + else + { + EventQueue.invokeAndWait(() -> + { + try + { + fireTableRowsDeleted(index, index); + } + catch(Exception e) + { + mLog.info("Exception firing table rows deleted for index [" + index + "]", e); + } + }); + } discoveredTuner.stop(); } } + catch(Exception e) + { + mLog.error("Unexpected error while shutting down discovered tuner", e); + } finally { mLock.unlock(); @@ -297,47 +357,57 @@ public void broadcast(TunerEvent event) } } - /** - * Requests to display the first tuner in this model. Invoke this method - * after all listeners have registered and tuners have been added to this - * model, in order to inform the primary display to use the first tuner. - */ - public void requestFirstTunerDisplay() - { -//TODO: move this out of the model ... is not part of the scope of this model -// SystemProperties properties = SystemProperties.getInstance(); -// boolean enabled = properties.get(SpectralDisplayPanel.SPECTRAL_DISPLAY_ENABLED, true); -// -// if(enabled && mDiscoveredTuners.size() > 0) -// { -// //Hack: the airspy tuner would lockup aperiodically and refuse to produce -// //transfer buffers ... delaying registering for buffers for 500 ms seems -// //to allow the airspy to stabilize before we start asking for samples. -// ThreadPool.SCHEDULED.schedule(new Runnable() -// { -// @Override -// public void run() -// { -// broadcast(new TunerEvent(mDiscoveredTuners.get(0), Event.REQUEST_MAIN_SPECTRAL_DISPLAY)); -// } -// }, 500, TimeUnit.MILLISECONDS); -// } -// else -// { -// broadcast(new TunerEvent(null, Event.CLEAR_MAIN_SPECTRAL_DISPLAY)); -// } - } - @Override public void tunerStatusUpdated(DiscoveredTuner discoveredTuner, TunerStatus previous, TunerStatus current) { if(current == TunerStatus.ENABLED && discoveredTuner.hasTuner()) { discoveredTuner.getTuner().addTunerEventListener(this); + int row = mDiscoveredTuners.indexOf(discoveredTuner); + EventQueue.invokeLater(() -> fireTableRowsUpdated(row, row)); + return; } - int row = mDiscoveredTuners.indexOf(discoveredTuner); - EventQueue.invokeLater(() -> fireTableRowsUpdated(row, row)); + if(current == TunerStatus.REMOVED) + { + mLog.info("Tuner removal detected - stopping and removing: " + discoveredTuner); + + //Note: RSPduo only gets device removal indication if the device is streaming. There may be situation where + //master only is streaming, or slave only is streaming. Ensure we remove both devices when detected. + + //Special handling for RSPduo Tuner 1 configured as master - remove the slave tuner also + if(discoveredTuner instanceof DiscoveredRspDuoTuner1 master1 && + master1.getDeviceInfo().getDeviceSelectionMode().isMasterMode()) + { + DiscoveredTuner slave2 = getDiscoveredTuner(master1.getSlaveId()); + + if(slave2 != null) + { + removeDiscoveredTuner(slave2); + } + + removeDiscoveredTuner(discoveredTuner); + } + //Special handling for RSPduo Tuner 2 configured as slave - remove the master tuner also + else if(discoveredTuner instanceof DiscoveredRspDuoTuner2 slave2 && + slave2.getDeviceInfo().getDeviceSelectionMode().isSlaveMode()) + { + String masterId = slave2.getMasterId(); + + removeDiscoveredTuner(slave2); + + DiscoveredTuner master1 = getDiscoveredTuner(masterId); + + if(master1 != null) + { + removeDiscoveredTuner(master1); + } + } + else + { + removeDiscoveredTuner(discoveredTuner); + } + } } @Override @@ -417,25 +487,6 @@ public Object getValueAt(int rowIndex, int columnIndex) { return ""; } -// case COLUMN_TUNER_ID: -// if(discoveredTuner.hasTuner()) -// { -// return discoveredTuner.getTuner().getUniqueID(); -// } -// else -// { -// return discoveredTuner.getId(); -// } -// case COLUMN_SAMPLE_RATE: -// if(discoveredTuner.hasTuner()) -// { -// double sampleRate = discoveredTuner.getTuner().getTunerController().getSampleRate(); -// return mSampleRateFormat.format(sampleRate / 1E6D) + MHZ; -// } -// else -// { -// return ""; -// } case COLUMN_FREQUENCY: if(discoveredTuner.hasTuner()) { @@ -456,40 +507,6 @@ public Object getValueAt(int rowIndex, int columnIndex) { return ""; } -// case COLUMN_FREQUENCY_ERROR: -// if(discoveredTuner.hasTuner()) -// { -// double ppm = discoveredTuner.getTuner().getTunerController().getFrequencyCorrection(); -// return mFrequencyErrorPPMFormat.format(ppm); -// } -// else -// { -// return ""; -// } -// case COLUMN_MEASURED_FREQUENCY_ERROR: -// if(discoveredTuner.hasTuner()) -// { -// if(discoveredTuner.getTuner().getTunerController().hasMeasuredFrequencyError()) -// { -// StringBuilder sb = new StringBuilder(); -// sb.append(discoveredTuner.getTuner().getTunerController().getMeasuredFrequencyError()); -// sb.append("Hz ("); -// sb.append(mFrequencyErrorPPMFormat.format(discoveredTuner.getTuner().getTunerController().getPPMFrequencyError())); -// sb.append("ppm)"); -// return sb.toString(); -// } -// } -// return ""; -// case COLUMN_ERROR_OR_SPECTRAL_DISPLAY_NEW: -// if(discoveredTuner.hasErrorMessage()) -// { -// return discoveredTuner.getErrorMessage(); -// } -// else if(discoveredTuner.hasTuner()) -// { -// return "New"; -// } -// return ""; default: break; } diff --git a/src/main/java/io/github/dsheirer/source/tuner/ui/TunerEditor.java b/src/main/java/io/github/dsheirer/source/tuner/ui/TunerEditor.java index 0fe7106e6..aab304341 100644 --- a/src/main/java/io/github/dsheirer/source/tuner/ui/TunerEditor.java +++ b/src/main/java/io/github/dsheirer/source/tuner/ui/TunerEditor.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 @@ -35,6 +35,7 @@ import io.github.dsheirer.source.tuner.manager.TunerStatus; import io.github.dsheirer.spectrum.SpectralDisplayPanel; import io.github.dsheirer.util.SwingUtils; +import io.github.dsheirer.util.ThreadPool; import java.awt.EventQueue; import java.text.CharacterIterator; import java.text.DecimalFormat; @@ -298,8 +299,8 @@ protected JButton getNewSpectrumButton() if(tuner != null) { - mTunerManager.getDiscoveredTunerModel().broadcast(new TunerEvent(tuner, - TunerEvent.Event.REQUEST_NEW_SPECTRAL_DISPLAY)); + ThreadPool.CACHED.submit(() -> mTunerManager.getDiscoveredTunerModel().broadcast(new TunerEvent(tuner, + TunerEvent.Event.REQUEST_NEW_SPECTRAL_DISPLAY))); } }); } @@ -324,8 +325,8 @@ protected JButton getViewSpectrumButton() { SystemProperties.getInstance().set(SpectralDisplayPanel.SPECTRAL_DISPLAY_ENABLED, true); - mTunerManager.getDiscoveredTunerModel().broadcast(new TunerEvent(tuner, - TunerEvent.Event.REQUEST_MAIN_SPECTRAL_DISPLAY)); + ThreadPool.CACHED.submit(() -> mTunerManager.getDiscoveredTunerModel().broadcast(new TunerEvent(tuner, + TunerEvent.Event.REQUEST_MAIN_SPECTRAL_DISPLAY))); } }); } diff --git a/src/main/java/io/github/dsheirer/source/tuner/ui/TunerSpectralDisplayManager.java b/src/main/java/io/github/dsheirer/source/tuner/ui/TunerSpectralDisplayManager.java index 5d9653616..a85db4229 100644 --- a/src/main/java/io/github/dsheirer/source/tuner/ui/TunerSpectralDisplayManager.java +++ b/src/main/java/io/github/dsheirer/source/tuner/ui/TunerSpectralDisplayManager.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 @@ -67,20 +67,18 @@ public TunerSpectralDisplayManager(SpectralDisplayPanel panel, PlaylistManager p */ public Tuner showFirstTuner() { - if(!SystemProperties.getInstance().get(SpectralDisplayPanel.SPECTRAL_DISPLAY_ENABLED, true)) + //Ensure spectral display is enabled before selecting first tuner + if(SystemProperties.getInstance().get(SpectralDisplayPanel.SPECTRAL_DISPLAY_ENABLED, true)) { - //Spectral display is disabled, stop - return null; - } - - List availableTuners = mDiscoveredTunerModel.getAvailableTuners(); + List availableTuners = mDiscoveredTunerModel.getAvailableTuners(); - for(DiscoveredTuner discoveredTuner: availableTuners) - { - if(discoveredTuner.hasTuner()) + for(DiscoveredTuner discoveredTuner: availableTuners) { - mSpectralDisplayPanel.showTuner(discoveredTuner.getTuner()); - return discoveredTuner.getTuner(); + if(discoveredTuner.hasTuner()) + { + mSpectralDisplayPanel.showTuner(discoveredTuner.getTuner()); + return discoveredTuner.getTuner(); + } } } diff --git a/src/main/java/io/github/dsheirer/source/tuner/usb/USBTunerController.java b/src/main/java/io/github/dsheirer/source/tuner/usb/USBTunerController.java index 8f425f3ec..fa1770a61 100644 --- a/src/main/java/io/github/dsheirer/source/tuner/usb/USBTunerController.java +++ b/src/main/java/io/github/dsheirer/source/tuner/usb/USBTunerController.java @@ -32,7 +32,6 @@ import java.util.List; import java.util.concurrent.LinkedTransferQueue; import java.util.concurrent.atomic.AtomicBoolean; -import java.util.concurrent.locks.ReentrantLock; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.usb4java.Context; @@ -66,7 +65,6 @@ public abstract class USBTunerController extends TunerController private TransferManager mTransferManager = new TransferManager(); private UsbEventProcessor mEventProcessor = new UsbEventProcessor(); private AtomicBoolean mStreaming = new AtomicBoolean(); - private ReentrantLock mListenerLock = new ReentrantLock(); private boolean mRunning = false; //Troubleshooting libusb bug: https://github.com/DSheirer/sdrtrunk/issues/1253 @@ -469,7 +467,7 @@ public void addBufferListener(Listener listener) { if(isRunning()) { - mListenerLock.lock(); + mBufferListenerLock.lock(); try { @@ -484,7 +482,7 @@ public void addBufferListener(Listener listener) } finally { - mListenerLock.unlock(); + mBufferListenerLock.unlock(); } } } @@ -495,7 +493,7 @@ public void addBufferListener(Listener listener) @Override public void removeBufferListener(Listener listener) { - mListenerLock.lock(); + mBufferListenerLock.lock(); try { @@ -508,7 +506,7 @@ public void removeBufferListener(Listener listener) } finally { - mListenerLock.unlock(); + mBufferListenerLock.unlock(); } } diff --git a/src/main/java/io/github/dsheirer/spectrum/SpectralDisplayPanel.java b/src/main/java/io/github/dsheirer/spectrum/SpectralDisplayPanel.java index 4bb4acbaa..7e825d8db 100644 --- a/src/main/java/io/github/dsheirer/spectrum/SpectralDisplayPanel.java +++ b/src/main/java/io/github/dsheirer/spectrum/SpectralDisplayPanel.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 @@ -432,18 +432,22 @@ public void showTuner(Tuner tuner) if(mTuner != null) { - //Register to receive frequency change events - mTuner.getTunerController().addListener(this); - //Register the dft processor to receive samples from the tuner mTuner.getTunerController().addBufferListener(mComplexDftProcessor); - mSpectrumPanel.setSampleSize(mTuner.getSampleSize()); + //Verify that the tuner is still non-null, in case it encountered an error on starting sample stream + if(mTuner != null) + { + //Register to receive frequency change events + mTuner.getTunerController().addListener(this); + + mSpectrumPanel.setSampleSize(mTuner.getSampleSize()); - //Fire frequency and sample rate change events so that the spectrum - //and overlay panels can synchronize - process(SourceEvent.frequencyChange(null, mTuner.getTunerController().getFrequency())); - process(SourceEvent.sampleRateChange(mTuner.getTunerController().getSampleRate())); + //Fire frequency and sample rate change events so that the spectrum + //and overlay panels can synchronize + process(SourceEvent.frequencyChange(null, mTuner.getTunerController().getFrequency())); + process(SourceEvent.sampleRateChange(mTuner.getTunerController().getSampleRate())); + } } }