#2594 Use jsdrplay library for RSP tuners and remove legacy implementation from the code base. (#2595)

Co-authored-by: denny <dennis.sheirer@gmail.com>
This commit is contained in:
Denny Sheirer
2026-11-07 05:57:34 -05:00
committed by GitHub
parent 9ca4ae4d8f
commit 5912a958b3
356 changed files with 1391 additions and 51580 deletions

View File

@@ -1,229 +0,0 @@
#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

View File

@@ -1,78 +0,0 @@
#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

View File

@@ -1,55 +0,0 @@
#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

View File

@@ -1,51 +0,0 @@
#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

View File

@@ -1,22 +0,0 @@
#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

View File

@@ -1,35 +0,0 @@
#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

View File

@@ -1,40 +0,0 @@
#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

View File

@@ -1,45 +0,0 @@
#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

View File

@@ -1,21 +0,0 @@
#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

View File

@@ -1,93 +0,0 @@
#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

View File

@@ -1,230 +0,0 @@
#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.08)
// 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_DLL_QUALIFIER sdrplay_api_ErrT sdrplay_api_Open(void);
// _SDRPLAY_DLL_QUALIFIER sdrplay_api_ErrT sdrplay_api_Close(void);
// _SDRPLAY_DLL_QUALIFIER sdrplay_api_ErrT sdrplay_api_ApiVersion(float *apiVer);
// _SDRPLAY_DLL_QUALIFIER sdrplay_api_ErrT sdrplay_api_LockDeviceApi(void);
// _SDRPLAY_DLL_QUALIFIER sdrplay_api_ErrT sdrplay_api_UnlockDeviceApi(void);
// _SDRPLAY_DLL_QUALIFIER sdrplay_api_ErrT sdrplay_api_GetDevices(sdrplay_api_DeviceT *devices, unsigned int *numDevs, unsigned int maxDevs);
// _SDRPLAY_DLL_QUALIFIER sdrplay_api_ErrT sdrplay_api_SelectDevice(sdrplay_api_DeviceT *device);
// _SDRPLAY_DLL_QUALIFIER sdrplay_api_ErrT sdrplay_api_ReleaseDevice(sdrplay_api_DeviceT *device);
// _SDRPLAY_DLL_QUALIFIER const char* sdrplay_api_GetErrorString(sdrplay_api_ErrT err);
// _SDRPLAY_DLL_QUALIFIER sdrplay_api_ErrorInfoT* sdrplay_api_GetLastError(sdrplay_api_DeviceT *device);
// _SDRPLAY_DLL_QUALIFIER sdrplay_api_ErrT sdrplay_api_DisableHeartbeat(void); // Must be called before sdrplay_api_SelectDevice()
//
// // Device API function definitions
// _SDRPLAY_DLL_QUALIFIER sdrplay_api_ErrT sdrplay_api_DebugEnable(HANDLE dev, sdrplay_api_DbgLvl_t enable);
// _SDRPLAY_DLL_QUALIFIER sdrplay_api_ErrT sdrplay_api_GetDeviceParams(HANDLE dev, sdrplay_api_DeviceParamsT **deviceParams);
// _SDRPLAY_DLL_QUALIFIER sdrplay_api_ErrT sdrplay_api_Init(HANDLE dev, sdrplay_api_CallbackFnsT *callbackFns, void *cbContext);
// _SDRPLAY_DLL_QUALIFIER sdrplay_api_ErrT sdrplay_api_Uninit(HANDLE dev);
// _SDRPLAY_DLL_QUALIFIER sdrplay_api_ErrT sdrplay_api_Update(HANDLE dev, sdrplay_api_TunerSelectT tuner, sdrplay_api_ReasonForUpdateT reasonForUpdate, sdrplay_api_ReasonForUpdateExtension1T reasonForUpdateExt1);
// _SDRPLAY_DLL_QUALIFIER sdrplay_api_ErrT sdrplay_api_SwapRspDuoActiveTuner(HANDLE dev, sdrplay_api_TunerSelectT *currentTuner, sdrplay_api_RspDuo_AmPortSelectT tuner1AmPortSel);
// _SDRPLAY_DLL_QUALIFIER sdrplay_api_ErrT sdrplay_api_SwapRspDuoDualTunerModeSampleRate(HANDLE dev, double *currentSampleRate, double newSampleRate);
// _SDRPLAY_DLL_QUALIFIER 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

View File

@@ -1,78 +0,0 @@
#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

View File

@@ -1,55 +0,0 @@
#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

View File

@@ -1,51 +0,0 @@
#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

View File

@@ -1,22 +0,0 @@
#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

View File

@@ -1,35 +0,0 @@
#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

View File

@@ -1,40 +0,0 @@
#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

View File

@@ -1,45 +0,0 @@
#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

View File

@@ -1,21 +0,0 @@
#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

View File

@@ -1,93 +0,0 @@
#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

View File

@@ -1,235 +0,0 @@
#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.15)
// 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)
#define SDRPLAY_RSP1B_ID (6)
#define SDRPLAY_RSPdxR2_ID (7)
// 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,
sdrplay_api_Update_RspDuo_ResetSlaveFlags = 0x00000040,
// 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_ErrorInfoT* (*sdrplay_api_GetLastErrorByType_t)(sdrplay_api_DeviceT *device, int type, unsigned long long *time);
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_DLL_QUALIFIER sdrplay_api_ErrT sdrplay_api_Open(void);
_SDRPLAY_DLL_QUALIFIER sdrplay_api_ErrT sdrplay_api_Close(void);
_SDRPLAY_DLL_QUALIFIER sdrplay_api_ErrT sdrplay_api_ApiVersion(float *apiVer);
_SDRPLAY_DLL_QUALIFIER sdrplay_api_ErrT sdrplay_api_LockDeviceApi(void);
_SDRPLAY_DLL_QUALIFIER sdrplay_api_ErrT sdrplay_api_UnlockDeviceApi(void);
_SDRPLAY_DLL_QUALIFIER sdrplay_api_ErrT sdrplay_api_GetDevices(sdrplay_api_DeviceT *devices, unsigned int *numDevs, unsigned int maxDevs);
_SDRPLAY_DLL_QUALIFIER sdrplay_api_ErrT sdrplay_api_SelectDevice(sdrplay_api_DeviceT *device);
_SDRPLAY_DLL_QUALIFIER sdrplay_api_ErrT sdrplay_api_ReleaseDevice(sdrplay_api_DeviceT *device);
_SDRPLAY_DLL_QUALIFIER const char* sdrplay_api_GetErrorString(sdrplay_api_ErrT err);
_SDRPLAY_DLL_QUALIFIER sdrplay_api_ErrorInfoT* sdrplay_api_GetLastError(sdrplay_api_DeviceT *device);
_SDRPLAY_DLL_QUALIFIER sdrplay_api_ErrorInfoT* sdrplay_api_GetLastErrorByType(sdrplay_api_DeviceT *device, int type, unsigned long long *time);
_SDRPLAY_DLL_QUALIFIER sdrplay_api_ErrT sdrplay_api_DisableHeartbeat(void); // Must be called before sdrplay_api_SelectDevice()
// Device API function definitions
_SDRPLAY_DLL_QUALIFIER sdrplay_api_ErrT sdrplay_api_DebugEnable(HANDLE dev, sdrplay_api_DbgLvl_t enable);
_SDRPLAY_DLL_QUALIFIER sdrplay_api_ErrT sdrplay_api_GetDeviceParams(HANDLE dev, sdrplay_api_DeviceParamsT **deviceParams);
_SDRPLAY_DLL_QUALIFIER sdrplay_api_ErrT sdrplay_api_Init(HANDLE dev, sdrplay_api_CallbackFnsT *callbackFns, void *cbContext);
_SDRPLAY_DLL_QUALIFIER sdrplay_api_ErrT sdrplay_api_Uninit(HANDLE dev);
_SDRPLAY_DLL_QUALIFIER sdrplay_api_ErrT sdrplay_api_Update(HANDLE dev, sdrplay_api_TunerSelectT tuner, sdrplay_api_ReasonForUpdateT reasonForUpdate, sdrplay_api_ReasonForUpdateExtension1T reasonForUpdateExt1);
_SDRPLAY_DLL_QUALIFIER sdrplay_api_ErrT sdrplay_api_SwapRspDuoActiveTuner(HANDLE dev, sdrplay_api_TunerSelectT *currentTuner, sdrplay_api_RspDuo_AmPortSelectT tuner1AmPortSel);
_SDRPLAY_DLL_QUALIFIER sdrplay_api_ErrT sdrplay_api_SwapRspDuoDualTunerModeSampleRate(HANDLE dev, double *currentSampleRate, double newSampleRate);
_SDRPLAY_DLL_QUALIFIER 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

View File

@@ -1,79 +0,0 @@
#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

View File

@@ -1,55 +0,0 @@
#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

View File

@@ -1,51 +0,0 @@
#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

View File

@@ -1,22 +0,0 @@
#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

View File

@@ -1,35 +0,0 @@
#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

View File

@@ -1,47 +0,0 @@
#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 resetGainUpdate; // default: 0
unsigned char resetRfUpdate; // default: 0
} sdrplay_api_RspDuo_ResetSlaveFlagsT;
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_RspDuo_ResetSlaveFlagsT resetSlaveFlags;
} sdrplay_api_RspDuoTunerParamsT;
#endif //SDRPLAY_API_RSPduo_H

View File

@@ -1,46 +0,0 @@
#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

View File

@@ -1,21 +0,0 @@
#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

View File

@@ -1,93 +0,0 @@
#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

View File

@@ -129,6 +129,7 @@ dependencies {
implementation 'io.github.dsheirer:jbladerf:2.6.0' //bladeRF tuners - GitHub release, see settings.gradle
implementation 'io.github.dsheirer:jhydrasdr:1.1.4' //HydraSDR tuners - GitHub release, see settings.gradle
implementation 'io.github.dsheirer:jrtl:1.4.0.1' //RTL-SDR tuners - GitHub release, see settings.gradle
implementation 'io.github.dsheirer:jsdrplay:3.15.3' //SDRplay RSP tuners - GitHub release, see settings.gradle
implementation 'io.github.dsheirer:radio-reference-api:18.0.0'
implementation 'io.github.dsheirer:usb4java-native-libraries:1.3.3' //OSX & Windows aarch64 native libs
implementation 'io.github.dsheirer:usb4java:1.3.5' //Fork with Loader support for OSX Multi-Version
@@ -168,8 +169,7 @@ def jvmArgsWindows =
'--enable-preview', //Project Panama Vector API is still in incubator
'--enable-native-access=ALL-UNNAMED', //Suppress unsafe warnings for FFM API Foreign Memory calls
'--enable-native-access=javafx.graphics', //JDK24 - suppress restricted java.lang.System calls
'--sun-misc-unsafe-memory-access=allow', //JDK24 - suppress sun.misc.Unsafe::allocateMemory warning
'-Djava.library.path=c:\\Program Files\\SDRplay\\API\\x64'] //SDRPlay API library path
'--sun-misc-unsafe-memory-access=allow'] //JDK24 - suppress sun.misc.Unsafe::allocateMemory warning
/**
* JVM Arguments for running the application on Linux.
@@ -180,7 +180,7 @@ def jvmArgsLinux =
'--enable-preview', //Project Panama Vector & Foreign Function APIs remain in incubator
'--sun-misc-unsafe-memory-access=allow', //JDK24 - suppress sun.misc.Unsafe::allocateMemory warning
'--enable-native-access=javafx.graphics', //JDK24 - suppress restricted java.lang.System calls
'--enable-native-access=ALL-UNNAMED'] //SDRPlay API library path
'--enable-native-access=ALL-UNNAMED'] //Suppress warnings for FFM API native calls (tuner libraries)
application {
mainClass = "io.github.dsheirer.gui.SDRTrunk"

View File

@@ -41,6 +41,15 @@ dependencyResolutionManagement {
content { includeModule 'io.github.dsheirer', 'jhydrasdr' }
}
//jsdrplay is published as a GitHub release. The jar does not contain the SDRplay API native library, which
//users install separately from sdrplay.com
ivy {
url = 'https://github.com/DSheirer/jsdrplay/releases/download'
patternLayout { artifact 'v[revision]/[artifact]-[revision].[ext]' }
metadataSources { artifact() }
content { includeModule 'io.github.dsheirer', 'jsdrplay' }
}
//jBladeRF is published as a GitHub release, with the native libraries for all platforms in the jar
ivy {
url = 'https://github.com/DSheirer/jBladeRF/releases/download'

View File

@@ -56,7 +56,6 @@ import io.github.dsheirer.source.tuner.Tuner;
import io.github.dsheirer.source.tuner.TunerEvent;
import io.github.dsheirer.source.tuner.manager.DiscoveredTuner;
import io.github.dsheirer.source.tuner.manager.TunerManager;
import io.github.dsheirer.source.tuner.sdrplay.api.SDRPlayLibraryHelper;
import io.github.dsheirer.source.tuner.ui.TunerSpectralDisplayManager;
import io.github.dsheirer.spectrum.DisableSpectrumWaterfallMenuItem;
import io.github.dsheirer.spectrum.ShowTunerMenuItem;
@@ -154,14 +153,6 @@ public class SDRTrunk implements Listener<TunerEvent>
mApplicationLog = new ApplicationLog(mUserPreferences);
mApplicationLog.start();
//Note: invoke this early in the application lifecycle, before the TunerManager causes the sdrplay classes
//to be loaded since the jextract auto-generated code attempts to load the library by name and that can fail
//when the library was not installed into a normal/default location, particularly on windows OS systems.
if(SDRPlayLibraryHelper.LOADED)
{
mLog.info("SDRPlay API native library preemptively loaded");
}
mResourceMonitor = new ResourceMonitor(mUserPreferences);
ThreadPool.logSettings();

View File

@@ -22,6 +22,8 @@ package io.github.dsheirer.source.tuner;
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.sdrplay.DeviceInfo;
import io.github.dsheirer.sdrplay.RspModel;
import io.github.dsheirer.source.SourceException;
import io.github.dsheirer.source.mixer.MixerManager;
import io.github.dsheirer.source.tuner.airspy.AirspyTuner;
@@ -68,17 +70,8 @@ import io.github.dsheirer.source.tuner.rtl.r8x.r820t.R820TTunerConfiguration;
import io.github.dsheirer.source.tuner.rtl.r8x.r828d.R828DTunerConfiguration;
import io.github.dsheirer.source.tuner.sdrplay.DiscoveredRspTuner;
import io.github.dsheirer.source.tuner.sdrplay.RspTuner;
import io.github.dsheirer.source.tuner.sdrplay.api.DeviceSelectionMode;
import io.github.dsheirer.source.tuner.sdrplay.api.SDRPlayException;
import io.github.dsheirer.source.tuner.sdrplay.api.SDRplay;
import io.github.dsheirer.source.tuner.sdrplay.api.device.Device;
import io.github.dsheirer.source.tuner.sdrplay.api.device.DeviceInfo;
import io.github.dsheirer.source.tuner.sdrplay.api.device.Rsp1Device;
import io.github.dsheirer.source.tuner.sdrplay.api.device.Rsp1aDevice;
import io.github.dsheirer.source.tuner.sdrplay.api.device.Rsp1bDevice;
import io.github.dsheirer.source.tuner.sdrplay.api.device.Rsp2Device;
import io.github.dsheirer.source.tuner.sdrplay.api.device.RspDuoDevice;
import io.github.dsheirer.source.tuner.sdrplay.api.device.RspDxDevice;
import io.github.dsheirer.source.tuner.sdrplay.DeviceSelectionMode;
import io.github.dsheirer.source.tuner.sdrplay.RspException;
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;
@@ -150,7 +143,7 @@ public class TunerFactory
{
List<DiscoveredRspTuner> tuners = new ArrayList<>();
switch(deviceInfo.getDeviceType())
switch(deviceInfo.model())
{
case RSP1:
tuners.add(new DiscoveredRsp1Tuner(deviceInfo, channelizerType));
@@ -164,181 +157,119 @@ public class TunerFactory
case RSP2:
tuners.add(new DiscoveredRsp2Tuner(deviceInfo, channelizerType));
break;
case RSPdx:
case RSPdxR2:
case RSPDX:
case RSPDX_R2:
tuners.add(new DiscoveredRspDxTuner(deviceInfo, channelizerType));
break;
case RSPduo:
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));
tuners.add(new DiscoveredRspDuoTuner2(deviceInfo, channelizerType, bridge));
break;
}
break;
default:
mLog.warn("SDRPlay API returned an unknown tuner type [" + deviceInfo.getDeviceType() +
"] with serial number [" + deviceInfo.getSerialNumber() + "]");
mLog.warn("SDRPlay API returned an unknown tuner type [" + deviceInfo.model() +
"] with serial number [" + deviceInfo.serialNumber() + "]");
}
return tuners;
}
/**
* Locates the matching RSP device described by the device info object and creates an RSP tuner instance.
* Creates an RSP tuner instance for the RSP device described by the device info object. The device is selected
* from the SDRplay API when the tuner is started.
* @param deviceInfo to match
* @param selectionMode for the device (RSPduo single tuner 1 or 2, or single tuner 1 for all others).
* @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
* @throws RspException if the device is not supported
*/
public static RspTuner getRspTuner(DeviceInfo deviceInfo, ChannelizerType channelizerType,
ITunerErrorListener tunerErrorListener) throws SDRPlayException
public static RspTuner getRspTuner(DeviceInfo deviceInfo, DeviceSelectionMode selectionMode,
ChannelizerType channelizerType, ITunerErrorListener tunerErrorListener)
throws RspException
{
//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 = null;
try
switch(deviceInfo.model())
{
api = new SDRplay();
case RSP1:
Rsp1TunerController rsp1TunerController = new Rsp1TunerController(new ControlRsp1(deviceInfo), tunerErrorListener);
return new RspTuner(rsp1TunerController, tunerErrorListener, channelizerType);
case RSP1A:
Rsp1aTunerController rsp1aTunerController = new Rsp1aTunerController(new ControlRsp1a(deviceInfo), tunerErrorListener);
return new RspTuner(rsp1aTunerController, tunerErrorListener, channelizerType);
case RSP1B:
Rsp1bTunerController rsp1bTunerController = new Rsp1bTunerController(new ControlRsp1b(deviceInfo), tunerErrorListener);
return new RspTuner(rsp1bTunerController, tunerErrorListener, channelizerType);
case RSP2:
Rsp2TunerController rsp2TunerController = new Rsp2TunerController(new ControlRsp2(deviceInfo), tunerErrorListener);
return new RspTuner(rsp2TunerController, tunerErrorListener, channelizerType);
case RSPDX:
case RSPDX_R2:
RspDxTunerController rspDxTunerController = new RspDxTunerController(new ControlRspDx(deviceInfo), tunerErrorListener);
return new RspTuner(rspDxTunerController, tunerErrorListener, channelizerType);
case RSPDUO:
switch(selectionMode)
{
case SINGLE_TUNER_1:
IControlRspDuoTuner1 controlRspDuoTuner1 = new ControlRspDuoTuner1Single(deviceInfo);
RspDuoTuner1Controller rspDuoTuner1Controller = new RspDuoTuner1Controller(controlRspDuoTuner1, tunerErrorListener);
return new RspTuner(rspDuoTuner1Controller, tunerErrorListener, channelizerType);
case SINGLE_TUNER_2:
IControlRspDuoTuner2 controlRspDuoTuner2 = new ControlRspDuoTuner2Single(deviceInfo);
RspDuoTuner2Controller rspDuoTuner2Controller = new RspDuoTuner2Controller(controlRspDuoTuner2, tunerErrorListener);
return new RspTuner(rspDuoTuner2Controller, tunerErrorListener, channelizerType);
default:
throw new RspException("This method only supports RSPduo single tuner configurations");
}
default:
mLog.warn("Unrecognized SDRplay RSP Device Type: " + deviceInfo.model() + " SER#: " + deviceInfo.serialNumber());
throw new RspException("Unsupported RSP device: " + deviceInfo);
}
catch(SDRPlayException se)
{
mLog.info("Caught the exception here ...", se);
api = null;
}
if(api != null && 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 RSP1B:
if(device instanceof Rsp1bDevice rsp1bDevice)
{
IControlRsp1b controlRsp1b = new ControlRsp1b(rsp1bDevice);
Rsp1bTunerController rsp1bTunerController = new Rsp1bTunerController(controlRsp1b, tunerErrorListener);
return new RspTuner(rsp1bTunerController, 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:
case RSPdxR2:
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;
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.
* Creates an RSPduo master (tuner 1) or slave (tuner 2) tuner instance for the device described by the device
* info object. The device is selected from the SDRplay API when the tuner is started.
* @param deviceInfo to match
* @param selectionMode master tuner 1 or slave tuner 2
* @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
* @throws RspException if the device is not an RSPduo or the selection mode is not master or slave
*/
public static RspTuner getRspDuoTuner(DeviceInfo deviceInfo, ChannelizerType channelizerType,
ITunerErrorListener tunerErrorListener, MasterSlaveBridge bridge) throws SDRPlayException
public static RspTuner getRspDuoTuner(DeviceInfo deviceInfo, DeviceSelectionMode selectionMode,
ChannelizerType channelizerType, ITunerErrorListener tunerErrorListener,
MasterSlaveBridge bridge) throws RspException
{
SDRplay api = new SDRplay();
if(api.isAvailable())
if(deviceInfo.model() != RspModel.RSPDUO)
{
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 RspException("Device is not an RSPduo: " + deviceInfo);
}
throw new SDRPlayException("Unable to obtain RSPduo tuner");
switch(selectionMode)
{
case MASTER_TUNER_1:
IControlRspDuoTuner1 controlRspDuoTuner1 = new ControlRspDuoTuner1Master(deviceInfo, bridge);
RspDuoTuner1Controller rspDuoTuner1Controller = new RspDuoTuner1Controller(controlRspDuoTuner1, tunerErrorListener);
return new RspTuner(rspDuoTuner1Controller, tunerErrorListener, channelizerType);
case SLAVE_TUNER_2:
IControlRspDuoTuner2 controlRspDuoTuner2 = new ControlRspDuoTuner2Slave(deviceInfo, bridge);
RspDuoTuner2Controller rspDuoTuner2Controller = new RspDuoTuner2Controller(controlRspDuoTuner2, tunerErrorListener);
return new RspTuner(rspDuoTuner2Controller, tunerErrorListener, channelizerType);
default:
throw new RspException("This method only supports RSPduo master/slave configurations");
}
}
/**
@@ -470,7 +401,7 @@ public class TunerFactory
case RSP:
if(discoveredTuner instanceof DiscoveredRspTuner discoveredRspTuner)
{
switch(discoveredRspTuner.getDeviceType())
switch(discoveredRspTuner.getModel())
{
case RSP1:
return new Rsp1TunerEditor(userPreferences, tunerManager, discoveredRspTuner);
@@ -480,10 +411,10 @@ public class TunerFactory
return new Rsp1bTunerEditor(userPreferences, tunerManager, discoveredRspTuner);
case RSP2:
return new Rsp2TunerEditor(userPreferences, tunerManager, discoveredRspTuner);
case RSPdx:
case RSPdxR2:
case RSPDX:
case RSPDX_R2:
return new RspDxTunerEditor(userPreferences, tunerManager, discoveredRspTuner);
case RSPduo:
case RSPDUO:
if(discoveredRspTuner instanceof DiscoveredRspDuoTuner1 duoTuner1)
{
return new RspDuoTuner1Editor(userPreferences, tunerManager, duoTuner1);
@@ -499,7 +430,7 @@ public class TunerFactory
}
case UNKNOWN:
throw new IllegalArgumentException("Unrecognized RSP device type: " +
discoveredRspTuner.getDeviceType());
discoveredRspTuner.getModel());
}
}
throw new IllegalArgumentException("Unrecognized discovered RSP tuner class: " +

View File

@@ -22,6 +22,9 @@ package io.github.dsheirer.source.tuner.manager;
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.sdrplay.DeviceInfo;
import io.github.dsheirer.sdrplay.SDRplay;
import io.github.dsheirer.sdrplay.SDRplayException;
import io.github.dsheirer.source.Source;
import io.github.dsheirer.source.SourceException;
import io.github.dsheirer.source.config.SourceConfigTuner;
@@ -39,9 +42,6 @@ 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.api.SDRPlayException;
import io.github.dsheirer.source.tuner.sdrplay.api.SDRplay;
import io.github.dsheirer.source.tuner.sdrplay.api.device.DeviceInfo;
import io.github.dsheirer.source.tuner.sdrplay.rspDuo.DiscoveredRspDuoTuner1;
import io.github.dsheirer.source.tuner.ui.DiscoveredTunerModel;
import io.github.dsheirer.util.ThreadPool;
@@ -181,11 +181,7 @@ public class TunerManager implements IDiscoveredTunerStatusListener
mDiscoveredTunerModel.releaseDiscoveredTuners();
//Shutdown SDRplay API instance
if(mSDRplay != null)
{
mSDRplay.close();
mSDRplay = null;
}
closeSDRplay();
//Shutdown LibUsb
if(mLibUsbInitialized)
@@ -360,31 +356,36 @@ public class TunerManager implements IDiscoveredTunerStatusListener
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.
if(!SDRplay.isInstalled())
{
mLog.info("SDRplay API is not installed - RSP tuners are not available");
return;
}
//Note: this session stays open while RSP tuners are in use. Each RSP tuner opens its own session and the
//sessions share a single connection to the SDRplay API service, which closes when the last session closes.
try
{
mSDRplay = new SDRplay();
mSDRplay = SDRplay.open();
mLog.info("SDRplay API version [" + mSDRplay.apiVersion() + "] loaded from [" + mSDRplay.location() + "]");
}
catch(SDRPlayException se)
catch(SDRplayException se)
{
mLog.error("Couldn't load SDRPlay API");
mLog.error("Couldn't open SDRplay API - " + se.getMessage());
mSDRplay = null;
}
if(mSDRplay != null && mSDRplay.isAvailable())
if(mSDRplay != null)
{
try
{
List<DeviceInfo> deviceInfos = mSDRplay.getDeviceInfos();
List<DeviceInfo> deviceInfos = mSDRplay.devices();
mLog.info("Discovered [" + deviceInfos.size() + "] RSP devices from SDRplay API");
if(deviceInfos.isEmpty())
{
mSDRplay.close();
mSDRplay = null;
closeSDRplay();
return;
}
@@ -398,17 +399,28 @@ public class TunerManager implements IDiscoveredTunerStatusListener
}
}
}
catch(SDRPlayException se)
catch(SDRplayException se)
{
mLog.info("Unable to get list of devices from SDRplay API");
mLog.info("Unable to get list of devices from SDRplay API - " + se.getMessage());
}
}
else
}
/**
* Closes the SDRplay API discovery session.
*/
private void closeSDRplay()
{
if(mSDRplay != null)
{
if(mSDRplay != null)
try
{
mSDRplay.close();
}
catch(SDRplayException se)
{
mLog.warn("Error closing SDRplay API - " + se.getMessage());
}
mSDRplay = null;
}
@@ -459,7 +471,7 @@ public class TunerManager implements IDiscoveredTunerStatusListener
}
//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())
if(discoveredTuner instanceof DiscoveredRspDuoTuner1 rspDuoTuner1 && rspDuoTuner1.getDeviceSelectionMode().isMasterMode())
{
String id = rspDuoTuner1.getId();
id = id.replace(DiscoveredRspDuoTuner1.RSP_DUO_ID_PREFIX + "1", DiscoveredRspDuoTuner1.RSP_DUO_ID_PREFIX + "2");

View File

@@ -1,6 +1,6 @@
/*
* *****************************************************************************
* Copyright (C) 2014-2024 Dennis Sheirer
* Copyright (C) 2014-2026 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,17 +19,18 @@
package io.github.dsheirer.source.tuner.sdrplay;
import io.github.dsheirer.source.tuner.sdrplay.api.DeviceSelectionMode;
import io.github.dsheirer.source.tuner.sdrplay.api.SDRPlayException;
import io.github.dsheirer.source.tuner.sdrplay.api.Status;
import io.github.dsheirer.source.tuner.sdrplay.api.UpdateReason;
import io.github.dsheirer.source.tuner.sdrplay.api.callback.IDeviceEventListener;
import io.github.dsheirer.source.tuner.sdrplay.api.callback.IStreamListener;
import io.github.dsheirer.source.tuner.sdrplay.api.device.Device;
import io.github.dsheirer.source.tuner.sdrplay.api.device.TunerSelect;
import io.github.dsheirer.source.tuner.sdrplay.api.parameter.control.AgcMode;
import io.github.dsheirer.source.tuner.sdrplay.api.parameter.tuner.IfMode;
import io.github.dsheirer.source.tuner.sdrplay.api.parameter.tuner.LoMode;
import io.github.dsheirer.sdrplay.DeviceEvent;
import io.github.dsheirer.sdrplay.DeviceEventListener;
import io.github.dsheirer.sdrplay.DeviceInfo;
import io.github.dsheirer.sdrplay.IfMode;
import io.github.dsheirer.sdrplay.LoMode;
import io.github.dsheirer.sdrplay.RspDevice;
import io.github.dsheirer.sdrplay.RxChannel;
import io.github.dsheirer.sdrplay.SDRplay;
import io.github.dsheirer.sdrplay.SDRplayError;
import io.github.dsheirer.sdrplay.SDRplayException;
import io.github.dsheirer.sdrplay.SampleListener;
import io.github.dsheirer.sdrplay.Tuner;
import io.github.dsheirer.util.ThreadPool;
import java.lang.ref.WeakReference;
import java.util.concurrent.locks.ReentrantLock;
@@ -37,17 +38,25 @@ import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
/**
* Base RSP control implementation
* Base RSP control implementation using the jsdrplay library.
*
* The device is selected from the SDRplay API when start() is invoked and released when stop() is invoked. Each
* control opens its own jsdrplay session, which shares the single process-wide connection to the API service.
*
* @param <T> jsdrplay device type for the RSP model
*/
public abstract class ControlRsp<T extends Device> implements IControlRsp
public abstract class ControlRsp<T extends RspDevice> implements IControlRsp
{
private static final Logger mLog = LoggerFactory.getLogger(ControlRsp.class);
private T mDevice;
private final DeviceInfo mDeviceInfo;
private final Class<T> mDeviceClass;
private SDRplay mSession;
private volatile T mDevice;
protected RspSampleRate mSampleRate = RspSampleRate.RATE_8_000;
protected int mLNA;
protected int mBasebandGainReduction;
private IDeviceEventListener mDeviceEventListener;
private IStreamListener mStreamListener;
private DeviceEventListener mDeviceEventListener;
private SampleListener mSampleListener;
protected WeakReference<ITunerStatusListener> mGainOverloadReference;
//Streaming control lock and boolean status indicator. Access to the boolean indicator is protected by the lock.
@@ -56,48 +65,161 @@ public abstract class ControlRsp<T extends Device> implements IControlRsp
/**
* Constructs an instance
* @param device for the device, obtained from the API
* @param deviceInfo for the device, obtained from the API
* @param deviceClass jsdrplay device class that the API returns for this RSP model
*/
public ControlRsp(T device)
public ControlRsp(DeviceInfo deviceInfo, Class<T> deviceClass)
{
mDevice = device;
mDeviceInfo = deviceInfo;
mDeviceClass = deviceClass;
}
@Override
public TunerSelect getTunerSelect()
public DeviceInfo getDeviceInfo()
{
return TunerSelect.TUNER_1;
return mDeviceInfo;
}
@Override
public void start() throws SDRPlayException
public Tuner getSdrplayTuner()
{
return Tuner.A;
}
@Override
public DeviceSelectionMode getDeviceSelectionMode()
{
//Default device selection mode for all tuners except the RSPduo
return DeviceSelectionMode.SINGLE_TUNER_1;
}
/**
* Selects the device from the API. Subclasses override this to select the RSPduo in a specific mode.
* @param session to select from
* @param deviceInfo current device info from the API
* @return selected device
* @throws SDRplayException if the API can't select the device
*/
protected RspDevice select(SDRplay session, DeviceInfo deviceInfo) throws SDRplayException
{
return session.select(deviceInfo);
}
/**
* IF mode to use for the selected tuner.
*/
protected IfMode getIfMode()
{
return IfMode.ZERO;
}
@Override
public void start() throws RspException
{
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 Mode
getDevice().setIfMode(IfMode.IF_ZERO);
getDevice().setLoMode(LoMode.AUTO);
return;
}
else
SDRplay session = null;
try
{
throw new SDRPlayException("Unable to start - device is null");
session = SDRplay.open();
RspDevice device = select(session, getCurrentDeviceInfo(session));
if(!mDeviceClass.isInstance(device))
{
device.close();
throw new RspException("Unexpected SDRplay device class [" + device.getClass().getSimpleName() +
"] for " + mDeviceInfo);
}
//Enable automatic DC and I/Q correction and setup IF and LO mode
RxChannel channel = device.channel();
channel.setDcOffsetCorrection(true);
channel.setIqCorrection(true);
channel.setIfMode(getIfMode());
channel.setLoMode(LoMode.AUTO);
mSession = session;
mDevice = mDeviceClass.cast(device);
}
catch(SDRplayException | RuntimeException e)
{
//Closing the session also closes any device selected through it
closeQuietly(session);
throw new RspException("Unable to select " + mDeviceInfo + " - " + e.getMessage(), e);
}
catch(RspException re)
{
closeQuietly(session);
throw re;
}
}
@Override
public void stop() throws SDRPlayException
/**
* Finds the current device info from the API for this device. The API lists only devices (or RSPduo tuners)
* that are not in use and the RSPduo modes that are currently available.
* @param session to query
* @return current device info
* @throws RspException if the device is not available
*/
private DeviceInfo getCurrentDeviceInfo(SDRplay session) throws SDRplayException, RspException
{
if(hasDevice())
for(DeviceInfo deviceInfo: session.devices())
{
stopStream();
getDevice().release();
clearDevice();
if(deviceInfo.serialNumber().equals(mDeviceInfo.serialNumber()))
{
return deviceInfo;
}
}
throw new RspException("Device is not available - it may be in use by another application");
}
@Override
public void stop() throws RspException
{
stopStream();
T device = mDevice;
SDRplay session = mSession;
mDevice = null;
mSession = null;
try
{
if(device != null)
{
device.close();
}
}
catch(SDRplayException | RuntimeException e)
{
throw new RspException("Error releasing " + mDeviceInfo, e);
}
finally
{
closeQuietly(session);
}
}
/**
* Closes the session, ignoring and logging any errors.
*/
private void closeQuietly(SDRplay session)
{
if(session != null)
{
try
{
session.close();
}
catch(Exception e)
{
mLog.warn("Error closing SDRplay API session - " + e.getMessage());
}
}
}
@@ -108,27 +230,25 @@ public abstract class ControlRsp<T extends Device> implements IControlRsp
try
{
if(hasDevice())
if(!mStreaming)
{
if(!mStreaming)
{
getDevice().initStreamA(getDeviceEventListener(), getStreamListener());
mStreaming = true;
}
}
else
{
mLog.error("Unable to start RSP device sample stream - device not started");
getDevice().start(mSampleListener, mDeviceEventListener);
mStreaming = true;
}
}
catch(SDRPlayException se)
catch(RspException re)
{
if(se.getStatus() == Status.FAIL)
mLog.error("Unable to start RSP device sample stream - device not started");
}
catch(SDRplayException se)
{
if(se.error() == SDRplayError.FAIL)
{
mLog.error("Unable to start RSP streaming - device may have been unplugged - removing.");
if(mDeviceEventListener != null)
{
mDeviceEventListener.processDeviceRemoval(getTunerSelect());
mDeviceEventListener.onEvent(new DeviceEvent.DeviceRemoved(getSdrplayTuner()));
}
}
else
@@ -136,6 +256,10 @@ public abstract class ControlRsp<T extends Device> implements IControlRsp
mLog.error("Unable to initialize/start streaming for RSP device", se);
}
}
catch(RuntimeException re)
{
mLog.error("Unable to initialize/start streaming for RSP device", re);
}
finally
{
mStreamingLock.unlock();
@@ -149,14 +273,16 @@ public abstract class ControlRsp<T extends Device> implements IControlRsp
try
{
if(hasDevice() && mStreaming)
T device = mDevice;
if(mStreaming && device != null && !device.isClosed())
{
getDevice().uninitialize();
device.stop();
}
}
catch(SDRPlayException se)
catch(SDRplayException | RuntimeException e)
{
mLog.error("Unable to uninitialize/stop streaming for RSP device");
mLog.error("Unable to uninitialize/stop streaming for RSP device - " + e.getMessage());
}
finally
{
@@ -165,85 +291,124 @@ public abstract class ControlRsp<T extends Device> implements IControlRsp
}
}
@Override
public DeviceSelectionMode getDeviceSelectionMode()
{
//Default device selection mode for all tuners except the RSPduo
return DeviceSelectionMode.SINGLE_TUNER_1;
}
/**
* Device descriptor for this device
* Started device.
* @return device
* @throws RspException if the device is not started or was closed.
*/
public T getDevice()
protected T getDevice() throws RspException
{
return mDevice;
T device = mDevice;
if(device == null || device.isClosed())
{
throw new RspException("RSP device is not started");
}
return device;
}
/**
* RSP device was unplugged from USB bus. Clear the device and do not attempt any further interaction with the
* device via the API.
* RSP device was unplugged from USB bus. Close the device to release it from the API.
*/
@Override
public void deviceRemoved()
{
clearDevice();
try
{
stop();
}
catch(RspException re)
{
mLog.info("Error releasing removed RSP device " + mDeviceInfo + " - " + re.getMessage());
}
}
mStreamingLock.lock();
@Override
public boolean hasDevice()
{
T device = mDevice;
return device != null && !device.isClosed();
}
/**
* Command that is applied to the device.
*/
@FunctionalInterface
protected interface DeviceCommand<D>
{
void apply(D device) throws SDRplayException;
}
/**
* Query that is applied to the device.
*/
@FunctionalInterface
protected interface DeviceQuery<D, R>
{
R get(D device) throws SDRplayException;
}
/**
* Applies the command to the started device, converting library and API errors to RspException.
* @param description of the command for error messages
* @param command to apply
* @throws RspException if the device is not started or the command fails
*/
protected void command(String description, DeviceCommand<T> command) throws RspException
{
T device = getDevice();
try
{
mStreaming = false;
command.apply(device);
}
finally
catch(SDRplayException | RuntimeException e)
{
mStreamingLock.unlock();
throw new RspException("Unable to " + description + " - " + e.getMessage(), e);
}
}
/**
* Clears/nullifies the device. This should be invoked after stopping the device to prevent reuse.
* Applies the query to the started device, converting library and API errors to RspException.
* @param description of the query for error messages
* @param query to apply
* @return query result
* @throws RspException if the device is not started or the query fails
*/
public void clearDevice()
protected <R> R query(String description, DeviceQuery<T,R> query) throws RspException
{
mDevice = null;
}
T device = getDevice();
/**
* Indicates if this control has a non-null device.
* @return true if non-null device.
*/
public boolean hasDevice()
{
return getDevice() != null;
try
{
return query.get(device);
}
catch(SDRplayException | RuntimeException e)
{
throw new RspException("Unable to " + description + " - " + e.getMessage(), e);
}
}
/**
* Sets the sample rate
* @param sampleRate enumeration value.
* @throws SDRPlayException
* @throws RspException if the device is not started or the API rejects the sample rate
*/
@Override
public void setSampleRate(RspSampleRate sampleRate) throws SDRPlayException
public void setSampleRate(RspSampleRate sampleRate) throws RspException
{
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");
}
command("set sample rate " + sampleRate, device -> {
device.channel().setBandwidth(sampleRate.getBandwidth());
device.setSampleRate(sampleRate.getSampleRate());
device.channel().setDecimation(sampleRate.getDecimation(), true);
});
mSampleRate = sampleRate;
}
@Override
public void setGain(int lna, int gr) throws SDRPlayException
public void setGain(int lna, int gr) throws RspException
{
int lnaLimited = Math.max(lna, 0);
lnaLimited = Math.min(lnaLimited, getMaximumLNASetting());
@@ -255,15 +420,18 @@ public abstract class ControlRsp<T extends Device> implements IControlRsp
{
mLog.warn("Setting gain - adjusted LNA from [" + lna + "] to [" + lnaLimited + "] and GR from [" + gr + "] to [" + grLimited + "]");
}
getDevice().getTuner().setGain(lnaLimited, grLimited);
final int lnaState = lnaLimited;
final int gainReduction = grLimited;
command("set gain", device -> device.channel().setGain(gainReduction, lnaState));
mLNA = lnaLimited;
mBasebandGainReduction = grLimited;
}
@Override
public float getCurrentGain() throws SDRPlayException
public float getCurrentGain() throws RspException
{
return getDevice().getTuner().getGain().getGainValues().getCurrent();
return query("get current gain", device -> device.channel().gainValues().current());
}
/**
@@ -281,64 +449,43 @@ public abstract class ControlRsp<T extends Device> implements IControlRsp
mGainOverloadReference = new WeakReference<>(listener);
}
@Override
public void acknowledgePowerOverload(TunerSelect tunerSelect) throws SDRPlayException
/**
* Optional weakly referenced tuner status listener.
* @return listener or null.
*/
protected ITunerStatusListener getTunerStatusListener()
{
if(hasDevice())
{
getDevice().acknowledgePowerOverload(tunerSelect);
}
else
{
throw new SDRPlayException("Device is not initialized");
}
return mGainOverloadReference != null ? mGainOverloadReference.get() : null;
}
//Notify an optional weakly referenced, registered listener that gain overload has been acknowledged.
if(mGainOverloadReference != null)
{
ITunerStatusListener listener = mGainOverloadReference.get();
@Override
public void processPowerOverload(Tuner tuner)
{
ITunerStatusListener listener = getTunerStatusListener();
if(listener != null)
{
ThreadPool.CACHED.submit(() -> listener.notifyGainOverload(tunerSelect));
}
if(listener != null)
{
ThreadPool.CACHED.submit(() -> listener.notifyGainOverload(tuner));
}
}
@Override
public long getTunedFrequency() throws SDRPlayException
public long getTunedFrequency() throws RspException
{
if(hasDevice())
{
return getDevice().getTuner().getFrequency();
}
else
{
throw new SDRPlayException("Device is not initialized");
}
return query("get frequency", device -> (long)device.channel().frequency());
}
@Override
public void setTunedFrequency(long frequency) throws SDRPlayException
public void setTunedFrequency(long frequency) throws RspException
{
if(hasDevice())
{
getDevice().getTuner().setFrequency(frequency);
command("set frequency " + frequency, device -> device.channel().setFrequency(frequency));
//Notify an optional weakly referenced, registered listener that gain overload has been acknowledged.
if(mGainOverloadReference != null)
{
ITunerStatusListener listener = mGainOverloadReference.get();
//Notify an optional weakly referenced, registered listener that the frequency changed.
ITunerStatusListener listener = getTunerStatusListener();
if(listener != null)
{
ThreadPool.CACHED.submit(() -> listener.frequencyUpdated());
}
}
}
else
if(listener != null)
{
throw new SDRPlayException("Device is not initialized");
ThreadPool.CACHED.submit(listener::frequencyUpdated);
}
}
@@ -382,12 +529,19 @@ public abstract class ControlRsp<T extends Device> implements IControlRsp
/**
* Current IF AGC mode setting.
* @return AGC mode.
* @return AGC mode or null if the device is not started.
*/
@Override
public AgcMode getAgcMode()
public RspAgcMode getAgcMode()
{
return getDevice().getCompositeParameters().getControlAParameters().getAgc().getAgcMode();
try
{
return query("get AGC mode", device -> RspAgcMode.fromAgcMode(device.channel().agcMode()));
}
catch(RspException re)
{
return null;
}
}
/**
@@ -395,39 +549,20 @@ public abstract class ControlRsp<T extends Device> implements IControlRsp
* @param mode to set.
*/
@Override
public void setAgcMode(AgcMode mode) throws SDRPlayException
public void setAgcMode(RspAgcMode mode) throws RspException
{
getDevice().getCompositeParameters().getControlAParameters().getAgc().setAgcMode(mode);
getDevice().update(getTunerSelect(), UpdateReason.CONTROL_AGC);
command("set AGC mode " + mode, device -> device.channel().setAgc(mode.getAgcMode()));
}
/**
* Registers listeners to receive device events and sample streams.
* @param deviceEventListener to receive device events
* @param streamListener to receive sample stream and related parameters.
* @param sampleListener to receive sample stream.
*/
@Override
public void resister(IDeviceEventListener deviceEventListener, IStreamListener streamListener)
public void register(DeviceEventListener deviceEventListener, SampleListener sampleListener)
{
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;
mSampleListener = sampleListener;
}
}

View File

@@ -1,6 +1,6 @@
/*
* *****************************************************************************
* Copyright (C) 2014-2023 Dennis Sheirer
* Copyright (C) 2014-2026 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
@@ -17,47 +17,33 @@
* ****************************************************************************
*/
package io.github.dsheirer.source.tuner.sdrplay.api;
package io.github.dsheirer.source.tuner.sdrplay;
import io.github.dsheirer.source.tuner.sdrplay.api.device.RspDuoMode;
import io.github.dsheirer.source.tuner.sdrplay.api.device.TunerSelect;
import java.util.EnumSet;
import io.github.dsheirer.sdrplay.RspDuoMode;
import io.github.dsheirer.sdrplay.Tuner;
/**
* Enumeration of modes that indicate how each SDRplay RSP device can be selected
* RSP device selection mode. All RSP devices use single tuner 1, except the RSPduo which can use either tuner as a
* single tuner, or both tuners with tuner 1 as master and tuner 2 as slave.
*/
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);
SINGLE_TUNER_1("Single Tuner 1", RspDuoMode.SINGLE_TUNER, Tuner.A),
SINGLE_TUNER_2("Single Tuner 2", RspDuoMode.SINGLE_TUNER, Tuner.B),
MASTER_TUNER_1("Master - Tuner 1", RspDuoMode.MASTER, Tuner.A),
SLAVE_TUNER_2("Slave - Tuner 2", RspDuoMode.SLAVE, Tuner.B);
private String mDescription;
private RspDuoMode mRspDuoMode;
private TunerSelect mTunerSelect;
private final String mDescription;
private final RspDuoMode mRspDuoMode;
private final Tuner mTuner;
/**
* 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)
DeviceSelectionMode(String description, RspDuoMode rspDuoMode, Tuner tuner)
{
mDescription = description;
mRspDuoMode = rspDuoMode;
mTunerSelect = tunerSelect;
mTuner = tuner;
}
/**
* Set of all selection modes available for the RSPduo
*/
public static final EnumSet<DeviceSelectionMode> MASTER_MODES = EnumSet.of(MASTER_TUNER_1);
public static final EnumSet<DeviceSelectionMode> SLAVE_MODES = EnumSet.of(SLAVE_TUNER_2);
public static final EnumSet<DeviceSelectionMode> SINGLE_TUNER_MODES = EnumSet.of(SINGLE_TUNER_1, SINGLE_TUNER_2);
/**
* RSPduo mode associated with the selection mode
*/
@@ -66,12 +52,20 @@ public enum DeviceSelectionMode
return mRspDuoMode;
}
/**
* Tuner associated with the selection mode
*/
public Tuner getTuner()
{
return mTuner;
}
/**
* Indicates if this mode is designated as a master mode.
*/
public boolean isMasterMode()
{
return MASTER_MODES.contains(this);
return this == MASTER_TUNER_1;
}
/**
@@ -79,7 +73,7 @@ public enum DeviceSelectionMode
*/
public boolean isSlaveMode()
{
return SLAVE_MODES.contains(this);
return this == SLAVE_TUNER_2;
}
/**
@@ -87,15 +81,7 @@ public enum DeviceSelectionMode
*/
public boolean isSingleTunerMode()
{
return SINGLE_TUNER_MODES.contains(this);
}
/**
* Tuner(s) associated with the selection mode
*/
public TunerSelect getTunerSelect()
{
return mTunerSelect;
return this == SINGLE_TUNER_1 || this == SINGLE_TUNER_2;
}
@Override

View File

@@ -23,8 +23,8 @@ 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;
import io.github.dsheirer.source.tuner.sdrplay.api.device.DeviceInfo;
import io.github.dsheirer.source.tuner.sdrplay.api.device.DeviceType;
import io.github.dsheirer.sdrplay.DeviceInfo;
import io.github.dsheirer.sdrplay.RspModel;
/**
* Discovered SDRplay RSP tuner
@@ -32,16 +32,31 @@ import io.github.dsheirer.source.tuner.sdrplay.api.device.DeviceType;
public abstract class DiscoveredRspTuner<R extends IControlRsp> extends DiscoveredTuner
{
private final DeviceInfo mDeviceInfo;
private final DeviceSelectionMode mDeviceSelectionMode;
private final ChannelizerType mChannelizerType;
/**
* Constructs an instance
* @param deviceInfo to select the device from the API
* @param deviceSelectionMode for selecting the device from the API
* @param channelizerType to use for the tuner
*/
public DiscoveredRspTuner(DeviceInfo deviceInfo, DeviceSelectionMode deviceSelectionMode,
ChannelizerType channelizerType)
{
mDeviceInfo = deviceInfo;
mDeviceSelectionMode = deviceSelectionMode;
mChannelizerType = channelizerType;
}
/**
* Constructs an instance for single tuner 1 selection mode.
* @param deviceInfo to select the device from the API
* @param channelizerType to use for the tuner
*/
public DiscoveredRspTuner(DeviceInfo deviceInfo, ChannelizerType channelizerType)
{
mDeviceInfo = deviceInfo;
mChannelizerType = channelizerType;
this(deviceInfo, DeviceSelectionMode.SINGLE_TUNER_1, channelizerType);
}
/**
@@ -53,6 +68,14 @@ public abstract class DiscoveredRspTuner<R extends IControlRsp> extends Discover
return mDeviceInfo;
}
/**
* Device selection mode for the discovered tuner
*/
public DeviceSelectionMode getDeviceSelectionMode()
{
return mDeviceSelectionMode;
}
/**
* Channelizer type to use for the tuner
*/
@@ -68,11 +91,32 @@ public abstract class DiscoveredRspTuner<R extends IControlRsp> extends Discover
}
/**
* Type of RSP tuner device
* RSP model
*/
public DeviceType getDeviceType()
public RspModel getModel()
{
return mDeviceInfo.getDeviceType();
return mDeviceInfo.model();
}
/**
* Model name used in tuner IDs and display names. Note: these names are used for tuner configuration IDs and
* must not change.
* @param model of RSP
* @return model name
*/
public static String getModelName(RspModel model)
{
return switch(model)
{
case RSP1 -> "RSP1";
case RSP1A -> "RSP1A";
case RSP1B -> "RSP1B";
case RSP2 -> "RSP2";
case RSPDUO -> "RSPduo";
case RSPDX -> "RSPdx";
case RSPDX_R2 -> "RSPdxR2";
default -> "UNKNOWN";
};
}
/**
@@ -85,11 +129,11 @@ public abstract class DiscoveredRspTuner<R extends IControlRsp> extends Discover
{
try
{
mTuner = TunerFactory.getRspTuner(getDeviceInfo(), getChannelizerType(), this);
mTuner = TunerFactory.getRspTuner(getDeviceInfo(), getDeviceSelectionMode(), getChannelizerType(), this);
}
catch(Exception se)
{
setErrorMessage("Tuner unavailable [" + getId() + "]");
setErrorMessage("Tuner unavailable [" + getId() + "] - " + se.getMessage());
mTuner = null;
}
@@ -101,7 +145,7 @@ public abstract class DiscoveredRspTuner<R extends IControlRsp> extends Discover
}
catch(Exception se)
{
setErrorMessage("Error starting tuner [" + getId() + "]");
setErrorMessage("Error starting tuner [" + getId() + "] - " + se.getMessage());
mTuner = null;
}
}
@@ -111,7 +155,7 @@ public abstract class DiscoveredRspTuner<R extends IControlRsp> extends Discover
@Override
public String getId()
{
return getDeviceType().name() + " SER#" + getDeviceInfo().getSerialNumber();
return getModelName(getModel()) + " SER#" + getDeviceInfo().serialNumber();
}
@Override

View File

@@ -1,6 +1,6 @@
/*
* *****************************************************************************
* Copyright (C) 2014-2024 Dennis Sheirer
* Copyright (C) 2014-2026 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,55 +19,62 @@
package io.github.dsheirer.source.tuner.sdrplay;
import io.github.dsheirer.source.tuner.sdrplay.api.DeviceSelectionMode;
import io.github.dsheirer.source.tuner.sdrplay.api.SDRPlayException;
import io.github.dsheirer.source.tuner.sdrplay.api.callback.IDeviceEventListener;
import io.github.dsheirer.source.tuner.sdrplay.api.callback.IStreamListener;
import io.github.dsheirer.source.tuner.sdrplay.api.device.Device;
import io.github.dsheirer.source.tuner.sdrplay.api.device.TunerSelect;
import io.github.dsheirer.source.tuner.sdrplay.api.parameter.control.AgcMode;
import io.github.dsheirer.sdrplay.DeviceEventListener;
import io.github.dsheirer.sdrplay.DeviceInfo;
import io.github.dsheirer.sdrplay.SampleListener;
import io.github.dsheirer.sdrplay.Tuner;
/**
* Control interface for base RSP device
*/
public interface IControlRsp
{
/**
* Device selection mode for this RSP. All RSP devices use single tuner 1, except the RSPduo.
*/
DeviceSelectionMode getDeviceSelectionMode();
/**
* Device descriptor for this RSP
* @return device descriptor
* Device information (model and serial number) for this RSP, as discovered from the API.
* @return device info
*/
Device getDevice();
DeviceInfo getDeviceInfo();
/**
* 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.
* Indicates if the device is started (selected from the API) and available for control.
*/
boolean hasDevice();
/**
* Process an RSP device removal. Closes the device and releases it from the API. Note: this method must not
* be invoked from an SDRplay API callback (stream or event listener) thread.
*/
void deviceRemoved();
/**
* Selected tuner for this RSP.
* Selected tuner for this RSP: tuner A for all RSP devices, except the RSPduo.
* @return selected tuner.
*/
TunerSelect getTunerSelect();
Tuner getSdrplayTuner();
/**
* Starts the device
* Starts the device: selects the device from the API for exclusive use.
* @throws RspException if the device is not available or can't be selected
*/
void start() throws SDRPlayException;
void start() throws RspException;
/**
* Stops the device
* Stops the device: stops streaming and releases the device back to the API.
* @throws RspException if there is an error
*/
void stop() throws SDRPlayException;
void stop() throws RspException;
/**
* 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.
* @param sampleListener to receive sample stream.
*/
void resister(IDeviceEventListener deviceEventListener, IStreamListener streamListener);
void register(DeviceEventListener deviceEventListener, SampleListener sampleListener);
/**
* Starts the sample stream and delivers the samples to the registered listener.
@@ -80,22 +87,22 @@ public interface IControlRsp
void stopStream();
/**
* Callback to acknowledge a power overload event.
* @param tunerSelect identifies the tuner where the power overload is happening.
* Process a power overload detected event from the API. The jsdrplay library acknowledges the event to the API.
* @param tuner where the power overload is happening.
*/
void acknowledgePowerOverload(TunerSelect tunerSelect) throws SDRPlayException;
void processPowerOverload(Tuner tuner);
/**
* Current center tune frequency
* @return frequency in Hertz
*/
long getTunedFrequency() throws SDRPlayException;
long getTunedFrequency() throws RspException;
/**
* Sets the center tune frequency
* @param frequency in Hertz
*/
void setTunedFrequency(long frequency) throws SDRPlayException;
void setTunedFrequency(long frequency) throws RspException;
/**
* Current sample rate enumeration value
@@ -107,7 +114,7 @@ public interface IControlRsp
* Sets the sample rate.
* @param rspSampleRate enumeration value.
*/
void setSampleRate(RspSampleRate rspSampleRate) throws SDRPlayException;
void setSampleRate(RspSampleRate rspSampleRate) throws RspException;
/**
* Current sample rate value.
@@ -119,15 +126,15 @@ public interface IControlRsp
* Set the lna state and gain reduction dB values separately.
* @param lna state (varies by tuner and frequency range)
* @param basebandGainReduction setting (20-59)
* @throws SDRPlayException
* @throws RspException if the device is not started or the API rejects the setting.
*/
void setGain(int lna, int basebandGainReduction) throws SDRPlayException;
void setGain(int lna, int basebandGainReduction) throws RspException;
/**
* Current gain setting as reported by the device.
* @return gain value in decibels
*/
float getCurrentGain() throws SDRPlayException;
float getCurrentGain() throws RspException;
/**
* Current LNA gain index value
@@ -149,18 +156,18 @@ public interface IControlRsp
/**
* Current IF AGC mode setting.
* @return IF agc mode
* @return IF agc mode, or null if the device is not started.
*/
AgcMode getAgcMode();
RspAgcMode getAgcMode();
/**
* Sets the IF AGC mode
* @param mode to set.
*/
void setAgcMode(AgcMode mode) throws SDRPlayException;
void setAgcMode(RspAgcMode mode) throws RspException;
/**
* Registers a listener to receive notifications of gain overload.
* Registers a listener to receive notifications of gain overload and frequency changes.
* @param listener to register
*/
void setGainOverloadListener(ITunerStatusListener listener);

View File

@@ -19,7 +19,7 @@
package io.github.dsheirer.source.tuner.sdrplay;
import io.github.dsheirer.source.tuner.sdrplay.api.device.TunerSelect;
import io.github.dsheirer.sdrplay.Tuner;
/**
* Listener interface to receive notifications of gain overload in the RSP device.
@@ -28,9 +28,9 @@ public interface ITunerStatusListener
{
/**
* Notify that there is a gain overload event in the specified tuner
* @param tunerSelect to id the tuner
* @param tuner to id the tuner
*/
void notifyGainOverload(TunerSelect tunerSelect);
void notifyGainOverload(Tuner tuner);
/**
* Notify that the tuner's frequency has changed.

View File

@@ -1,6 +1,6 @@
/*
* *****************************************************************************
* Copyright (C) 2014-2023 Dennis Sheirer
* Copyright (C) 2014-2026 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
@@ -17,51 +17,43 @@
* ****************************************************************************
*/
package io.github.dsheirer.source.tuner.sdrplay.api.parameter.tuner;
package io.github.dsheirer.source.tuner.sdrplay;
import io.github.dsheirer.source.tuner.sdrplay.api.v3_07.sdrplay_api_h;
import io.github.dsheirer.sdrplay.AgcMode;
/**
* RSP-2 AM Port
* IF AGC mode for RSP tuners. Entry names are persisted in tuner configurations.
*/
public enum Rsp2AmPort
public enum RspAgcMode
{
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");
DISABLE(AgcMode.DISABLED, "DISABLE"),
ENABLE(AgcMode.CONTROL_ENABLED, "ENABLE");
private int mValue;
private String mDescription;
private final AgcMode mAgcMode;
private final String mDescription;
Rsp2AmPort(int value, String description)
RspAgcMode(AgcMode agcMode, String description)
{
mValue = value;
mAgcMode = agcMode;
mDescription = description;
}
/**
* Numeric value
* SDRplay API AGC mode for this entry
*/
public int getValue()
public AgcMode getAgcMode()
{
return mValue;
return mAgcMode;
}
/**
* Lookup the entry from a return code
* @param value to lookup
* @return entry or PORT 2 if the code is not recognized
* Lookup the entry that matches the SDRplay API AGC mode.
* @param agcMode from the API
* @return ENABLE for any of the enabled AGC modes, or DISABLE
*/
public static Rsp2AmPort fromValue(int value)
public static RspAgcMode fromAgcMode(AgcMode agcMode)
{
for(Rsp2AmPort status: Rsp2AmPort.values())
{
if(status.getValue() == value)
{
return status;
}
}
return PORT_2_SMA;
return agcMode == null || agcMode == AgcMode.DISABLED ? DISABLE : ENABLE;
}
@Override

View File

@@ -1,6 +1,6 @@
/*
* *****************************************************************************
* Copyright (C) 2014-2024 Dennis Sheirer
* Copyright (C) 2014-2026 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
@@ -17,21 +17,30 @@
* ****************************************************************************
*/
package io.github.dsheirer.source.tuner.sdrplay.api.parameter.device;
import java.lang.foreign.MemorySegment;
package io.github.dsheirer.source.tuner.sdrplay;
/**
* RSP-1 Device Parameters structure
* Error while controlling an SDRplay RSP device. Wraps errors reported by the jsdrplay library and the SDRplay API,
* and errors for a device that is not started.
*/
public class Rsp1DeviceParameters extends DeviceParameters
public class RspException extends Exception
{
/**
* Constructs an instance
* @param devParams for an allocated sdrplay_api_DevParamsT structure
* @param message describing the error
*/
public Rsp1DeviceParameters(MemorySegment devParams)
public RspException(String message)
{
super(devParams);
super(message);
}
/**
* Constructs an instance
* @param message describing the error
* @param cause of the error
*/
public RspException(String message, Throwable cause)
{
super(message, cause);
}
}

View File

@@ -19,8 +19,7 @@
package io.github.dsheirer.source.tuner.sdrplay;
import io.github.dsheirer.source.tuner.sdrplay.api.device.Decimate;
import io.github.dsheirer.source.tuner.sdrplay.api.parameter.tuner.Bandwidth;
import io.github.dsheirer.sdrplay.Bandwidth;
import java.util.EnumSet;
/**
@@ -30,35 +29,35 @@ import java.util.EnumSet;
*/
public enum RspSampleRate
{
RATE_0_250(8_000_000, 16_000, Bandwidth.BW_0_300, Decimate.X32, "0.250 MHz (0.234 usable)"),
RATE_0_500(8_000_000, 24_000, Bandwidth.BW_0_600, Decimate.X16, "0.500 MHz (0.476 usable)"),
RATE_1_000(8_000_000, 100_000, Bandwidth.BW_1_536, Decimate.X8, "1.000 MHz (0.900 usable)"),
RATE_1_500(6_000_000, 140_000, Bandwidth.BW_1_536, Decimate.X4, "1.500 MHz (1.360 usable)"),
RATE_2_048(8_192_000, 248_000, Bandwidth.BW_1_536, Decimate.X4, "2.048 MHz (1.800 usable)"),
RATE_3_000(6_000_000, 300_000, Bandwidth.BW_5_000, Decimate.X2, "3.000 MHz (2.700 usable)"),
RATE_4_000(8_000_000, 340_000, Bandwidth.BW_5_000, Decimate.X2, "4.000 MHz (3.560 usable)"),
RATE_5_000(5_000_000, 880_000, Bandwidth.BW_5_000, Decimate.X1, "5.000 MHz (4.120 usable)"),
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)"),
RATE_0_250(8_000_000, 16_000, Bandwidth.KHZ_300, 32, "0.250 MHz (0.234 usable)"),
RATE_0_500(8_000_000, 24_000, Bandwidth.KHZ_600, 16, "0.500 MHz (0.476 usable)"),
RATE_1_000(8_000_000, 100_000, Bandwidth.KHZ_1536, 8, "1.000 MHz (0.900 usable)"),
RATE_1_500(6_000_000, 140_000, Bandwidth.KHZ_1536, 4, "1.500 MHz (1.360 usable)"),
RATE_2_048(8_192_000, 248_000, Bandwidth.KHZ_1536, 4, "2.048 MHz (1.800 usable)"),
RATE_3_000(6_000_000, 300_000, Bandwidth.MHZ_5, 2, "3.000 MHz (2.700 usable)"),
RATE_4_000(8_000_000, 340_000, Bandwidth.MHZ_5, 2, "4.000 MHz (3.560 usable)"),
RATE_5_000(5_000_000, 880_000, Bandwidth.MHZ_5, 1, "5.000 MHz (4.120 usable)"),
RATE_6_000(6_000_000, 800_000, Bandwidth.MHZ_6, 1, "6.000 MHz (5.200 usable)"),
RATE_7_000(7_000_000, 1_040_000, Bandwidth.MHZ_7, 1, "7.000 MHz (5.960 usable)"),
RATE_8_000(8_000_000, 1_060_000, Bandwidth.MHZ_8, 1, "8.000 MHz (6.940 usable)"),
RATE_9_000(9_000_000, 1_620_000, Bandwidth.MHZ_8, 1, "9.000 MHz (7.380 usable)"),
RATE_10_000(10_000_000, 1_500_000, Bandwidth.MHZ_8, 1, "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)"),
DUO_RATE_0_500(8_000_000, 50_000, Bandwidth.MHZ_8, 4, "0.500 MHz (0.450 usable)"),
DUO_RATE_1_000(8_000_000, 50_000, Bandwidth.MHZ_8, 2, "1.000 MHz (0.950 usable)"),
DUO_RATE_1_500(6_000_000, 0, Bandwidth.MHZ_6, 1, "1.500 MHz (1.500 usable)"),
DUO_RATE_2_000(8_000_000, 0, Bandwidth.MHZ_8, 1, "2.000 MHz (2.000 usable)"),
UNDEFINED(0, 0, Bandwidth.UNDEFINED, Decimate.X1, "UNDEFINED");
UNDEFINED(0, 0, Bandwidth.UNDEFINED, 1, "UNDEFINED");
private final long mSampleRate;
private final long mUnusable;
private final Bandwidth mBandwidth;
private final Decimate mDecimation;
private final int mDecimation;
private final String mDescription;
/**
@@ -66,10 +65,11 @@ public enum RspSampleRate
* @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 decimation factor (1, 2, 4, 8, 16 or 32) 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)
RspSampleRate(long sampleRate, long unusable, Bandwidth bandwidth, int decimation, String description)
{
mSampleRate = sampleRate;
mUnusable = unusable;
@@ -84,9 +84,18 @@ public enum RspSampleRate
public static final EnumSet<RspSampleRate> SINGLE_TUNER_SAMPLE_RATES = EnumSet.range(RATE_0_250, RATE_10_000);
/**
* RSPduo dual-tuner mode sample rates
* RSPduo dual-tuner mode sample rates. Note: DUO_RATE_1_500 is not supported. It requires a 6 MHz master sample
* rate, which is fixed when the master tuner is selected, and the SDRplay API rejects changing it before streaming
* starts or while the slave tuner is streaming. The entry is retained so that existing tuner configurations load,
* and the RSPduo tuner controllers replace it with the default dual tuner sample rate.
*/
public static final EnumSet<RspSampleRate> DUAL_TUNER_SAMPLE_RATES = EnumSet.range(DUO_RATE_0_500, DUO_RATE_2_000);
public static final EnumSet<RspSampleRate> DUAL_TUNER_SAMPLE_RATES = EnumSet.of(DUO_RATE_0_500, DUO_RATE_1_000,
DUO_RATE_2_000);
/**
* All RSPduo dual-tuner mode sample rate entries, including unsupported entries.
*/
private static final EnumSet<RspSampleRate> DUAL_TUNER_ENTRIES = EnumSet.range(DUO_RATE_0_500, DUO_RATE_2_000);
/**
* Sample Rate
@@ -116,7 +125,7 @@ public enum RspSampleRate
*/
public boolean isDualTunerSampleRate()
{
return DUAL_TUNER_SAMPLE_RATES.contains(this);
return DUAL_TUNER_ENTRIES.contains(this);
}
/**
@@ -125,14 +134,21 @@ public enum RspSampleRate
*/
public int getSampleSize()
{
return mDecimation.getSampleSize();
//Effective sample size by decimation factor (same values as the legacy SDRplay API wrapper)
return switch(mDecimation)
{
case 4, 8 -> 17;
case 16 -> 18;
case 32 -> 20;
default -> 16;
};
}
/**
* Decimation rate to be applied against sample rate.
* @return decimation value
* Decimation factor to be applied against sample rate.
* @return decimation factor: 1 (none), 2, 4, 8, 16 or 32
*/
public Decimate getDecimation()
public int getDecimation()
{
return mDecimation;
}
@@ -148,11 +164,11 @@ public enum RspSampleRate
{
//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;
return getSampleRate() / getDecimation() / 4;
}
else
{
return getSampleRate() / getDecimation().getValue();
return getSampleRate() / getDecimation();
}
}

View File

@@ -20,6 +20,7 @@
package io.github.dsheirer.source.tuner.sdrplay;
import io.github.dsheirer.preference.source.ChannelizerType;
import io.github.dsheirer.sdrplay.DeviceInfo;
import io.github.dsheirer.source.tuner.ITunerErrorListener;
import io.github.dsheirer.source.tuner.Tuner;
import io.github.dsheirer.source.tuner.TunerClass;
@@ -52,7 +53,7 @@ public class RspTuner extends Tuner
@Override
public String getUniqueID()
{
return getRspTunerController().getControlRsp().getDevice().getSerialNumber();
return getRspTunerController().getControlRsp().getDeviceInfo().serialNumber();
}
@Override
@@ -72,28 +73,20 @@ public class RspTuner extends Tuner
@Override
public String getPreferredName()
{
if(getRspTunerController().getControlRsp() instanceof IControlRspDuoTuner1 &&
getRspTunerController().getControlRsp().getDevice() != null)
IControlRsp controlRsp = getRspTunerController().getControlRsp();
DeviceInfo deviceInfo = controlRsp.getDeviceInfo();
String name = DiscoveredRspTuner.getModelName(deviceInfo.model()) + " SER:" + deviceInfo.serialNumber();
if(controlRsp instanceof IControlRspDuoTuner1)
{
return getRspTunerController().getControlRsp().getDevice().getDeviceType() +
" SER:" + getRspTunerController().getControlRsp().getDevice().getSerialNumber() + " Tuner 1";
return name + " Tuner 1";
}
else if(getRspTunerController().getControlRsp() instanceof IControlRspDuoTuner2 &&
getRspTunerController().getControlRsp().getDevice() != null)
else if(controlRsp instanceof IControlRspDuoTuner2)
{
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";
return name + " Tuner 2";
}
return name;
}
@Override

View File

@@ -23,7 +23,6 @@ import com.fasterxml.jackson.annotation.JsonSubTypes;
import com.fasterxml.jackson.annotation.JsonTypeInfo;
import com.fasterxml.jackson.dataformat.xml.annotation.JacksonXmlProperty;
import io.github.dsheirer.source.tuner.configuration.TunerConfiguration;
import io.github.dsheirer.source.tuner.sdrplay.api.parameter.control.AgcMode;
import io.github.dsheirer.source.tuner.sdrplay.rsp1.Rsp1TunerConfiguration;
import io.github.dsheirer.source.tuner.sdrplay.rsp1a.Rsp1aTunerConfiguration;
import io.github.dsheirer.source.tuner.sdrplay.rsp1b.Rsp1bTunerConfiguration;
@@ -53,7 +52,7 @@ public abstract class RspTunerConfiguration extends TunerConfiguration
private RspSampleRate mRspSampleRate = DEFAULT_SINGLE_TUNER_SAMPLE_RATE;
private int mLNA = 0;
private int mBasebandGainReduction = 50;
private AgcMode mAgcMode = AgcMode.ENABLE;
private RspAgcMode mAgcMode = RspAgcMode.ENABLE;
/**
* JAXB Constructor
@@ -132,7 +131,7 @@ public abstract class RspTunerConfiguration extends TunerConfiguration
* @return mode
*/
@JacksonXmlProperty(isAttribute = true, localName = "agcMode")
public AgcMode getAgcMode()
public RspAgcMode getAgcMode()
{
return mAgcMode;
}
@@ -141,7 +140,7 @@ public abstract class RspTunerConfiguration extends TunerConfiguration
* Sets the IF AGC mode
* @param mode to set
*/
public void setAgcMode(AgcMode mode)
public void setAgcMode(RspAgcMode mode)
{
mAgcMode = mode;
}

View File

@@ -25,15 +25,12 @@ 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 io.github.dsheirer.source.tuner.sdrplay.api.SDRPlayException;
import io.github.dsheirer.source.tuner.sdrplay.api.callback.IDeviceEventListener;
import io.github.dsheirer.source.tuner.sdrplay.api.callback.IStreamListener;
import io.github.dsheirer.source.tuner.sdrplay.api.callback.StreamCallbackParameters;
import io.github.dsheirer.source.tuner.sdrplay.api.device.TunerSelect;
import io.github.dsheirer.source.tuner.sdrplay.api.parameter.event.EventType;
import io.github.dsheirer.source.tuner.sdrplay.api.parameter.event.GainCallbackParameters;
import io.github.dsheirer.source.tuner.sdrplay.api.parameter.event.PowerOverloadCallbackParameters;
import io.github.dsheirer.source.tuner.sdrplay.api.parameter.event.RspDuoModeCallbackParameters;
import io.github.dsheirer.sdrplay.DeviceEvent;
import io.github.dsheirer.sdrplay.DeviceEventListener;
import io.github.dsheirer.sdrplay.SampleBuffer;
import io.github.dsheirer.sdrplay.SampleListener;
import io.github.dsheirer.sdrplay.Tuner;
import io.github.dsheirer.util.ThreadPool;
import java.util.List;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@@ -42,7 +39,7 @@ import org.slf4j.LoggerFactory;
* Abstract/Base RSP tuner controller
*/
public abstract class RspTunerController<I extends IControlRsp> extends TunerController
implements IDeviceEventListener, IStreamListener
implements DeviceEventListener, SampleListener
{
private static final Logger mLog = LoggerFactory.getLogger(RspTunerController.class);
protected static final long MINIMUM_TUNABLE_FREQUENCY_HZ = 100_000;
@@ -64,7 +61,7 @@ public abstract class RspTunerController<I extends IControlRsp> extends TunerCon
mControlRsp = controlRsp;
//Register this controller to receive device events and sample streams when startStream() is invoked.
mControlRsp.resister(this, this);
mControlRsp.register(this, this);
setMinimumFrequency(MINIMUM_TUNABLE_FREQUENCY_HZ);
setMaximumFrequency(MAXIMUM_TUNABLE_FREQUENCY_HZ);
@@ -84,7 +81,7 @@ public abstract class RspTunerController<I extends IControlRsp> extends TunerCon
{
setSampleRate(rtc.getSampleRate());
}
catch(SDRPlayException se)
catch(RspException se)
{
mLog.error("Error setting RSP sample rate to " + rtc.getSampleRate(), se);
}
@@ -95,7 +92,7 @@ public abstract class RspTunerController<I extends IControlRsp> extends TunerCon
int gr = rtc.getBasebandGainReduction();
getControlRsp().setGain(lna, gr);
}
catch(SDRPlayException se)
catch(RspException se)
{
mLog.error("Error setting RSP LNA [" + rtc.getLNA() + "] and baseband [" + rtc.getBasebandGainReduction() + "]");
}
@@ -110,41 +107,54 @@ public abstract class RspTunerController<I extends IControlRsp> extends TunerCon
return mControlRsp;
}
@Override
public TunerSelect getTunerSelect()
/**
* SDRplay tuner (A or B) for this controller.
*/
public Tuner getSdrplayTuner()
{
return mControlRsp.getTunerSelect();
return mControlRsp.getSdrplayTuner();
}
/**
* Processes samples from the API. Invoked on the API's stream callback thread.
* @param sampleBuffer containing the samples, valid only until this method returns.
*/
@Override
public void processStream(short[] inphase, short[] quadrature,
StreamCallbackParameters parameters, boolean reset)
public void onSamples(SampleBuffer sampleBuffer)
{
//The native buffer factory repackages the samples into buffers with the largest power-of-2 length that is
//smaller than the incoming buffer length and no smaller than 128 to ensure that down-stream vector optimized
//The native buffer factory repackages the samples into buffers with the smallest power-of-2 length that is
//no smaller than the incoming buffer length (minimum 128) to ensure that down-stream vector optimized
//functions can process the data.
List<RspNativeBuffer> buffers = mNativeBufferFactory.get(inphase, quadrature, System.currentTimeMillis());
List<RspNativeBuffer> buffers = mNativeBufferFactory.get(sampleBuffer.copyI(), sampleBuffer.copyQ(),
System.currentTimeMillis());
for(RspNativeBuffer buffer: buffers)
{
mNativeBufferBroadcaster.broadcast(buffer);
}
}
if(reset)
/**
* Processes device events from the API. Invoked on the API's event callback thread. The jsdrplay library
* acknowledges power overload events to the API before invoking this method.
* @param event from the API
*/
@Override
public void onEvent(DeviceEvent event)
{
switch(event)
{
// 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");
case DeviceEvent.PowerOverload overload ->
{
if(overload.overloaded())
{
getControlRsp().processPowerOverload(overload.tuner());
}
}
//The device can't be closed from an API callback thread, so process the removal on another thread
case DeviceEvent.DeviceRemoved removed -> ThreadPool.CACHED.submit(() -> processDeviceRemoval(removed.tuner()));
case DeviceEvent.DeviceFailure failure -> ThreadPool.CACHED.submit(() -> processDeviceRemoval(failure.tuner()));
default -> {} //Ignore gain change and RSPduo mode change events
}
}
@@ -159,9 +169,9 @@ public abstract class RspTunerController<I extends IControlRsp> extends TunerCon
{
mControlRsp.start();
}
catch(SDRPlayException se)
catch(RspException se)
{
throw new SourceException("Unable to select tuner - in use");
throw new SourceException("Unable to select tuner - " + se.getMessage(), se);
}
}
@@ -172,7 +182,7 @@ public abstract class RspTunerController<I extends IControlRsp> extends TunerCon
{
mControlRsp.stop();
}
catch(SDRPlayException se)
catch(RspException se)
{
mLog.error("Error releasing RSP tuner device", se);
}
@@ -238,7 +248,7 @@ public abstract class RspTunerController<I extends IControlRsp> extends TunerCon
{
return getControlRsp().getTunedFrequency();
}
catch(SDRPlayException se)
catch(RspException se)
{
throw new SourceException("Error setting tuned frequency", se);
}
@@ -256,7 +266,7 @@ public abstract class RspTunerController<I extends IControlRsp> extends TunerCon
{
getControlRsp().setTunedFrequency(frequency);
}
catch(SDRPlayException se)
catch(RspException se)
{
throw new SourceException("Unable to set center frequency [" + frequency + "]", se);
}
@@ -265,9 +275,9 @@ public abstract class RspTunerController<I extends IControlRsp> extends TunerCon
/**
* Sets the sample rate
* @param rspSampleRate to apply
* @throws SDRPlayException if there is an error
* @throws RspException if there is an error
*/
public void setSampleRate(RspSampleRate rspSampleRate) throws SDRPlayException
public void setSampleRate(RspSampleRate rspSampleRate) throws RspException
{
getControlRsp().setSampleRate(rspSampleRate);
@@ -297,34 +307,14 @@ public abstract class RspTunerController<I extends IControlRsp> extends TunerCon
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)
/**
* Processes a device removal (or failure) event.
* @param tuner that was removed
*/
public void processDeviceRemoval(Tuner tuner)
{
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
mLog.info("Processing device removal for tuner [" + tuner + "] controller class [" + getClass().getSimpleName() + "]");
//Command the control RSP to release the device so that we cease all attempts to control the device via the API
if(getControlRsp() != null)
{
getControlRsp().deviceRemoved();

View File

@@ -21,9 +21,7 @@ package io.github.dsheirer.source.tuner.sdrplay;
import io.github.dsheirer.preference.UserPreferences;
import io.github.dsheirer.source.tuner.manager.TunerManager;
import io.github.dsheirer.source.tuner.sdrplay.api.SDRPlayException;
import io.github.dsheirer.source.tuner.sdrplay.api.device.TunerSelect;
import io.github.dsheirer.source.tuner.sdrplay.api.parameter.control.AgcMode;
import io.github.dsheirer.sdrplay.Tuner;
import io.github.dsheirer.source.tuner.ui.TunerEditor;
import io.github.dsheirer.util.ThreadPool;
import java.awt.Color;
@@ -133,10 +131,10 @@ public abstract class RspTunerEditor<C extends RspTunerConfiguration> extends Tu
{
try
{
getTunerController().getControlRsp().setAgcMode(mAgcButton.isSelected() ? AgcMode.ENABLE : AgcMode.DISABLE);
getTunerController().getControlRsp().setAgcMode(mAgcButton.isSelected() ? RspAgcMode.ENABLE : RspAgcMode.DISABLE);
updateGainLabel();
}
catch(SDRPlayException se)
catch(RspException se)
{
mLog.error("Error setting AGC mode on RSP device");
}
@@ -175,9 +173,9 @@ public abstract class RspTunerEditor<C extends RspTunerConfiguration> extends Tu
}
@Override
public void notifyGainOverload(TunerSelect tunerSelect)
public void notifyGainOverload(Tuner tuner)
{
if(hasTuner() && getTuner().getRspTunerController().getTunerSelect() == tunerSelect)
if(hasTuner() && getTuner().getRspTunerController().getSdrplayTuner() == tuner)
{
//Set overload alert
EventQueue.invokeLater(() -> setGainOverloadAlert(true));
@@ -291,7 +289,7 @@ public abstract class RspTunerEditor<C extends RspTunerConfiguration> extends Tu
float currentGain = getTunerController().getControlRsp().getCurrentGain();
getGainValueLabel().setText((int)currentGain + " dB");
}
catch(SDRPlayException se)
catch(RspException se)
{
mLog.error("Error accessing current gain value from RSP tuner", se);
}

View File

@@ -1,87 +0,0 @@
SDRplay API
All source class files are auto-created from sdrplay api header files using JDK 22 jextract tool:
Version 3.07 is the oldest supported version. Versions 3.08 through 3.14 are all functionally equivalent and
versions 3.15+ are functionally equivalent.
We use the jextract tool to generate java source files from the API include files that are located in
the /artifacts directory.
With each new JDK release where they change something about the Foreign Function api, we have to regenerate
the java source files. My approach is to generate the java files into the source code directories alongside
the existing source files and then delete the existing files and rename the parent version package to the
same as was used by the existing classes so that we don't cause problems in any of the derivative classes.
If you need to find the SDRPlay API header/include files:
1. Install the sdrplay api
2. On Linux, headers are located here: /usr/local/include/*.h
3. On Windows, headers are located here: c:\Program Files\SDRPlay\api
Generate Source Files from SDRPlay API Headers
- Download latest jextract tool and alias the jextract command.
- cd into the (project)/jSDRplay/sdrplay-api/src/main/java/ directory
Note: each version is auto-generated with a _1 suffix to avoid overwriting the existing implementation. Then,
you can just delete the original implementation and rename the suffixed versions to remove the _1. Then,
resolve any import or syntax errors to integrate the new auto-gen code into the existing codebase.
Version 3.07
- cd into the same folder where the v3.07 header files are located.
- jextract -t io.github.dsheirer.source.tuner.sdrplay.api.v3_07 -l sdrplay_api --output ~/IdeaProjects/sdrtrunk/src/main/java/io/github/dsheirer/source/tuner/sdrplay/api/v3_07_1/ sdrplay_api.h
Version 3.08
- cd into the same folder where the v3.08 header files are located.
- jextract -t io.github.dsheirer.source.tuner.sdrplay.api.v3_08 -l sdrplay_api --output ~/IdeaProjects/sdrtrunk/src/main/java/io/github/dsheirer/source/tuner/sdrplay/api/v3_08_1/ sdrplay_api.h
Version 3.15 - Adds support for RSP dx2
- cd into the same folder where the v3.15 header files are located.
- jextract -t io.github.dsheirer.source.tuner.sdrplay.api.v3_15 -l sdrplay_api --output ~/IdeaProjects/sdrtrunk/src/main/java/io/github/dsheirer/source/tuner/sdrplay/api/v3_15_1/ sdrplay_api.h
As a final step, delete the original api version branches and rename each of the new api version branches to remove the _1 suffix.
Code Modifications: for each version, modify the sdrplay_api_h.java class to wrap the SYMBOL_LOOKUP variable using the
following changes, so that the code doesn't throw an error on systems that don't have the API installed:
//jextract auto-generated code modified to wrap with exception handler for systems that don't have the library
static SymbolLookup SYMBOL_LOOKUP;
static
{
try
{
SYMBOL_LOOKUP = SymbolLookup.libraryLookup(System.mapLibraryName("sdrplay_api"), LIBRARY_ARENA)
.or(SymbolLookup.loaderLookup())
.or(Linker.nativeLinker().defaultLookup());
}
catch(Exception e)
{
if(SDRPlayLibraryHelper.LOADED_FROM_PATH)
{
try
{
SYMBOL_LOOKUP = SymbolLookup.libraryLookup(SDRPlayLibraryHelper.LIBRARY_PATH, LIBRARY_ARENA)
.or(SymbolLookup.loaderLookup())
.or(Linker.nativeLinker().defaultLookup());
}
catch(Exception e2)
{
SYMBOL_LOOKUP = null;
}
}
else
{
SYMBOL_LOOKUP = null;
}
}
}
... and add null checking to the findOrThrow() method ...
if(SYMBOL_LOOKUP == null)
{
throw new UnsatisfiedLinkError("unresolved symbol:" + symbol);
}
IntelliJ setup
1. Run configuration
2. JVM Option: --enable-native-access=ALL-UNNAMED

View File

@@ -1,63 +0,0 @@
/*
* *****************************************************************************
* 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 <http://www.gnu.org/licenses/>
* ****************************************************************************
*/
package io.github.dsheirer.source.tuner.sdrplay.api;
/**
* 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;
}
}

View File

@@ -1,121 +0,0 @@
/*
* *****************************************************************************
* Copyright (C) 2014-2024 Dennis Sheirer
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>
* ****************************************************************************
*/
package io.github.dsheirer.source.tuner.sdrplay.api;
import java.nio.file.Files;
import java.nio.file.Path;
import org.apache.commons.lang3.SystemUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
/**
* Helper utility to load the SDRPlay API native library into the VM.
*
* Note: the jextract auto-generated code attempts to load the native library by simple library name without any path
* information. On Windows this can fail because the API library is not installed in the normal Windows library location
* and for some reason the system library VM option with the specific location that is passed in as an argument on
* the command line doesn't help the system loader to resolve the library path. So, we preemptively load the library
* here.
*/
public class SDRPlayLibraryHelper
{
private static final Logger mLog = LoggerFactory.getLogger(SDRPlayLibraryHelper.class);
private static final String SDRPLAY_API_LIBRARY_NAME = "sdrplay_api";
private static final String SDRPLAY_API_PATH_LINUX = "/usr/local/lib/libsdrplay_api.so";
private static final String SDRPLAY_API_PATH_MAC_OS = "/usr/local/lib/libsdrplay_api.dylib";
private static final String SDRPLAY_API_PATH_MAC_OS_ALTERNATE = "/usr/local/lib/libsdrplay_api.so";
private static final String SDRPLAY_API_PATH_WINDOWS = System.getenv("ProgramFiles") +
"\\SDRplay\\API\\x64\\" + SDRPLAY_API_LIBRARY_NAME;
public static final boolean LOADED;
public static final boolean LOADED_FROM_PATH;
public static final Path LIBRARY_PATH = Path.of(getSDRplayLibraryPath());
static
{
boolean loaded = false;
boolean loadedFromPath = false;
try
{
System.loadLibrary(SDRPLAY_API_LIBRARY_NAME);
mLog.info("SDRPLay API library loaded by name [" + SDRPLAY_API_LIBRARY_NAME + "]");
loaded = true;
}
catch(Throwable t)
{
String libraryPath = getSDRplayLibraryPath();
Path path = Path.of(libraryPath);
boolean exists = Files.exists(path);
if(exists)
{
try
{
System.load(libraryPath);
mLog.info("SDRPLay API library loaded by path [" + libraryPath + "]");
loaded = true;
loadedFromPath = true;
}
catch(Throwable t2)
{
mLog.info("SDRPlay API native library not found at " + libraryPath);
}
}
else
{
mLog.info("SDRPlay API native library not found at: " + libraryPath);
}
}
LOADED = loaded;
LOADED_FROM_PATH = loadedFromPath;
}
/**
* 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)
{
//API versions 3.14 and earlier used a (.so) extension and 3.15 and later use the (.dylib) extension
if(Files.exists(Path.of(SDRPLAY_API_PATH_MAC_OS)))
{
return SDRPLAY_API_PATH_MAC_OS;
}
else
{
return SDRPLAY_API_PATH_MAC_OS_ALTERNATE;
}
}
mLog.error("Unrecognized operating system. Cannot identify sdrplay api library path");
return "";
}
}

View File

@@ -1,49 +0,0 @@
/*
* *****************************************************************************
* 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 <http://www.gnu.org/licenses/>
* ****************************************************************************
*/
package io.github.dsheirer.source.tuner.sdrplay.api;
import java.util.ArrayList;
import java.util.List;
/**
* SDRplay failed update request checked exception.
*/
public class SDRPlayUpdateException extends SDRPlayException
{
private List<UpdateReason> mUpdateReasons = new ArrayList<>();
/**
* Creates an operation exception
* @param status of the operation
* @param updateReasons that were submitted
*/
public SDRPlayUpdateException(Status status, List<UpdateReason> updateReasons)
{
super("Unable to update device parameters: " + updateReasons, status);
}
/**
* List of update reasons that failed.
*/
public List<UpdateReason> getUpdateReasons()
{
return mUpdateReasons;
}
}

View File

@@ -1,646 +0,0 @@
/*
* *****************************************************************************
* Copyright (C) 2014-2024 Dennis Sheirer
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>
* ****************************************************************************
*/
package io.github.dsheirer.source.tuner.sdrplay.api;
import io.github.dsheirer.source.tuner.sdrplay.api.callback.CallbackFunctions;
import io.github.dsheirer.source.tuner.sdrplay.api.callback.IDeviceEventListener;
import io.github.dsheirer.source.tuner.sdrplay.api.callback.IStreamListener;
import io.github.dsheirer.source.tuner.sdrplay.api.device.Device;
import io.github.dsheirer.source.tuner.sdrplay.api.device.DeviceFactory;
import io.github.dsheirer.source.tuner.sdrplay.api.device.DeviceInfo;
import io.github.dsheirer.source.tuner.sdrplay.api.device.DeviceType;
import io.github.dsheirer.source.tuner.sdrplay.api.device.IDeviceStruct;
import io.github.dsheirer.source.tuner.sdrplay.api.device.TunerSelect;
import io.github.dsheirer.source.tuner.sdrplay.api.error.DebugLevel;
import io.github.dsheirer.source.tuner.sdrplay.api.error.ErrorInformation;
import io.github.dsheirer.source.tuner.sdrplay.api.parameter.composite.CompositeParameters;
import io.github.dsheirer.source.tuner.sdrplay.api.parameter.composite.CompositeParametersFactory;
import io.github.dsheirer.source.tuner.sdrplay.api.util.Flag;
import io.github.dsheirer.source.tuner.sdrplay.api.v3_07.sdrplay_api_DeviceParamsT;
import io.github.dsheirer.source.tuner.sdrplay.api.v3_07.sdrplay_api_ErrorInfoT;
import io.github.dsheirer.source.tuner.sdrplay.api.v3_07.sdrplay_api_h;
import java.lang.foreign.Arena;
import java.lang.foreign.MemorySegment;
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.slf4j.Logger;
import org.slf4j.LoggerFactory;
/**
* SDRplay API wrapper.
*/
public class SDRplay
{
private static final Logger mLog = LoggerFactory.getLogger(SDRplay.class);
/**
* Foreign memory arena allocation resource scope. We use a shared arena with a lifetime bounded by the
* lifetime of this API.
*/
private final Arena mSharedArena = Arena.ofShared();
/**
* 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<MemorySegment, CallbackFunctions> 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() throws SDRPlayException
{
mSdrplayLibraryLoaded = SDRPlayLibraryHelper.LOADED;
if(mSdrplayLibraryLoaded)
{
Status openStatus = open();
mAvailable = openStatus.success() && getVersion().isSupported();
if(openStatus == Status.FAIL)
{
throw new SDRPlayException("Service not available - open status: " + openStatus);
}
}
else
{
mAvailable = false;
}
if(isAvailable())
{
if(sLibraryLoadStatusLogging)
{
mLog.info("API library v" + getVersion() + " - loaded");
}
}
else
{
if(sLibraryLoadStatusLogging)
{
if(!getVersion().isSupported())
{
mLog.info("API library is not available - unsupported version: " + getVersion());
}
else
{
mLog.info("API library is not available.");
}
}
}
sLibraryLoadStatusLogging = false;
}
/**
* Open Shared Memory Arena for this API instance
*/
private Arena getSharedArena()
{
return mSharedArena;
}
/**
* List of devices available via the API
* @return list of device infos.
* @throws SDRPlayException if there is an error
*/
public List<DeviceInfo> 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<IDeviceStruct> getDeviceStructures() throws SDRPlayException
{
List<IDeviceStruct> deviceStructs = new ArrayList<>();
//Get a version-correct array of DeviceT structures
MemorySegment devicesArray = DeviceFactory.createDeviceArray(getVersion(), getSharedArena());
MemorySegment deviceCount = getSharedArena().allocate(ValueLayout.JAVA_INT);
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<IDeviceStruct> 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 parameters
*/
public CompositeParameters getCompositeParameters(DeviceType deviceType, MemorySegment deviceHandle) throws SDRPlayException
{
//The GetDeviceParams function call returns a C pointer-to-pointer so we have to:
// 1) Allocate native memory to receive the address
// 2) Invoke the method call
// 3) Reinterpret the address to 8-bytes so we can get the returned address value
// 4) Allocate a memory segment for that address
// 5) Reinterpret the memory segment to the size of the DeviceParamsT structure
// 6) Finally, wrap the native memory in a composite parameters instance
MemorySegment pointerToPointer = getSharedArena().allocate(ValueLayout.ADDRESS);
Status status = Status.fromValue(sdrplay_api_h.sdrplay_api_GetDeviceParams(deviceHandle, pointerToPointer));
if(status.success())
{
MemorySegment pointer = pointerToPointer.reinterpret(ValueLayout.ADDRESS.byteSize());
MemorySegment deviceParamsAddress = MemorySegment.ofAddress(pointer.get(ValueLayout.JAVA_LONG, 0));
MemorySegment deviceParams = deviceParamsAddress.reinterpret(sdrplay_api_DeviceParamsT.sizeof(), getSharedArena(), null);
return CompositeParametersFactory.create(getVersion(), deviceType, deviceParams, getSharedArena());
}
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(MemorySegment deviceHandle, MemorySegment callbackFunctions) throws SDRPlayException
{
//Since we don't need/use the callback context ... setup as a pointer to the callback functions
MemorySegment contextPointer = Arena.ofAuto().allocate(ValueLayout.ADDRESS);
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, MemorySegment deviceHandle, IDeviceEventListener eventListener,
IStreamListener streamListener) throws SDRPlayException
{
CallbackFunctions callbackFunctions = mDeviceCallbackFunctionsMap.get(deviceHandle);
if(callbackFunctions == null)
{
callbackFunctions = new CallbackFunctions(getSharedArena(), 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, MemorySegment deviceHandle, IDeviceEventListener eventListener,
IStreamListener streamListener) throws SDRPlayException
{
CallbackFunctions callbackFunctions = mDeviceCallbackFunctionsMap.get(deviceHandle);
if(callbackFunctions == null)
{
callbackFunctions = new CallbackFunctions(getSharedArena(), 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(MemorySegment 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.
* <p>
* 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, MemorySegment 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)
{
MemorySegment errorAddress = sdrplay_api_h.sdrplay_api_GetLastError(deviceSegment);
MemorySegment errorSegment = errorAddress.reinterpret(sdrplay_api_ErrorInfoT.layout().byteSize(), getSharedArena(), null);
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(MemorySegment 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 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()
{
if(mSdrplayLibraryLoaded)
{
Status closeStatus;
try
{
closeStatus = Status.fromValue(sdrplay_api_h.sdrplay_api_Close());
}
catch(Exception e)
{
closeStatus = Status.FAIL;
mLog.error("Error closing SDRPlay API");
}
getSharedArena().close();
mSdrplayLibraryLoaded = false;
mAvailable = false;
return closeStatus;
}
else
{
getSharedArena().close();
return Status.API_UNAVAILABLE;
}
}
/**
* 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 = getSharedArena().allocate(ValueLayout.JAVA_FLOAT);
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);
}
}
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.
*/
try
{
SDRplay sdrplay = new SDRplay();
Status status = sdrplay.open();
mLog.info("Open Status: " + status);
for(DeviceInfo deviceInfo: sdrplay.getDeviceInfos())
{
mLog.info("Found: " + deviceInfo);
}
Status closeStatus = sdrplay.close();
mLog.info("Close Status: " + closeStatus);
}
catch(SDRPlayException se)
{
mLog.info("Error", se);
}
}
}

View File

@@ -1,109 +0,0 @@
/*
* *****************************************************************************
* 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 <http://www.gnu.org/licenses/>
* ****************************************************************************
*/
package io.github.dsheirer.source.tuner.sdrplay.api;
import io.github.dsheirer.source.tuner.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;
}
}

View File

@@ -1,197 +0,0 @@
/*
* *****************************************************************************
* Copyright (C) 2014-2024 Dennis Sheirer
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>
* ****************************************************************************
*/
package io.github.dsheirer.source.tuner.sdrplay.api;
import io.github.dsheirer.source.tuner.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_RSP_DUO_RESET_SLAVE_FLAGS(io.github.dsheirer.source.tuner.sdrplay.api.v3_15.sdrplay_api_h.sdrplay_api_Update_RspDuo_ResetSlaveFlags(), "RSPDuo Reset Slave Flags"),
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<UpdateReason> 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<UpdateReason> 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;
}
}

View File

@@ -1,106 +0,0 @@
/*
* *****************************************************************************
* Copyright (C) 2014-2024 Dennis Sheirer
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>
* ****************************************************************************
*/
package io.github.dsheirer.source.tuner.sdrplay.api;
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),
V3_12(3.12f, true),
V3_13(3.13f, true), //No changes - OSX build only.
V3_14(3.14f, true),
V3_15(3.15f, true),
V3_16(3.16f, 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);
}
}

View File

@@ -1,227 +0,0 @@
/*
* *****************************************************************************
* 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 <http://www.gnu.org/licenses/>
* ****************************************************************************
*/
package io.github.dsheirer.source.tuner.sdrplay.api.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 <R> expected return type upon completion of the operation
*/
public class AsyncFuture<R> implements Future<R>
{
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();
}
}
}

View File

@@ -1,100 +0,0 @@
/*
* *****************************************************************************
* 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 <http://www.gnu.org/licenses/>
* ****************************************************************************
*/
package io.github.dsheirer.source.tuner.sdrplay.api.async;
import io.github.dsheirer.source.tuner.sdrplay.api.Status;
import io.github.dsheirer.source.tuner.sdrplay.api.UpdateReason;
import io.github.dsheirer.source.tuner.sdrplay.api.device.TunerSelect;
/**
* Asynchronous future for an SDRplay API update operation.
*/
public class AsyncUpdateFuture extends AsyncFuture<Status>
{
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());
}
}

View File

@@ -1,57 +0,0 @@
/*
* *****************************************************************************
* 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 <http://www.gnu.org/licenses/>
* ****************************************************************************
*/
package io.github.dsheirer.source.tuner.sdrplay.api.async;
import io.github.dsheirer.source.tuner.sdrplay.api.UpdateReason;
import io.github.dsheirer.source.tuner.sdrplay.api.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;
}
}

View File

@@ -1,32 +0,0 @@
/*
* *****************************************************************************
* 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 <http://www.gnu.org/licenses/>
* ****************************************************************************
*/
package io.github.dsheirer.source.tuner.sdrplay.api.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);
}

View File

@@ -1,133 +0,0 @@
/*
* *****************************************************************************
* Copyright (C) 2014-2024 Dennis Sheirer
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>
* ****************************************************************************
*/
package io.github.dsheirer.source.tuner.sdrplay.api.callback;
import io.github.dsheirer.source.tuner.sdrplay.api.v3_07.sdrplay_api_CallbackFnsT;
import io.github.dsheirer.source.tuner.sdrplay.api.v3_07.sdrplay_api_EventCallback_t;
import io.github.dsheirer.source.tuner.sdrplay.api.v3_07.sdrplay_api_StreamCallback_t;
import java.lang.foreign.Arena;
import java.lang.foreign.MemorySegment;
/**
* Callback functions (sdrplay_api_CallbackFnsT) factory
*/
public class CallbackFunctions
{
private final DeviceEventAdapter mDeviceEventAdapter;
private final StreamCallbackAdapter mStreamACallbackAdapter;
private final StreamCallbackAdapter mStreamBCallbackAdapter;
private final MemorySegment mCallbackFunctionsMemorySegment;
/**
* Constructs a callback functions for single-tuner use.
* @param arena for native memory allocation for long lifecycle objects.
* @param deviceEventListener for device events
* @param streamListener for streaming samples
* @param streamCallbackListener for streaming events
*/
public CallbackFunctions(Arena arena, IDeviceEventListener deviceEventListener, IStreamListener streamListener,
IStreamCallbackListener streamCallbackListener)
{
//Create the event callback function
mDeviceEventAdapter = new DeviceEventAdapter(deviceEventListener);
MemorySegment eventFunction = sdrplay_api_EventCallback_t.allocate(mDeviceEventAdapter, arena);
//Create the stream A callback function
mStreamACallbackAdapter = new StreamCallbackAdapter(streamListener, streamCallbackListener);
MemorySegment streamAFunction = sdrplay_api_StreamCallback_t.allocate(mStreamACallbackAdapter, arena);
mStreamBCallbackAdapter = null;
//Create the callback functions union and populate the callback functions
mCallbackFunctionsMemorySegment = sdrplay_api_CallbackFnsT.allocate(arena);
sdrplay_api_CallbackFnsT.EventCbFn(mCallbackFunctionsMemorySegment, eventFunction);
sdrplay_api_CallbackFnsT.StreamACbFn(mCallbackFunctionsMemorySegment, streamAFunction);
// sdrplay_api_CallbackFnsT.EventCbFn$set(mCallbackFunctionsMemorySegment, eventFunction);
// sdrplay_api_CallbackFnsT.StreamACbFn$set(mCallbackFunctionsMemorySegment, streamAFunction);
}
/**
* Constructs a callback functions for dual-tuner use.
* @param arena 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(Arena arena, IDeviceEventListener deviceEventListener,
IStreamListener streamAListener, IStreamListener streamBListener,
IStreamCallbackListener streamCallbackListener)
{
//Create the event callback function
mDeviceEventAdapter = new DeviceEventAdapter(deviceEventListener);
MemorySegment eventFunction = sdrplay_api_EventCallback_t.allocate(mDeviceEventAdapter, arena);
//Create the stream A callback function
mStreamACallbackAdapter = new StreamCallbackAdapter(streamAListener, streamCallbackListener);
MemorySegment streamAFunction = sdrplay_api_StreamCallback_t.allocate(mStreamACallbackAdapter, arena);
//Create the stream B callback function
mStreamBCallbackAdapter = new StreamCallbackAdapter(streamBListener, streamCallbackListener);
MemorySegment streamBFunction = sdrplay_api_StreamCallback_t.allocate(mStreamBCallbackAdapter, arena);
//Create the callback functions union and populate the callback functions
mCallbackFunctionsMemorySegment = sdrplay_api_CallbackFnsT.allocate(arena);
sdrplay_api_CallbackFnsT.EventCbFn(mCallbackFunctionsMemorySegment, eventFunction);
sdrplay_api_CallbackFnsT.StreamACbFn(mCallbackFunctionsMemorySegment, streamAFunction);
sdrplay_api_CallbackFnsT.StreamBCbFn(mCallbackFunctionsMemorySegment, streamBFunction);
// sdrplay_api_CallbackFnsT.EventCbFn$set(mCallbackFunctionsMemorySegment, eventFunction);
// sdrplay_api_CallbackFnsT.StreamACbFn$set(mCallbackFunctionsMemorySegment, streamAFunction);
// sdrplay_api_CallbackFnsT.StreamBCbFn$set(mCallbackFunctionsMemorySegment, streamBFunction);
}
/**
* 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);
}
}

View File

@@ -1,108 +0,0 @@
/*
* *****************************************************************************
* Copyright (C) 2014-2025 Dennis Sheirer
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>
* ****************************************************************************
*/
package io.github.dsheirer.source.tuner.sdrplay.api.callback;
import io.github.dsheirer.source.tuner.sdrplay.api.device.TunerSelect;
import io.github.dsheirer.source.tuner.sdrplay.api.parameter.event.EventParametersFactory;
import io.github.dsheirer.source.tuner.sdrplay.api.parameter.event.EventType;
import io.github.dsheirer.source.tuner.sdrplay.api.v3_07.sdrplay_api_EventCallback_t;
import io.github.dsheirer.source.tuner.sdrplay.api.v3_07.sdrplay_api_EventParamsT;
import java.lang.foreign.Arena;
import java.lang.foreign.MemorySegment;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
/**
* 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.Function
{
private static final Logger mLog = LoggerFactory.getLogger(DeviceEventAdapter.class);
private IDeviceEventListener mDeviceEventListener;
/**
* Constructs an instance.
* @param listener to receive translated device events.
*/
public DeviceEventAdapter(IDeviceEventListener listener)
{
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, MemorySegment eventParametersPointer,
MemorySegment callbackContext)
{
//Use an auto arena to allow the garbage collector to deallocate, since we don't know if the device event
//listener will ever hold onto any object that is backed by our memory segment.
MemorySegment eventParams = eventParametersPointer.reinterpret(sdrplay_api_EventParamsT.sizeof(), Arena.ofAuto(), null);
EventType eventType = EventType.fromValue(eventTypeId);
TunerSelect tunerSelect = TunerSelect.fromValue(tunerSelectId);
switch(eventType)
{
case GAIN_CHANGE ->
{
mDeviceEventListener.processGainChange(tunerSelect,
EventParametersFactory.createGainCallbackParameters(eventParams));
}
case POWER_OVERLOAD_CHANGE ->
{
mDeviceEventListener.processPowerOverload(tunerSelect,
EventParametersFactory.createPowerOverloadCallbackParameters(eventParams));
}
case DEVICE_REMOVED, DEVICE_FAILURE ->
{
mDeviceEventListener.processDeviceRemoval(tunerSelect);
}
case RSP_DUO_MODE_CHANGE ->
{
mDeviceEventListener.processRspDuoModeChange(tunerSelect,
EventParametersFactory.createRspDuoModeCallbackParameters(eventParams));
}
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);
}
}
}
}

View File

@@ -1,67 +0,0 @@
/*
* *****************************************************************************
* 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 <http://www.gnu.org/licenses/>
* ****************************************************************************
*/
package io.github.dsheirer.source.tuner.sdrplay.api.callback;
import io.github.dsheirer.source.tuner.sdrplay.api.device.TunerSelect;
import io.github.dsheirer.source.tuner.sdrplay.api.parameter.event.EventType;
import io.github.dsheirer.source.tuner.sdrplay.api.parameter.event.GainCallbackParameters;
import io.github.dsheirer.source.tuner.sdrplay.api.parameter.event.PowerOverloadCallbackParameters;
import io.github.dsheirer.source.tuner.sdrplay.api.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);
}

View File

@@ -1,32 +0,0 @@
/*
* *****************************************************************************
* 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 <http://www.gnu.org/licenses/>
* ****************************************************************************
*/
package io.github.dsheirer.source.tuner.sdrplay.api.callback;
import io.github.dsheirer.source.tuner.sdrplay.api.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);
}

View File

@@ -1,45 +0,0 @@
/*
* *****************************************************************************
* 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 <http://www.gnu.org/licenses/>
* ****************************************************************************
*/
package io.github.dsheirer.source.tuner.sdrplay.api.callback;
import io.github.dsheirer.source.tuner.sdrplay.api.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();
}

View File

@@ -1,102 +0,0 @@
/*
* *****************************************************************************
* Copyright (C) 2014-2024 Dennis Sheirer
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>
* ****************************************************************************
*/
package io.github.dsheirer.source.tuner.sdrplay.api.callback;
import io.github.dsheirer.source.tuner.sdrplay.api.util.Flag;
import io.github.dsheirer.source.tuner.sdrplay.api.v3_07.sdrplay_api_StreamCallback_t;
import io.github.dsheirer.source.tuner.sdrplay.api.v3_07.sdrplay_api_StreamCbParamsT;
import java.lang.foreign.Arena;
import java.lang.foreign.MemorySegment;
import java.lang.foreign.ValueLayout;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
/**
* 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.Function
{
private static final Logger mLog = LoggerFactory.getLogger(StreamCallbackAdapter.class);
private IStreamListener mStreamListener;
private IStreamCallbackListener mStreamCallbackListener;
/**
* Constructs an instance of the callback implementation
* @param streamListener to receive transferred I/Q samples and event details
* @param listener to receive callback parameters
*/
public StreamCallbackAdapter(IStreamListener streamListener, IStreamCallbackListener listener)
{
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(MemorySegment iSamplesPointer, MemorySegment qSamplesPointer, MemorySegment parametersPointer,
int sampleCount, int reset, MemorySegment deviceContext)
{
if(mStreamListener != null || mStreamCallbackListener != null)
{
try(Arena confinedArena = Arena.ofConfined())
{
//Translate the callback parameters pointer to a memory segment and re-construct the parameters as a Java object
MemorySegment memorySegment = parametersPointer.reinterpret(sdrplay_api_StreamCbParamsT.sizeof(), confinedArena, null);
StreamCallbackParameters parameters = new StreamCallbackParameters(memorySegment);
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 = iSamplesPointer.reinterpret(arrayByteSize, confinedArena, null);
MemorySegment qSamples = qSamplesPointer.reinterpret(arrayByteSize, confinedArena, null);
// MemorySegment iSamples = MemorySegment.ofAddress(iSamplesPointer.address(), arrayByteSize, confinedArena.scope());
// MemorySegment qSamples = MemorySegment.ofAddress(qSamplesPointer.address(), arrayByteSize, confinedArena.scope());
short[] i = iSamples.toArray(ValueLayout.JAVA_SHORT);
short[] q = qSamples.toArray(ValueLayout.JAVA_SHORT);
mStreamListener.processStream(i, q, parameters, Flag.evaluate(reset));
}
}
}
}
}

View File

@@ -1,88 +0,0 @@
/*
* *****************************************************************************
* Copyright (C) 2014-2024 Dennis Sheirer
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>
* ****************************************************************************
*/
package io.github.dsheirer.source.tuner.sdrplay.api.callback;
import io.github.dsheirer.source.tuner.sdrplay.api.util.Flag;
import io.github.dsheirer.source.tuner.sdrplay.api.v3_07.sdrplay_api_StreamCbParamsT;
import java.lang.foreign.MemorySegment;
/**
* Stream Callback Parameters structure (sdrplay_api_StreamCbParamsT)
*/
public class StreamCallbackParameters
{
private final int mFirstSampleNumber;
private final boolean mGainReductionChanged;
private final boolean mRfFrequencyChanged;
private final boolean mSampleRateChanged;
private final long mNumberSamples;
/**
* Constructs an instance from the foreign memory segment
*/
public StreamCallbackParameters(MemorySegment memorySegment)
{
mFirstSampleNumber = sdrplay_api_StreamCbParamsT.firstSampleNum(memorySegment);
mGainReductionChanged = Flag.evaluate(sdrplay_api_StreamCbParamsT.grChanged(memorySegment));
mRfFrequencyChanged = Flag.evaluate(sdrplay_api_StreamCbParamsT.rfChanged(memorySegment));
mSampleRateChanged = Flag.evaluate(sdrplay_api_StreamCbParamsT.fsChanged(memorySegment));
mNumberSamples = sdrplay_api_StreamCbParamsT.numSamples(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;
}
}

View File

@@ -1,84 +0,0 @@
/*
* *****************************************************************************
* 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 <http://www.gnu.org/licenses/>
* ****************************************************************************
*/
package io.github.dsheirer.source.tuner.sdrplay.api.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();
}
}

View File

@@ -1,695 +0,0 @@
/*
* *****************************************************************************
* 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 <http://www.gnu.org/licenses/>
* ****************************************************************************
*/
package io.github.dsheirer.source.tuner.sdrplay.api.device;
import io.github.dsheirer.source.tuner.sdrplay.api.SDRPlayException;
import io.github.dsheirer.source.tuner.sdrplay.api.SDRplay;
import io.github.dsheirer.source.tuner.sdrplay.api.Status;
import io.github.dsheirer.source.tuner.sdrplay.api.UpdateReason;
import io.github.dsheirer.source.tuner.sdrplay.api.async.AsyncUpdateFuture;
import io.github.dsheirer.source.tuner.sdrplay.api.async.CompletedAsyncUpdate;
import io.github.dsheirer.source.tuner.sdrplay.api.callback.IDeviceEventListener;
import io.github.dsheirer.source.tuner.sdrplay.api.callback.IStreamCallbackListener;
import io.github.dsheirer.source.tuner.sdrplay.api.callback.IStreamListener;
import io.github.dsheirer.source.tuner.sdrplay.api.callback.StreamCallbackParameters;
import io.github.dsheirer.source.tuner.sdrplay.api.error.DebugLevel;
import io.github.dsheirer.source.tuner.sdrplay.api.parameter.composite.CompositeParameters;
import io.github.dsheirer.source.tuner.sdrplay.api.parameter.tuner.IfMode;
import io.github.dsheirer.source.tuner.sdrplay.api.parameter.tuner.LoMode;
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<T extends CompositeParameters<?,?>, 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
*/
MemorySegment 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<AsyncUpdateFuture> mUpdateQueue = new ConcurrentLinkedQueue();
private final Queue<CompletedAsyncUpdate> 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);
}
}
}
}

View File

@@ -1,163 +0,0 @@
/*
* *****************************************************************************
* Copyright (C) 2014-2024 Dennis Sheirer
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>
* ****************************************************************************
*/
package io.github.dsheirer.source.tuner.sdrplay.api.device;
import io.github.dsheirer.source.tuner.sdrplay.api.SDRPlayException;
import io.github.dsheirer.source.tuner.sdrplay.api.SDRplay;
import io.github.dsheirer.source.tuner.sdrplay.api.Version;
import io.github.dsheirer.source.tuner.sdrplay.api.v3_07.sdrplay_api_DeviceT;
import io.github.dsheirer.source.tuner.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;
/**
* Factory methods for creating new RSP Device instances
*/
public class DeviceFactory
{
/**
* 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 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<DeviceInfo> parseDeviceInfos(List<IDeviceStruct> deviceStructs)
{
List<DeviceInfo> 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 SDRPlayException if version is unrecognized or unsupported
*/
public static List<IDeviceStruct> parseDeviceStructs(Version version, MemorySegment devicesArray, int count)
throws SDRPlayException
{
List<IDeviceStruct> deviceStructs = new ArrayList<>();
if(version.gte(Version.V3_08))
{
devicesArray.elements(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 deviceStruct 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 RSP1B -> {
return new Rsp1bDevice(sdrPlay, deviceStruct);
}
case RSP2 -> {
return new Rsp2Device(sdrPlay, deviceStruct);
}
case RSPduo -> {
return new RspDuoDevice(sdrPlay, deviceStruct);
}
case RSPdx, RSPdxR2 -> {
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);
}
}
}

View File

@@ -1,140 +0,0 @@
/*
* *****************************************************************************
* 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 <http://www.gnu.org/licenses/>
* ****************************************************************************
*/
package io.github.dsheirer.source.tuner.sdrplay.api.device;
import io.github.dsheirer.source.tuner.sdrplay.api.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);
}
}

View File

@@ -1,98 +0,0 @@
/*
* *****************************************************************************
* Copyright (C) 2014-2024 Dennis Sheirer
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>
* ****************************************************************************
*/
package io.github.dsheirer.source.tuner.sdrplay.api.device;
import io.github.dsheirer.source.tuner.sdrplay.api.v3_07.sdrplay_api_DeviceT;
import java.lang.foreign.MemorySegment;
/**
* sdrplay_api_DeviceT structure parser for API version 3.07
*/
public class DeviceStruct_v3_07 implements IDeviceStruct
{
private final MemorySegment mDeviceMemorySegment;
private final DeviceType mDeviceType;
private final 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(mDeviceMemorySegment));
MemorySegment serialSegment = sdrplay_api_DeviceT.SerNo(mDeviceMemorySegment);
mSerialNumber = serialSegment.getString(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(getDeviceMemorySegment()));
}
@Override public RspDuoMode getRspDuoMode()
{
return RspDuoMode.fromValue(sdrplay_api_DeviceT.rspDuoMode(getDeviceMemorySegment()));
}
@Override
public void setRspDuoMode(RspDuoMode mode)
{
sdrplay_api_DeviceT.rspDuoMode(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(getDeviceMemorySegment());
}
@Override
public void setRspDuoSampleFrequency(double frequency)
{
sdrplay_api_DeviceT.rspDuoSampleFreq(getDeviceMemorySegment(), frequency);
}
@Override public MemorySegment getDeviceHandle()
{
return sdrplay_api_DeviceT.dev(getDeviceMemorySegment());
}
}

View File

@@ -1,109 +0,0 @@
/*
* *****************************************************************************
* Copyright (C) 2014-2024 Dennis Sheirer
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>
* ****************************************************************************
*/
package io.github.dsheirer.source.tuner.sdrplay.api.device;
import io.github.dsheirer.source.tuner.sdrplay.api.v3_08.sdrplay_api_DeviceT;
import java.lang.foreign.MemorySegment;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
/**
* sdrplay_api_DeviceT structure parser for API version 3.08+
*/
public class DeviceStruct_v3_08 implements IDeviceStruct
{
private static final Logger LOGGER = LoggerFactory.getLogger(DeviceStruct_v3_08.class);
private final MemorySegment mDeviceMemorySegment;
private final DeviceType mDeviceType;
private final String mSerialNumber;
/**
* Constructs an instance
* @param deviceMemorySegment of foreign memory
*/
public DeviceStruct_v3_08(MemorySegment deviceMemorySegment)
{
mDeviceMemorySegment = deviceMemorySegment;
int deviceTypeValue = 0xFF & sdrplay_api_DeviceT.hwVer(mDeviceMemorySegment);
mDeviceType = DeviceType.fromValue(deviceTypeValue);
MemorySegment serialSegment = sdrplay_api_DeviceT.SerNo(mDeviceMemorySegment);
mSerialNumber = serialSegment.getString(0);
if(mDeviceType == DeviceType.UNKNOWN)
{
LOGGER.warn("Unrecognized RSP tuner device type value [" + deviceTypeValue + "] with serial number [" +
mSerialNumber + "]");
}
}
@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(getDeviceMemorySegment()));
}
@Override public RspDuoMode getRspDuoMode()
{
return RspDuoMode.fromValue(sdrplay_api_DeviceT.rspDuoMode(getDeviceMemorySegment()));
}
@Override
public void setRspDuoMode(RspDuoMode mode)
{
sdrplay_api_DeviceT.rspDuoMode(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(getDeviceMemorySegment());
}
@Override
public void setRspDuoSampleFrequency(double frequency)
{
sdrplay_api_DeviceT.rspDuoSampleFreq(getDeviceMemorySegment(), frequency);
}
@Override public MemorySegment getDeviceHandle()
{
return sdrplay_api_DeviceT.dev(getDeviceMemorySegment());
}
}

View File

@@ -1,78 +0,0 @@
/*
* *****************************************************************************
* Copyright (C) 2014-2024 Dennis Sheirer
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>
* ****************************************************************************
*/
package io.github.dsheirer.source.tuner.sdrplay.api.device;
import io.github.dsheirer.source.tuner.sdrplay.api.v3_15.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"),
RSP1B(sdrplay_api_h.SDRPLAY_RSP1B_ID(), "RSP1B"),
RSP2(sdrplay_api_h.SDRPLAY_RSP2_ID(), "RSP2"),
RSPduo(sdrplay_api_h.SDRPLAY_RSPduo_ID(), "RSPduo"),
RSPdx(sdrplay_api_h.SDRPLAY_RSPdx_ID(), "RSPdx"),
RSPdxR2(sdrplay_api_h.SDRPLAY_RSPdxR2_ID(), "RSPdxR2"),
UNKNOWN(Integer.MIN_VALUE, "UNKNOWN");
private final int mValue;
private final 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;
}
}

View File

@@ -1,80 +0,0 @@
/*
* *****************************************************************************
* 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 <http://www.gnu.org/licenses/>
* ****************************************************************************
*/
package io.github.dsheirer.source.tuner.sdrplay.api.device;
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.
*/
MemorySegment getDeviceHandle();
}

View File

@@ -1,61 +0,0 @@
/*
* *****************************************************************************
* 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 <http://www.gnu.org/licenses/>
* ****************************************************************************
*/
package io.github.dsheirer.source.tuner.sdrplay.api.device;
import io.github.dsheirer.source.tuner.sdrplay.api.SDRPlayException;
import io.github.dsheirer.source.tuner.sdrplay.api.SDRplay;
import io.github.dsheirer.source.tuner.sdrplay.api.parameter.composite.Rsp1CompositeParameters;
/**
* RSP1 Device
*/
public class Rsp1Device extends Device<Rsp1CompositeParameters, Rsp1Tuner>
{
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;
}
}

View File

@@ -1,46 +0,0 @@
/*
* *****************************************************************************
* 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 <http://www.gnu.org/licenses/>
* ****************************************************************************
*/
package io.github.dsheirer.source.tuner.sdrplay.api.device;
import io.github.dsheirer.source.tuner.sdrplay.api.SDRplay;
import io.github.dsheirer.source.tuner.sdrplay.api.parameter.control.ControlParameters;
import io.github.dsheirer.source.tuner.sdrplay.api.parameter.device.Rsp1DeviceParameters;
import io.github.dsheirer.source.tuner.sdrplay.api.parameter.tuner.Rsp1TunerParameters;
/**
* RSP1 Tuner
*/
public class Rsp1Tuner extends RspTuner<Rsp1DeviceParameters, Rsp1TunerParameters>
{
/**
* 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);
}
}

View File

@@ -1,61 +0,0 @@
/*
* *****************************************************************************
* 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 <http://www.gnu.org/licenses/>
* ****************************************************************************
*/
package io.github.dsheirer.source.tuner.sdrplay.api.device;
import io.github.dsheirer.source.tuner.sdrplay.api.SDRPlayException;
import io.github.dsheirer.source.tuner.sdrplay.api.SDRplay;
import io.github.dsheirer.source.tuner.sdrplay.api.parameter.composite.Rsp1aCompositeParameters;
/**
* RSP1A Device
*/
public class Rsp1aDevice extends Device<Rsp1aCompositeParameters, Rsp1aTuner>
{
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;
}
}

View File

@@ -1,105 +0,0 @@
/*
* *****************************************************************************
* 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 <http://www.gnu.org/licenses/>
* ****************************************************************************
*/
package io.github.dsheirer.source.tuner.sdrplay.api.device;
import io.github.dsheirer.source.tuner.sdrplay.api.SDRPlayException;
import io.github.dsheirer.source.tuner.sdrplay.api.SDRplay;
import io.github.dsheirer.source.tuner.sdrplay.api.UpdateReason;
import io.github.dsheirer.source.tuner.sdrplay.api.parameter.control.ControlParameters;
import io.github.dsheirer.source.tuner.sdrplay.api.parameter.device.Rsp1aDeviceParameters;
import io.github.dsheirer.source.tuner.sdrplay.api.parameter.tuner.Rsp1aTunerParameters;
/**
* RSP1A Tuner
*/
public class Rsp1aTuner extends RspTuner<Rsp1aDeviceParameters, Rsp1aTunerParameters>
{
/**
* 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);
}
}

View File

@@ -1,61 +0,0 @@
/*
* *****************************************************************************
* Copyright (C) 2014-2024 Dennis Sheirer
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>
* ****************************************************************************
*/
package io.github.dsheirer.source.tuner.sdrplay.api.device;
import io.github.dsheirer.source.tuner.sdrplay.api.SDRPlayException;
import io.github.dsheirer.source.tuner.sdrplay.api.SDRplay;
import io.github.dsheirer.source.tuner.sdrplay.api.parameter.composite.Rsp1bCompositeParameters;
/**
* RSP1B Device
*/
public class Rsp1bDevice extends Device<Rsp1bCompositeParameters, Rsp1bTuner>
{
private Rsp1bTuner mTuner1;
/**
* Constructs an SDRPlay RSP1B device from the foreign memory segment
*
* @param sdrPlay api instance that created this device
* @param deviceStruct parser
*/
Rsp1bDevice(SDRplay sdrPlay, IDeviceStruct deviceStruct)
{
super(sdrPlay, deviceStruct);
}
@Override
public Rsp1bTuner getTuner() throws SDRPlayException
{
if(!isSelected())
{
throw new SDRPlayException("Device must be selected before accessing the tuner");
}
if(mTuner1 == null)
{
mTuner1 = new Rsp1bTuner(Rsp1bDevice.this, getAPI(), getTunerSelect(),
getCompositeParameters().getDeviceParameters(), getCompositeParameters().getTunerAParameters(),
getCompositeParameters().getControlAParameters());
}
return mTuner1;
}
}

View File

@@ -1,107 +0,0 @@
/*
* *****************************************************************************
* Copyright (C) 2014-2024 Dennis Sheirer
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>
* ****************************************************************************
*/
package io.github.dsheirer.source.tuner.sdrplay.api.device;
import io.github.dsheirer.source.tuner.sdrplay.api.SDRPlayException;
import io.github.dsheirer.source.tuner.sdrplay.api.SDRplay;
import io.github.dsheirer.source.tuner.sdrplay.api.UpdateReason;
import io.github.dsheirer.source.tuner.sdrplay.api.parameter.control.ControlParameters;
import io.github.dsheirer.source.tuner.sdrplay.api.parameter.device.Rsp1aDeviceParameters;
import io.github.dsheirer.source.tuner.sdrplay.api.parameter.tuner.Rsp1aTunerParameters;
/**
* RSP1B Tuner
*
* Note: the RSP1B uses the same device and tuner parameters structures as the RSP1A
*/
public class Rsp1bTuner extends RspTuner<Rsp1aDeviceParameters, Rsp1aTunerParameters>
{
/**
* 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 Rsp1bTuner(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);
}
}

View File

@@ -1,61 +0,0 @@
/*
* *****************************************************************************
* 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 <http://www.gnu.org/licenses/>
* ****************************************************************************
*/
package io.github.dsheirer.source.tuner.sdrplay.api.device;
import io.github.dsheirer.source.tuner.sdrplay.api.SDRPlayException;
import io.github.dsheirer.source.tuner.sdrplay.api.SDRplay;
import io.github.dsheirer.source.tuner.sdrplay.api.parameter.composite.Rsp2CompositeParameters;
/**
* RSP2 Device
*/
public class Rsp2Device extends Device<Rsp2CompositeParameters, Rsp2Tuner>
{
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;
}
}

View File

@@ -1,145 +0,0 @@
/*
* *****************************************************************************
* 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 <http://www.gnu.org/licenses/>
* ****************************************************************************
*/
package io.github.dsheirer.source.tuner.sdrplay.api.device;
import io.github.dsheirer.source.tuner.sdrplay.api.SDRPlayException;
import io.github.dsheirer.source.tuner.sdrplay.api.SDRplay;
import io.github.dsheirer.source.tuner.sdrplay.api.UpdateReason;
import io.github.dsheirer.source.tuner.sdrplay.api.parameter.control.ControlParameters;
import io.github.dsheirer.source.tuner.sdrplay.api.parameter.device.Rsp2DeviceParameters;
import io.github.dsheirer.source.tuner.sdrplay.api.parameter.tuner.Rsp2AmPort;
import io.github.dsheirer.source.tuner.sdrplay.api.parameter.tuner.Rsp2Antenna;
import io.github.dsheirer.source.tuner.sdrplay.api.parameter.tuner.Rsp2TunerParameters;
/**
* RSP2 Tuner
*/
public class Rsp2Tuner extends RspTuner<Rsp2DeviceParameters, Rsp2TunerParameters>
{
/**
* 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);
}
}

View File

@@ -1,208 +0,0 @@
/*
* *****************************************************************************
* Copyright (C) 2014-2024 Dennis Sheirer
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>
* ****************************************************************************
*/
package io.github.dsheirer.source.tuner.sdrplay.api.device;
import io.github.dsheirer.source.tuner.sdrplay.api.SDRPlayException;
import io.github.dsheirer.source.tuner.sdrplay.api.SDRplay;
import io.github.dsheirer.source.tuner.sdrplay.api.UpdateReason;
import io.github.dsheirer.source.tuner.sdrplay.api.parameter.composite.RspDuoCompositeParameters;
import io.github.dsheirer.source.tuner.sdrplay.api.parameter.tuner.IfMode;
import io.github.dsheirer.source.tuner.sdrplay.api.parameter.tuner.LoMode;
import io.github.dsheirer.source.tuner.sdrplay.api.v3_07.sdrplay_api_DeviceT;
/**
* RSPduo Device
*/
public class RspDuoDevice extends Device<RspDuoCompositeParameters, RspDuoTuner>
{
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(getDeviceMemorySegment()));
}
/**
* Sets the selected tuner(s)
*/
public void setTunerSelect(TunerSelect tunerSelect)
{
sdrplay_api_DeviceT.tuner(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();
}
}

View File

@@ -1,75 +0,0 @@
/*
* *****************************************************************************
* 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 <http://www.gnu.org/licenses/>
* ****************************************************************************
*/
package io.github.dsheirer.source.tuner.sdrplay.api.device;
import io.github.dsheirer.source.tuner.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;
}
}

View File

@@ -1,105 +0,0 @@
/*
* *****************************************************************************
* 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 <http://www.gnu.org/licenses/>
* ****************************************************************************
*/
package io.github.dsheirer.source.tuner.sdrplay.api.device;
import io.github.dsheirer.source.tuner.sdrplay.api.SDRPlayException;
import io.github.dsheirer.source.tuner.sdrplay.api.SDRplay;
import io.github.dsheirer.source.tuner.sdrplay.api.UpdateReason;
import io.github.dsheirer.source.tuner.sdrplay.api.parameter.control.ControlParameters;
import io.github.dsheirer.source.tuner.sdrplay.api.parameter.device.RspDuoDeviceParameters;
import io.github.dsheirer.source.tuner.sdrplay.api.parameter.tuner.RspDuoTunerParameters;
/**
* RSPduo Tuner
*/
public abstract class RspDuoTuner extends RspTuner<RspDuoDeviceParameters, RspDuoTunerParameters>
{
/**
* 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);
}
}

View File

@@ -1,87 +0,0 @@
/*
* *****************************************************************************
* 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 <http://www.gnu.org/licenses/>
* ****************************************************************************
*/
package io.github.dsheirer.source.tuner.sdrplay.api.device;
import io.github.dsheirer.source.tuner.sdrplay.api.SDRPlayException;
import io.github.dsheirer.source.tuner.sdrplay.api.SDRplay;
import io.github.dsheirer.source.tuner.sdrplay.api.UpdateReason;
import io.github.dsheirer.source.tuner.sdrplay.api.parameter.control.ControlParameters;
import io.github.dsheirer.source.tuner.sdrplay.api.parameter.device.RspDuoDeviceParameters;
import io.github.dsheirer.source.tuner.sdrplay.api.parameter.tuner.RspDuoAmPort;
import io.github.dsheirer.source.tuner.sdrplay.api.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);
}
}

View File

@@ -1,67 +0,0 @@
/*
* *****************************************************************************
* 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 <http://www.gnu.org/licenses/>
* ****************************************************************************
*/
package io.github.dsheirer.source.tuner.sdrplay.api.device;
import io.github.dsheirer.source.tuner.sdrplay.api.SDRPlayException;
import io.github.dsheirer.source.tuner.sdrplay.api.SDRplay;
import io.github.dsheirer.source.tuner.sdrplay.api.UpdateReason;
import io.github.dsheirer.source.tuner.sdrplay.api.parameter.control.ControlParameters;
import io.github.dsheirer.source.tuner.sdrplay.api.parameter.device.RspDuoDeviceParameters;
import io.github.dsheirer.source.tuner.sdrplay.api.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);
}
}

View File

@@ -1,62 +0,0 @@
/*
* *****************************************************************************
* 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 <http://www.gnu.org/licenses/>
* ****************************************************************************
*/
package io.github.dsheirer.source.tuner.sdrplay.api.device;
import io.github.dsheirer.source.tuner.sdrplay.api.SDRPlayException;
import io.github.dsheirer.source.tuner.sdrplay.api.SDRplay;
import io.github.dsheirer.source.tuner.sdrplay.api.parameter.composite.RspDxCompositeParameters;
/**
* RSPdx Device
*/
public class RspDxDevice extends Device<RspDxCompositeParameters, RspDxTuner>
{
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;
}
}

View File

@@ -1,164 +0,0 @@
/*
* *****************************************************************************
* 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 <http://www.gnu.org/licenses/>
* ****************************************************************************
*/
package io.github.dsheirer.source.tuner.sdrplay.api.device;
import io.github.dsheirer.source.tuner.sdrplay.api.SDRPlayException;
import io.github.dsheirer.source.tuner.sdrplay.api.SDRplay;
import io.github.dsheirer.source.tuner.sdrplay.api.UpdateReason;
import io.github.dsheirer.source.tuner.sdrplay.api.parameter.control.ControlParameters;
import io.github.dsheirer.source.tuner.sdrplay.api.parameter.device.RspDxDeviceParameters;
import io.github.dsheirer.source.tuner.sdrplay.api.parameter.tuner.HdrModeBandwidth;
import io.github.dsheirer.source.tuner.sdrplay.api.parameter.tuner.RspDxAntenna;
import io.github.dsheirer.source.tuner.sdrplay.api.parameter.tuner.RspDxTunerParameters;
/**
* RSPdx Tuner
*/
public class RspDxTuner extends RspTuner<RspDxDeviceParameters, RspDxTunerParameters>
{
/**
* 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);
}
}

View File

@@ -1,381 +0,0 @@
/*
* *****************************************************************************
* Copyright (C) 2014-2024 Dennis Sheirer
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>
* ****************************************************************************
*/
package io.github.dsheirer.source.tuner.sdrplay.api.device;
import io.github.dsheirer.source.tuner.sdrplay.api.SDRPlayException;
import io.github.dsheirer.source.tuner.sdrplay.api.SDRplay;
import io.github.dsheirer.source.tuner.sdrplay.api.UpdateReason;
import io.github.dsheirer.source.tuner.sdrplay.api.async.AsyncUpdateFuture;
import io.github.dsheirer.source.tuner.sdrplay.api.parameter.control.AgcMode;
import io.github.dsheirer.source.tuner.sdrplay.api.parameter.control.ControlParameters;
import io.github.dsheirer.source.tuner.sdrplay.api.parameter.device.DeviceParameters;
import io.github.dsheirer.source.tuner.sdrplay.api.parameter.tuner.Bandwidth;
import io.github.dsheirer.source.tuner.sdrplay.api.parameter.tuner.Gain;
import io.github.dsheirer.source.tuner.sdrplay.api.parameter.tuner.IfMode;
import io.github.dsheirer.source.tuner.sdrplay.api.parameter.tuner.LoMode;
import io.github.dsheirer.source.tuner.sdrplay.api.parameter.tuner.TunerParameters;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
/**
* Abstract RSP device tuner
* @param <T> RSP device implementation
*/
public abstract class RspTuner<D extends DeviceParameters, T extends TunerParameters>
{
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;
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);
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;
}
}
/**
* Sets the LNA state and Baseband Gain Reduction values.
* @param lna state (varies by tuner and frequency range)
* @param basebandGainReduction in range 20-59 dB
* @throws SDRPlayException
*/
public void setGain(int lna, int basebandGainReduction) throws SDRPlayException
{
getTunerParameters().getGain().setLNA(lna);
getTunerParameters().getGain().setGainReductionDb(basebandGainReduction);
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();
}
/**
* 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);
}
}

View File

@@ -1,74 +0,0 @@
/*
* *****************************************************************************
* 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 <http://www.gnu.org/licenses/>
* ****************************************************************************
*/
package io.github.dsheirer.source.tuner.sdrplay.api.device;
import io.github.dsheirer.source.tuner.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;
}
}

View File

@@ -1,46 +0,0 @@
/*
* *****************************************************************************
* 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 <http://www.gnu.org/licenses/>
* ****************************************************************************
*/
package io.github.dsheirer.source.tuner.sdrplay.api.device;
import io.github.dsheirer.source.tuner.sdrplay.api.SDRPlayException;
import io.github.dsheirer.source.tuner.sdrplay.api.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");
}
}

View File

@@ -1,76 +0,0 @@
/*
* *****************************************************************************
* 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 <http://www.gnu.org/licenses/>
* ****************************************************************************
*/
package io.github.dsheirer.source.tuner.sdrplay.api.error;
import io.github.dsheirer.source.tuner.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;
}
}

View File

@@ -1,77 +0,0 @@
/*
* *****************************************************************************
* Copyright (C) 2014-2024 Dennis Sheirer
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>
* ****************************************************************************
*/
package io.github.dsheirer.source.tuner.sdrplay.api.error;
import io.github.dsheirer.source.tuner.sdrplay.api.v3_07.sdrplay_api_ErrorInfoT;
import java.lang.foreign.MemorySegment;
/**
* Error Information structure (sdrplay_api_ErrorInfoT)
*/
public class ErrorInformation
{
private final String mFile;
private final String mFunction;
private final int mLine;
private final String mMessage;
/**
* Constructs an instance from the foreign memory segment
*/
public ErrorInformation(MemorySegment memorySegment)
{
mFile = sdrplay_api_ErrorInfoT.file(memorySegment).getString(0);
mFunction = sdrplay_api_ErrorInfoT.function(memorySegment).getString(0);
mLine = sdrplay_api_ErrorInfoT.line(memorySegment);
mMessage = sdrplay_api_ErrorInfoT.message(memorySegment).getString(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();
}
}

View File

@@ -1,110 +0,0 @@
/*
* *****************************************************************************
* Copyright (C) 2014-2024 Dennis Sheirer
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>
* ****************************************************************************
*/
package io.github.dsheirer.source.tuner.sdrplay.api.parameter.composite;
import io.github.dsheirer.source.tuner.sdrplay.api.Version;
import io.github.dsheirer.source.tuner.sdrplay.api.device.DeviceType;
import io.github.dsheirer.source.tuner.sdrplay.api.parameter.control.ControlParameters;
import io.github.dsheirer.source.tuner.sdrplay.api.parameter.device.DeviceParameters;
import io.github.dsheirer.source.tuner.sdrplay.api.parameter.device.DeviceParametersFactory;
import io.github.dsheirer.source.tuner.sdrplay.api.parameter.tuner.TunerParameters;
import io.github.dsheirer.source.tuner.sdrplay.api.parameter.tuner.TunerParametersFactory;
import io.github.dsheirer.source.tuner.sdrplay.api.v3_07.sdrplay_api_ControlParamsT;
import io.github.dsheirer.source.tuner.sdrplay.api.v3_07.sdrplay_api_DevParamsT;
import io.github.dsheirer.source.tuner.sdrplay.api.v3_07.sdrplay_api_DeviceParamsT;
import io.github.dsheirer.source.tuner.sdrplay.api.v3_07.sdrplay_api_RxChannelParamsT;
import java.lang.foreign.Arena;
import java.lang.foreign.MemorySegment;
/**
* Composite Device Parameters structure (sdrplay_api_DeviceParamsT) providing access to the device parameters and
* the tuner 1 parameter. Tuner 2 parameters are only accessible via the RSPduo subclass implementation.
*
* Note: subclass implementations will constrain access to the appropriate sub-structures of the DeviceParamsT
* structure for each specific device.
*/
public class CompositeParameters<D extends DeviceParameters, T extends TunerParameters>
{
private final D mDeviceParameters;
private final T mTunerAParameters;
private final ControlParameters mControlAParameters;
/**
* Constructs an instance from the foreign memory segment
*
* @param version of the API
* @param deviceType to create
* @param deviceParamsT native memory sdrplay_api_DeviceParamsT structure
* @param arena for allocating additional memory segments for the sub-structures.
*/
public CompositeParameters(Version version, DeviceType deviceType, MemorySegment deviceParamsT, Arena arena)
{
MemorySegment addressDevParams = sdrplay_api_DeviceParamsT.devParams(deviceParamsT);
MemorySegment devParams = addressDevParams.reinterpret(sdrplay_api_DevParamsT.sizeof(), arena, null);
mDeviceParameters = (D) DeviceParametersFactory.create(deviceType, devParams);
MemorySegment addressRxA = sdrplay_api_DeviceParamsT.rxChannelA(deviceParamsT);
MemorySegment rxA = addressRxA.reinterpret(sdrplay_api_RxChannelParamsT.sizeof(), arena, null);
mTunerAParameters = (T) TunerParametersFactory.create(version, deviceType, rxA);
MemorySegment tunerACtrlParams = rxA.asSlice(sdrplay_api_RxChannelParamsT.ctrlParams$offset(), sdrplay_api_ControlParamsT.sizeof());
mControlAParameters = new ControlParameters(tunerACtrlParams);
}
/**
* 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();
}
}

View File

@@ -1,67 +0,0 @@
/*
* *****************************************************************************
* Copyright (C) 2014-2024 Dennis Sheirer
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>
* ****************************************************************************
*/
package io.github.dsheirer.source.tuner.sdrplay.api.parameter.composite;
import io.github.dsheirer.source.tuner.sdrplay.api.Version;
import io.github.dsheirer.source.tuner.sdrplay.api.device.DeviceType;
import java.lang.foreign.Arena;
import java.lang.foreign.MemorySegment;
/**
* Creates a composite parameters instance for a device type
*/
public class CompositeParametersFactory
{
/**
* Creates a composite parameters instance for the specified device type
* @param version of the api
* @param deviceType to create
* @param deviceParams sdrplay_api_DeviceParamsT structure
* @param arena to allocate additional memory structures
* @return instance
*/
public static CompositeParameters create(Version version, DeviceType deviceType, MemorySegment deviceParams,
Arena arena)
{
switch(deviceType)
{
case RSP1 -> {
return new Rsp1CompositeParameters(version, deviceParams, arena);
}
case RSP1A -> {
return new Rsp1aCompositeParameters(version, deviceParams, arena);
}
case RSP1B -> {
return new Rsp1bCompositeParameters(version, deviceParams, arena);
}
case RSP2 -> {
return new Rsp2CompositeParameters(version, deviceParams, arena);
}
case RSPduo -> {
return new RspDuoCompositeParameters(version, deviceParams, arena);
}
case RSPdx, RSPdxR2 -> {
return new RspDxCompositeParameters(version, deviceParams, arena);
}
}
throw new IllegalArgumentException("Unrecognized device type: " + deviceType);
}
}

View File

@@ -1,45 +0,0 @@
/*
* *****************************************************************************
* Copyright (C) 2014-2024 Dennis Sheirer
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>
* ****************************************************************************
*/
package io.github.dsheirer.source.tuner.sdrplay.api.parameter.composite;
import io.github.dsheirer.source.tuner.sdrplay.api.Version;
import io.github.dsheirer.source.tuner.sdrplay.api.device.DeviceType;
import io.github.dsheirer.source.tuner.sdrplay.api.parameter.device.Rsp1DeviceParameters;
import io.github.dsheirer.source.tuner.sdrplay.api.parameter.tuner.Rsp1TunerParameters;
import java.lang.foreign.Arena;
import java.lang.foreign.MemorySegment;
/**
* RSP1 Composite parameters (device and tuner)
*/
public class Rsp1CompositeParameters extends CompositeParameters<Rsp1DeviceParameters, Rsp1TunerParameters>
{
/**
* Constructs an instance from the foreign memory segment
*
* @param version of the API
* @param deviceParams for the composite structure in foreign memory
* @param arena for allocating additional memory segments for the sub-structures.
*/
public Rsp1CompositeParameters(Version version, MemorySegment deviceParams, Arena arena)
{
super(version, DeviceType.RSP1, deviceParams, arena);
}
}

View File

@@ -1,45 +0,0 @@
/*
* *****************************************************************************
* Copyright (C) 2014-2024 Dennis Sheirer
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>
* ****************************************************************************
*/
package io.github.dsheirer.source.tuner.sdrplay.api.parameter.composite;
import io.github.dsheirer.source.tuner.sdrplay.api.Version;
import io.github.dsheirer.source.tuner.sdrplay.api.device.DeviceType;
import io.github.dsheirer.source.tuner.sdrplay.api.parameter.device.Rsp1aDeviceParameters;
import io.github.dsheirer.source.tuner.sdrplay.api.parameter.tuner.Rsp1aTunerParameters;
import java.lang.foreign.Arena;
import java.lang.foreign.MemorySegment;
/**
* RSP1A Composite parameters (device and tuner)
*/
public class Rsp1aCompositeParameters extends CompositeParameters<Rsp1aDeviceParameters, Rsp1aTunerParameters>
{
/**
* Constructs an instance from the foreign memory segment
*
* @param version of the API
* @param deviceParams for the composite structure in foreign memory
* @param arena for allocating additional memory segments for the sub-structures.
*/
public Rsp1aCompositeParameters(Version version, MemorySegment deviceParams, Arena arena)
{
super(version, DeviceType.RSP1A, deviceParams, arena);
}
}

View File

@@ -1,47 +0,0 @@
/*
* *****************************************************************************
* Copyright (C) 2014-2024 Dennis Sheirer
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>
* ****************************************************************************
*/
package io.github.dsheirer.source.tuner.sdrplay.api.parameter.composite;
import io.github.dsheirer.source.tuner.sdrplay.api.Version;
import io.github.dsheirer.source.tuner.sdrplay.api.device.DeviceType;
import io.github.dsheirer.source.tuner.sdrplay.api.parameter.device.Rsp1aDeviceParameters;
import io.github.dsheirer.source.tuner.sdrplay.api.parameter.tuner.Rsp1aTunerParameters;
import java.lang.foreign.Arena;
import java.lang.foreign.MemorySegment;
/**
* RSP1B Composite parameters (device and tuner)
*
* Note: RSP1B uses RSP1A device and tuner parameters structures.
*/
public class Rsp1bCompositeParameters extends CompositeParameters<Rsp1aDeviceParameters, Rsp1aTunerParameters>
{
/**
* Constructs an instance from the foreign memory segment
*
* @param version of the API
* @param deviceParams for the composite structure in foreign memory
* @param arena for allocating additional memory segments for the sub-structures.
*/
public Rsp1bCompositeParameters(Version version, MemorySegment deviceParams, Arena arena)
{
super(version, DeviceType.RSP1B, deviceParams, arena);
}
}

View File

@@ -1,45 +0,0 @@
/*
* *****************************************************************************
* Copyright (C) 2014-2024 Dennis Sheirer
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>
* ****************************************************************************
*/
package io.github.dsheirer.source.tuner.sdrplay.api.parameter.composite;
import io.github.dsheirer.source.tuner.sdrplay.api.Version;
import io.github.dsheirer.source.tuner.sdrplay.api.device.DeviceType;
import io.github.dsheirer.source.tuner.sdrplay.api.parameter.device.Rsp2DeviceParameters;
import io.github.dsheirer.source.tuner.sdrplay.api.parameter.tuner.Rsp2TunerParameters;
import java.lang.foreign.Arena;
import java.lang.foreign.MemorySegment;
/**
* RSP2 Composite parameters (device and tuner)
*/
public class Rsp2CompositeParameters extends CompositeParameters<Rsp2DeviceParameters, Rsp2TunerParameters>
{
/**
* Constructs an instance from the foreign memory segment
*
* @param version of the API
* @param deviceParams for the composite structure in foreign memory
* @param arena for allocating additional memory segments for the sub-structures.
*/
public Rsp2CompositeParameters(Version version, MemorySegment deviceParams, Arena arena)
{
super(version, DeviceType.RSP2, deviceParams, arena);
}
}

Some files were not shown because too many files have changed in this diff Show More