Compare commits

...

13 Commits

Author SHA1 Message Date
Denny Sheirer
aeeed71231 #1834 DMR CapMax Adv mode call events can have 'No Frequency'. Updated message class to ensure all 4x channels get nominated for timeslot frequency enrichment where previously the timeslot 2 channels might not receive a frequency enrichment. Also protected against bad logging for an UnknownCSBKMessage that gets constructed and CRC correction causing the message to have a valid channel grant opcode. (#1835)
Co-authored-by: Dennis Sheirer <dsheirer@github.com>
2024-02-10 04:42:50 -05:00
Denny Sheirer
f6c4cc8a5f 1810 P25 Voice frame list concurrent modification error. Added synchronized to method to deconflict when the audio module or the binary frame recorder can access the message and not step on each other. Issue was noted in the phase 2 module, but update the phase 1 module as well to protect against the issue. (#1833)
Co-authored-by: Dennis Sheirer <dsheirer@github.com>
2024-02-10 03:40:57 -05:00
Denny Sheirer
d019388034 1826 Vector Oscillator fails to generate MPT1327 correlator reference samples on SIMD-512 machines. (#1832)
Co-authored-by: Dennis Sheirer <dsheirer@github.com>
2024-02-09 10:39:46 -05:00
Denny Sheirer
e125d6a452 #1830 Health & Diagnostic Monitor feature. (#1831)
Co-authored-by: Dennis Sheirer <dsheirer@github.com>
2024-02-09 10:05:51 -05:00
Denny Sheirer
6b5a1fb827 #1802 Traffic channels stuck in TEARDOWN. Resolves: (#1829)
1. Tuner channel processing runnables were being interruptibly shutdown, preventing the channel from clearing any owned locks (ie DMRTrafficChannelManager) causing thread deadlock and eventually causing out of memory situation or tying up all threads in the thread pool to the point that the application stopped processing any data.

2. DMR Traffic Channel Manager was erroneously processing non-owned traffic channel events.

Co-authored-by: Dennis Sheirer <dsheirer@github.com>
2024-02-09 06:05:19 -05:00
Denny Sheirer
0491b08818 #1827 USB Hotplug support callback can block the UI thread causing blank white screen. (#1828)
Co-authored-by: Dennis Sheirer <dsheirer@github.com>
2024-02-09 03:38:12 -05:00
Denny Sheirer
7b9adc1da2 #1824 Adds diagnostic report generation to File>>Reports menu to log thread dumps and generate a processing diagnostic/status report. (#1825)
Co-authored-by: Dennis Sheirer <dsheirer@github.com>
2024-02-04 09:59:53 -05:00
Denny Sheirer
3acaea0019 #1821 Resolves issue with SDRPlay IF Gain auto/manual modes and slider adjustment. (#1822)
Co-authored-by: Dennis Sheirer <dsheirer@github.com>
2024-02-03 16:12:01 -05:00
Denny Sheirer
be02393f65 #1819 SDRPlay RSP1B tuner is now constructed correctly. (#1820)
Co-authored-by: Dennis Sheirer <dsheirer@github.com>
2024-02-03 15:28:39 -05:00
Denny Sheirer
614bf72f01 SDRPlay API version 3.14 & RSP1B (#1817)
* #1812 sdrplay adds support for RSP1B and changes gain to expose LNA and Baseband gain settings for all tuners.

* Updates build to 0.6.1 beta 1.

---------

Co-authored-by: Dennis Sheirer <dsheirer@github.com>
2024-02-03 10:18:05 -05:00
Peter Hicks
bed28b82ab Fix the channel power meter so that the heading displays without truncation (#1814) 2024-01-30 04:10:49 -05:00
Peter Hicks
c047d48d91 Merge pull request #1813
* OSM Tileserver now supports TLSv1.3, so we should use this in prefere…
2024-01-30 04:08:46 -05:00
Moto
5222bffce4 Merge pull request #1808
* Inherit preferred tuner configuration to P25 traffic channels
2024-01-30 04:05:19 -05:00
174 changed files with 12181 additions and 1237 deletions

View File

@@ -30,7 +30,11 @@ typedef void *HANDLE;
..\SDRtrunk\sdrplay-api\src\main\java
4. Generate the code:
c:\Users\Denny\Downloads\jdk-19-ea2-panama\bin\jextract "C:\Users\Denny\git\sdrtrunk\sdrplay-api\api\v3_11\sdrplay_api.h" -l libsdrplay_api --source
Windows:
c:\Users\Denny\Downloads\jdk-19-ea2-panama\bin\jextract "C:\Users\Denny\git\sdrtrunk\sdrplay-api\api\v3_11\sdrplay_api.h" -l libsdrplay_api --source -t io.github.dsheirer.source.tuner.sdrplay.api.v3_14
5. Do this for all versions of the API.
Linux:
~/Downloads/jextract-20/bin/jextract ~/IdeaProjects/sdrtrunk/artifacts/sdrplay-api-headers/v3_14/sdrplay_api.h -l libsdrplay_api --source -t io.github.dsheirer.source.tuner.sdrplay.api.v3_14
5. Compare the 3.07 header files to the newest version header files. Delete any auto-generated files that have not
changed and then update the factory class to construct variation classes where there are differences.

View File

@@ -0,0 +1,234 @@
#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.14)
// 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)
// 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

@@ -0,0 +1,79 @@
#ifndef SDRPLAY_API_CALLBACK_H
#define SDRPLAY_API_CALLBACK_H
// Event callback enums
typedef enum
{
sdrplay_api_Overload_Detected = 0,
sdrplay_api_Overload_Corrected = 1,
} sdrplay_api_PowerOverloadCbEventIdT;
typedef enum
{
sdrplay_api_MasterInitialised = 0,
sdrplay_api_SlaveAttached = 1,
sdrplay_api_SlaveDetached = 2,
sdrplay_api_SlaveInitialised = 3,
sdrplay_api_SlaveUninitialised = 4,
sdrplay_api_MasterDllDisappeared = 5,
sdrplay_api_SlaveDllDisappeared = 6,
} sdrplay_api_RspDuoModeCbEventIdT;
typedef enum
{
sdrplay_api_GainChange = 0,
sdrplay_api_PowerOverloadChange = 1,
sdrplay_api_DeviceRemoved = 2,
sdrplay_api_RspDuoModeChange = 3,
sdrplay_api_DeviceFailure = 4,
} sdrplay_api_EventT;
// Event callback parameter structs
typedef struct
{
unsigned int gRdB;
unsigned int lnaGRdB;
double currGain;
} sdrplay_api_GainCbParamT;
typedef struct
{
sdrplay_api_PowerOverloadCbEventIdT powerOverloadChangeType;
} sdrplay_api_PowerOverloadCbParamT;
typedef struct
{
sdrplay_api_RspDuoModeCbEventIdT modeChangeType;
} sdrplay_api_RspDuoModeCbParamT;
// Event parameters overlay
typedef union
{
sdrplay_api_GainCbParamT gainParams;
sdrplay_api_PowerOverloadCbParamT powerOverloadParams;
sdrplay_api_RspDuoModeCbParamT rspDuoModeParams;
} sdrplay_api_EventParamsT;
// Stream callback parameter structs
typedef struct
{
unsigned int firstSampleNum;
int grChanged;
int rfChanged;
int fsChanged;
unsigned int numSamples;
} sdrplay_api_StreamCbParamsT;
// Callback function prototypes
typedef void (*sdrplay_api_StreamCallback_t)(short *xi, short *xq, sdrplay_api_StreamCbParamsT *params, unsigned int numSamples, unsigned int reset, void *cbContext);
typedef void (*sdrplay_api_EventCallback_t)(sdrplay_api_EventT eventId, sdrplay_api_TunerSelectT tuner, sdrplay_api_EventParamsT *params, void *cbContext);
// Callback function struct
typedef struct
{
sdrplay_api_StreamCallback_t StreamACbFn;
sdrplay_api_StreamCallback_t StreamBCbFn;
sdrplay_api_EventCallback_t EventCbFn;
} sdrplay_api_CallbackFnsT;
#endif //SDRPLAY_API_CALLBACK_H

View File

@@ -0,0 +1,55 @@
#ifndef SDRPLAY_API_CONTROL_H
#define SDRPLAY_API_CONTROL_H
// Control parameter enums
typedef enum
{
sdrplay_api_AGC_DISABLE = 0,
sdrplay_api_AGC_100HZ = 1,
sdrplay_api_AGC_50HZ = 2,
sdrplay_api_AGC_5HZ = 3,
sdrplay_api_AGC_CTRL_EN = 4
} sdrplay_api_AgcControlT;
typedef enum
{
sdrplay_api_ADSB_DECIMATION = 0,
sdrplay_api_ADSB_NO_DECIMATION_LOWPASS = 1,
sdrplay_api_ADSB_NO_DECIMATION_BANDPASS_2MHZ = 2,
sdrplay_api_ADSB_NO_DECIMATION_BANDPASS_3MHZ = 3
} sdrplay_api_AdsbModeT;
// Control parameter structs
typedef struct
{
unsigned char DCenable; // default: 1
unsigned char IQenable; // default: 1
} sdrplay_api_DcOffsetT;
typedef struct
{
unsigned char enable; // default: 0
unsigned char decimationFactor; // default: 1
unsigned char wideBandSignal; // default: 0
} sdrplay_api_DecimationT;
typedef struct
{
sdrplay_api_AgcControlT enable; // default: sdrplay_api_AGC_50HZ
int setPoint_dBfs; // default: -60
unsigned short attack_ms; // default: 0
unsigned short decay_ms; // default: 0
unsigned short decay_delay_ms; // default: 0
unsigned short decay_threshold_dB; // default: 0
int syncUpdate; // default: 0
} sdrplay_api_AgcT;
typedef struct
{
sdrplay_api_DcOffsetT dcOffset;
sdrplay_api_DecimationT decimation;
sdrplay_api_AgcT agc;
sdrplay_api_AdsbModeT adsbMode; //default: sdrplay_api_ADSB_DECIMATION
} sdrplay_api_ControlParamsT;
#endif //SDRPLAY_API_CONTROL_H

View File

@@ -0,0 +1,51 @@
#ifndef SDRPLAY_API_DEV_H
#define SDRPLAY_API_DEV_H
#include "sdrplay_api_rsp1a.h"
#include "sdrplay_api_rsp2.h"
#include "sdrplay_api_rspDuo.h"
#include "sdrplay_api_rspDx.h"
// Dev parameter enums
typedef enum
{
sdrplay_api_ISOCH = 0,
sdrplay_api_BULK = 1
} sdrplay_api_TransferModeT;
// Dev parameter structs
typedef struct
{
double fsHz; // default: 2000000.0
unsigned char syncUpdate; // default: 0
unsigned char reCal; // default: 0
} sdrplay_api_FsFreqT;
typedef struct
{
unsigned int sampleNum; // default: 0
unsigned int period; // default: 0
} sdrplay_api_SyncUpdateT;
typedef struct
{
unsigned char resetGainUpdate; // default: 0
unsigned char resetRfUpdate; // default: 0
unsigned char resetFsUpdate; // default: 0
} sdrplay_api_ResetFlagsT;
typedef struct
{
double ppm; // default: 0.0
sdrplay_api_FsFreqT fsFreq;
sdrplay_api_SyncUpdateT syncUpdate;
sdrplay_api_ResetFlagsT resetFlags;
sdrplay_api_TransferModeT mode; // default: sdrplay_api_ISOCH
unsigned int samplesPerPkt; // default: 0 (output param)
sdrplay_api_Rsp1aParamsT rsp1aParams;
sdrplay_api_Rsp2ParamsT rsp2Params;
sdrplay_api_RspDuoParamsT rspDuoParams;
sdrplay_api_RspDxParamsT rspDxParams;
} sdrplay_api_DevParamsT;
#endif //SDRPLAY_API_DEV_H

View File

@@ -0,0 +1,22 @@
#ifndef SDRPLAY_API_RSP1A_H
#define SDRPLAY_API_RSP1A_H
#define RSPIA_NUM_LNA_STATES 10
#define RSPIA_NUM_LNA_STATES_AM 7
#define RSPIA_NUM_LNA_STATES_LBAND 9
// RSP1A parameter enums
// RSP1A parameter structs
typedef struct
{
unsigned char rfNotchEnable; // default: 0
unsigned char rfDabNotchEnable; // default: 0
} sdrplay_api_Rsp1aParamsT;
typedef struct
{
unsigned char biasTEnable; // default: 0
} sdrplay_api_Rsp1aTunerParamsT;
#endif //SDRPLAY_API_RSP1A_H

View File

@@ -0,0 +1,35 @@
#ifndef SDRPLAY_API_RSP2_H
#define SDRPLAY_API_RSP2_H
#define RSPII_NUM_LNA_STATES 9
#define RSPII_NUM_LNA_STATES_AMPORT 5
#define RSPII_NUM_LNA_STATES_420MHZ 6
// RSP2 parameter enums
typedef enum
{
sdrplay_api_Rsp2_ANTENNA_A = 5,
sdrplay_api_Rsp2_ANTENNA_B = 6,
} sdrplay_api_Rsp2_AntennaSelectT;
typedef enum
{
sdrplay_api_Rsp2_AMPORT_1 = 1,
sdrplay_api_Rsp2_AMPORT_2 = 0,
} sdrplay_api_Rsp2_AmPortSelectT;
// RSP2 parameter structs
typedef struct
{
unsigned char extRefOutputEn; // default: 0
} sdrplay_api_Rsp2ParamsT;
typedef struct
{
unsigned char biasTEnable; // default: 0
sdrplay_api_Rsp2_AmPortSelectT amPortSel; // default: sdrplay_api_Rsp2_AMPORT_2
sdrplay_api_Rsp2_AntennaSelectT antennaSel; // default: sdrplay_api_Rsp2_ANTENNA_A
unsigned char rfNotchEnable; // default: 0
} sdrplay_api_Rsp2TunerParamsT;
#endif //SDRPLAY_API_RSP2_H

View File

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

@@ -0,0 +1,46 @@
#ifndef SDRPLAY_API_RSPDX_H
#define SDRPLAY_API_RSPDX_H
#include "sdrplay_api_tuner.h"
#define RSPDX_NUM_LNA_STATES 28 // Number of LNA states in all bands (except where defined differently below)
#define RSPDX_NUM_LNA_STATES_AMPORT2_0_12 19 // Number of LNA states when using AM Port 2 between 0 and 12MHz
#define RSPDX_NUM_LNA_STATES_AMPORT2_12_50 20 // Number of LNA states when using AM Port 2 between 12 and 50MHz
#define RSPDX_NUM_LNA_STATES_AMPORT2_50_60 25 // Number of LNA states when using AM Port 2 between 50 and 60MHz
#define RSPDX_NUM_LNA_STATES_VHF_BAND3 27 // Number of LNA states in VHF and Band3
#define RSPDX_NUM_LNA_STATES_420MHZ 21 // Number of LNA states in 420MHz band
#define RSPDX_NUM_LNA_STATES_LBAND 19 // Number of LNA states in L-band
#define RSPDX_NUM_LNA_STATES_DX 22 // Number of LNA states in DX path
// RSPdx parameter enums
typedef enum
{
sdrplay_api_RspDx_ANTENNA_A = 0,
sdrplay_api_RspDx_ANTENNA_B = 1,
sdrplay_api_RspDx_ANTENNA_C = 2,
} sdrplay_api_RspDx_AntennaSelectT;
typedef enum
{
sdrplay_api_RspDx_HDRMODE_BW_0_200 = 0,
sdrplay_api_RspDx_HDRMODE_BW_0_500 = 1,
sdrplay_api_RspDx_HDRMODE_BW_1_200 = 2,
sdrplay_api_RspDx_HDRMODE_BW_1_700 = 3,
} sdrplay_api_RspDx_HdrModeBwT;
// RSPdx parameter structs
typedef struct
{
unsigned char hdrEnable; // default: 0
unsigned char biasTEnable; // default: 0
sdrplay_api_RspDx_AntennaSelectT antennaSel; // default: sdrplay_api_RspDx_ANTENNA_A
unsigned char rfNotchEnable; // default: 0
unsigned char rfDabNotchEnable; // default: 0
} sdrplay_api_RspDxParamsT;
typedef struct
{
sdrplay_api_RspDx_HdrModeBwT hdrBw; // default: sdrplay_api_RspDx_HDRMODE_BW_1_700
} sdrplay_api_RspDxTunerParamsT;
#endif //SDRPLAY_API_RSPDX_H

View File

@@ -0,0 +1,21 @@
#ifndef SDRPLAY_API_RX_CHANNEL_H
#define SDRPLAY_API_RX_CHANNEL_H
#include "sdrplay_api_tuner.h"
#include "sdrplay_api_control.h"
#include "sdrplay_api_rsp1a.h"
#include "sdrplay_api_rsp2.h"
#include "sdrplay_api_rspDuo.h"
#include "sdrplay_api_rspDx.h"
typedef struct
{
sdrplay_api_TunerParamsT tunerParams;
sdrplay_api_ControlParamsT ctrlParams;
sdrplay_api_Rsp1aTunerParamsT rsp1aTunerParams;
sdrplay_api_Rsp2TunerParamsT rsp2TunerParams;
sdrplay_api_RspDuoTunerParamsT rspDuoTunerParams;
sdrplay_api_RspDxTunerParamsT rspDxTunerParams;
} sdrplay_api_RxChannelParamsT;
#endif //SDRPLAY_API_RX_CHANNEL_H

View File

@@ -0,0 +1,93 @@
#ifndef SDRPLAY_API_TUNER_H
#define SDRPLAY_API_TUNER_H
#define MAX_BB_GR (59)
// Tuner parameter enums
typedef enum
{
sdrplay_api_BW_Undefined = 0,
sdrplay_api_BW_0_200 = 200,
sdrplay_api_BW_0_300 = 300,
sdrplay_api_BW_0_600 = 600,
sdrplay_api_BW_1_536 = 1536,
sdrplay_api_BW_5_000 = 5000,
sdrplay_api_BW_6_000 = 6000,
sdrplay_api_BW_7_000 = 7000,
sdrplay_api_BW_8_000 = 8000
} sdrplay_api_Bw_MHzT;
typedef enum
{
sdrplay_api_IF_Undefined = -1,
sdrplay_api_IF_Zero = 0,
sdrplay_api_IF_0_450 = 450,
sdrplay_api_IF_1_620 = 1620,
sdrplay_api_IF_2_048 = 2048
} sdrplay_api_If_kHzT;
typedef enum
{
sdrplay_api_LO_Undefined = 0,
sdrplay_api_LO_Auto = 1,
sdrplay_api_LO_120MHz = 2,
sdrplay_api_LO_144MHz = 3,
sdrplay_api_LO_168MHz = 4
} sdrplay_api_LoModeT;
typedef enum
{
sdrplay_api_EXTENDED_MIN_GR = 0,
sdrplay_api_NORMAL_MIN_GR = 20
} sdrplay_api_MinGainReductionT;
typedef enum
{
sdrplay_api_Tuner_Neither = 0,
sdrplay_api_Tuner_A = 1,
sdrplay_api_Tuner_B = 2,
sdrplay_api_Tuner_Both = 3,
} sdrplay_api_TunerSelectT;
// Tuner parameter structs
typedef struct
{
float curr;
float max;
float min;
} sdrplay_api_GainValuesT;
typedef struct
{
int gRdB; // default: 50
unsigned char LNAstate; // default: 0
unsigned char syncUpdate; // default: 0
sdrplay_api_MinGainReductionT minGr; // default: sdrplay_api_NORMAL_MIN_GR
sdrplay_api_GainValuesT gainVals; // output parameter
} sdrplay_api_GainT;
typedef struct
{
double rfHz; // default: 200000000.0
unsigned char syncUpdate; // default: 0
} sdrplay_api_RfFreqT;
typedef struct
{
unsigned char dcCal; // default: 3 (Periodic mode)
unsigned char speedUp; // default: 0 (No speedup)
int trackTime; // default: 1 (=> time in uSec = (72 * 3 * trackTime) / 24e6 = 9uSec)
int refreshRateTime; // default: 2048 (=> time in uSec = (72 * 3 * refreshRateTime) / 24e6 = 18432uSec)
} sdrplay_api_DcOffsetTunerT;
typedef struct
{
sdrplay_api_Bw_MHzT bwType; // default: sdrplay_api_BW_0_200
sdrplay_api_If_kHzT ifType; // default: sdrplay_api_IF_Zero
sdrplay_api_LoModeT loMode; // default: sdrplay_api_LO_Auto
sdrplay_api_GainT gain;
sdrplay_api_RfFreqT rfFreq;
sdrplay_api_DcOffsetTunerT dcOffsetTuner;
} sdrplay_api_TunerParamsT;
#endif //SDRPLAY_API_TUNER_H

View File

@@ -28,4 +28,4 @@
# tag name, specifically the dashes inserted before and after the alpha/beta labels.
# See: https://github.com/DSheirer/sdrtrunk/issues/1651
projectVersion=0.7.0-alpha-1
projectVersion=0.6.1-beta-1

View File

@@ -1,6 +1,6 @@
/*
* *****************************************************************************
* Copyright (C) 2014-2022 Dennis Sheirer
* 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
@@ -35,11 +35,10 @@ import io.github.dsheirer.identifier.configuration.SystemConfigurationIdentifier
import io.github.dsheirer.identifier.decoder.ChannelStateIdentifier;
import io.github.dsheirer.identifier.decoder.DecoderLogicalChannelNameIdentifier;
import io.github.dsheirer.sample.Listener;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.util.Collections;
import java.util.List;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
/**
* Channel metadata containing details about the channel configuration, decoder state and current
@@ -66,17 +65,51 @@ public class ChannelMetadata implements Listener<IdentifierUpdateNotification>,
private AliasModel mAliasModel;
private AliasList mAliasList;
/**
* Constructs an instance
* @param aliasModel for alias lookups
* @param timeslot for this metadata
*/
public ChannelMetadata(AliasModel aliasModel, Integer timeslot)
{
mAliasModel = aliasModel;
mTimeslot = timeslot;
}
/**
* Constructs an instance
* @param aliasModel for alias lookups
*/
public ChannelMetadata(AliasModel aliasModel)
{
this(aliasModel, null);
}
/**
* Creates a textual description of this channel metadata.
*/
public String getDescription()
{
StringBuilder sb = new StringBuilder();
sb.append("Channel Metadata Description\n");
sb.append("\tTimeslot: ").append(mTimeslot).append("\n");
Identifier decoder = getDecoderTypeConfigurationIdentifier();
sb.append("\tDecoder: ").append(decoder != null ? decoder : "(null)").append("\n");
Identifier state = getChannelStateIdentifier();
sb.append("\tState: ").append(state != null ? state : "(null)").append("\n");
Identifier system = getSystemConfigurationIdentifier();
sb.append("\tSystem: ").append(system != null ? system : "(null)").append("\n");
Identifier site = getSiteConfigurationIdentifier();
sb.append("\tSite: ").append(site != null ? site : "(null)").append("\n");
Identifier channel = getChannelNameConfigurationIdentifier();
sb.append("\tChannel: ").append(channel != null ? channel : "(null)").append("\n");
Identifier frequency = getFrequencyConfigurationIdentifier();
sb.append("\tFrequency: ").append(frequency != null ? frequency : "(null)").append("\n");
Identifier logical = getDecoderLogicalChannelNameIdentifier();
sb.append("\tLogical Channel: ").append(logical != null ? logical : "(null)").append("\n");
return sb.toString();
}
public Integer getTimeslot()
{
return mTimeslot;

View File

@@ -1,23 +1,20 @@
/*
* *****************************************************************************
* Copyright (C) 2014-2024 Dennis Sheirer
*
* * ******************************************************************************
* * Copyright (C) 2014-2020 Dennis Sheirer
* *
* * This program is free software: you can redistribute it and/or modify
* * it under the terms of the GNU General Public License as published by
* * the Free Software Foundation, either version 3 of the License, or
* * (at your option) any later version.
* *
* * This program is distributed in the hope that it will be useful,
* * but WITHOUT ANY WARRANTY; without even the implied warranty of
* * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* * GNU General Public License for more details.
* *
* * You should have received a copy of the GNU General Public License
* * along with this program. If not, see <http://www.gnu.org/licenses/>
* * *****************************************************************************
* This 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.channel.metadata;
@@ -29,16 +26,16 @@ import io.github.dsheirer.identifier.Identifier;
import io.github.dsheirer.identifier.decoder.DecoderLogicalChannelNameIdentifier;
import io.github.dsheirer.preference.PreferenceType;
import io.github.dsheirer.sample.Listener;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import javax.swing.table.AbstractTableModel;
import java.awt.EventQueue;
import java.util.ArrayList;
import java.util.Collection;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import javax.swing.table.AbstractTableModel;
public class ChannelMetadataModel extends AbstractTableModel implements IChannelMetadataUpdateListener
{
@@ -84,6 +81,47 @@ public class ChannelMetadataModel extends AbstractTableModel implements IChannel
}
}
/**
* Creates a diagnostic description of the channel metadata and metadata-channel map.
* @return diagnostic description.
*/
public String getDiagnosticInformation()
{
StringBuilder sb = new StringBuilder();
Map<ChannelMetadata,Channel> mapCopy = new HashMap<>(mMetadataChannelMap);
List<ChannelMetadata> metadataCopy = new ArrayList<>(mChannelMetadata);
sb.append("Channel Metadata Model Diagnostics\n");
for(ChannelMetadata channelMetadata: metadataCopy)
{
sb.append("\n--------------- CHANNEL METADATA ITEM --------------------\n\n");
if(mapCopy.containsKey(channelMetadata))
{
Channel channel = mapCopy.get(channelMetadata);
sb.append("\tMapped Channel:").append(channel).append("\n");
sb.append("\t\tSource Configuration: ").append(channel.getSourceConfiguration()).append("\n");
}
else
{
sb.append("\tMapped Channel: **Channel Metadata Is Not In the Metadata:Channel Map**\n");
}
sb.append(channelMetadata.getDescription());
}
//Check for orphaned map entries that don't match the current channel metadata list.
for(Map.Entry<ChannelMetadata,Channel> entry: mapCopy.entrySet())
{
if(!metadataCopy.contains(entry.getKey()))
{
sb.append("\n\tWARNING: orphaned Metadata Channel map entry - channel: " + entry.getValue()).append("\n");
}
}
return sb.toString();
}
public void dispose()
{
MyEventBus.getGlobalEventBus().unregister(this);

View File

@@ -1,23 +1,20 @@
/*
* *****************************************************************************
* Copyright (C) 2014-2024 Dennis Sheirer
*
* * ******************************************************************************
* * Copyright (C) 2014-2019 Dennis Sheirer
* *
* * This 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/>
* * *****************************************************************************
* This 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.channel.state;
@@ -47,9 +44,37 @@ public abstract class AbstractDecoderState extends Module implements ActivitySum
protected Broadcaster<IDecodeEvent> mDecodeEventBroadcaster = new Broadcaster<>();
protected Listener<DecoderStateEvent> mDecoderStateListener;
private DecoderStateEventListener mDecoderStateEventListener = new DecoderStateEventListener();
private boolean mRunning;
public abstract DecoderType getDecoderType();
/**
* Implements module start and sets the mRunning flag to true so that messages can be processed.
*/
@Override
public void start()
{
mRunning = true;
}
/**
* Implements the module stop and sets the mRunning flag to false to stop message processing
*/
@Override
public void stop()
{
mRunning = false;
}
/**
* Indicates if this module is running and can process/pass messages down to sub-class implementations.
* @return true if running
*/
public boolean isRunning()
{
return mRunning;
}
/**
* Provides subclass reference to the decode event broadcaster
*/
@@ -145,4 +170,22 @@ public abstract class AbstractDecoderState extends Module implements ActivitySum
}
}
/**
* Message listener that only passes messages while we're running. This is important because each of the decoders
* can process blocks of samples and that can result in additional messages being generated even after shutdown
* and so we shut off the processing of decoded messages when we're commanded to stop. The sample processing thread
* cannot be shutdown or forcefully interrupted because downstream decoder and channel states may have acquired
* locks that have to be properly released.
*/
private class MessageListener implements Listener<IMessage>
{
@Override
public void receive(IMessage message)
{
if(isRunning())
{
receive(message);
}
}
}
}

View File

@@ -1,102 +0,0 @@
/*
* *****************************************************************************
* Copyright (C) 2014-2020 Dennis Sheirer
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>
* ****************************************************************************
*/
package io.github.dsheirer.channel.state;
import io.github.dsheirer.channel.state.DecoderStateEvent.Event;
import io.github.dsheirer.identifier.Form;
import io.github.dsheirer.identifier.Identifier;
import io.github.dsheirer.identifier.IdentifierClass;
import io.github.dsheirer.identifier.Role;
import io.github.dsheirer.identifier.string.SimpleStringIdentifier;
import io.github.dsheirer.message.IMessage;
import io.github.dsheirer.module.decode.DecoderType;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
/**
* Basic decoder channel state - provides the minimum channel state functionality
* to support an always un-squelched audio decoder.
*/
public class AlwaysUnsquelchedDecoderState extends DecoderState
{
private final static Logger mLog = LoggerFactory.getLogger(AlwaysUnsquelchedDecoderState.class);
private static final String NO_SQUELCH = "No Squelch";
private Identifier mChannelNameIdentifier;
private DecoderType mDecoderType;
private String mChannelName;
public AlwaysUnsquelchedDecoderState(DecoderType decoderType, String channelName)
{
mDecoderType = decoderType;
mChannelName = (channelName != null && !channelName.isEmpty()) ? channelName : decoderType.name() + " CHANNEL";
mChannelNameIdentifier = new SimpleStringIdentifier(mChannelName, IdentifierClass.USER, Form.CHANNEL_NAME, Role.TO);
}
@Override
public void init()
{
}
@Override
public String getActivitySummary()
{
StringBuilder sb = new StringBuilder();
sb.append("Activity Summary\n");
sb.append("\tDecoder:\t");
sb.append(mDecoderType);
sb.append("\n\n");
return sb.toString();
}
@Override
public void receive(IMessage t)
{
/* Not implemented */
}
@Override
public void receiveDecoderStateEvent(DecoderStateEvent event)
{
if(event.getEvent() == Event.REQUEST_RESET)
{
getIdentifierCollection().update(mChannelNameIdentifier);
}
}
@Override
public DecoderType getDecoderType()
{
return mDecoderType;
}
@Override
public void start()
{
broadcast(new DecoderStateEvent(this, Event.REQUEST_ALWAYS_UNSQUELCH, State.IDLE));
getIdentifierCollection().update(mChannelNameIdentifier);
}
@Override
public void stop()
{
}
}

View File

@@ -1,6 +1,6 @@
/*
* *****************************************************************************
* Copyright (C) 2014-2022 Dennis Sheirer
* 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
@@ -54,6 +54,7 @@ public abstract class DecoderState extends AbstractDecoderState
@Override
public void start()
{
super.start();
//Broadcast the existing identifiers (as add events) so that they can be received by external listeners
mIdentifierCollection.broadcastIdentifiers();
}

View File

@@ -24,6 +24,7 @@ import io.github.dsheirer.audio.AudioSegment;
import io.github.dsheirer.channel.metadata.ChannelAndMetadata;
import io.github.dsheirer.channel.metadata.ChannelMetadata;
import io.github.dsheirer.channel.metadata.ChannelMetadataModel;
import io.github.dsheirer.channel.state.AbstractChannelState;
import io.github.dsheirer.controller.channel.event.ChannelStartProcessingRequest;
import io.github.dsheirer.controller.channel.event.ChannelStopProcessingRequest;
import io.github.dsheirer.controller.channel.event.PreloadDataContent;
@@ -52,6 +53,7 @@ import io.github.dsheirer.source.tuner.manager.TunerManager;
import io.github.dsheirer.util.ThreadPool;
import java.awt.GraphicsEnvironment;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
@@ -72,9 +74,10 @@ import org.slf4j.LoggerFactory;
*/
public class ChannelProcessingManager implements Listener<ChannelEvent>
{
private static final String DIVIDER = "-------------------------------------------------------------------------\n";
private final static Logger mLog = LoggerFactory.getLogger(ChannelProcessingManager.class);
private static final String TUNER_UNAVAILABLE_DESCRIPTION = "TUNER UNAVAILABLE";
private Map<Channel,ProcessingChain> mProcessingChains = new ConcurrentHashMap<>();
private Map<Channel,ProcessingChain> mProcessingChainsMap = new ConcurrentHashMap<>();
private Lock mLock = new ReentrantLock();
private ChannelSourceEventErrorListener mSourceErrorListener = new ChannelSourceEventErrorListener();
@@ -131,7 +134,7 @@ public class ChannelProcessingManager implements Listener<ChannelEvent>
try
{
isProcessing = mProcessingChains.containsKey(channel) && mProcessingChains.get(channel).isProcessing();
isProcessing = mProcessingChainsMap.containsKey(channel) && mProcessingChainsMap.get(channel).isProcessing();
}
finally
{
@@ -147,7 +150,7 @@ public class ChannelProcessingManager implements Listener<ChannelEvent>
*/
public boolean isProcessing()
{
return !mProcessingChains.isEmpty();
return !mProcessingChainsMap.isEmpty();
}
/**
@@ -156,7 +159,7 @@ public class ChannelProcessingManager implements Listener<ChannelEvent>
*/
public ProcessingChain getProcessingChain(Channel channel)
{
return mProcessingChains.get(channel);
return mProcessingChainsMap.get(channel);
}
/**
@@ -175,7 +178,7 @@ public class ChannelProcessingManager implements Listener<ChannelEvent>
try
{
for(Map.Entry<Channel,ProcessingChain> entry : mProcessingChains.entrySet())
for(Map.Entry<Channel,ProcessingChain> entry : mProcessingChainsMap.entrySet())
{
if(entry.getValue() == processingChain)
{
@@ -206,7 +209,7 @@ public class ChannelProcessingManager implements Listener<ChannelEvent>
try
{
for(Map.Entry<Channel,ProcessingChain> entry : mProcessingChains.entrySet())
for(Map.Entry<Channel,ProcessingChain> entry : mProcessingChainsMap.entrySet())
{
if(entry.getValue().hasSource(tunerChannelSource))
{
@@ -556,10 +559,10 @@ public class ChannelProcessingManager implements Listener<ChannelEvent>
try
{
if(!mProcessingChains.containsKey(channel))
if(!mProcessingChainsMap.containsKey(channel))
{
added = true;
mProcessingChains.put(channel, processingChain);
mProcessingChainsMap.put(channel, processingChain);
getChannelMetadataModel().add(new ChannelAndMetadata(channel, processingChain.getChannelState().getChannelMetadata()));
}
}
@@ -584,7 +587,7 @@ public class ChannelProcessingManager implements Listener<ChannelEvent>
try
{
removed = mProcessingChains.remove(channel);
removed = mProcessingChainsMap.remove(channel);
if(removed != null)
{
@@ -633,6 +636,8 @@ public class ChannelProcessingManager implements Listener<ChannelEvent>
processingChain.removeFrequencyChangeListener(channel);
channel.resetFrequencyCorrection();
//Notify all processing chains that this channel is shutting down so that if this is a traffic channel,
//the owning parent channel's traffic channel manager can cleanup it's accounting.
mChannelEventBroadcaster.broadcast(new ChannelEvent(channel, ChannelEvent.Event.NOTIFICATION_PROCESSING_STOP));
mChannelEventBroadcaster.removeListener(processingChain);
@@ -660,7 +665,7 @@ public class ChannelProcessingManager implements Listener<ChannelEvent>
mDelayedChannelStartTasks.remove(delayedTask);
}
List<Channel> channelsToStop = new ArrayList<>(mProcessingChains.keySet());
List<Channel> channelsToStop = new ArrayList<>(mProcessingChainsMap.keySet());
for(Channel channel : channelsToStop)
{
@@ -683,7 +688,7 @@ public class ChannelProcessingManager implements Listener<ChannelEvent>
public void convertToTrafficChannel(ChannelConversionRequest request)
{
//Update the channel to processing chain map.
ProcessingChain processingChain = mProcessingChains.remove(request.getCurrentChannel());
ProcessingChain processingChain = mProcessingChainsMap.remove(request.getCurrentChannel());
if(processingChain != null)
{
@@ -697,7 +702,7 @@ public class ChannelProcessingManager implements Listener<ChannelEvent>
request.getTrafficChannel().setProcessing(true);
});
mProcessingChains.put(request.getTrafficChannel(), processingChain);
mProcessingChainsMap.put(request.getTrafficChannel(), processingChain);
mChannelMetadataModel.updateChannelMetadataToChannelMap(processingChain.getChannelState().getChannelMetadata(),
request.getTrafficChannel());
@@ -803,7 +808,7 @@ public class ChannelProcessingManager implements Listener<ChannelEvent>
try
{
for(Map.Entry<Channel,ProcessingChain> entry: mProcessingChains.entrySet())
for(Map.Entry<Channel,ProcessingChain> entry: mProcessingChainsMap.entrySet())
{
if(entry.getValue().hasSource(sourceEvent.getSource()))
{
@@ -841,4 +846,54 @@ public class ChannelProcessingManager implements Listener<ChannelEvent>
}
}
}
/**
* Creates a diagnostic report.
* @return report text.
*/
public String getDiagnosticInformation()
{
StringBuilder sb = new StringBuilder();
sb.append("Channel Processing Manager - Diagnostics Report\n\n");
sb.append(DIVIDER);
sb.append("\tChannel to Processing Chain Map Contents\n");
Map<Channel,ProcessingChain> mapCopy = new HashMap<>(mProcessingChainsMap);
for(Map.Entry<Channel,ProcessingChain> entry: mapCopy.entrySet())
{
sb.append("\n\n--------------- CHANNEL:PROCESSING CHAIN MAP ENTRY --------------------\n");
try
{
Channel channel = entry.getKey();
sb.append("\tChannel: " + channel).append("\n");
sb.append("\t\tSource Configuration: " + channel.getSourceConfiguration()).append("\n");
ProcessingChain chain = entry.getValue();
sb.append("\tProcessing Chain - Processing: ").append(chain.isProcessing()).append("\n");
AbstractChannelState state = chain.getChannelState();
sb.append("Channel State: ").append(state.getClass()).append("\n");
for(ChannelMetadata metadata: state.getChannelMetadata())
{
sb.append(metadata.getDescription()).append("\n");
}
Source source = chain.getSource();
if(source != null)
{
sb.append("Channel Source Class: " + source.getClass()).append("\n");
sb.append("\t\tTo String:").append(source).append("\n");
sb.append("\t\tHash:").append(Integer.toHexString(source.hashCode()).toUpperCase()).append("\n");
}
else
{
sb.append("Channel Source: (null)\n");
}
}
catch(Throwable t)
{
sb.append("\tError while logging diagnostics of map entry - " + t.getMessage()).append("\n");
}
}
return sb.toString();
}
}

View File

@@ -1,6 +1,6 @@
/*
* *****************************************************************************
* Copyright (C) 2014-2023 Dennis Sheirer
* 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
@@ -147,6 +147,7 @@ public class PolyphaseChannelManager implements ISourceEventProcessor
sb.append(" REQUESTED CF: ").append(FREQUENCY_FORMAT.format(requestedCenterFrequency / 1E6d));
sb.append(" MIXER:").append(FREQUENCY_FORMAT.format(appliedFrequencyOffset / 1E6d));
sb.append(" | Polyphase Indices: ").append(indexes);
sb.append(" HASH:").append(Integer.toHexString(pcs.hashCode()).toUpperCase());
}
return sb.toString();

View File

@@ -1,6 +1,6 @@
/*
* *****************************************************************************
* Copyright (C) 2014-2022 Dennis Sheirer
* 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
@@ -19,6 +19,7 @@
package io.github.dsheirer.dsp.oscillator;
import java.util.Arrays;
import jdk.incubator.vector.FloatVector;
import jdk.incubator.vector.VectorOperators;
import jdk.incubator.vector.VectorSpecies;
@@ -45,7 +46,15 @@ public class VectorRealOscillator extends AbstractOscillator implements IRealOsc
@Override
public float[] generate(int sampleCount)
{
float[] samples = new float[sampleCount];
int length = sampleCount;
//Increase the length until it aligns as a multiple of the vector species length
while(length % VECTOR_SPECIES.length() != 0)
{
length++;
}
float[] samples = new float[length];
for(int samplePointer = 0; samplePointer < sampleCount; samplePointer += VECTOR_SPECIES.length())
{
@@ -58,6 +67,7 @@ public class VectorRealOscillator extends AbstractOscillator implements IRealOsc
generated.intoArray(samples, samplePointer);
}
return samples;
//Truncate the array to the requested length, if we increased it for SIMD alignment.
return Arrays.copyOf(samples, sampleCount);
}
}

View File

@@ -1,6 +1,6 @@
/*
* *****************************************************************************
* Copyright (C) 2014-2023 Dennis Sheirer
* 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
@@ -43,6 +43,7 @@ import io.github.dsheirer.icon.IconModel;
import io.github.dsheirer.log.ApplicationLog;
import io.github.dsheirer.map.MapService;
import io.github.dsheirer.module.log.EventLogManager;
import io.github.dsheirer.monitor.DiagnosticMonitor;
import io.github.dsheirer.monitor.ResourceMonitor;
import io.github.dsheirer.playlist.PlaylistManager;
import io.github.dsheirer.preference.UserPreferences;
@@ -125,6 +126,7 @@ public class SDRTrunk implements Listener<TunerEvent>
private AudioStreamingManager mAudioStreamingManager;
private BroadcastStatusPanel mBroadcastStatusPanel;
private ControllerPanel mControllerPanel;
private DiagnosticMonitor mDiagnosticMonitor;
private IconModel mIconModel = new IconModel();
private PlaylistManager mPlaylistManager;
private SettingsManager mSettingsManager;
@@ -187,7 +189,13 @@ public class SDRTrunk implements Listener<TunerEvent>
EventLogManager eventLogManager = new EventLogManager(aliasModel, mUserPreferences);
mPlaylistManager = new PlaylistManager(mUserPreferences, mTunerManager, aliasModel, eventLogManager, mIconModel);
if(!GraphicsEnvironment.isHeadless())
boolean headless = GraphicsEnvironment.isHeadless();
mDiagnosticMonitor = new DiagnosticMonitor(mUserPreferences, mPlaylistManager.getChannelProcessingManager(),
mTunerManager, headless);
mDiagnosticMonitor.start();
if(!headless)
{
mJavaFxWindowManager = new JavaFxWindowManager(mUserPreferences, mTunerManager, mPlaylistManager);
}
@@ -411,6 +419,46 @@ public class SDRTrunk implements Listener<TunerEvent>
JMenu fileMenu = new JMenu("File");
menuBar.add(fileMenu);
JMenuItem processingStatusReportMenuItem = new JMenuItem("Processing Diagnostic Report");
processingStatusReportMenuItem.addActionListener(e -> {
try
{
Path path = mDiagnosticMonitor.generateProcessingDiagnosticReport("User initiated diagnostic report");
JOptionPane.showMessageDialog(mMainGui, "Report created: " +
path.toString(), "Processing Status Report Created", JOptionPane.INFORMATION_MESSAGE);
}
catch(IOException ioe)
{
mLog.error("Error creating processing status report file", ioe);
JOptionPane.showMessageDialog(mMainGui, "Unable to create report file. Please " +
"see application log for details.", "Processing Status Report Failed", JOptionPane.ERROR_MESSAGE);
}
});
JMenuItem threadDumpReportMenuItem = new JMenuItem("Thread Dump Report");
threadDumpReportMenuItem.addActionListener(e -> {
try
{
Path path = mDiagnosticMonitor.generateThreadDumpReport();
JOptionPane.showMessageDialog(mMainGui, "Report created: " +
path.toString(), "Thread Dump Report Created", JOptionPane.INFORMATION_MESSAGE);
}
catch(IOException ioe)
{
mLog.error("Error creating thread dump report file", ioe);
JOptionPane.showMessageDialog(mMainGui, "Unable to create report file. Please " +
"see application log for details.", "Thread Dump Report Failed", JOptionPane.ERROR_MESSAGE);
}
});
JMenu diagnosticMenu = new JMenu(("Reports"));
diagnosticMenu.add(processingStatusReportMenuItem);
diagnosticMenu.add(threadDumpReportMenuItem);
fileMenu.add(diagnosticMenu);
fileMenu.add(new JSeparator(JSeparator.HORIZONTAL));
JMenuItem exitMenu = new JMenuItem("Exit");
exitMenu.addActionListener(event -> {
processShutdown();
@@ -578,6 +626,7 @@ public class SDRTrunk implements Listener<TunerEvent>
private void processShutdown()
{
mLog.info("Application shutdown started ...");
mDiagnosticMonitor.stop();
mUserPreferences.getSwingPreference().setLocation(WINDOW_FRAME_IDENTIFIER, mMainGui.getLocation());
mUserPreferences.getSwingPreference().setDimension(WINDOW_FRAME_IDENTIFIER, mMainGui.getSize());
mUserPreferences.getSwingPreference().setMaximized(WINDOW_FRAME_IDENTIFIER,

View File

@@ -39,7 +39,7 @@ public class DbPowerMeter extends JComponent
*/
public DbPowerMeter()
{
setPreferredSize(new Dimension(80, 100));
setPreferredSize(new Dimension(90, 100));
setBorder(BorderFactory.createTitledBorder("Power (dB)"));
}

View File

@@ -1,6 +1,6 @@
/*
* *****************************************************************************
* Copyright (C) 2014-2023 Dennis Sheirer
* 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
@@ -23,10 +23,16 @@ import io.github.dsheirer.preference.UserPreferences;
import io.github.dsheirer.preference.application.ApplicationPreference;
import javafx.geometry.HPos;
import javafx.geometry.Insets;
import javafx.geometry.Orientation;
import javafx.scene.control.Label;
import javafx.scene.control.Separator;
import javafx.scene.control.Spinner;
import javafx.scene.layout.ColumnConstraints;
import javafx.scene.layout.GridPane;
import javafx.scene.layout.HBox;
import javafx.scene.layout.Priority;
import javafx.scene.layout.VBox;
import org.controlsfx.control.ToggleSwitch;
/**
@@ -38,6 +44,7 @@ public class ApplicationPreferenceEditor extends HBox
private GridPane mEditorPane;
private Label mAutoStartTimeoutLabel;
private Spinner<Integer> mTimeoutSpinner;
private ToggleSwitch mAutomaticDiagnosticMonitoringToggle;
/**
* Constructs an instance
@@ -46,7 +53,14 @@ public class ApplicationPreferenceEditor extends HBox
public ApplicationPreferenceEditor(UserPreferences userPreferences)
{
mApplicationPreference = userPreferences.getApplicationPreference();
getChildren().add(getEditorPane());
setMaxWidth(Double.MAX_VALUE);
VBox vbox = new VBox();
vbox.setMaxHeight(Double.MAX_VALUE);
vbox.setMaxWidth(Double.MAX_VALUE);
vbox.getChildren().add(getEditorPane());
HBox.setHgrow(vbox, Priority.ALWAYS);
getChildren().add(vbox);
}
private GridPane getEditorPane()
@@ -55,13 +69,31 @@ public class ApplicationPreferenceEditor extends HBox
{
int row = 0;
mEditorPane = new GridPane();
mEditorPane.setMaxWidth(Double.MAX_VALUE);
mEditorPane.setVgap(10);
mEditorPane.setHgap(10);
mEditorPane.setHgap(3);
mEditorPane.setPadding(new Insets(10, 10, 10, 10));
GridPane.setHalignment(getAutoStartTimeoutLabel(), HPos.RIGHT);
mEditorPane.add(getAutoStartTimeoutLabel(), 0, row);
mEditorPane.add(getTimeoutSpinner(), 1, row);
mEditorPane.add(new Label("seconds"), 2, row);
Label monitoringLabel = new Label("Application Health and Diagnostic Monitoring.");
mEditorPane.add(monitoringLabel, 0, row, 2, 1);
GridPane.setHalignment(getAutomaticDiagnosticMonitoringToggle(), HPos.RIGHT);
mEditorPane.add(getAutomaticDiagnosticMonitoringToggle(), 0, ++row);
mEditorPane.add(new Label("Enable Diagnostic Monitoring"), 1, row, 2, 1);
Separator separator = new Separator(Orientation.HORIZONTAL);
GridPane.setHgrow(separator, Priority.ALWAYS);
mEditorPane.add(separator, 0, ++row, 3, 1);
mEditorPane.add(getAutoStartTimeoutLabel(), 0, ++row, 2, 1);
GridPane.setHalignment(getTimeoutSpinner(), HPos.RIGHT);
mEditorPane.add(getTimeoutSpinner(), 0, ++row);
mEditorPane.add(new Label("seconds"), 1, row);
ColumnConstraints c1 = new ColumnConstraints();
c1.setPercentWidth(30);
ColumnConstraints c2 = new ColumnConstraints();
c2.setHgrow(Priority.ALWAYS);
mEditorPane.getColumnConstraints().addAll(c1, c2);
}
return mEditorPane;
@@ -91,4 +123,20 @@ public class ApplicationPreferenceEditor extends HBox
return mTimeoutSpinner;
}
/**
* Toggle switch to enable/disable automatic diagnostic monitoring.
*/
private ToggleSwitch getAutomaticDiagnosticMonitoringToggle()
{
if(mAutomaticDiagnosticMonitoringToggle == null)
{
mAutomaticDiagnosticMonitoringToggle = new ToggleSwitch();
mAutomaticDiagnosticMonitoringToggle.setSelected(mApplicationPreference.isAutomaticDiagnosticMonitoring());
mAutomaticDiagnosticMonitoringToggle.selectedProperty().addListener((observable, oldValue, enabled) ->
mApplicationPreference.setAutomaticDiagnosticMonitoring(enabled));
}
return mAutomaticDiagnosticMonitoringToggle;
}
}

View File

@@ -1,7 +1,6 @@
/*
* ******************************************************************************
* sdrtrunk
* Copyright (C) 2014-2018 Dennis Sheirer
* *****************************************************************************
* 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
@@ -15,7 +14,7 @@
*
* 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.log;
@@ -30,16 +29,15 @@ import com.google.common.eventbus.Subscribe;
import io.github.dsheirer.eventbus.MyEventBus;
import io.github.dsheirer.preference.PreferenceType;
import io.github.dsheirer.preference.UserPreferences;
import org.apache.commons.io.FileUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.io.IOException;
import java.net.URL;
import java.nio.file.Path;
import java.util.Enumeration;
import java.util.jar.Attributes;
import java.util.jar.Manifest;
import org.apache.commons.io.FileUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
/**
* Logback and SLF4j logging implementation.
@@ -182,7 +180,11 @@ public class ApplicationLog
}
}
private Attributes findManifestAttributes() {
/**
* Finds the jar manifest attributes
* @return attributes or null.
*/
public Attributes findManifestAttributes() {
try {
Enumeration<URL> resources = getClass().getClassLoader().getResources("META-INF/MANIFEST.MF");
while (resources.hasMoreElements()) {
@@ -197,9 +199,12 @@ public class ApplicationLog
return null;
}
}
} catch (Exception ex) {
}
catch (Exception ex)
{
return null;
}
return null;
}
}

View File

@@ -1,6 +1,6 @@
/*
* *****************************************************************************
* Copyright (C) 2014-2023 Dennis Sheirer
* 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
@@ -145,11 +145,10 @@ public abstract class AnalogDecoderState extends DecoderState implements ISource
@Override
public void start()
{
super.start();
getIdentifierCollection().update(getChannelNameIdentifier());
}
@Override
public void stop() {}
@Override
public void init() {}
@Override

View File

@@ -1,6 +1,6 @@
/*
* *****************************************************************************
* Copyright (C) 2014-2023 Dennis Sheirer
* 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
@@ -115,9 +115,4 @@ public class DCSDecoderState extends DecoderState
public void init()
{
}
@Override
public void stop()
{
}
}

View File

@@ -46,6 +46,7 @@ import io.github.dsheirer.module.decode.dmr.identifier.DMRTalkgroup;
import io.github.dsheirer.module.decode.dmr.message.DMRMessage;
import io.github.dsheirer.module.decode.dmr.message.data.DataMessage;
import io.github.dsheirer.module.decode.dmr.message.data.csbk.CSBKMessage;
import io.github.dsheirer.module.decode.dmr.message.data.csbk.UnknownCSBKMessage;
import io.github.dsheirer.module.decode.dmr.message.data.csbk.hytera.HyteraTrafficChannelTalkerStatus;
import io.github.dsheirer.module.decode.dmr.message.data.csbk.motorola.CapacityMaxAdvantageModeVoiceChannelUpdate;
import io.github.dsheirer.module.decode.dmr.message.data.csbk.motorola.CapacityMaxAloha;
@@ -886,7 +887,12 @@ public class DMRDecoderState extends TimeslotDecoderState
}
else
{
mLog.error("Unrecognized DMR channel grant CSBK ignored: " + csbk.getClass());
//Log when a CSBK that is not the Unknown CSBK is processed, to detect when new opcodes are added
//that are not ChannelGrant subclass implementations.
if(!(csbk instanceof UnknownCSBKMessage))
{
mLog.error("Unrecognized DMR channel grant CSBK ignored: " + csbk.getClass());
}
}
break;
case MOTOROLA_CAPMAX_ALOHA:
@@ -1472,6 +1478,8 @@ public class DMRDecoderState extends TimeslotDecoderState
@Override
public void start()
{
super.start();
//Change the default (45-second) traffic channel timeout to 1 second
if(mChannel.isTrafficChannel())
{
@@ -1483,9 +1491,4 @@ public class DMRDecoderState extends TimeslotDecoderState
public void init()
{
}
@Override
public void stop()
{
}
}

View File

@@ -201,6 +201,9 @@ public class DMRTrafficChannelManager extends TrafficChannelManager implements I
}
mAvailableTrafficChannels.addAll(trafficChannelList);
//Keep track of the complete list so that we can check channel events to determine if the channel event
//is for a traffic channel owned by this traffic channel manager.
mAllocatedTrafficChannels = Collections.unmodifiableList(trafficChannelList);
}
}
@@ -795,7 +798,10 @@ public class DMRTrafficChannelManager extends TrafficChannelManager implements I
}
/**
* Process traffic channel processing stop or processing start rejected events.
/**
* Process channel events from the ChannelProcessingManager to account for owned child traffic channels.
* Note: this method sees events for ALL channels and not just DMR channels managed by this instance.
*
* @param channelEvent to process
*/
@Override
@@ -803,7 +809,8 @@ public class DMRTrafficChannelManager extends TrafficChannelManager implements I
{
Channel channel = channelEvent.getChannel();
if(channel.isTrafficChannel())
//Only process the event if it's one of the traffic channels managed by this instance.
if(mAllocatedTrafficChannels.contains(channel))
{
switch(channelEvent.getEvent())
{

View File

@@ -1,6 +1,6 @@
/*
* *****************************************************************************
* Copyright (C) 2014-2023 Dennis Sheirer
* 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
@@ -30,7 +30,6 @@ import io.github.dsheirer.module.decode.dmr.identifier.DMRTalkgroup;
import io.github.dsheirer.module.decode.dmr.message.CACH;
import io.github.dsheirer.module.decode.dmr.message.data.SlotType;
import io.github.dsheirer.module.decode.dmr.message.data.csbk.CSBKMessage;
import java.util.ArrayList;
import java.util.List;
@@ -281,18 +280,19 @@ public class CapacityMaxAdvantageModeVoiceChannelUpdate extends CSBKMessage impl
public int[] getLogicalChannelNumbers()
{
//Since both timeslots share the same LCN, we use just TS1's channel for both channel 1 and channel 2
if(hasChannel1Timeslot1() && hasChannel2Timeslot1())
if((hasChannel1Timeslot1() || hasChannel1Timeslot2()) && (hasChannel2Timeslot1() || hasChannel2Timeslot2()))
{
return new int[]{getChannel1TS1().getChannelId(), getChannel2TS1().getChannelId()};
}
else if(hasChannel1Timeslot1())
else if((hasChannel1Timeslot1() || hasChannel1Timeslot2()))
{
return new int[]{getChannel1TS1().getChannelId()};
}
else if(hasChannel2Timeslot1())
else if((hasChannel2Timeslot1() || hasChannel2Timeslot2()))
{
return new int[]{getChannel2TS1().getChannelId()};
}
return getChannel1TS1().getLogicalChannelNumbers();
}

View File

@@ -1,6 +1,6 @@
/*
* *****************************************************************************
* Copyright (C) 2014-2023 Dennis Sheirer
* 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
@@ -53,20 +53,7 @@ public class Fleetsync2DecoderState extends DecoderState
}
@Override
public void start()
{
}
@Override
public void stop()
{
}
@Override
public void init()
{
}
public void init() {}
@Override
public void receive(IMessage message)

View File

@@ -1,6 +1,6 @@
/*
* *****************************************************************************
* Copyright (C) 2014-2023 Dennis Sheirer
* 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
@@ -150,20 +150,5 @@ public class LJ1200DecoderState extends DecoderState
}
@Override
public void start()
{
}
@Override
public void stop()
{
}
@Override
public void init()
{
}
public void init() {}
}

View File

@@ -1,6 +1,6 @@
/*
* *****************************************************************************
* Copyright (C) 2014-2023 Dennis Sheirer
* 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
@@ -586,19 +586,7 @@ public class LTRNetDecoderState extends DecoderState
}
@Override
public void start()
{
}
@Override
public void stop()
{
}
@Override
public void init()
{
}
public void init() {}
/**
* Resets the decoder state after a call or other decode event

View File

@@ -1,6 +1,6 @@
/*
* *****************************************************************************
* Copyright (C) 2014-2023 Dennis Sheirer
* 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
@@ -153,19 +153,7 @@ public class LTRStandardDecoderState extends DecoderState
}
@Override
public void start()
{
}
@Override
public void stop()
{
}
@Override
public void init()
{
}
public void init() {}
/**
* Performs a temporal reset following a call or other decode event

View File

@@ -1,6 +1,6 @@
/*
* *****************************************************************************
* Copyright (C) 2014-2023 Dennis Sheirer
* 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
@@ -58,22 +58,7 @@ public class MDCDecoderState extends DecoderState
}
@Override
public void start()
{
}
@Override
public void stop()
{
}
@Override
public void init()
{
}
public void init() {}
@Override
public void receive(IMessage message)

View File

@@ -1,6 +1,6 @@
/*
* *****************************************************************************
* Copyright (C) 2014-2023 Dennis Sheirer
* 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
@@ -220,6 +220,7 @@ public class MPT1327DecoderState extends DecoderState
@Override
public void start()
{
super.start();
//Send call start event for traffic channels to unsquelch the audio. Decoded return to channel message
//or fade timeout expire will end the call event.
if(mChannelType == ChannelType.TRAFFIC)
@@ -228,18 +229,8 @@ public class MPT1327DecoderState extends DecoderState
broadcast(new DecoderStateEvent(this, Event.START, State.CALL));
}
}
@Override
public void stop()
{
}
@Override
public void init()
{
}
public void init() {}
protected void resetState()
{

View File

@@ -1,6 +1,6 @@
/*
* *****************************************************************************
* Copyright (C) 2014-2023 Dennis Sheirer
* 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
@@ -301,6 +301,13 @@ public class MPT1327TrafficChannelManager extends TrafficChannelManager implemen
*/
public class TrafficChannelTeardownMonitor implements Listener<ChannelEvent>
{
/**
* Process channel events from the ChannelProcessingManager to account for owned child traffic channels.
* Note: this method sees events for ALL channels and not just MPT1327 channels managed by this instance.
*
* @param channelEvent to process
*/
@Override
public synchronized void receive(ChannelEvent channelEvent)
{

View File

@@ -1,6 +1,6 @@
/*
* *****************************************************************************
* Copyright (C) 2014-2023 Dennis Sheirer
* 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
@@ -309,6 +309,10 @@ public class P25TrafficChannelManager extends TrafficChannelManager implements I
broadcast(event);
SourceConfigTuner sourceConfig = new SourceConfigTuner();
sourceConfig.setFrequency(frequency);
if(mParentChannel.getSourceConfiguration() instanceof SourceConfigTuner parentConfigTuner)
{
sourceConfig.setPreferredTuner(parentConfigTuner.getPreferredTuner());
}
trafficChannel.setSourceConfiguration(sourceConfig);
mAllocatedTrafficChannelMap.put(frequency, trafficChannel);
@@ -356,6 +360,10 @@ public class P25TrafficChannelManager extends TrafficChannelManager implements I
SourceConfigTuner sourceConfig = new SourceConfigTuner();
sourceConfig.setFrequency(frequency);
if(mParentChannel.getSourceConfiguration() instanceof SourceConfigTuner parentConfigTuner)
{
sourceConfig.setPreferredTuner(parentConfigTuner.getPreferredTuner());
}
trafficChannel.setSourceConfiguration(sourceConfig);
mAllocatedTrafficChannelMap.put(frequency, trafficChannel);
@@ -455,6 +463,10 @@ public class P25TrafficChannelManager extends TrafficChannelManager implements I
broadcast(event);
SourceConfigTuner sourceConfig = new SourceConfigTuner();
sourceConfig.setFrequency(frequency);
if(mParentChannel.getSourceConfiguration() instanceof SourceConfigTuner parentConfigTuner)
{
sourceConfig.setPreferredTuner(parentConfigTuner.getPreferredTuner());
}
trafficChannel.setSourceConfiguration(sourceConfig);
mAllocatedTrafficChannelMap.put(frequency, trafficChannel);
@@ -517,6 +529,10 @@ public class P25TrafficChannelManager extends TrafficChannelManager implements I
SourceConfigTuner sourceConfig = new SourceConfigTuner();
sourceConfig.setFrequency(frequency);
if(mParentChannel.getSourceConfiguration() instanceof SourceConfigTuner parentConfigTuner)
{
sourceConfig.setPreferredTuner(parentConfigTuner.getPreferredTuner());
}
trafficChannel.setSourceConfiguration(sourceConfig);
mAllocatedTrafficChannelMap.put(frequency, trafficChannel);
@@ -778,6 +794,12 @@ public class P25TrafficChannelManager extends TrafficChannelManager implements I
}
}
/**
* Process channel events from the ChannelProcessingManager to account for owned child traffic channels.
* Note: this method sees events for ALL channels and not just P25 channels managed by this instance.
*
* @param channelEvent to process
*/
@Override
public synchronized void receive(ChannelEvent channelEvent)
{

View File

@@ -1,6 +1,6 @@
/*
* *****************************************************************************
* Copyright (C) 2014-2023 Dennis Sheirer
* 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
@@ -1948,6 +1948,7 @@ public class P25P1DecoderState extends DecoderState implements IChannelEventList
@Override
public void start()
{
super.start();
mPatchGroupManager.clear();
//Change the default (45-second) traffic channel timeout to 1 second
@@ -1965,6 +1966,7 @@ public class P25P1DecoderState extends DecoderState implements IChannelEventList
@Override
public void stop()
{
super.stop();
mPatchGroupManager.clear();
}
}

View File

@@ -1,7 +1,6 @@
/*
* ******************************************************************************
* sdrtrunk
* Copyright (C) 2014-2019 Dennis Sheirer
* *****************************************************************************
* 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
@@ -15,23 +14,21 @@
*
* 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.module.decode.p25.phase1.message.ldu;
import io.github.dsheirer.bits.CorrectedBinaryMessage;
import io.github.dsheirer.module.decode.p25.phase1.message.P25Message;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.util.ArrayList;
import java.util.List;
/**
* LDU voice frame
*/
public abstract class LDUMessage extends P25Message
{
private final static Logger mLog = LoggerFactory.getLogger(LDUMessage.class);
public static final int IMBE_FRAME_1 = 0;
public static final int IMBE_FRAME_2 = 144;
public static final int IMBE_FRAME_3 = 328;
@@ -41,10 +38,16 @@ public abstract class LDUMessage extends P25Message
public static final int IMBE_FRAME_7 = 1064;
public static final int IMBE_FRAME_8 = 1248;
public static final int IMBE_FRAME_9 = 1424;
public static final int[] LOW_SPEED_DATA = {1392, 1393, 1394, 1395, 1396, 1397, 1398, 1399, 1408, 1409, 1410, 1411,
1412, 1413, 1414, 1415};
private List<byte[]> mIMBIFrames;
public static final int[] LOW_SPEED_DATA = {1392, 1393, 1394, 1395, 1396, 1397,
1398, 1399, 1408, 1409, 1410, 1411, 1412, 1413, 1414, 1415};
/**
* Constructs an instance
* @param message with data
* @param nac code
* @param timestamp for the message
*/
public LDUMessage(CorrectedBinaryMessage message, int nac, long timestamp)
{
super(message, nac, timestamp);
@@ -58,6 +61,10 @@ public abstract class LDUMessage extends P25Message
return getMessage().getHex(LOW_SPEED_DATA, 4);
}
/**
* Base message used by subclass implementations.
* @return base message
*/
public String getMessageStub()
{
StringBuilder sb = new StringBuilder();
@@ -70,24 +77,25 @@ public abstract class LDUMessage extends P25Message
}
/**
* Returns a 162 byte array containing 9 IMBE voice frames of 18-bytes
* (144-bits) each. Each frame is intact as transmitted and requires
* deinterleaving, error correction, derandomizing, etc.
* Returns a 162 byte array containing 9 IMBE voice frames of 18-bytes* (144-bits) each. Each frame is intact as
* transmitted and requires deinterleaving, error correction, derandomizing, etc.
*/
public List<byte[]> getIMBEFrames()
public synchronized List<byte[]> getIMBEFrames()
{
List<byte[]> frames = new ArrayList<byte[]>();
if(mIMBIFrames == null)
{
mIMBIFrames = new ArrayList<>();
mIMBIFrames.add(getMessage().get(IMBE_FRAME_1, IMBE_FRAME_1 + 144).toByteArray());
mIMBIFrames.add(getMessage().get(IMBE_FRAME_2, IMBE_FRAME_2 + 144).toByteArray());
mIMBIFrames.add(getMessage().get(IMBE_FRAME_3, IMBE_FRAME_3 + 144).toByteArray());
mIMBIFrames.add(getMessage().get(IMBE_FRAME_4, IMBE_FRAME_4 + 144).toByteArray());
mIMBIFrames.add(getMessage().get(IMBE_FRAME_5, IMBE_FRAME_5 + 144).toByteArray());
mIMBIFrames.add(getMessage().get(IMBE_FRAME_6, IMBE_FRAME_6 + 144).toByteArray());
mIMBIFrames.add(getMessage().get(IMBE_FRAME_7, IMBE_FRAME_7 + 144).toByteArray());
mIMBIFrames.add(getMessage().get(IMBE_FRAME_8, IMBE_FRAME_8 + 144).toByteArray());
mIMBIFrames.add(getMessage().get(IMBE_FRAME_9, IMBE_FRAME_9 + 144).toByteArray());
}
frames.add(getMessage().get(IMBE_FRAME_1, IMBE_FRAME_1 + 144).toByteArray());
frames.add(getMessage().get(IMBE_FRAME_2, IMBE_FRAME_2 + 144).toByteArray());
frames.add(getMessage().get(IMBE_FRAME_3, IMBE_FRAME_3 + 144).toByteArray());
frames.add(getMessage().get(IMBE_FRAME_4, IMBE_FRAME_4 + 144).toByteArray());
frames.add(getMessage().get(IMBE_FRAME_5, IMBE_FRAME_5 + 144).toByteArray());
frames.add(getMessage().get(IMBE_FRAME_6, IMBE_FRAME_6 + 144).toByteArray());
frames.add(getMessage().get(IMBE_FRAME_7, IMBE_FRAME_7 + 144).toByteArray());
frames.add(getMessage().get(IMBE_FRAME_8, IMBE_FRAME_8 + 144).toByteArray());
frames.add(getMessage().get(IMBE_FRAME_9, IMBE_FRAME_9 + 144).toByteArray());
return frames;
return mIMBIFrames;
}
}

View File

@@ -1,6 +1,6 @@
/*
* *****************************************************************************
* Copyright (C) 2014-2023 Dennis Sheirer
* 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
@@ -1161,6 +1161,7 @@ public class P25P2DecoderState extends TimeslotDecoderState implements Identifie
@Override
public void start()
{
super.start();
mPatchGroupManager.clear();
//Change the default (45-second) traffic channel timeout to 1 second
@@ -1178,6 +1179,7 @@ public class P25P2DecoderState extends TimeslotDecoderState implements Identifie
@Override
public void stop()
{
super.stop();
mPatchGroupManager.clear();
}
}

View File

@@ -1,23 +1,20 @@
/*
* *****************************************************************************
* Copyright (C) 2014-2024 Dennis Sheirer
*
* * ******************************************************************************
* * Copyright (C) 2014-2019 Dennis Sheirer
* *
* * This 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/>
* * *****************************************************************************
* This 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.module.decode.p25.phase2.timeslot;
@@ -25,7 +22,6 @@ package io.github.dsheirer.module.decode.p25.phase2.timeslot;
import io.github.dsheirer.bits.BinaryMessage;
import io.github.dsheirer.bits.CorrectedBinaryMessage;
import io.github.dsheirer.module.decode.p25.phase2.enumeration.DataUnitID;
import java.util.ArrayList;
import java.util.List;
@@ -61,7 +57,7 @@ public class Voice2Timeslot extends AbstractVoiceTimeslot
/**
* Voice frames contained in this timeslot
*/
public List<BinaryMessage> getVoiceFrames()
public synchronized List<BinaryMessage> getVoiceFrames()
{
if(mVoiceFrames == null)
{

View File

@@ -1,23 +1,20 @@
/*
* *****************************************************************************
* Copyright (C) 2014-2024 Dennis Sheirer
*
* * ******************************************************************************
* * Copyright (C) 2014-2019 Dennis Sheirer
* *
* * This 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/>
* * *****************************************************************************
* This 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.module.decode.p25.phase2.timeslot;
@@ -25,7 +22,6 @@ package io.github.dsheirer.module.decode.p25.phase2.timeslot;
import io.github.dsheirer.bits.BinaryMessage;
import io.github.dsheirer.bits.CorrectedBinaryMessage;
import io.github.dsheirer.module.decode.p25.phase2.enumeration.DataUnitID;
import java.util.ArrayList;
import java.util.List;
@@ -62,7 +58,7 @@ public class Voice4Timeslot extends AbstractVoiceTimeslot
/**
* Voice frames contained in this timeslot
*/
public List<BinaryMessage> getVoiceFrames()
public synchronized List<BinaryMessage> getVoiceFrames()
{
if(mVoiceFrames == null)
{
@@ -71,7 +67,6 @@ public class Voice4Timeslot extends AbstractVoiceTimeslot
mVoiceFrames.add(getMessage().getSubMessage(FRAME_2_START, FRAME_2_START + FRAME_LENGTH));
mVoiceFrames.add(getMessage().getSubMessage(FRAME_3_START, FRAME_3_START + FRAME_LENGTH));
mVoiceFrames.add(getMessage().getSubMessage(FRAME_4_START, FRAME_4_START + FRAME_LENGTH));
return mVoiceFrames;
}
return mVoiceFrames;

View File

@@ -1,6 +1,6 @@
/*
* *****************************************************************************
* Copyright (C) 2014-2023 Dennis Sheirer
* 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
@@ -327,22 +327,7 @@ public class PassportDecoderState extends DecoderState
}
@Override
public void start()
{
}
@Override
public void stop()
{
}
@Override
public void init()
{
}
public void init() {}
protected void resetState()
{

View File

@@ -1,6 +1,6 @@
/*
* *****************************************************************************
* Copyright (C) 2014-2023 Dennis Sheirer
* 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
@@ -58,22 +58,7 @@ public class Tait1200DecoderState extends DecoderState
}
@Override
public void start()
{
}
@Override
public void stop()
{
}
@Override
public void init()
{
}
public void init() {}
@Override
public void receive(IMessage message)

View File

@@ -0,0 +1,325 @@
/*
* *****************************************************************************
* 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.monitor;
import io.github.dsheirer.controller.channel.ChannelProcessingManager;
import io.github.dsheirer.log.LoggingSuppressor;
import io.github.dsheirer.preference.UserPreferences;
import io.github.dsheirer.source.tuner.manager.TunerManager;
import io.github.dsheirer.util.ThreadPool;
import io.github.dsheirer.util.TimeStamp;
import java.io.IOException;
import java.lang.management.ManagementFactory;
import java.lang.management.ThreadInfo;
import java.lang.management.ThreadMXBean;
import java.net.URL;
import java.nio.file.Files;
import java.nio.file.Path;
import java.util.Enumeration;
import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.ScheduledFuture;
import java.util.concurrent.TimeUnit;
import java.util.jar.Attributes;
import java.util.jar.Manifest;
import org.apache.commons.io.FileUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import javax.swing.JOptionPane;
/**
* Utility class for monitoring system components and producing logging reports.
*/
public class DiagnosticMonitor
{
private static final Logger LOGGER = LoggerFactory.getLogger(DiagnosticMonitor.class);
private final LoggingSuppressor LOG_SUPPRESSOR = new LoggingSuppressor(LOGGER);
private static final String DIVIDER = "\n\n=========================================================================\n\n";
private UserPreferences mUserPreferences;
private ChannelProcessingManager mChannelProcessingManager;
private TunerManager mTunerManager;
private ScheduledFuture<?> mBlockedThreadMonitorHandle;
private BlockedThreadMonitor mMonitor = new BlockedThreadMonitor();
private boolean mUserAlertedToBlockedThreadCondition = false;
private Map<Integer,Integer> mBlockedThreadDetectionCountMap = new HashMap<>();
private boolean mHeadless;
/**
* Constructs an instance
* @param userPreferences for application logging directory lookup.
* @param channelProcessingManager for accessing running channel information
* @param tunerManager for accessing allocated tuner channel information
* @param headless to indicate if the thread deadlock monitor should show a user notification.
*/
public DiagnosticMonitor(UserPreferences userPreferences, ChannelProcessingManager channelProcessingManager,
TunerManager tunerManager, boolean headless)
{
mUserPreferences = userPreferences;
mChannelProcessingManager = channelProcessingManager;
mTunerManager = tunerManager;
mHeadless = headless;
}
/**
* Starts monitoring for blocked threads
*/
public void start()
{
if(mBlockedThreadMonitorHandle != null)
{
mBlockedThreadMonitorHandle.cancel(true);
}
if(mUserPreferences.getApplicationPreference().isAutomaticDiagnosticMonitoring())
{
LOGGER.info("Diagnostic monitoring enabled running every 30 seconds");
mBlockedThreadMonitorHandle = ThreadPool.SCHEDULED.scheduleAtFixedRate(mMonitor, 30, 30, TimeUnit.SECONDS);
}
else
{
LOGGER.info("Diagnostic monitoring disabled per user preference (application).");
}
}
/**
* Stops monitoring for blocked threads.
*/
public void stop()
{
if(mBlockedThreadMonitorHandle != null)
{
mBlockedThreadMonitorHandle.cancel(true);
}
mBlockedThreadMonitorHandle = null;
}
/**
* Checks for blocked threads and on discovery, generates a diagnostic report and notifies the user (once).
*/
private void checkForBlockedThreads()
{
if(!mUserAlertedToBlockedThreadCondition)
{
try
{
ThreadMXBean bean = ManagementFactory.getThreadMXBean();
long ids[] = bean.findDeadlockedThreads();
if(ids != null)
{
mUserAlertedToBlockedThreadCondition = true;
ThreadInfo threadInfo[] = bean.getThreadInfo(ids);
StringBuilder sb = new StringBuilder();
sb.append("sdrtrunk detected a critical application error with a threading deadlock, described as follows:\n");
for (ThreadInfo threadInfo1 : threadInfo)
{
sb.append("Thread ID[").append(threadInfo1.getThreadId());
sb.append("] Name [").append(threadInfo1.getThreadName());
sb.append("] Lock [").append(threadInfo1.getLockName());
sb.append("] Owned By [ID:").append(threadInfo1.getLockOwnerId());
sb.append(" | NAME:").append(threadInfo1.getLockName());
sb.append("]\n");
}
LOGGER.error(sb.toString());
Path reportPath = generateProcessingDiagnosticReport(sb + DIVIDER);
LOGGER.error("Thread deadlock report generated: " + reportPath);
if(!mHeadless)
{
String title = "sdrtrunk: Critical Error Detected";
String message = "The sdrtrunk application has detected a thread deadlock situation.\n" +
"The application may degrade over time and eventually run out of memory.\n" +
"A diagnostic report was generated. Please open an issue on the GitHub\n" +
"website and attach this diagnostic report:\n\n" + reportPath.toString();
JOptionPane.showMessageDialog(null, message, title, JOptionPane.ERROR_MESSAGE);
}
}
}
catch(Exception e)
{
LOG_SUPPRESSOR.error("run error", 1, "Error while monitoring for deadlocked " +
"threads: " + e.getLocalizedMessage());
//Set the flag so that we don't try to run again.
mUserAlertedToBlockedThreadCondition = true;
}
}
}
/**
* Creates a diagnostic report containing state information for channels that are in a processing state.
* @param message to prepend to the report
* @return path for the log file that was created.
*/
public Path generateProcessingDiagnosticReport(String message) throws IOException
{
StringBuilder sb = new StringBuilder();
sb.append(message);
sb.append("\n\nsdrtrunk Processing Diagnostic Report\n");
sb.append(DIVIDER);
sb.append(getEnvironmentReport());
sb.append(DIVIDER);
sb.append(mTunerManager.getDiscoveredTunerModel().getDiagnosticReport());
sb.append(DIVIDER);
sb.append(mChannelProcessingManager.getDiagnosticInformation());
sb.append(DIVIDER);
sb.append(mChannelProcessingManager.getChannelMetadataModel().getDiagnosticInformation());
sb.append(DIVIDER);
sb.append(getThreadDumpReport());
sb.append(DIVIDER);
Path logDirectory = mUserPreferences.getDirectoryPreference().getDirectoryApplicationLog();
String file = TimeStamp.getFileFormattedDateTime() + "_sdrtrunk_processing_diagnostic_report.log";
Path output = logDirectory.resolve(file);
Files.write(output, sb.toString().getBytes());
return output;
}
/**
* Dumps the current threads to a log file with current date and time to the application log directory.
* @return path to the thread dump log file that was created.
* @throws IOException if there is an issue writing the contents to the log file.
*/
public Path generateThreadDumpReport() throws IOException
{
String report = getThreadDumpReport();
Path logDirectory = mUserPreferences.getDirectoryPreference().getDirectoryApplicationLog();
String file = TimeStamp.getFileFormattedDateTime() + "_sdrtrunk_thread_dump.log";
Path output = logDirectory.resolve(file);
Files.write(output, report.getBytes());
return output;
}
/**
* Creates a thread dump report.
* @return report text.
*/
public String getThreadDumpReport()
{
StringBuilder sb = new StringBuilder();
sb.append("Thread Dump Report\n\n");
for(Map.Entry<Thread, StackTraceElement[]> entry : Thread.getAllStackTraces().entrySet())
{
sb.append(entry.getKey() + " " + entry.getKey().getState()).append("\n");
for(StackTraceElement ste : entry.getValue())
{
sb.append("\tat " + ste).append("\n");
}
sb.append("\n\n");
}
return sb.toString();
}
/**
* Generates a JVM and application environment report
*/
public String getEnvironmentReport()
{
StringBuilder sb = new StringBuilder();
sb.append("JVM and Application Environment Report\n");
Attributes atts = findManifestAttributes();
if (atts != null) {
sb.append("\nVersion : " + atts.getValue("Implementation-Version"));
sb.append("\nGradle Version : " + atts.getValue("Created-By"));
sb.append("\nBuild Timestamp : " + atts.getValue("Build-Timestamp"));
sb.append("\nBuild-JDK : " + atts.getValue("Build-JDK"));
sb.append("\nBuild OS : " + atts.getValue("Build-OS"));
}
else
{
sb.append("\nApplication: no build information available");
}
sb.append("\nHost OS Name: " + System.getProperty("os.name"));
sb.append("\nHost OS Arch: " + System.getProperty("os.arch"));
sb.append("\nHost OS Version: " + System.getProperty("os.version"));
sb.append("\nHost CPU Cores: " + Runtime.getRuntime().availableProcessors());
sb.append("\nHost Max Java Memory: " + FileUtils.byteCountToDisplaySize(Runtime.getRuntime().maxMemory()));
sb.append("\nHost Allocated Memory: " + FileUtils.byteCountToDisplaySize(Runtime.getRuntime().totalMemory()));
sb.append("\nHost Free Memory: " + FileUtils.byteCountToDisplaySize(Runtime.getRuntime().freeMemory()));
sb.append("\nHost Used Memory: " + FileUtils.byteCountToDisplaySize(Runtime.getRuntime().totalMemory() -
Runtime.getRuntime().freeMemory()));
sb.append("\nStorage Directories:");
sb.append("\n Application Root: " + mUserPreferences.getDirectoryPreference().getDirectoryApplicationRoot());
sb.append("\n Application Log: " + mUserPreferences.getDirectoryPreference().getDirectoryApplicationLog());
sb.append("\n Event Log: " + mUserPreferences.getDirectoryPreference().getDirectoryEventLog());
sb.append("\n Playlist: " + mUserPreferences.getDirectoryPreference().getDirectoryPlaylist());
sb.append("\n Recordings: " + mUserPreferences.getDirectoryPreference().getDirectoryRecording());
sb.append("\n");
return sb.toString();
}
/**
* Finds the jar manifest attributes
* @return attributes or null.
*/
public Attributes findManifestAttributes() {
try {
Enumeration<URL> resources = getClass().getClassLoader().getResources("META-INF/MANIFEST.MF");
while (resources.hasMoreElements()) {
try {
Manifest manifest = new Manifest(resources.nextElement().openStream());
Attributes atts = manifest.getMainAttributes();
Boolean hasTitle = atts.containsValue("sdrtrunk project");
if (hasTitle) {
return atts;
}
} catch (IOException E) {
return null;
}
}
}
catch (Exception ex)
{
return null;
}
return null;
}
/**
* Runnable to periodically check for blocked threads
*/
public class BlockedThreadMonitor implements Runnable
{
@Override
public void run()
{
try
{
checkForBlockedThreads();
}
catch(Throwable t)
{
LOG_SUPPRESSOR.error("Error", 3, "Error while checking for blocked threads", t);
}
}
}
}

View File

@@ -1,6 +1,6 @@
/*
* *****************************************************************************
* Copyright (C) 2014-2023 Dennis Sheirer
* 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
@@ -31,11 +31,13 @@ import org.slf4j.LoggerFactory;
*/
public class ApplicationPreference extends Preference
{
private static final String PREFERENCE_KEY_CHANNEL_AUTO_DIAGNOSTIC_MONITORING = "automatic.diagnostic.monitoring";
private static final String PREFERENCE_KEY_CHANNEL_AUTO_START_TIMEOUT = "channel.auto.start.timeout";
private final static Logger mLog = LoggerFactory.getLogger(ApplicationPreference.class);
private Preferences mPreferences = Preferences.userNodeForPackage(ApplicationPreference.class);
private Integer mChannelAutoStartTimeout;
private Boolean mAutomaticDiagnosticMonitoring;
/**
* Constructs an instance
@@ -77,4 +79,29 @@ public class ApplicationPreference extends Preference
mPreferences.putInt(PREFERENCE_KEY_CHANNEL_AUTO_START_TIMEOUT, timeout);
notifyPreferenceUpdated();
}
/**
* Indicates if automatic diagnostic monitoring is enabled.
* @return enabled.
*/
public boolean isAutomaticDiagnosticMonitoring()
{
if(mAutomaticDiagnosticMonitoring == null)
{
mAutomaticDiagnosticMonitoring = mPreferences.getBoolean(PREFERENCE_KEY_CHANNEL_AUTO_DIAGNOSTIC_MONITORING, true);
}
return mAutomaticDiagnosticMonitoring;
}
/**
* Sets the enabled state for automatic diagnostic monitoring.
* @param enabled true to turn on monitoring.
*/
public void setAutomaticDiagnosticMonitoring(boolean enabled)
{
mAutomaticDiagnosticMonitoring = enabled;
mPreferences.putBoolean(PREFERENCE_KEY_CHANNEL_AUTO_DIAGNOSTIC_MONITORING, enabled);
notifyPreferenceUpdated();
}
}

View File

@@ -1,6 +1,6 @@
/*
* *****************************************************************************
* Copyright (C) 2014-2023 Dennis Sheirer
* 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
@@ -72,6 +72,7 @@ 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;
@@ -87,6 +88,12 @@ import io.github.dsheirer.source.tuner.sdrplay.rsp1a.IControlRsp1a;
import io.github.dsheirer.source.tuner.sdrplay.rsp1a.Rsp1aTunerConfiguration;
import io.github.dsheirer.source.tuner.sdrplay.rsp1a.Rsp1aTunerController;
import io.github.dsheirer.source.tuner.sdrplay.rsp1a.Rsp1aTunerEditor;
import io.github.dsheirer.source.tuner.sdrplay.rsp1b.ControlRsp1b;
import io.github.dsheirer.source.tuner.sdrplay.rsp1b.DiscoveredRsp1bTuner;
import io.github.dsheirer.source.tuner.sdrplay.rsp1b.IControlRsp1b;
import io.github.dsheirer.source.tuner.sdrplay.rsp1b.Rsp1bTunerConfiguration;
import io.github.dsheirer.source.tuner.sdrplay.rsp1b.Rsp1bTunerController;
import io.github.dsheirer.source.tuner.sdrplay.rsp1b.Rsp1bTunerEditor;
import io.github.dsheirer.source.tuner.sdrplay.rsp2.ControlRsp2;
import io.github.dsheirer.source.tuner.sdrplay.rsp2.DiscoveredRsp2Tuner;
import io.github.dsheirer.source.tuner.sdrplay.rsp2.IControlRsp2;
@@ -148,6 +155,9 @@ public class TunerFactory
case RSP1A:
tuners.add(new DiscoveredRsp1aTuner(deviceInfo, channelizerType));
break;
case RSP1B:
tuners.add(new DiscoveredRsp1bTuner(deviceInfo, channelizerType));
break;
case RSP2:
tuners.add(new DiscoveredRsp2Tuner(deviceInfo, channelizerType));
break;
@@ -228,6 +238,14 @@ public class TunerFactory
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)
{
@@ -411,6 +429,8 @@ public class TunerFactory
return new Rsp1TunerConfiguration(uniqueID);
case RSP_1A:
return new Rsp1aTunerConfiguration(uniqueID);
case RSP_1B:
return new Rsp1bTunerConfiguration(uniqueID);
case RSP_2:
return new Rsp2TunerConfiguration(uniqueID);
case RSP_DUO_1:
@@ -451,6 +471,8 @@ public class TunerFactory
return new Rsp1TunerEditor(userPreferences, tunerManager, discoveredRspTuner);
case RSP1A:
return new Rsp1aTunerEditor(userPreferences, tunerManager, discoveredRspTuner);
case RSP1B:
return new Rsp1bTunerEditor(userPreferences, tunerManager, discoveredRspTuner);
case RSP2:
return new Rsp2TunerEditor(userPreferences, tunerManager, discoveredRspTuner);
case RSPdx:

View File

@@ -1,6 +1,6 @@
/*
* *****************************************************************************
* Copyright (C) 2014-2023 Dennis Sheirer
* 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
@@ -40,6 +40,7 @@ public enum TunerType
RAFAELMICRO_R828D("R828D"),
RSP_1("RSP1"),
RSP_1A("RSP1A"),
RSP_1B("RSP1B"),
RSP_2("RSP2"),
RSP_DUO_1("RSPduo Tuner 1"),
RSP_DUO_2("RSPduo Tuner 2"),

View File

@@ -1,6 +1,6 @@
/*
* *****************************************************************************
* Copyright (C) 2014-2023 Dennis Sheirer
* 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
@@ -59,13 +59,27 @@ public abstract class DiscoveredTuner implements ITunerErrorListener
* Logs current state of the tuner
*/
public void logState()
{
mLog.info(getDiagnosticReport());
}
/**
* Generates a state report for this tuner.
* @return
*/
public String getDiagnosticReport()
{
StringBuilder sb = new StringBuilder();
sb.append("Discovered Tuner: ").append(getId());
sb.append("\n\tClass:").append(getClass());
if(hasTuner())
{
sb.append("\n\tTuner - Frequency:").append(getTuner().getTunerController().getFrequency());
sb.append("\n\tTuner Class:").append(getTuner().getClass());
sb.append("\n\tTuner Controller Class:").append(getTuner().getTunerController().getClass());
sb.append("\n\tFrequency:").append(getTuner().getTunerController().getFrequency());
sb.append("\n\tError:").append(getErrorMessage());
sb.append("\n\tChannel Manager Class:").append(getTuner().getChannelSourceManager().getClass());
sb.append("\n\tChannel Manager:").append(getTuner().getChannelSourceManager().getStateDescription());
}
else
@@ -73,7 +87,7 @@ public abstract class DiscoveredTuner implements ITunerErrorListener
sb.append("\n\tTuner - no tuner");
}
mLog.info(sb.toString());
return sb.toString();
}
/**

View File

@@ -1,6 +1,6 @@
/*
* *****************************************************************************
* Copyright (C) 2014-2023 Dennis Sheirer
* 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
@@ -72,6 +72,7 @@ public class HeterodyneChannelSourceManager extends ChannelSourceManager
.append("] Frequency [").append(channelSource.getFrequency())
.append("] Mixer [").append(channelSource.getMixerFrequency())
.append("]");
sb.append(" HASH:").append(Integer.toHexString(channelSource.hashCode()).toUpperCase());
}
return sb.toString();

View File

@@ -1,6 +1,6 @@
/*
* *****************************************************************************
* Copyright (C) 2014-2023 Dennis Sheirer
* 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
@@ -776,16 +776,4 @@ public class TunerManager implements IDiscoveredTunerStatusListener
}
}
}
public static void main(String[] args)
{
mLog.info("Starting ...");
UserPreferences userPreferences = new UserPreferences();
TunerManager tunerManager = new TunerManager(userPreferences);
tunerManager.start();
while(true);
// mLog.info("Finished!");
}
}

View File

@@ -1,6 +1,6 @@
/*
* *****************************************************************************
* Copyright (C) 2014-2023 Dennis Sheirer
* 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
@@ -28,7 +28,6 @@ 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.GainReduction;
import io.github.dsheirer.source.tuner.sdrplay.api.parameter.tuner.IfMode;
import io.github.dsheirer.source.tuner.sdrplay.api.parameter.tuner.LoMode;
import io.github.dsheirer.util.ThreadPool;
@@ -45,10 +44,11 @@ public abstract class ControlRsp<T extends Device> implements IControlRsp
private static final Logger mLog = LoggerFactory.getLogger(ControlRsp.class);
private T mDevice;
protected RspSampleRate mSampleRate = RspSampleRate.RATE_8_000;
protected int mGain;
protected int mLNA;
protected int mBasebandGainReduction;
private IDeviceEventListener mDeviceEventListener;
private IStreamListener mStreamListener;
protected WeakReference<IGainOverloadListener> mGainOverloadReference;
protected WeakReference<ITunerStatusListener> mGainOverloadReference;
//Streaming control lock and boolean status indicator. Access to the boolean indicator is protected by the lock.
protected ReentrantLock mStreamingLock = new ReentrantLock();
@@ -242,21 +242,28 @@ public abstract class ControlRsp<T extends Device> implements IControlRsp
}
}
/**
* Sets the gain index
* @param gain index value (0 - 28)
* @throws SDRPlayException
*/
@Override
public void setGain(int gain) throws SDRPlayException
public void setGain(int lna, int gr) throws SDRPlayException
{
validateGain(gain);
int lnaLimited = Math.max(lna, 0);
lnaLimited = Math.min(lnaLimited, getMaximumLNASetting());
if(gain != mGain)
int grLimited = Math.max(gr, 20);
grLimited = Math.min(grLimited, 59);
if(lna != lnaLimited || gr != grLimited)
{
mGain = gain;
getDevice().getTuner().setGain(mGain);
mLog.warn("Setting gain - adjusted LNA from [" + lna + "] to [" + lnaLimited + "] and GR from [" + gr + "] to [" + grLimited + "]");
}
getDevice().getTuner().setGain(lnaLimited, grLimited);
mLNA = lnaLimited;
mBasebandGainReduction = grLimited;
}
@Override
public float getCurrentGain() throws SDRPlayException
{
return getDevice().getTuner().getGain().getGainValues().getCurrent();
}
/**
@@ -264,7 +271,7 @@ public abstract class ControlRsp<T extends Device> implements IControlRsp
* @param listener to register
*/
@Override
public void setGainOverloadListener(IGainOverloadListener listener)
public void setGainOverloadListener(ITunerStatusListener listener)
{
if(mGainOverloadReference != null && mGainOverloadReference.get() != null)
{
@@ -289,7 +296,7 @@ public abstract class ControlRsp<T extends Device> implements IControlRsp
//Notify an optional weakly referenced, registered listener that gain overload has been acknowledged.
if(mGainOverloadReference != null)
{
IGainOverloadListener listener = mGainOverloadReference.get();
ITunerStatusListener listener = mGainOverloadReference.get();
if(listener != null)
{
@@ -317,6 +324,17 @@ public abstract class ControlRsp<T extends Device> implements IControlRsp
if(hasDevice())
{
getDevice().getTuner().setFrequency(frequency);
//Notify an optional weakly referenced, registered listener that gain overload has been acknowledged.
if(mGainOverloadReference != null)
{
ITunerStatusListener listener = mGainOverloadReference.get();
if(listener != null)
{
ThreadPool.CACHED.submit(() -> listener.frequencyUpdated());
}
}
}
else
{
@@ -343,27 +361,23 @@ public abstract class ControlRsp<T extends Device> implements IControlRsp
}
/**
* Current gain index
* @return gain index
* Current LNA gain setting
* @return LNA gain
*/
@Override
public int getGain()
public int getLNA()
{
return mGain;
return mLNA;
}
/**
* Verifies that the requested gain index setting is within the range of valid gain values.
* @param gain to validate
* @throws SDRPlayException if the gain index value is outside the range of valid values.
* Current Baseband gain reduction setting
* @return baseband gain reduction
*/
protected void validateGain(int gain) throws SDRPlayException
@Override
public int getBasebandGainReduction()
{
if(gain < GainReduction.MIN_GAIN_INDEX || gain > GainReduction.MAX_GAIN_INDEX)
{
throw new SDRPlayException("Invalid gain index value [" + gain + "]. Valid range is " +
GainReduction.MIN_GAIN_INDEX + " - " + GainReduction.MAX_GAIN_INDEX);
}
return mBasebandGainReduction;
}
/**

View File

@@ -1,6 +1,6 @@
/*
* *****************************************************************************
* Copyright (C) 2014-2023 Dennis Sheirer
* 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
@@ -116,16 +116,36 @@ public interface IControlRsp
double getCurrentSampleRate();
/**
* Sets the gain index value.
* @param gain index value (0 - 28)
* 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
*/
void setGain(int gain) throws SDRPlayException;
void setGain(int lna, int basebandGainReduction) throws SDRPlayException;
/**
* Current gain index value
* @return gain index value (0 - 28)
* Current gain setting as reported by the device.
* @return gain value in decibels
*/
int getGain();
float getCurrentGain() throws SDRPlayException;
/**
* Current LNA gain index value
* @return LNA gain value.
*/
int getLNA();
/**
* Maximum LNA setting index value.
* @return max LNA that varies by tuner type.
*/
int getMaximumLNASetting();
/**
* Current gain reduction value.
* @return gain reduction value.
*/
int getBasebandGainReduction();
/**
* Current IF AGC mode setting.
@@ -143,5 +163,5 @@ public interface IControlRsp
* Registers a listener to receive notifications of gain overload.
* @param listener to register
*/
void setGainOverloadListener(IGainOverloadListener listener);
void setGainOverloadListener(ITunerStatusListener listener);
}

View File

@@ -1,6 +1,6 @@
/*
* *****************************************************************************
* Copyright (C) 2014-2023 Dennis Sheirer
* 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
@@ -24,7 +24,16 @@ import io.github.dsheirer.source.tuner.sdrplay.api.device.TunerSelect;
/**
* Listener interface to receive notifications of gain overload in the RSP device.
*/
public interface IGainOverloadListener
public interface ITunerStatusListener
{
/**
* Notify that there is a gain overload event in the specified tuner
* @param tunerSelect to id the tuner
*/
void notifyGainOverload(TunerSelect tunerSelect);
/**
* Notify that the tuner's frequency has changed.
*/
void frequencyUpdated();
}

View File

@@ -1,6 +1,6 @@
/*
* *****************************************************************************
* Copyright (C) 2014-2023 Dennis Sheirer
* 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
@@ -24,9 +24,9 @@ import com.fasterxml.jackson.annotation.JsonTypeInfo;
import com.fasterxml.jackson.dataformat.xml.annotation.JacksonXmlProperty;
import io.github.dsheirer.source.tuner.configuration.TunerConfiguration;
import io.github.dsheirer.source.tuner.sdrplay.api.parameter.control.AgcMode;
import io.github.dsheirer.source.tuner.sdrplay.api.parameter.tuner.GainReduction;
import io.github.dsheirer.source.tuner.sdrplay.rsp1.Rsp1TunerConfiguration;
import io.github.dsheirer.source.tuner.sdrplay.rsp1a.Rsp1aTunerConfiguration;
import io.github.dsheirer.source.tuner.sdrplay.rsp1b.Rsp1bTunerConfiguration;
import io.github.dsheirer.source.tuner.sdrplay.rsp2.Rsp2TunerConfiguration;
import io.github.dsheirer.source.tuner.sdrplay.rspDuo.RspDuoTuner1Configuration;
import io.github.dsheirer.source.tuner.sdrplay.rspDuo.RspDuoTuner2Configuration;
@@ -39,6 +39,7 @@ import io.github.dsheirer.source.tuner.sdrplay.rspDx.RspDxTunerConfiguration;
@JsonSubTypes({
@JsonSubTypes.Type(value = Rsp1TunerConfiguration.class, name = "rsp1TunerConfiguration"),
@JsonSubTypes.Type(value = Rsp1aTunerConfiguration.class, name = "rsp1aTunerConfiguration"),
@JsonSubTypes.Type(value = Rsp1bTunerConfiguration.class, name = "rsp1bTunerConfiguration"),
@JsonSubTypes.Type(value = Rsp2TunerConfiguration.class, name = "rsp2TunerConfiguration"),
@JsonSubTypes.Type(value = RspDuoTuner1Configuration.class, name = "rspDuoTuner1Configuration"),
@JsonSubTypes.Type(value = RspDuoTuner2Configuration.class, name = "rspDuoTuner2Configuration"),
@@ -50,7 +51,8 @@ public abstract class RspTunerConfiguration extends TunerConfiguration
public static final RspSampleRate DEFAULT_DUAL_TUNER_SAMPLE_RATE = RspSampleRate.DUO_RATE_2_000;
private RspSampleRate mRspSampleRate = DEFAULT_SINGLE_TUNER_SAMPLE_RATE;
private int mGain = 24;
private int mLNA = 0;
private int mBasebandGainReduction = 50;
private AgcMode mAgcMode = AgcMode.ENABLE;
/**
@@ -87,25 +89,41 @@ public abstract class RspTunerConfiguration extends TunerConfiguration
}
/**
* Gain index to use
* @return gain index, 0 - 28
* LNA setting
* @return LNA setting
*/
@JacksonXmlProperty(isAttribute = true, localName = "gain")
public int getGain()
@JacksonXmlProperty(isAttribute = true, localName = "lna")
public int getLNA()
{
return mGain;
return mLNA;
}
/**
* Sets the gain index
* @param gain index, 0 - 28
* Sets the LNA state
* @param LNA state, 0 - xx, varies by tuner and frequency range.
*/
public void setGain(int gain)
public void setLNA(int lna)
{
if(GainReduction.MIN_GAIN_INDEX <= gain && gain <= GainReduction.MAX_GAIN_INDEX)
{
mGain = gain;
}
mLNA = lna;
}
/**
* Baseband gain reduction
* @return gain reduction in range 20-59 dB
*/
@JacksonXmlProperty(isAttribute = true, localName = "gr")
public int getBasebandGainReduction()
{
return mBasebandGainReduction;
}
/**
* Sets the baseband gain reduction value.
* @param basebandGainReduction value
*/
public void setBasebandGainReduction(int basebandGainReduction)
{
mBasebandGainReduction = basebandGainReduction;
}
/**

View File

@@ -1,6 +1,6 @@
/*
* *****************************************************************************
* Copyright (C) 2014-2023 Dennis Sheirer
* 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
@@ -91,11 +91,13 @@ public abstract class RspTunerController<I extends IControlRsp> extends TunerCon
try
{
getControlRsp().setGain(rtc.getGain());
int lna = rtc.getLNA();
int gr = rtc.getBasebandGainReduction();
getControlRsp().setGain(lna, gr);
}
catch(SDRPlayException se)
{
mLog.error("Error setting RSP gain index to " + rtc.getGain());
mLog.error("Error setting RSP LNA [" + rtc.getLNA() + "] and baseband [" + rtc.getBasebandGainReduction() + "]");
}
}
}

View File

@@ -1,6 +1,6 @@
/*
* *****************************************************************************
* Copyright (C) 2014-2023 Dennis Sheirer
* 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
@@ -24,32 +24,37 @@ import io.github.dsheirer.source.tuner.manager.TunerManager;
import io.github.dsheirer.source.tuner.sdrplay.api.SDRPlayException;
import io.github.dsheirer.source.tuner.sdrplay.api.device.TunerSelect;
import io.github.dsheirer.source.tuner.sdrplay.api.parameter.control.AgcMode;
import io.github.dsheirer.source.tuner.sdrplay.api.parameter.tuner.GainReduction;
import io.github.dsheirer.source.tuner.ui.TunerEditor;
import io.github.dsheirer.util.ThreadPool;
import java.awt.Color;
import java.awt.EventQueue;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicBoolean;
import net.miginfocom.swing.MigLayout;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import javax.swing.JButton;
import javax.swing.JLabel;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.JSlider;
import javax.swing.JToggleButton;
/**
* Abstract RSP tuner editor
*/
public abstract class RspTunerEditor<C extends RspTunerConfiguration> extends TunerEditor<RspTuner,C> implements IGainOverloadListener
public abstract class RspTunerEditor<C extends RspTunerConfiguration> extends TunerEditor<RspTuner,C> implements ITunerStatusListener
{
private Logger mLog = LoggerFactory.getLogger(RspTunerEditor.class);
private JSlider mGainSlider;
private JLabel mGainValueLabel;
protected static final String MANUAL = "Manual";
protected static final String AUTOMATIC = "Automatic";
private JToggleButton mAgcButton;
private JLabel mGainValueLabel;
private LnaSlider mLNASlider;
private IfGainSlider mIfGainSlider;
private JButton mGainOverloadButton;
private JPanel mGainPanel;
private AtomicBoolean mGainOverloadAlert = new AtomicBoolean();
/**
@@ -69,40 +74,23 @@ public abstract class RspTunerEditor<C extends RspTunerConfiguration> extends Tu
}
/**
* Gain reduction slider control
* Gain controls panel
* @return gain panel
*/
protected JSlider getGainSlider()
protected JPanel getGainPanel()
{
if(mGainSlider == null)
if(mGainPanel == null)
{
mGainSlider = new JSlider(JSlider.HORIZONTAL, GainReduction.MIN_GAIN_INDEX,
GainReduction.MAX_GAIN_INDEX, GainReduction.MIN_GAIN_INDEX);
mGainSlider.setEnabled(false);
mGainSlider.setMajorTickSpacing(1);
mGainSlider.setPaintTicks(true);
mGainSlider.addChangeListener(event ->
{
int gain = mGainSlider.getValue();
if(hasTuner() && !isLoading())
{
try
{
getTunerController().getControlRsp().setGain(gain);
save();
}
catch(Exception e)
{
mLog.error("Couldn't set RSP gain to:" + gain, e);
JOptionPane.showMessageDialog(mGainSlider, "Couldn't set RSP gain value to " + gain);
}
}
getGainValueLabel().setText(String.valueOf(gain));
});
mGainPanel = new JPanel();
mGainPanel.setLayout(new MigLayout("insets 0","[][][grow,fill][][]",""));
mGainPanel.add(getGainValueLabel());
mGainPanel.add(getGainOverloadButton());
mGainPanel.add(new JLabel()); //empty label to grow to fill space
mGainPanel.add(new JLabel("IF Gain Mode:"));
mGainPanel.add(getAgcButton());
}
return mGainSlider;
return mGainPanel;
}
/**
@@ -126,7 +114,7 @@ public abstract class RspTunerEditor<C extends RspTunerConfiguration> extends Tu
{
if(mAgcButton == null)
{
mAgcButton = new JToggleButton("IF AGC");
mAgcButton = new JToggleButton(MANUAL);
mAgcButton.setEnabled(false);
mAgcButton.addActionListener(e -> {
if(hasTuner() && !isLoading())
@@ -134,6 +122,7 @@ public abstract class RspTunerEditor<C extends RspTunerConfiguration> extends Tu
try
{
getTunerController().getControlRsp().setAgcMode(mAgcButton.isSelected() ? AgcMode.ENABLE : AgcMode.DISABLE);
updateGainLabel();
}
catch(SDRPlayException se)
{
@@ -141,6 +130,17 @@ public abstract class RspTunerEditor<C extends RspTunerConfiguration> extends Tu
}
save();
}
getIfGainSlider().setEnabled(!getAgcButton().isSelected());
if(mAgcButton.isSelected())
{
getAgcButton().setText(AUTOMATIC);
}
else
{
getAgcButton().setText(MANUAL);
}
});
}
@@ -175,6 +175,12 @@ public abstract class RspTunerEditor<C extends RspTunerConfiguration> extends Tu
}
}
@Override
public void frequencyUpdated()
{
updateLnaSlider();
}
/**
* Toggles the alert styling of the disabled gain overload button to indicate an alert condition or a normal
* operating condition.
@@ -194,9 +200,177 @@ public abstract class RspTunerEditor<C extends RspTunerConfiguration> extends Tu
getGainOverloadButton().setForeground(getForeground());
getGainOverloadButton().setBackground(getBackground());
}
else
}
/**
* Updates the LNA slider with the number of LNA states available for the current frequency.
*/
protected void updateLnaSlider()
{
if(hasTuner())
{
mLog.info("Ignoring duplicate gain alerting - alert[" + alert + "] atomic [" + mGainOverloadAlert.get() + "]");
int max = getTunerController().getControlRsp().getMaximumLNASetting();
if(max != getLNASlider().getMaximum())
{
EventQueue.invokeLater(() -> {
setLoading(true);
//Adjust the value if it's less than max
getLNASlider().setValue(Math.min(getLNASlider().getValue(), max));
getLNASlider().setMaximum(max);
setLoading(false);
});
}
}
}
/**
* LNA Gain Slider
*/
protected LnaSlider getLNASlider()
{
if(mLNASlider == null)
{
mLNASlider = new LnaSlider();
mLNASlider.setEnabled(true);
mLNASlider.setMajorTickSpacing(1);
mLNASlider.setPaintTicks(true);
mLNASlider.addChangeListener(event ->
{
JSlider source = (JSlider)event.getSource();
if(!source.getValueIsAdjusting())
{
updateGain();
}
});
}
return mLNASlider;
}
/**
* Updates the gain settings when the LNA or Baseband gain value is changed by the user.
*/
private void updateGain()
{
int lna = getLNASlider().getLNA();
int gr = getIfGainSlider().getGR();
if(hasTuner() && !isLoading())
{
try
{
getTunerController().getControlRsp().setGain(lna, gr);
save();
updateGainLabel();
}
catch(Exception e)
{
mLog.error("Couldn't set RSP gain to LNA:" + lna + " Gain Reduction:" + gr, e);
JOptionPane.showMessageDialog(mIfGainSlider, "Couldn't set RSP gain value to LNA:" + lna + " Gain Reduction:" + gr);
}
}
}
protected void updateGainLabel()
{
try
{
float currentGain = getTunerController().getControlRsp().getCurrentGain();
getGainValueLabel().setText((int)currentGain + " dB");
}
catch(SDRPlayException se)
{
mLog.error("Error accessing current gain value from RSP tuner", se);
}
}
/**
* IF Gain Slider
*/
protected IfGainSlider getIfGainSlider()
{
if(mIfGainSlider == null)
{
mIfGainSlider = new IfGainSlider();
mIfGainSlider.setEnabled(true);
mIfGainSlider.setMajorTickSpacing(1);
mIfGainSlider.setPaintTicks(true);
mIfGainSlider.addChangeListener(event ->
{
JSlider source = (JSlider)event.getSource();
if(!source.getValueIsAdjusting())
{
updateGain();
}
});
}
return mIfGainSlider;
}
/**
* JSlider implementation that inverts the scale to support LNA values.
*/
public class LnaSlider extends JSlider
{
/**
* Constructs an instance
*/
public LnaSlider()
{
super(JSlider.HORIZONTAL, 0,9,9);
}
/**
* Slider value converted to the LNA scale.
* @return lna value.
*/
public int getLNA()
{
return getMaximum() - getValue();
}
/**
* Sets the slider with the value converted from the provided LNA value.
* @param lna value to apply
*/
public void setLNA(int lna)
{
setValue(getMaximum() - lna);
}
}
/**
* JSlider implementation that inverts the scale to support IF Gain (aka Gain Reduction) values.
*/
public class IfGainSlider extends JSlider
{
/**
* Constructs an instance
*/
public IfGainSlider()
{
super(JSlider.HORIZONTAL, 0, 39, 30);
}
/**
* Slider value converted to the gain reduction scale.
* @return gain reduction value.
*/
public int getGR()
{
return getIfGainSlider().getMaximum() - getIfGainSlider().getValue() + 20;
}
/**
* Sets the slider with the value converted from the provided gain reduction value.
* @param gainReduction value to apply
*/
public void setGR(int gainReduction)
{
setValue(getMaximum() - (gainReduction - 20));
}
}
}

View File

@@ -1,6 +1,6 @@
/*
* *****************************************************************************
* Copyright (C) 2014-2023 Dennis Sheirer
* 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
@@ -352,7 +352,7 @@ public class SDRplay
*
* @param deviceType to load parameters
* @param deviceHandle to device
* @return constructed device composite paramaters
* @return constructed device composite parameters
*/
public CompositeParameters getCompositeParameters(DeviceType deviceType, MemorySegment deviceHandle) throws SDRPlayException
{
@@ -367,7 +367,7 @@ public class SDRplay
//The structure's memory is already allocated ... wrap a memory segment around it
MemorySegment memorySegment = sdrplay_api_DeviceT.ofAddress(memoryAddress, getArena().scope());
return CompositeParametersFactory.create(deviceType, memorySegment, getArena());
return CompositeParametersFactory.create(getVersion(), deviceType, memorySegment, getArena());
}
else
{

View File

@@ -1,6 +1,6 @@
/*
* *****************************************************************************
* Copyright (C) 2014-2023 Dennis Sheirer
* 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
@@ -78,6 +78,7 @@ public enum UpdateReason
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_14.sdrplay_api_h.sdrplay_api_Update_RspDuo_ResetSlaveFlags(), "RSPDuo Reset Slave Flags"),
EXTENSION_NONE(sdrplay_api_h.sdrplay_api_Update_Ext1_None(), "NONE"),

View File

@@ -1,6 +1,6 @@
/*
* *****************************************************************************
* Copyright (C) 2014-2023 Dennis Sheirer
* 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
@@ -33,7 +33,9 @@ public enum Version
V3_09(3.09f, true),
V3_10(3.10f, true),
V3_11(3.11f, true),
V3_12(3.12f, true);
V3_12(3.12f, true),
V3_13(3.13f, true), //No changes - OSX build only.
V3_14(3.14f, true);
private float mValue;
private boolean mSupported;

View File

@@ -1,6 +1,6 @@
/*
* *****************************************************************************
* Copyright (C) 2014-2023 Dennis Sheirer
* 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
@@ -125,6 +125,9 @@ public class DeviceFactory
case RSP1A -> {
return new Rsp1aDevice(sdrPlay, deviceStruct);
}
case RSP1B -> {
return new Rsp1bDevice(sdrPlay, deviceStruct);
}
case RSP2 -> {
return new Rsp2Device(sdrPlay, deviceStruct);
}

View File

@@ -1,6 +1,6 @@
/*
* *****************************************************************************
* Copyright (C) 2014-2023 Dennis Sheirer
* 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
@@ -28,6 +28,7 @@ public enum DeviceType
{
RSP1(sdrplay_api_h.SDRPLAY_RSP1_ID(), "RSP1"),
RSP1A(sdrplay_api_h.SDRPLAY_RSP1A_ID(), "RSP1A"),
RSP1B(io.github.dsheirer.source.tuner.sdrplay.api.v3_14.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"),

View File

@@ -0,0 +1,61 @@
/*
* *****************************************************************************
* 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

@@ -0,0 +1,107 @@
/*
* *****************************************************************************
* 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,6 +1,6 @@
/*
* *****************************************************************************
* Copyright (C) 2014-2023 Dennis Sheirer
* 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
@@ -28,7 +28,6 @@ import io.github.dsheirer.source.tuner.sdrplay.api.parameter.control.ControlPara
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.GainReduction;
import io.github.dsheirer.source.tuner.sdrplay.api.parameter.tuner.IfMode;
import io.github.dsheirer.source.tuner.sdrplay.api.parameter.tuner.LoMode;
import io.github.dsheirer.source.tuner.sdrplay.api.parameter.tuner.TunerParameters;
@@ -49,8 +48,6 @@ public abstract class RspTuner<D extends DeviceParameters, T extends TunerParame
private final T mTunerParameters;
private final ControlParameters mControlParameters;
private GainReduction mGainReduction;
RspTuner(Device device, SDRplay sdrplay, TunerSelect tunerSelect, D deviceParameters, T tunerParameters,
ControlParameters controlParameters)
{
@@ -180,7 +177,6 @@ public abstract class RspTuner<D extends DeviceParameters, T extends TunerParame
try
{
getTunerParameters().getRfFrequency().setFrequency(frequency, false);
updateGainReduction(frequency);
return updateAsync(UpdateReason.TUNER_FREQUENCY_RF, UpdateReason.TUNER_FREQUENCY_RF);
}
catch(SDRPlayException se)
@@ -193,39 +189,15 @@ public abstract class RspTuner<D extends DeviceParameters, T extends TunerParame
}
/**
* Gain reduction in use for this device with the current RF frequency
* 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 GainReduction getGainReduction()
public void setGain(int lna, int basebandGainReduction) throws SDRPlayException
{
if(mGainReduction == null)
{
updateGainReduction(getFrequency());
}
return mGainReduction;
}
/**
* Updates the gain reduction, if necessary, for the specified RF frequency
*
* @param frequency value
*/
private void updateGainReduction(long frequency)
{
if(mGainReduction == null || !mGainReduction.isValidFor(frequency))
{
mGainReduction = GainReduction.lookup(getDevice().getDeviceType(), frequency);
}
}
/**
* Selects a gain value index from the current gain reduction values
*
* @param index of the gain reduction values to use
*/
public void setGain(int index) throws SDRPlayException
{
getTunerParameters().getGain().setGain(getGainReduction(), index);
getTunerParameters().getGain().setLNA(lna);
getTunerParameters().getGain().setGainReductionDb(basebandGainReduction);
update(UpdateReason.TUNER_GAIN_REDUCTION);
}
@@ -257,16 +229,6 @@ public abstract class RspTuner<D extends DeviceParameters, T extends TunerParame
return getTunerParameters().getGain();
}
/**
* Current gain index value.
* @return current gain index value or -1 if the current gain setting does not match the possible gain reduction options.
*/
public int getGainIndex()
{
int gainDb = getGain().getGainReductionDb();
return getGainReduction().getGainIndex(gainDb);
}
/**
* Enables or disables DC correction
*

View File

@@ -1,6 +1,6 @@
/*
* *****************************************************************************
* Copyright (C) 2014-2023 Dennis Sheirer
* 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
@@ -19,6 +19,7 @@
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;
@@ -47,11 +48,12 @@ public class CompositeParameters<D extends DeviceParameters, T extends TunerPara
/**
* Constructs an instance from the foreign memory segment
*
* @param version of the API
* @param deviceType to create
* @param memorySegment for the composite structure in foreign memory
* @param arena for allocating additional memory segments for the sub-structures.
*/
public CompositeParameters(DeviceType deviceType, MemorySegment memorySegment, Arena arena)
public CompositeParameters(Version version, DeviceType deviceType, MemorySegment memorySegment, Arena arena)
{
MemorySegment parametersMemoryAddress = sdrplay_api_DeviceParamsT.devParams$get(memorySegment);
MemorySegment parametersMemorySegment = sdrplay_api_DevParamsT.ofAddress(parametersMemoryAddress, arena.scope());
@@ -59,7 +61,7 @@ public class CompositeParameters<D extends DeviceParameters, T extends TunerPara
MemorySegment memoryAddressRxA = sdrplay_api_DeviceParamsT.rxChannelA$get(memorySegment);
MemorySegment memorySegmentRxA = sdrplay_api_RxChannelParamsT.ofAddress(memoryAddressRxA, arena.scope());
mTunerAParameters = (T) TunerParametersFactory.create(deviceType, memorySegmentRxA);
mTunerAParameters = (T) TunerParametersFactory.create(version, deviceType, memorySegmentRxA);
MemorySegment tunerAControlParametersMemorySegment = sdrplay_api_RxChannelParamsT.ctrlParams$slice(memorySegmentRxA);
mControlAParameters = new ControlParameters(tunerAControlParametersMemorySegment);

View File

@@ -1,6 +1,6 @@
/*
* *****************************************************************************
* Copyright (C) 2014-2023 Dennis Sheirer
* 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
@@ -19,6 +19,7 @@
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;
@@ -30,29 +31,34 @@ public class CompositeParametersFactory
{
/**
* Creates a composite parameters instance for the specified device type
* @param version of the api
* @param deviceType to create
* @param memorySegment of foreign memory structure for the composite parameters
* @param arena to allocate additional memory structures
* @return instance
*/
public static CompositeParameters create(DeviceType deviceType, MemorySegment memorySegment, Arena arena)
public static CompositeParameters create(Version version, DeviceType deviceType, MemorySegment memorySegment,
Arena arena)
{
switch(deviceType)
{
case RSP1 -> {
return new Rsp1CompositeParameters(memorySegment, arena);
return new Rsp1CompositeParameters(version, memorySegment, arena);
}
case RSP1A -> {
return new Rsp1aCompositeParameters(memorySegment, arena);
return new Rsp1aCompositeParameters(version, memorySegment, arena);
}
case RSP1B -> {
return new Rsp1bCompositeParameters(version, memorySegment, arena);
}
case RSP2 -> {
return new Rsp2CompositeParameters(memorySegment, arena);
return new Rsp2CompositeParameters(version, memorySegment, arena);
}
case RSPduo -> {
return new RspDuoCompositeParameters(memorySegment, arena);
return new RspDuoCompositeParameters(version, memorySegment, arena);
}
case RSPdx -> {
return new RspDxCompositeParameters(memorySegment, arena);
return new RspDxCompositeParameters(version, memorySegment, arena);
}
}

View File

@@ -1,6 +1,6 @@
/*
* *****************************************************************************
* Copyright (C) 2014-2023 Dennis Sheirer
* 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
@@ -19,6 +19,7 @@
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;
@@ -33,11 +34,12 @@ public class Rsp1CompositeParameters extends CompositeParameters<Rsp1DeviceParam
/**
* Constructs an instance from the foreign memory segment
*
* @param version of the API
* @param memorySegment for the composite structure in foreign memory
* @param arena for allocating additional memory segments for the sub-structures.
*/
public Rsp1CompositeParameters(MemorySegment memorySegment, Arena arena)
public Rsp1CompositeParameters(Version version, MemorySegment memorySegment, Arena arena)
{
super(DeviceType.RSP1, memorySegment, arena);
super(version, DeviceType.RSP1, memorySegment, arena);
}
}

View File

@@ -1,6 +1,6 @@
/*
* *****************************************************************************
* Copyright (C) 2014-2023 Dennis Sheirer
* 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
@@ -19,6 +19,7 @@
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;
@@ -33,11 +34,12 @@ public class Rsp1aCompositeParameters extends CompositeParameters<Rsp1aDevicePar
/**
* Constructs an instance from the foreign memory segment
*
* @param version of the API
* @param memorySegment for the composite structure in foreign memory
* @param arena for allocating additional memory segments for the sub-structures.
*/
public Rsp1aCompositeParameters(MemorySegment memorySegment, Arena arena)
public Rsp1aCompositeParameters(Version version, MemorySegment memorySegment, Arena arena)
{
super(DeviceType.RSP1A, memorySegment, arena);
super(version, DeviceType.RSP1A, memorySegment, arena);
}
}

View File

@@ -0,0 +1,47 @@
/*
* *****************************************************************************
* 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 memorySegment for the composite structure in foreign memory
* @param arena for allocating additional memory segments for the sub-structures.
*/
public Rsp1bCompositeParameters(Version version, MemorySegment memorySegment, Arena arena)
{
super(version, DeviceType.RSP1B, memorySegment, arena);
}
}

View File

@@ -1,6 +1,6 @@
/*
* *****************************************************************************
* Copyright (C) 2014-2023 Dennis Sheirer
* 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
@@ -19,6 +19,7 @@
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;
@@ -33,11 +34,12 @@ public class Rsp2CompositeParameters extends CompositeParameters<Rsp2DeviceParam
/**
* Constructs an instance from the foreign memory segment
*
* @param version of the API
* @param memorySegment for the composite structure in foreign memory
* @param arena for allocating additional memory segments for the sub-structures.
*/
public Rsp2CompositeParameters(MemorySegment memorySegment, Arena arena)
public Rsp2CompositeParameters(Version version, MemorySegment memorySegment, Arena arena)
{
super(DeviceType.RSP2, memorySegment, arena);
super(version, DeviceType.RSP2, memorySegment, arena);
}
}

View File

@@ -1,6 +1,6 @@
/*
* *****************************************************************************
* Copyright (C) 2014-2023 Dennis Sheirer
* 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
@@ -19,6 +19,7 @@
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.RspDuoDeviceParameters;
@@ -40,16 +41,17 @@ public class RspDuoCompositeParameters extends CompositeParameters<RspDuoDeviceP
/**
* Constructs an instance from the foreign memory segment
*
* @param version for constructing the correct version structure.
* @param memorySegment for the composite structure in foreign memory
* @param arena for allocating additional memory segments for the sub-structures.
*/
public RspDuoCompositeParameters(MemorySegment memorySegment, Arena arena)
public RspDuoCompositeParameters(Version version, MemorySegment memorySegment, Arena arena)
{
super(DeviceType.RSPduo, memorySegment, arena);
super(version, DeviceType.RSPduo, memorySegment, arena);
MemorySegment memoryAddressRxB = sdrplay_api_DeviceParamsT.rxChannelB$get(memorySegment);
MemorySegment memorySegmentRxB = sdrplay_api_RxChannelParamsT.ofAddress(memoryAddressRxB, arena.scope());
mTunerBParameters = (RspDuoTunerParameters) TunerParametersFactory.create(DeviceType.RSPduo, memorySegmentRxB);
mTunerBParameters = (RspDuoTunerParameters) TunerParametersFactory.create(version, DeviceType.RSPduo, memorySegmentRxB);
MemorySegment tunerBControlParametersMemorySegment = sdrplay_api_RxChannelParamsT.ctrlParams$slice(memorySegmentRxB);
mControlBParameters = new ControlParameters(tunerBControlParametersMemorySegment);

View File

@@ -1,6 +1,6 @@
/*
* *****************************************************************************
* Copyright (C) 2014-2023 Dennis Sheirer
* 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
@@ -19,6 +19,7 @@
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.RspDxDeviceParameters;
import io.github.dsheirer.source.tuner.sdrplay.api.parameter.tuner.RspDxTunerParameters;
@@ -33,11 +34,12 @@ public class RspDxCompositeParameters extends CompositeParameters<RspDxDevicePar
/**
* Constructs an instance from the foreign memory segment
*
* @param version of the API
* @param memorySegment for the composite structure in foreign memory
* @param arena for allocating additional memory segments for the sub-structures.
*/
public RspDxCompositeParameters(MemorySegment memorySegment, Arena arena)
public RspDxCompositeParameters(Version version, MemorySegment memorySegment, Arena arena)
{
super(DeviceType.RSPdx, memorySegment, arena);
super(version, DeviceType.RSPdx, memorySegment, arena);
}
}

View File

@@ -1,6 +1,6 @@
/*
* *****************************************************************************
* Copyright (C) 2014-2023 Dennis Sheirer
* 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
@@ -40,7 +40,8 @@ public class DeviceParametersFactory
case RSP1 -> {
return new Rsp1DeviceParameters(memorySegment);
}
case RSP1A -> {
//RSP1A and RSP1B share the same device parameters structures
case RSP1A, RSP1B -> {
return new Rsp1aDeviceParameters(memorySegment);
}
case RSP2 -> {

View File

@@ -1,6 +1,6 @@
/*
* *****************************************************************************
* Copyright (C) 2014-2023 Dennis Sheirer
* 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
@@ -30,11 +30,17 @@ public enum EventType
POWER_OVERLOAD_CHANGE(sdrplay_api_h.sdrplay_api_PowerOverloadChange(), "POWER OVERLOAD CHANGE"),
DEVICE_REMOVED(sdrplay_api_h.sdrplay_api_DeviceRemoved(), "DEVICE REMOVED"),
RSP_DUO_MODE_CHANGE(sdrplay_api_h.sdrplay_api_RspDuoModeChange(), "RSP-DUO MODE CHANGE"),
DEVICE_FAILURE(io.github.dsheirer.source.tuner.sdrplay.api.v3_14.sdrplay_api_h.sdrplay_api_DeviceFailure(), "DEVICE FAILURE"),
UNKNOWN(-1, "UNKNOWN");
private int mValue;
private String mDescription;
/**
* Constructs an instance
* @param value of the entry
* @param description for the entry
*/
EventType(int value, String description)
{
mValue = value;

View File

@@ -1,104 +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.parameter.tuner;
import java.util.EnumSet;
/**
* RSP Frequency Bands
*/
public enum FrequencyBand
{
BAND_0_12(1_000, 12_000_000, "0.001-12 MHz"),
BAND_12_60(12_000_000, 60_000_000, "12-60 MHz"),
BAND_60_250(60_000_000, 250_000_000, "60-250 MHz"),
BAND_250_420(250_000_000, 420_000_000, "250-420 MHz"),
BAND_420_1000(420_000_000, 1_000_000_000, "420-1000 MHz"),
BAND_1000_2000(1_000_000_000, 2_000_000_000, "1000-2000 MHz"),
UNKNOWN(-1, 0,"UNKNOWN");
private long mMinimum;
private long mMaximum;
private String mDescription;
FrequencyBand(long min, long max, String description)
{
mMinimum = min;
mMaximum = max;
mDescription = description;
}
/**
* Valid frequency bands
*/
public static EnumSet<FrequencyBand> VALID_FREQUENCY_BANDS = EnumSet.range(BAND_0_12, BAND_1000_2000);
/**
* Minimum frequency
* @return frequency in Hertz
*/
public long getMinimum()
{
return mMinimum;
}
/**
* Maximum frequency
* @return frequency in Hertz
*/
public long getMaximum()
{
return mMaximum;
}
/**
* Lookup the entry from a return code
* @param frequency to lookup
* @return entry or UNKNOWN if the code is not recognized
*/
public static FrequencyBand fromValue(long frequency)
{
for(FrequencyBand band: FrequencyBand.values())
{
if(band.contains(frequency))
{
return band;
}
}
return UNKNOWN;
}
/**
* Indicates if this frequency band entry contains the specified frequency
* @param frequency to check
* @return true if this entry contains the frequency
*/
public boolean contains(long frequency)
{
return getMinimum() <= frequency && frequency < getMaximum();
}
@Override
public String toString()
{
return mDescription;
}
}

View File

@@ -1,6 +1,6 @@
/*
* *****************************************************************************
* Copyright (C) 2014-2023 Dennis Sheirer
* 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
@@ -52,17 +52,6 @@ public class Gain
return mMemorySegment;
}
/**
* Sets the LNA state and gain reduction from the set of gain reduction values using the specified index
* @param gainReduction for the current frequency band
* @param index into the gain values to use for LNA state and gain reduction
*/
public void setGain(GainReduction gainReduction, int index)
{
setLNA(gainReduction.getLnaState(index));
setGainReductionDb(gainReduction.getGainReduction(index));
}
/**
* Current gain reduction
* @return gain dB

View File

@@ -1,354 +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.parameter.tuner;
import io.github.dsheirer.source.tuner.sdrplay.api.device.DeviceType;
import java.util.EnumSet;
/**
* RSP Gain Reduction values and LNA states for each RSP model.
*
* Use lookup() as convenience method to find a gain reduction entry for a device type and frequency band.
*
* Reference: SDRplay API Specification, Gain Reduction Tables
* and https://github.com/SDRplay/RSPTCPServer/blob/master/rsp_tcp.c
*/
public enum GainReduction
{
RSP1_BAND_0_12(FrequencyBand.BAND_0_12,
new int[]{ 3, 3, 3, 3, 3, 3, 3, 1, 1, 1, 1, 1, 1, 2, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
new int[]{ 59,56,53,50,47,44,41,58,55,52,49,46,43,45,42,58,55,52,49,46,43,41,38,35,32,29,26,23,20 }),
RSP1_BAND_12_60(FrequencyBand.BAND_12_60,
new int[]{ 3, 3, 3, 3, 3, 3, 3, 1, 1, 1, 1, 1, 1, 2, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
new int[]{ 59,56,53,50,47,44,41,58,55,52,49,46,43,45,42,58,55,52,49,46,43,41,38,35,32,29,26,23,20 }),
RSP1_BAND_60_250(FrequencyBand.BAND_60_250,
new int[]{ 3, 3, 3, 3, 3, 3, 3, 1, 1, 1, 1, 1, 1, 2, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
new int[]{ 59,56,53,50,47,44,41,58,55,52,49,46,43,45,42,58,55,52,49,46,43,41,38,35,32,29,26,23,20 }),
RSP1_BAND_250_420(FrequencyBand.BAND_250_420,
new int[]{ 3, 3, 3, 3, 3, 3, 3, 1, 1, 1, 1, 1, 1, 2, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
new int[]{ 59,56,53,50,47,44,41,58,55,52,49,46,43,45,42,58,55,52,49,46,43,41,38,35,32,29,26,23,20 }),
RSP1_BAND_420_1000(FrequencyBand.BAND_420_1000,
new int[]{ 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 2, 2, 2, 1, 1, 1, 1, 1, 0, 0, 0, 0 },
new int[]{ 59,57,54,52,50,47,45,43,40,38,36,33,31,29,27,24,22,27,24,22,32,29,27,25,22,27,25,22,20 }),
RSP1_BAND_1000_2000(FrequencyBand.BAND_1000_2000,
new int[]{ 3, 3, 3, 3, 3, 3, 3, 3, 3, 2, 2, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
new int[]{ 59,57,55,52,50,48,46,43,41,44,42,53,51,49,47,44,42,45,43,40,38,36,34,31,29,27,25,22,20 }),
RSP1A_BAND_0_12(FrequencyBand.BAND_0_12,
new int[]{ 6, 6, 6, 6, 6, 6, 5, 5, 5, 5, 5, 4, 4, 3, 3, 3, 3, 3, 2, 2, 1, 0, 0, 0, 0, 0, 0, 0, 0 },
new int[]{ 59,55,52,48,45,41,57,53,49,46,42,44,40,56,52,48,45,41,44,40,43,45,41,38,34,31,27,24,20 }),
RSP1A_BAND_12_60(FrequencyBand.BAND_12_60,
new int[]{ 9, 9, 9, 9, 9, 9, 8, 7, 7, 7, 7, 7, 6, 6, 5, 5, 4, 3, 2, 2, 1, 0, 0, 0, 0, 0, 0, 0, 0 },
new int[]{ 59,55,52,48,45,41,42,58,54,51,47,43,46,42,44,41,43,42,44,40,43,45,42,38,34,31,27,24,20 }),
RSP1A_BAND_60_250(FrequencyBand.BAND_60_250,
new int[]{ 9, 9, 9, 9, 9, 9, 8, 7, 7, 7, 7, 7, 6, 6, 5, 5, 4, 3, 2, 2, 1, 0, 0, 0, 0, 0, 0, 0, 0 },
new int[]{ 59,55,52,48,45,41,42,58,54,51,47,43,46,42,44,41,43,42,44,40,43,45,42,38,34,31,27,24,20 }),
RSP1A_BAND_250_420(FrequencyBand.BAND_250_420,
new int[]{ 9, 9, 9, 9, 9, 9, 8, 7, 7, 7, 7, 7, 6, 6, 5, 5, 4, 3, 2, 2, 1, 0, 0, 0, 0, 0, 0, 0, 0 },
new int[]{ 59,55,52,48,45,41,42,58,54,51,47,43,46,42,44,41,43,42,44,40,43,45,42,38,34,31,27,24,20 }),
RSP1A_BAND_420_1000(FrequencyBand.BAND_420_1000,
new int[]{ 9, 9, 9, 9, 9, 9, 8, 8, 8, 8, 8, 7, 6, 6, 5, 5, 4, 4, 2, 2, 1, 0, 0, 0, 0, 0, 0, 0, 0 },
new int[]{ 59,55,52,48,44,41,56,52,49,45,41,44,46,42,45,41,44,40,44,40,42,46,42,38,35,31,27,24,20 }),
RSP1A_BAND_1000_2000(FrequencyBand.BAND_1000_2000,
new int[]{ 8, 8, 8, 8, 8, 8, 7, 7, 7, 7, 7, 6, 5, 5, 4, 4, 3, 2, 2, 2, 1, 0, 0, 0, 0, 0, 0, 0, 0 },
new int[]{ 59,55,52,48,45,41,56,53,49,46,42,43,46,42,44,41,43,48,44,40,43,45,42,38,34,31,27,24,20 }),
RSP2_BAND_0_12(FrequencyBand.BAND_0_12,
new int[]{ 8, 8, 8, 8, 8, 8, 7, 7, 7, 7, 7, 6, 5, 5, 4, 4, 4, 2, 2, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
new int[]{ 59,55,52,48,44,41,56,52,49,45,41,44,45,41,48,44,40,45,42,43,49,46,42,38,35,31,27,24,20 }),
RSP2_BAND_12_60(FrequencyBand.BAND_12_60,
new int[]{ 8, 8, 8, 8, 8, 8, 7, 7, 7, 7, 7, 6, 5, 5, 4, 4, 4, 2, 2, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
new int[]{ 59,55,52,48,44,41,56,52,49,45,41,44,45,41,48,44,40,45,42,43,49,46,42,38,35,31,27,24,20 }),
RSP2_BAND_60_250(FrequencyBand.BAND_60_250,
new int[]{ 8, 8, 8, 8, 8, 8, 7, 7, 7, 7, 7, 6, 5, 5, 4, 4, 4, 2, 2, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
new int[]{ 59,55,52,48,44,41,56,52,49,45,41,44,45,41,48,44,40,45,42,43,49,46,42,38,35,31,27,24,20 }),
RSP2_BAND_250_420(FrequencyBand.BAND_250_420,
new int[]{ 8, 8, 8, 8, 8, 8, 7, 7, 7, 7, 7, 6, 5, 5, 4, 4, 4, 2, 2, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
new int[]{ 59,55,52,48,44,41,56,52,49,45,41,44,45,41,48,44,40,45,42,43,49,46,42,38,35,31,27,24,20 }),
RSP2_BAND_420_1000(FrequencyBand.BAND_420_1000,
new int[]{ 5, 5, 5, 5, 5, 5, 5, 4, 4, 4, 4, 4, 4, 4, 3, 3, 2, 2, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
new int[]{ 59,56,53,50,48,45,42,58,55,52,49,47,44,41,43,40,44,41,42,46,43,40,37,34,31,29,26,23,20 }),
RSP2_BAND_1000_2000(FrequencyBand.BAND_1000_2000,
new int[]{ 4, 4, 4, 4, 4, 4, 4, 4, 3, 3, 3, 3, 3, 3, 3, 2, 2, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
new int[]{ 59,56,54,51,48,45,43,40,56,54,51,48,45,43,40,43,41,44,41,44,42,39,36,34,31,28,25,23,20 }),
RSP_DUO_BAND_0_12(FrequencyBand.BAND_0_12,
new int[]{ 6, 6, 6, 6, 6, 6, 5, 5, 5, 5, 5, 4, 4, 3, 3, 3, 3, 3, 2, 2, 1, 0, 0, 0, 0, 0, 0, 0, 0 },
new int[]{ 59,55,52,48,45,41,57,53,49,46,42,44,40,56,52,48,45,41,44,40,43,45,41,38,34,31,27,24,20 }),
RSP_DUO_BAND_12_60(FrequencyBand.BAND_12_60,
new int[]{ 9, 9, 9, 9, 9, 9, 8, 7, 7, 7, 7, 7, 6, 6, 5, 5, 4, 3, 2, 2, 1, 0, 0, 0, 0, 0, 0, 0, 0 },
new int[]{ 59,55,52,48,45,41,42,58,54,51,47,43,46,42,44,41,43,42,44,40,43,45,42,38,34,31,27,24,20 }),
RSP_DUO_BAND_60_250(FrequencyBand.BAND_60_250,
new int[]{ 9, 9, 9, 9, 9, 9, 8, 7, 7, 7, 7, 7, 6, 6, 5, 5, 4, 3, 2, 2, 1, 0, 0, 0, 0, 0, 0, 0, 0 },
new int[]{ 59,55,52,48,45,41,42,58,54,51,47,43,46,42,44,41,43,42,44,40,43,45,42,38,34,31,27,24,20 }),
RSP_DUO_BAND_250_420(FrequencyBand.BAND_250_420,
new int[]{ 9, 9, 9, 9, 9, 9, 8, 7, 7, 7, 7, 7, 6, 6, 5, 5, 4, 3, 2, 2, 1, 0, 0, 0, 0, 0, 0, 0, 0 },
new int[]{ 59,55,52,48,45,41,42,58,54,51,47,43,46,42,44,41,43,42,44,40,43,45,42,38,34,31,27,24,20 }),
RSP_DUO_BAND_420_1000(FrequencyBand.BAND_420_1000,
new int[]{ 9, 9, 9, 9, 9, 9, 8, 8, 8, 8, 8, 7, 6, 6, 5, 5, 4, 4, 2, 2, 1, 0, 0, 0, 0, 0, 0, 0, 0 },
new int[]{ 59,55,52,48,44,41,56,52,49,45,41,44,46,42,45,41,44,40,44,40,42,46,42,38,35,31,27,24,20 }),
RSP_DUO_BAND_1000_2000(FrequencyBand.BAND_1000_2000,
new int[]{ 8, 8, 8, 8, 8, 8, 7, 7, 7, 7, 7, 6, 5, 5, 4, 4, 3, 2, 2, 2, 1, 0, 0, 0, 0, 0, 0, 0, 0 },
new int[]{ 59,55,52,48,45,41,56,53,49,46,42,43,46,42,44,41,43,48,44,40,43,45,42,38,34,31,27,24,20 }),
RSP_DX_BAND_0_12(FrequencyBand.BAND_0_12,
new int[]{ 18,18,18,18,18,18,17,16,14,13,12,11,10, 9, 7, 6, 5, 5, 5, 3, 2, 1, 0, 0, 0, 0, 0, 0, 0 },
new int[]{ 59,55,52,48,45,41,41,40,43,42,42,41,41,40,42,42,47,44,40,43,42,42,41,38,34,31,27,24,20 }),
RSP_DX_BAND_12_60(FrequencyBand.BAND_12_60,
new int[]{ 26,26,26,26,26,25,23,22,20,19,17,16,14,13,11,10, 8, 7, 5, 5, 5, 3, 2, 0, 0, 0, 0, 0, 0 },
new int[]{ 59,55,50,46,41,40,42,40,42,40,42,41,42,41,43,41,43,41,49,45,40,42,40,42,38,33,29,24,20 }),
RSP_DX_BAND_60_250(FrequencyBand.BAND_60_250,
new int[]{ 26,26,26,26,26,25,23,22,20,19,17,16,14,13,11,10, 8, 7, 5, 5, 5, 3, 2, 0, 0, 0, 0, 0, 0 },
new int[]{ 59,55,50,46,41,40,42,40,42,40,42,41,42,41,43,41,43,41,49,45,40,42,40,42,38,33,29,24,20 }),
RSP_DX_BAND_250_420(FrequencyBand.BAND_250_420,
new int[]{ 27,27,27,27,27,26,24,23,21,20,18,17,15,14,12,11, 9, 8, 6, 6, 5, 3, 2, 0, 0, 0, 0, 0, 0 },
new int[]{ 59,55,50,46,41,40,42,40,42,40,42,41,42,41,43,41,43,41,46,42,40,42,40,42,38,33,29,24,20 }),
RSP_DX_BAND_420_1000(FrequencyBand.BAND_420_1000,
new int[]{ 20,20,20,20,20,20,18,17,16,14,13,12,11, 9, 8, 7, 7, 5, 4, 3, 2, 0, 0, 0, 0, 0, 0, 0, 0 },
new int[]{ 59,55,51,48,44,40,42,42,41,43,42,41,41,43,42,44,40,43,42,41,40,46,43,39,35,31,28,24,20 }),
RSP_DX_BAND_1000_2000(FrequencyBand.BAND_1000_2000,
new int[]{ 18,18,18,18,18,18,16,15,14,13,11,10, 9, 8, 7, 6, 6, 6, 5, 3, 2, 1, 0, 0, 0, 0, 0, 0, 0 },
new int[]{ 59,55,52,48,44,40,43,42,41,41,43,42,41,41,40,48,45,41,40,42,42,41,42,39,35,31,27,24,20 }),
//HiZ Port - RSP2 and RSPduo
RSP_2_AND_DUO_HIZ_BAND_0_12(FrequencyBand.BAND_0_12,
new int[]{ 4, 4, 4, 4, 4, 4, 4, 4, 3, 3, 3, 3, 3, 3, 3, 2, 2, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
new int[]{ 59,56,54,51,48,45,43,40,56,54,51,48,45,43,40,43,41,44,41,44,42,39,36,34,31,28,25,23,20 }),
RSP_2_AND_DUO_HIZ_BAND_12_60(FrequencyBand.BAND_12_60,
new int[]{ 4, 4, 4, 4, 4, 4, 4, 4, 3, 3, 3, 3, 3, 3, 3, 2, 2, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
new int[]{ 59,56,54,51,48,45,43,40,56,54,51,48,45,43,40,43,41,44,41,44,42,39,36,34,31,28,25,23,20 }),
//RSPdx HDR Mode
RSP_DX_HDR_BAND_0_2(FrequencyBand.BAND_0_12,
new int[]{ 18,18,18,18,18,18,17,16,14,13,12,11,10, 9, 7, 6, 5, 5, 5, 3, 2, 1, 0, 0, 0, 0, 0, 0, 0 },
new int[]{ 59,55,52,48,45,41,41,40,43,42,42,41,41,40,42,42,47,44,40,43,42,42,41,38,34,31,27,24,20 }),
UNKNOWN(FrequencyBand.UNKNOWN, new int[]{}, new int[]{});
private FrequencyBand mFrequencyBand;
private int[] mLnaStates;
private int[] mGainReductions;
GainReduction(FrequencyBand frequencyBand, int[] lnaStates, int[] gainReductions)
{
mFrequencyBand = frequencyBand;
mLnaStates = lnaStates;
mGainReductions = gainReductions;
}
/**
* Identifies the index of the gain reduction value from the array of possible gain reduction values.
* @param gainReductionValue to lookup index
* @return matching index or -1 if a matching index is not found.
*/
public int getGainIndex(int gainReductionValue)
{
for(int x = 0; x < mGainReductions.length; x++)
{
if(mGainReductions[x] == gainReductionValue)
{
return x;
}
}
return -1;
}
/**
* Minimum index for gain values
*/
public static int MIN_GAIN_INDEX = 0;
/**
* Maximum index for gain values
*/
public static int MAX_GAIN_INDEX = 28;
/**
* Number of discrete gain steps available for each entry
*/
public static int GAIN_STEPS_AVAILABLE = 29;
/**
* RSP1 Gain Reduction Tables
*/
public static EnumSet<GainReduction> RSP_1_GAINS = EnumSet.range(RSP1_BAND_0_12, RSP1_BAND_1000_2000);
/**
* RSP1A Gain Reduction Tables
*/
public static EnumSet<GainReduction> RSP_1A_GAINS = EnumSet.range(RSP1A_BAND_0_12, RSP1A_BAND_1000_2000);
/**
* RSP2 Gain Reduction Tables
*/
public static EnumSet<GainReduction> RSP_2_GAINS = EnumSet.range(RSP2_BAND_0_12, RSP2_BAND_1000_2000);
/**
* RSPduo Gain Reduction Tables
*/
public static EnumSet<GainReduction> RSP_DUO_GAINS = EnumSet.range(RSP_DUO_BAND_0_12, RSP_DUO_BAND_1000_2000);
/**
* RSPdx Gain Reduction Tables
*/
public static EnumSet<GainReduction> RSP_DX_GAINS = EnumSet.range(RSP_DX_BAND_0_12, RSP_DX_BAND_1000_2000);
/**
* RSPdx HDR Mode Gain Reduction Tables
*/
public static EnumSet<GainReduction> RSP_DX_HDR_GAINS = EnumSet.of(RSP_DX_HDR_BAND_0_2);
/**
* RSP2 and RSPduo HiZ Port Gain Reduction Tables
*/
public static EnumSet<GainReduction> RSP_HIZ_GAINS = EnumSet.range(RSP_2_AND_DUO_HIZ_BAND_0_12, RSP_2_AND_DUO_HIZ_BAND_12_60);
/**
* Lookup the gain reduction entry for a device that matches the frequency band.
*
* Note: directly use the RSP_DX_HDR_GAINS and RSP_HIZ_GAINS enumeration sets to match for HDR or HIZ modes.
*
* @param deviceType to lookup
* @param frequencyBand to match
* @return entry or UNKNOWN
*/
public static GainReduction lookup(DeviceType deviceType, FrequencyBand frequencyBand)
{
switch(deviceType)
{
case RSP1 -> {
return fromBand(frequencyBand, RSP_1_GAINS);
}
case RSP1A -> {
return fromBand(frequencyBand, RSP_1A_GAINS);
}
case RSP2 -> {
return fromBand(frequencyBand, RSP_2_GAINS);
}
case RSPduo -> {
return fromBand(frequencyBand, RSP_DUO_GAINS);
}
case RSPdx -> {
return fromBand(frequencyBand, RSP_DX_GAINS);
}
}
return UNKNOWN;
}
/**
* Lookup the gain reduction entry for a device that matches the specified frequency
* @param deviceType to lookup
* @param frequency to map to a frequency band
* @return gain reduction entry or UNKNOWN
*/
public static GainReduction lookup(DeviceType deviceType, long frequency)
{
FrequencyBand band = FrequencyBand.fromValue(frequency);
return lookup(deviceType, band);
}
/**
* Look up the gain reduction value that matches the frequency band from the set of gain reduction values.
* @param frequencyBand to lookup
* @param values to choose from
* @return matching entry or UNKNOWN
*/
private static GainReduction fromBand(FrequencyBand frequencyBand, EnumSet<GainReduction> values)
{
for(GainReduction gainReduction: values)
{
if(gainReduction.getFrequencyBand() == frequencyBand)
{
return gainReduction;
}
}
return UNKNOWN;
}
/**
* Frequency band for the range of LNA state and gain reduction values.
*/
public FrequencyBand getFrequencyBand()
{
return mFrequencyBand;
}
/**
* Array of LNA states
*/
private int[] getLnaStates()
{
return mLnaStates;
}
/**
* Array of gain reduction values
*/
private int[] getGainReductions()
{
return mGainReductions;
}
/**
* LNA state value for the specified gain index
* @param index for the gain (0 - 29)
* @return lna state
*/
public int getLnaState(int index)
{
if(MIN_GAIN_INDEX <= index && index <= MAX_GAIN_INDEX)
{
return getLnaStates()[index];
}
throw new IllegalArgumentException("Unrecognized gain index [" + index + "] - valid range: " +
MIN_GAIN_INDEX + " <> " + MAX_GAIN_INDEX);
}
/**
* Gain reduction value for the specified gain index
* @param index for the gain (0 - 29)
* @return gain reduction value (dB)
*/
public int getGainReduction(int index)
{
if(MIN_GAIN_INDEX <= index && index <= MAX_GAIN_INDEX)
{
return getGainReductions()[index];
}
throw new IllegalArgumentException("Unrecognized gain index [" + index + "] - valid range: " +
MIN_GAIN_INDEX + " <> " + MAX_GAIN_INDEX);
}
/**
* Indicates if this gain reduction entry is valid for the specified frequency by checking the frequency band
* of this entry and testing for containment.
* @param frequency to check
* @return true if the frequency is contained in the frequency band for this entry.
*/
public boolean isValidFor(long frequency)
{
return getFrequencyBand().contains(frequency);
}
}

View File

@@ -1,6 +1,6 @@
/*
* *****************************************************************************
* Copyright (C) 2014-2023 Dennis Sheirer
* 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
@@ -19,14 +19,12 @@
package io.github.dsheirer.source.tuner.sdrplay.api.parameter.tuner;
import io.github.dsheirer.source.tuner.sdrplay.api.util.Flag;
import io.github.dsheirer.source.tuner.sdrplay.api.v3_07.sdrplay_api_RspDuoTunerParamsT;
import java.lang.foreign.MemorySegment;
/**
* RSPduo Tuner Parameters structure
* RSPduo abstract Tuner Parameters structure
*/
public class RspDuoTunerParameters extends TunerParameters
public abstract class RspDuoTunerParameters extends TunerParameters
{
private MemorySegment mRspDuoMemorySegment;
@@ -44,7 +42,7 @@ public class RspDuoTunerParameters extends TunerParameters
/**
* Foreign memory segment for this structure
*/
private MemorySegment getRspDuoMemorySegment()
MemorySegment getRspDuoMemorySegment()
{
return mRspDuoMemorySegment;
}
@@ -52,80 +50,50 @@ public class RspDuoTunerParameters extends TunerParameters
/**
* Indicates if the Bias-T is enabled
*/
public boolean isBiasT()
{
return Flag.evaluate(sdrplay_api_RspDuoTunerParamsT.biasTEnable$get(getRspDuoMemorySegment()));
}
public abstract boolean isBiasT();
/**
* Enables or disables the Bias-T
*/
public void setBiasT(boolean enable)
{
sdrplay_api_RspDuoTunerParamsT.biasTEnable$set(getRspDuoMemorySegment(), Flag.of(enable));
}
public abstract void setBiasT(boolean enable);
/**
* Tuner 1 AM port setting
*/
public RspDuoAmPort getTuner1AmPort()
{
return RspDuoAmPort.fromValue(sdrplay_api_RspDuoTunerParamsT.tuner1AmPortSel$get(getRspDuoMemorySegment()));
}
public abstract RspDuoAmPort getTuner1AmPort();
/**
* Set Tuner 1 AM port setting
*/
public void setTuner1AmPort(RspDuoAmPort amPort)
{
sdrplay_api_RspDuoTunerParamsT.tuner1AmPortSel$set(getRspDuoMemorySegment(), amPort.getValue());
}
public abstract void setTuner1AmPort(RspDuoAmPort amPort);
/**
* Indicates if Tuner 1 AM notch is enabled
*/
public boolean isTuner1AmNotch()
{
return Flag.evaluate(sdrplay_api_RspDuoTunerParamsT.tuner1AmNotchEnable$get(getRspDuoMemorySegment()));
}
public abstract boolean isTuner1AmNotch();
/**
* Enables or disables the Tuner 1 AM notch
*/
public void setTuner1AmNotch(boolean enable)
{
sdrplay_api_RspDuoTunerParamsT.tuner1AmNotchEnable$set(getRspDuoMemorySegment(), Flag.of(enable));
}
public abstract void setTuner1AmNotch(boolean enable);
/**
* Indicates if the RF notch is enabled
*/
public boolean isRfNotch()
{
return Flag.evaluate(sdrplay_api_RspDuoTunerParamsT.rfNotchEnable$get(getRspDuoMemorySegment()));
}
public abstract boolean isRfNotch();
/**
* Enables or disables the RF notch
*/
public void setRfNotch(boolean enable)
{
sdrplay_api_RspDuoTunerParamsT.rfNotchEnable$set(getRspDuoMemorySegment(), Flag.of(enable));
}
public abstract void setRfNotch(boolean enable);
/**
* Indicates if the RF DAB notch is enabled
*/
public boolean isRfDabNotch()
{
return Flag.evaluate(sdrplay_api_RspDuoTunerParamsT.rfDabNotchEnable$get(getRspDuoMemorySegment()));
}
public abstract boolean isRfDabNotch();
/**
* Enables or disables the RF DAB notch
*/
public void setRfDabNotch(boolean enable)
{
sdrplay_api_RspDuoTunerParamsT.rfDabNotchEnable$set(getRspDuoMemorySegment(), Flag.of(enable));
}
public abstract void setRfDabNotch(boolean enable);
}

View File

@@ -0,0 +1,120 @@
/*
* *****************************************************************************
* 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.tuner;
import io.github.dsheirer.source.tuner.sdrplay.api.util.Flag;
import io.github.dsheirer.source.tuner.sdrplay.api.v3_07.sdrplay_api_RspDuoTunerParamsT;
import java.lang.foreign.MemorySegment;
/**
* RSPduo Tuner Parameters structure for API Versions 3.07 - 3.12.
*/
public class RspDuoTunerParametersV3_07 extends RspDuoTunerParameters
{
/**
* Constructs an instance from the foreign memory segment
* @param tunerParametersMemorySegment of foreign memory structure
* @param rspDuoMemorySegment of foreign memory structure
*/
RspDuoTunerParametersV3_07(MemorySegment tunerParametersMemorySegment, MemorySegment rspDuoMemorySegment)
{
super(tunerParametersMemorySegment, rspDuoMemorySegment);
}
/**
* Indicates if the Bias-T is enabled
*/
public boolean isBiasT()
{
return Flag.evaluate(sdrplay_api_RspDuoTunerParamsT.biasTEnable$get(getRspDuoMemorySegment()));
}
/**
* Enables or disables the Bias-T
*/
public void setBiasT(boolean enable)
{
sdrplay_api_RspDuoTunerParamsT.biasTEnable$set(getRspDuoMemorySegment(), Flag.of(enable));
}
/**
* Tuner 1 AM port setting
*/
public RspDuoAmPort getTuner1AmPort()
{
return RspDuoAmPort.fromValue(sdrplay_api_RspDuoTunerParamsT.tuner1AmPortSel$get(getRspDuoMemorySegment()));
}
/**
* Set Tuner 1 AM port setting
*/
public void setTuner1AmPort(RspDuoAmPort amPort)
{
sdrplay_api_RspDuoTunerParamsT.tuner1AmPortSel$set(getRspDuoMemorySegment(), amPort.getValue());
}
/**
* Indicates if Tuner 1 AM notch is enabled
*/
public boolean isTuner1AmNotch()
{
return Flag.evaluate(sdrplay_api_RspDuoTunerParamsT.tuner1AmNotchEnable$get(getRspDuoMemorySegment()));
}
/**
* Enables or disables the Tuner 1 AM notch
*/
public void setTuner1AmNotch(boolean enable)
{
sdrplay_api_RspDuoTunerParamsT.tuner1AmNotchEnable$set(getRspDuoMemorySegment(), Flag.of(enable));
}
/**
* Indicates if the RF notch is enabled
*/
public boolean isRfNotch()
{
return Flag.evaluate(sdrplay_api_RspDuoTunerParamsT.rfNotchEnable$get(getRspDuoMemorySegment()));
}
/**
* Enables or disables the RF notch
*/
public void setRfNotch(boolean enable)
{
sdrplay_api_RspDuoTunerParamsT.rfNotchEnable$set(getRspDuoMemorySegment(), Flag.of(enable));
}
/**
* Indicates if the RF DAB notch is enabled
*/
public boolean isRfDabNotch()
{
return Flag.evaluate(sdrplay_api_RspDuoTunerParamsT.rfDabNotchEnable$get(getRspDuoMemorySegment()));
}
/**
* Enables or disables the RF DAB notch
*/
public void setRfDabNotch(boolean enable)
{
sdrplay_api_RspDuoTunerParamsT.rfDabNotchEnable$set(getRspDuoMemorySegment(), Flag.of(enable));
}
}

View File

@@ -0,0 +1,123 @@
/*
* *****************************************************************************
* 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.tuner;
import io.github.dsheirer.source.tuner.sdrplay.api.util.Flag;
import io.github.dsheirer.source.tuner.sdrplay.api.v3_14.sdrplay_api_RspDuoTunerParamsT;
import java.lang.foreign.MemorySegment;
/**
* RSPduo Tuner Parameters structure for API Versions 3.14+.
*
* Note: version 3.14 is different from version 3.07-3.12 because it adds the RspDuo_ResetSlaveFlagsT structure and
* methods, however these are not used/implemented in this class or in the parent abstract class.
*/
public class RspDuoTunerParametersV3_14 extends RspDuoTunerParameters
{
/**
* Constructs an instance from the foreign memory segment
* @param tunerParametersMemorySegment of foreign memory structure
* @param rspDuoMemorySegment of foreign memory structure
*/
RspDuoTunerParametersV3_14(MemorySegment tunerParametersMemorySegment, MemorySegment rspDuoMemorySegment)
{
super(tunerParametersMemorySegment, rspDuoMemorySegment);
}
/**
* Indicates if the Bias-T is enabled
*/
public boolean isBiasT()
{
return Flag.evaluate(sdrplay_api_RspDuoTunerParamsT.biasTEnable$get(getRspDuoMemorySegment()));
}
/**
* Enables or disables the Bias-T
*/
public void setBiasT(boolean enable)
{
sdrplay_api_RspDuoTunerParamsT.biasTEnable$set(getRspDuoMemorySegment(), Flag.of(enable));
}
/**
* Tuner 1 AM port setting
*/
public RspDuoAmPort getTuner1AmPort()
{
return RspDuoAmPort.fromValue(sdrplay_api_RspDuoTunerParamsT.tuner1AmPortSel$get(getRspDuoMemorySegment()));
}
/**
* Set Tuner 1 AM port setting
*/
public void setTuner1AmPort(RspDuoAmPort amPort)
{
sdrplay_api_RspDuoTunerParamsT.tuner1AmPortSel$set(getRspDuoMemorySegment(), amPort.getValue());
}
/**
* Indicates if Tuner 1 AM notch is enabled
*/
public boolean isTuner1AmNotch()
{
return Flag.evaluate(sdrplay_api_RspDuoTunerParamsT.tuner1AmNotchEnable$get(getRspDuoMemorySegment()));
}
/**
* Enables or disables the Tuner 1 AM notch
*/
public void setTuner1AmNotch(boolean enable)
{
sdrplay_api_RspDuoTunerParamsT.tuner1AmNotchEnable$set(getRspDuoMemorySegment(), Flag.of(enable));
}
/**
* Indicates if the RF notch is enabled
*/
public boolean isRfNotch()
{
return Flag.evaluate(sdrplay_api_RspDuoTunerParamsT.rfNotchEnable$get(getRspDuoMemorySegment()));
}
/**
* Enables or disables the RF notch
*/
public void setRfNotch(boolean enable)
{
sdrplay_api_RspDuoTunerParamsT.rfNotchEnable$set(getRspDuoMemorySegment(), Flag.of(enable));
}
/**
* Indicates if the RF DAB notch is enabled
*/
public boolean isRfDabNotch()
{
return Flag.evaluate(sdrplay_api_RspDuoTunerParamsT.rfDabNotchEnable$get(getRspDuoMemorySegment()));
}
/**
* Enables or disables the RF DAB notch
*/
public void setRfDabNotch(boolean enable)
{
sdrplay_api_RspDuoTunerParamsT.rfDabNotchEnable$set(getRspDuoMemorySegment(), Flag.of(enable));
}
}

View File

@@ -1,6 +1,6 @@
/*
* *****************************************************************************
* Copyright (C) 2014-2023 Dennis Sheirer
* 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
@@ -19,6 +19,7 @@
package io.github.dsheirer.source.tuner.sdrplay.api.parameter.tuner;
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.v3_07.sdrplay_api_RxChannelParamsT;
import java.lang.foreign.MemorySegment;
@@ -34,7 +35,7 @@ public class TunerParametersFactory
* @param memorySegment for the sdrplay_api_RxChannelParamsT structure
* @return tuner parameters
*/
public static TunerParameters create(DeviceType deviceType, MemorySegment memorySegment)
public static TunerParameters create(Version version, DeviceType deviceType, MemorySegment memorySegment)
{
MemorySegment tunerParametersMemorySegment = sdrplay_api_RxChannelParamsT.tunerParams$slice(memorySegment);
@@ -43,7 +44,8 @@ public class TunerParametersFactory
case RSP1 -> {
return new Rsp1TunerParameters(tunerParametersMemorySegment);
}
case RSP1A -> {
//RSP1A and RSP1B share the same tuner parameters structures
case RSP1A, RSP1B -> {
MemorySegment rsp1AMemorySegment = sdrplay_api_RxChannelParamsT.rsp1aTunerParams$slice(memorySegment);
return new Rsp1aTunerParameters(memorySegment, rsp1AMemorySegment);
}
@@ -52,8 +54,20 @@ public class TunerParametersFactory
return new Rsp2TunerParameters(memorySegment, rsp2MemorySegment);
}
case RSPduo -> {
MemorySegment rspDuoMemorySegment = sdrplay_api_RxChannelParamsT.rspDuoTunerParams$slice(memorySegment);
return new RspDuoTunerParameters(memorySegment, rspDuoMemorySegment);
if(version.gte(Version.V3_14))
{
MemorySegment rspDuoMemorySegment = io.github.dsheirer.source.tuner.sdrplay.api.v3_14.sdrplay_api_RxChannelParamsT.rspDuoTunerParams$slice(memorySegment);
return new RspDuoTunerParametersV3_14(memorySegment, rspDuoMemorySegment);
}
else if(version.gte(Version.V3_07))
{
MemorySegment rspDuoMemorySegment = sdrplay_api_RxChannelParamsT.rspDuoTunerParams$slice(memorySegment);
return new RspDuoTunerParametersV3_07(memorySegment, rspDuoMemorySegment);
}
else
{
throw new IllegalArgumentException("Unrecognized API version: " + version);
}
}
case RSPdx -> {
MemorySegment rspDxMemorySegment = sdrplay_api_RxChannelParamsT.rspDxTunerParams$slice(memorySegment);

View File

@@ -0,0 +1,55 @@
/*
* *****************************************************************************
* 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/>
* ****************************************************************************
*/
// Generated by jextract
package io.github.dsheirer.source.tuner.sdrplay.api.v3_14;
import static java.lang.foreign.ValueLayout.ADDRESS;
import static java.lang.foreign.ValueLayout.JAVA_BOOLEAN;
import static java.lang.foreign.ValueLayout.JAVA_BYTE;
import static java.lang.foreign.ValueLayout.JAVA_DOUBLE;
import static java.lang.foreign.ValueLayout.JAVA_FLOAT;
import static java.lang.foreign.ValueLayout.JAVA_INT;
import static java.lang.foreign.ValueLayout.JAVA_LONG;
import static java.lang.foreign.ValueLayout.JAVA_SHORT;
import static java.lang.foreign.ValueLayout.OfAddress;
import static java.lang.foreign.ValueLayout.OfBoolean;
import static java.lang.foreign.ValueLayout.OfByte;
import static java.lang.foreign.ValueLayout.OfDouble;
import static java.lang.foreign.ValueLayout.OfFloat;
import static java.lang.foreign.ValueLayout.OfInt;
import static java.lang.foreign.ValueLayout.OfLong;
import static java.lang.foreign.ValueLayout.OfShort;
final class Constants$root {
// Suppresses default constructor, ensuring non-instantiability.
private Constants$root() {}
static final OfBoolean C_BOOL$LAYOUT = JAVA_BOOLEAN;
static final OfByte C_CHAR$LAYOUT = JAVA_BYTE;
static final OfShort C_SHORT$LAYOUT = JAVA_SHORT;
static final OfInt C_INT$LAYOUT = JAVA_INT;
static final OfLong C_LONG$LAYOUT = JAVA_LONG;
static final OfLong C_LONG_LONG$LAYOUT = JAVA_LONG;
static final OfFloat C_FLOAT$LAYOUT = JAVA_FLOAT;
static final OfDouble C_DOUBLE$LAYOUT = JAVA_DOUBLE;
static final OfAddress C_POINTER$LAYOUT = ADDRESS.withBitAlignment(64).asUnbounded();
}

View File

@@ -0,0 +1,253 @@
/*
* *****************************************************************************
* 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.v3_14;
// Generated by jextract
import java.lang.foreign.FunctionDescriptor;
import java.lang.foreign.GroupLayout;
import java.lang.foreign.Linker;
import java.lang.foreign.MemoryLayout;
import java.lang.foreign.MemorySegment;
import java.lang.foreign.SegmentAllocator;
import java.lang.foreign.SegmentScope;
import java.lang.foreign.SymbolLookup;
import java.lang.foreign.ValueLayout;
import java.lang.invoke.MethodHandle;
import java.lang.invoke.MethodHandles;
import java.lang.invoke.MethodType;
import static java.lang.foreign.ValueLayout.ADDRESS;
import static java.lang.foreign.ValueLayout.JAVA_DOUBLE;
import static java.lang.foreign.ValueLayout.JAVA_LONG;
final class RuntimeHelper {
private static final Linker LINKER = Linker.nativeLinker();
private static final ClassLoader LOADER = RuntimeHelper.class.getClassLoader();
private static final MethodHandles.Lookup MH_LOOKUP = MethodHandles.lookup();
private static final SymbolLookup SYMBOL_LOOKUP;
private static final SegmentAllocator THROWING_ALLOCATOR = (x, y) -> { throw new AssertionError("should not reach here"); };
final static SegmentAllocator CONSTANT_ALLOCATOR =
(size, align) -> MemorySegment.allocateNative(size, align, SegmentScope.auto());
static {
System.loadLibrary("libsdrplay_api");
SymbolLookup loaderLookup = SymbolLookup.loaderLookup();
SYMBOL_LOOKUP = name -> loaderLookup.find(name).or(() -> LINKER.defaultLookup().find(name));
}
// Suppresses default constructor, ensuring non-instantiability.
private RuntimeHelper() {}
static <T> T requireNonNull(T obj, String symbolName) {
if (obj == null) {
throw new UnsatisfiedLinkError("unresolved symbol: " + symbolName);
}
return obj;
}
static MemorySegment lookupGlobalVariable(String name, MemoryLayout layout) {
return SYMBOL_LOOKUP.find(name).map(symbol -> MemorySegment.ofAddress(symbol.address(), layout.byteSize(), symbol.scope())).orElse(null);
}
static MethodHandle downcallHandle(String name, FunctionDescriptor fdesc) {
return SYMBOL_LOOKUP.find(name).
map(addr -> LINKER.downcallHandle(addr, fdesc)).
orElse(null);
}
static MethodHandle downcallHandle(FunctionDescriptor fdesc) {
return LINKER.downcallHandle(fdesc);
}
static MethodHandle downcallHandleVariadic(String name, FunctionDescriptor fdesc) {
return SYMBOL_LOOKUP.find(name).
map(addr -> VarargsInvoker.make(addr, fdesc)).
orElse(null);
}
static MethodHandle upcallHandle(Class<?> fi, String name, FunctionDescriptor fdesc) {
try {
return MH_LOOKUP.findVirtual(fi, name, fdesc.toMethodType());
} catch (Throwable ex) {
throw new AssertionError(ex);
}
}
static <Z> MemorySegment upcallStub(MethodHandle fiHandle, Z z, FunctionDescriptor fdesc, SegmentScope scope) {
try {
fiHandle = fiHandle.bindTo(z);
return LINKER.upcallStub(fiHandle, fdesc, scope);
} catch (Throwable ex) {
throw new AssertionError(ex);
}
}
static MemorySegment asArray(MemorySegment addr, MemoryLayout layout, int numElements, SegmentScope scope) {
return MemorySegment.ofAddress(addr.address(), numElements * layout.byteSize(), scope);
}
// Internals only below this point
private static final class VarargsInvoker {
private static final MethodHandle INVOKE_MH;
private final MemorySegment symbol;
private final FunctionDescriptor function;
private VarargsInvoker(MemorySegment symbol, FunctionDescriptor function) {
this.symbol = symbol;
this.function = function;
}
static {
try {
INVOKE_MH = MethodHandles.lookup().findVirtual(VarargsInvoker.class, "invoke", MethodType.methodType(Object.class, SegmentAllocator.class, Object[].class));
} catch (ReflectiveOperationException e) {
throw new RuntimeException(e);
}
}
static MethodHandle make(MemorySegment symbol, FunctionDescriptor function) {
VarargsInvoker invoker = new VarargsInvoker(symbol, function);
MethodHandle handle = INVOKE_MH.bindTo(invoker).asCollector(Object[].class, function.argumentLayouts().size() + 1);
MethodType mtype = MethodType.methodType(function.returnLayout().isPresent() ? carrier(function.returnLayout().get(), true) : void.class);
for (MemoryLayout layout : function.argumentLayouts()) {
mtype = mtype.appendParameterTypes(carrier(layout, false));
}
mtype = mtype.appendParameterTypes(Object[].class);
boolean needsAllocator = function.returnLayout().isPresent() &&
function.returnLayout().get() instanceof GroupLayout;
if (needsAllocator) {
mtype = mtype.insertParameterTypes(0, SegmentAllocator.class);
} else {
handle = MethodHandles.insertArguments(handle, 0, THROWING_ALLOCATOR);
}
return handle.asType(mtype);
}
static Class<?> carrier(MemoryLayout layout, boolean ret) {
if (layout instanceof ValueLayout valueLayout) {
return valueLayout.carrier();
} else if (layout instanceof GroupLayout) {
return MemorySegment.class;
} else {
throw new AssertionError("Cannot get here!");
}
}
private Object invoke(SegmentAllocator allocator, Object[] args) throws Throwable {
// one trailing Object[]
int nNamedArgs = function.argumentLayouts().size();
assert(args.length == nNamedArgs + 1);
// The last argument is the array of vararg collector
Object[] unnamedArgs = (Object[]) args[args.length - 1];
int argsCount = nNamedArgs + unnamedArgs.length;
Class<?>[] argTypes = new Class<?>[argsCount];
MemoryLayout[] argLayouts = new MemoryLayout[nNamedArgs + unnamedArgs.length];
int pos = 0;
for (pos = 0; pos < nNamedArgs; pos++) {
argLayouts[pos] = function.argumentLayouts().get(pos);
}
assert pos == nNamedArgs;
for (Object o: unnamedArgs) {
argLayouts[pos] = variadicLayout(normalize(o.getClass()));
pos++;
}
assert pos == argsCount;
FunctionDescriptor f = (function.returnLayout().isEmpty()) ?
FunctionDescriptor.ofVoid(argLayouts) :
FunctionDescriptor.of(function.returnLayout().get(), argLayouts);
MethodHandle mh = LINKER.downcallHandle(symbol, f);
boolean needsAllocator = function.returnLayout().isPresent() &&
function.returnLayout().get() instanceof GroupLayout;
if (needsAllocator) {
mh = mh.bindTo(allocator);
}
// flatten argument list so that it can be passed to an asSpreader MH
Object[] allArgs = new Object[nNamedArgs + unnamedArgs.length];
System.arraycopy(args, 0, allArgs, 0, nNamedArgs);
System.arraycopy(unnamedArgs, 0, allArgs, nNamedArgs, unnamedArgs.length);
return mh.asSpreader(Object[].class, argsCount).invoke(allArgs);
}
private static Class<?> unboxIfNeeded(Class<?> clazz) {
if (clazz == Boolean.class) {
return boolean.class;
} else if (clazz == Void.class) {
return void.class;
} else if (clazz == Byte.class) {
return byte.class;
} else if (clazz == Character.class) {
return char.class;
} else if (clazz == Short.class) {
return short.class;
} else if (clazz == Integer.class) {
return int.class;
} else if (clazz == Long.class) {
return long.class;
} else if (clazz == Float.class) {
return float.class;
} else if (clazz == Double.class) {
return double.class;
} else {
return clazz;
}
}
private Class<?> promote(Class<?> c) {
if (c == byte.class || c == char.class || c == short.class || c == int.class) {
return long.class;
} else if (c == float.class) {
return double.class;
} else {
return c;
}
}
private Class<?> normalize(Class<?> c) {
c = unboxIfNeeded(c);
if (c.isPrimitive()) {
return promote(c);
}
if (c == MemorySegment.class) {
return MemorySegment.class;
}
throw new IllegalArgumentException("Invalid type for ABI: " + c.getTypeName());
}
private MemoryLayout variadicLayout(Class<?> c) {
if (c == long.class) {
return JAVA_LONG;
} else if (c == double.class) {
return JAVA_DOUBLE;
} else if (c == MemorySegment.class) {
return ADDRESS;
} else {
throw new IllegalArgumentException("Unhandled variadic argument class: " + c);
}
}
}
}

View File

@@ -0,0 +1,89 @@
/*
* *****************************************************************************
* 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/>
* ****************************************************************************
*/
// Generated by jextract
package io.github.dsheirer.source.tuner.sdrplay.api.v3_14;
import java.lang.foreign.FunctionDescriptor;
import java.lang.invoke.MethodHandle;
final class constants$0 {
// Suppresses default constructor, ensuring non-instantiability.
private constants$0() {}
static final FunctionDescriptor sdrplay_api_StreamCallback_t$FUNC = FunctionDescriptor.ofVoid(
Constants$root.C_POINTER$LAYOUT,
Constants$root.C_POINTER$LAYOUT,
Constants$root.C_POINTER$LAYOUT,
Constants$root.C_INT$LAYOUT,
Constants$root.C_INT$LAYOUT,
Constants$root.C_POINTER$LAYOUT
);
static final FunctionDescriptor sdrplay_api_StreamCallback_t_UP$FUNC = FunctionDescriptor.ofVoid(
Constants$root.C_POINTER$LAYOUT,
Constants$root.C_POINTER$LAYOUT,
Constants$root.C_POINTER$LAYOUT,
Constants$root.C_INT$LAYOUT,
Constants$root.C_INT$LAYOUT,
Constants$root.C_POINTER$LAYOUT
);
static final MethodHandle sdrplay_api_StreamCallback_t_UP$MH = RuntimeHelper.upcallHandle(sdrplay_api_StreamCallback_t.class, "apply", constants$0.sdrplay_api_StreamCallback_t_UP$FUNC);
static final FunctionDescriptor sdrplay_api_StreamCallback_t_DOWN$FUNC = FunctionDescriptor.ofVoid(
Constants$root.C_POINTER$LAYOUT,
Constants$root.C_POINTER$LAYOUT,
Constants$root.C_POINTER$LAYOUT,
Constants$root.C_INT$LAYOUT,
Constants$root.C_INT$LAYOUT,
Constants$root.C_POINTER$LAYOUT
);
static final MethodHandle sdrplay_api_StreamCallback_t_DOWN$MH = RuntimeHelper.downcallHandle(
constants$0.sdrplay_api_StreamCallback_t_DOWN$FUNC
);
static final FunctionDescriptor sdrplay_api_EventCallback_t$FUNC = FunctionDescriptor.ofVoid(
Constants$root.C_INT$LAYOUT,
Constants$root.C_INT$LAYOUT,
Constants$root.C_POINTER$LAYOUT,
Constants$root.C_POINTER$LAYOUT
);
static final FunctionDescriptor sdrplay_api_EventCallback_t_UP$FUNC = FunctionDescriptor.ofVoid(
Constants$root.C_INT$LAYOUT,
Constants$root.C_INT$LAYOUT,
Constants$root.C_POINTER$LAYOUT,
Constants$root.C_POINTER$LAYOUT
);
static final MethodHandle sdrplay_api_EventCallback_t_UP$MH = RuntimeHelper.upcallHandle(sdrplay_api_EventCallback_t.class, "apply", constants$0.sdrplay_api_EventCallback_t_UP$FUNC);
static final FunctionDescriptor sdrplay_api_EventCallback_t_DOWN$FUNC = FunctionDescriptor.ofVoid(
Constants$root.C_INT$LAYOUT,
Constants$root.C_INT$LAYOUT,
Constants$root.C_POINTER$LAYOUT,
Constants$root.C_POINTER$LAYOUT
);
static final MethodHandle sdrplay_api_EventCallback_t_DOWN$MH = RuntimeHelper.downcallHandle(
constants$0.sdrplay_api_EventCallback_t_DOWN$FUNC
);
static final FunctionDescriptor sdrplay_api_Open_t$FUNC = FunctionDescriptor.of(Constants$root.C_INT$LAYOUT);
static final FunctionDescriptor sdrplay_api_Open_t_UP$FUNC = FunctionDescriptor.of(Constants$root.C_INT$LAYOUT);
static final MethodHandle sdrplay_api_Open_t_UP$MH = RuntimeHelper.upcallHandle(sdrplay_api_Open_t.class, "apply", constants$0.sdrplay_api_Open_t_UP$FUNC);
static final FunctionDescriptor sdrplay_api_Open_t_DOWN$FUNC = FunctionDescriptor.of(Constants$root.C_INT$LAYOUT);
static final MethodHandle sdrplay_api_Open_t_DOWN$MH = RuntimeHelper.downcallHandle(
constants$0.sdrplay_api_Open_t_DOWN$FUNC
);
}

View File

@@ -0,0 +1,59 @@
/*
* *****************************************************************************
* 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/>
* ****************************************************************************
*/
// Generated by jextract
package io.github.dsheirer.source.tuner.sdrplay.api.v3_14;
import java.lang.foreign.FunctionDescriptor;
import java.lang.invoke.MethodHandle;
final class constants$1 {
// Suppresses default constructor, ensuring non-instantiability.
private constants$1() {}
static final FunctionDescriptor sdrplay_api_Close_t$FUNC = FunctionDescriptor.of(Constants$root.C_INT$LAYOUT);
static final FunctionDescriptor sdrplay_api_Close_t_UP$FUNC = FunctionDescriptor.of(Constants$root.C_INT$LAYOUT);
static final MethodHandle sdrplay_api_Close_t_UP$MH = RuntimeHelper.upcallHandle(sdrplay_api_Close_t.class, "apply", constants$1.sdrplay_api_Close_t_UP$FUNC);
static final FunctionDescriptor sdrplay_api_Close_t_DOWN$FUNC = FunctionDescriptor.of(Constants$root.C_INT$LAYOUT);
static final MethodHandle sdrplay_api_Close_t_DOWN$MH = RuntimeHelper.downcallHandle(
constants$1.sdrplay_api_Close_t_DOWN$FUNC
);
static final FunctionDescriptor sdrplay_api_ApiVersion_t$FUNC = FunctionDescriptor.of(Constants$root.C_INT$LAYOUT,
Constants$root.C_POINTER$LAYOUT
);
static final FunctionDescriptor sdrplay_api_ApiVersion_t_UP$FUNC = FunctionDescriptor.of(Constants$root.C_INT$LAYOUT,
Constants$root.C_POINTER$LAYOUT
);
static final MethodHandle sdrplay_api_ApiVersion_t_UP$MH = RuntimeHelper.upcallHandle(sdrplay_api_ApiVersion_t.class, "apply", constants$1.sdrplay_api_ApiVersion_t_UP$FUNC);
static final FunctionDescriptor sdrplay_api_ApiVersion_t_DOWN$FUNC = FunctionDescriptor.of(Constants$root.C_INT$LAYOUT,
Constants$root.C_POINTER$LAYOUT
);
static final MethodHandle sdrplay_api_ApiVersion_t_DOWN$MH = RuntimeHelper.downcallHandle(
constants$1.sdrplay_api_ApiVersion_t_DOWN$FUNC
);
static final FunctionDescriptor sdrplay_api_LockDeviceApi_t$FUNC = FunctionDescriptor.of(Constants$root.C_INT$LAYOUT);
static final FunctionDescriptor sdrplay_api_LockDeviceApi_t_UP$FUNC = FunctionDescriptor.of(Constants$root.C_INT$LAYOUT);
static final MethodHandle sdrplay_api_LockDeviceApi_t_UP$MH = RuntimeHelper.upcallHandle(sdrplay_api_LockDeviceApi_t.class, "apply", constants$1.sdrplay_api_LockDeviceApi_t_UP$FUNC);
static final FunctionDescriptor sdrplay_api_LockDeviceApi_t_DOWN$FUNC = FunctionDescriptor.of(Constants$root.C_INT$LAYOUT);
static final MethodHandle sdrplay_api_LockDeviceApi_t_DOWN$MH = RuntimeHelper.downcallHandle(
constants$1.sdrplay_api_LockDeviceApi_t_DOWN$FUNC
);
}

View File

@@ -0,0 +1,74 @@
/*
* *****************************************************************************
* 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/>
* ****************************************************************************
*/
// Generated by jextract
package io.github.dsheirer.source.tuner.sdrplay.api.v3_14;
import java.lang.foreign.FunctionDescriptor;
import java.lang.invoke.MethodHandle;
final class constants$10 {
// Suppresses default constructor, ensuring non-instantiability.
private constants$10() {}
static final FunctionDescriptor sdrplay_api_Update$FUNC = FunctionDescriptor.of(Constants$root.C_INT$LAYOUT,
Constants$root.C_POINTER$LAYOUT,
Constants$root.C_INT$LAYOUT,
Constants$root.C_INT$LAYOUT,
Constants$root.C_INT$LAYOUT
);
static final MethodHandle sdrplay_api_Update$MH = RuntimeHelper.downcallHandle(
"sdrplay_api_Update",
constants$10.sdrplay_api_Update$FUNC
);
static final FunctionDescriptor sdrplay_api_SwapRspDuoActiveTuner$FUNC = FunctionDescriptor.of(Constants$root.C_INT$LAYOUT,
Constants$root.C_POINTER$LAYOUT,
Constants$root.C_POINTER$LAYOUT,
Constants$root.C_INT$LAYOUT
);
static final MethodHandle sdrplay_api_SwapRspDuoActiveTuner$MH = RuntimeHelper.downcallHandle(
"sdrplay_api_SwapRspDuoActiveTuner",
constants$10.sdrplay_api_SwapRspDuoActiveTuner$FUNC
);
static final FunctionDescriptor sdrplay_api_SwapRspDuoDualTunerModeSampleRate$FUNC = FunctionDescriptor.of(Constants$root.C_INT$LAYOUT,
Constants$root.C_POINTER$LAYOUT,
Constants$root.C_POINTER$LAYOUT,
Constants$root.C_DOUBLE$LAYOUT
);
static final MethodHandle sdrplay_api_SwapRspDuoDualTunerModeSampleRate$MH = RuntimeHelper.downcallHandle(
"sdrplay_api_SwapRspDuoDualTunerModeSampleRate",
constants$10.sdrplay_api_SwapRspDuoDualTunerModeSampleRate$FUNC
);
static final FunctionDescriptor sdrplay_api_SwapRspDuoMode$FUNC = FunctionDescriptor.of(Constants$root.C_INT$LAYOUT,
Constants$root.C_POINTER$LAYOUT,
Constants$root.C_POINTER$LAYOUT,
Constants$root.C_INT$LAYOUT,
Constants$root.C_DOUBLE$LAYOUT,
Constants$root.C_INT$LAYOUT,
Constants$root.C_INT$LAYOUT,
Constants$root.C_INT$LAYOUT,
Constants$root.C_INT$LAYOUT
);
static final MethodHandle sdrplay_api_SwapRspDuoMode$MH = RuntimeHelper.downcallHandle(
"sdrplay_api_SwapRspDuoMode",
constants$10.sdrplay_api_SwapRspDuoMode$FUNC
);
}

View File

@@ -0,0 +1,71 @@
/*
* *****************************************************************************
* 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/>
* ****************************************************************************
*/
// Generated by jextract
package io.github.dsheirer.source.tuner.sdrplay.api.v3_14;
import java.lang.foreign.FunctionDescriptor;
import java.lang.invoke.MethodHandle;
final class constants$2 {
// Suppresses default constructor, ensuring non-instantiability.
private constants$2() {}
static final FunctionDescriptor sdrplay_api_UnlockDeviceApi_t$FUNC = FunctionDescriptor.of(Constants$root.C_INT$LAYOUT);
static final FunctionDescriptor sdrplay_api_UnlockDeviceApi_t_UP$FUNC = FunctionDescriptor.of(Constants$root.C_INT$LAYOUT);
static final MethodHandle sdrplay_api_UnlockDeviceApi_t_UP$MH = RuntimeHelper.upcallHandle(sdrplay_api_UnlockDeviceApi_t.class, "apply", constants$2.sdrplay_api_UnlockDeviceApi_t_UP$FUNC);
static final FunctionDescriptor sdrplay_api_UnlockDeviceApi_t_DOWN$FUNC = FunctionDescriptor.of(Constants$root.C_INT$LAYOUT);
static final MethodHandle sdrplay_api_UnlockDeviceApi_t_DOWN$MH = RuntimeHelper.downcallHandle(
constants$2.sdrplay_api_UnlockDeviceApi_t_DOWN$FUNC
);
static final FunctionDescriptor sdrplay_api_GetDevices_t$FUNC = FunctionDescriptor.of(Constants$root.C_INT$LAYOUT,
Constants$root.C_POINTER$LAYOUT,
Constants$root.C_POINTER$LAYOUT,
Constants$root.C_INT$LAYOUT
);
static final FunctionDescriptor sdrplay_api_GetDevices_t_UP$FUNC = FunctionDescriptor.of(Constants$root.C_INT$LAYOUT,
Constants$root.C_POINTER$LAYOUT,
Constants$root.C_POINTER$LAYOUT,
Constants$root.C_INT$LAYOUT
);
static final MethodHandle sdrplay_api_GetDevices_t_UP$MH = RuntimeHelper.upcallHandle(sdrplay_api_GetDevices_t.class, "apply", constants$2.sdrplay_api_GetDevices_t_UP$FUNC);
static final FunctionDescriptor sdrplay_api_GetDevices_t_DOWN$FUNC = FunctionDescriptor.of(Constants$root.C_INT$LAYOUT,
Constants$root.C_POINTER$LAYOUT,
Constants$root.C_POINTER$LAYOUT,
Constants$root.C_INT$LAYOUT
);
static final MethodHandle sdrplay_api_GetDevices_t_DOWN$MH = RuntimeHelper.downcallHandle(
constants$2.sdrplay_api_GetDevices_t_DOWN$FUNC
);
static final FunctionDescriptor sdrplay_api_SelectDevice_t$FUNC = FunctionDescriptor.of(Constants$root.C_INT$LAYOUT,
Constants$root.C_POINTER$LAYOUT
);
static final FunctionDescriptor sdrplay_api_SelectDevice_t_UP$FUNC = FunctionDescriptor.of(Constants$root.C_INT$LAYOUT,
Constants$root.C_POINTER$LAYOUT
);
static final MethodHandle sdrplay_api_SelectDevice_t_UP$MH = RuntimeHelper.upcallHandle(sdrplay_api_SelectDevice_t.class, "apply", constants$2.sdrplay_api_SelectDevice_t_UP$FUNC);
static final FunctionDescriptor sdrplay_api_SelectDevice_t_DOWN$FUNC = FunctionDescriptor.of(Constants$root.C_INT$LAYOUT,
Constants$root.C_POINTER$LAYOUT
);
static final MethodHandle sdrplay_api_SelectDevice_t_DOWN$MH = RuntimeHelper.downcallHandle(
constants$2.sdrplay_api_SelectDevice_t_DOWN$FUNC
);
}

View File

@@ -0,0 +1,71 @@
/*
* *****************************************************************************
* 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/>
* ****************************************************************************
*/
// Generated by jextract
package io.github.dsheirer.source.tuner.sdrplay.api.v3_14;
import java.lang.foreign.FunctionDescriptor;
import java.lang.invoke.MethodHandle;
final class constants$3 {
// Suppresses default constructor, ensuring non-instantiability.
private constants$3() {}
static final FunctionDescriptor sdrplay_api_ReleaseDevice_t$FUNC = FunctionDescriptor.of(Constants$root.C_INT$LAYOUT,
Constants$root.C_POINTER$LAYOUT
);
static final FunctionDescriptor sdrplay_api_ReleaseDevice_t_UP$FUNC = FunctionDescriptor.of(Constants$root.C_INT$LAYOUT,
Constants$root.C_POINTER$LAYOUT
);
static final MethodHandle sdrplay_api_ReleaseDevice_t_UP$MH = RuntimeHelper.upcallHandle(sdrplay_api_ReleaseDevice_t.class, "apply", constants$3.sdrplay_api_ReleaseDevice_t_UP$FUNC);
static final FunctionDescriptor sdrplay_api_ReleaseDevice_t_DOWN$FUNC = FunctionDescriptor.of(Constants$root.C_INT$LAYOUT,
Constants$root.C_POINTER$LAYOUT
);
static final MethodHandle sdrplay_api_ReleaseDevice_t_DOWN$MH = RuntimeHelper.downcallHandle(
constants$3.sdrplay_api_ReleaseDevice_t_DOWN$FUNC
);
static final FunctionDescriptor sdrplay_api_GetErrorString_t$FUNC = FunctionDescriptor.of(Constants$root.C_POINTER$LAYOUT,
Constants$root.C_INT$LAYOUT
);
static final FunctionDescriptor sdrplay_api_GetErrorString_t_UP$FUNC = FunctionDescriptor.of(Constants$root.C_POINTER$LAYOUT,
Constants$root.C_INT$LAYOUT
);
static final MethodHandle sdrplay_api_GetErrorString_t_UP$MH = RuntimeHelper.upcallHandle(sdrplay_api_GetErrorString_t.class, "apply", constants$3.sdrplay_api_GetErrorString_t_UP$FUNC);
static final FunctionDescriptor sdrplay_api_GetErrorString_t_DOWN$FUNC = FunctionDescriptor.of(Constants$root.C_POINTER$LAYOUT,
Constants$root.C_INT$LAYOUT
);
static final MethodHandle sdrplay_api_GetErrorString_t_DOWN$MH = RuntimeHelper.downcallHandle(
constants$3.sdrplay_api_GetErrorString_t_DOWN$FUNC
);
static final FunctionDescriptor sdrplay_api_GetLastError_t$FUNC = FunctionDescriptor.of(Constants$root.C_POINTER$LAYOUT,
Constants$root.C_POINTER$LAYOUT
);
static final FunctionDescriptor sdrplay_api_GetLastError_t_UP$FUNC = FunctionDescriptor.of(Constants$root.C_POINTER$LAYOUT,
Constants$root.C_POINTER$LAYOUT
);
static final MethodHandle sdrplay_api_GetLastError_t_UP$MH = RuntimeHelper.upcallHandle(sdrplay_api_GetLastError_t.class, "apply", constants$3.sdrplay_api_GetLastError_t_UP$FUNC);
static final FunctionDescriptor sdrplay_api_GetLastError_t_DOWN$FUNC = FunctionDescriptor.of(Constants$root.C_POINTER$LAYOUT,
Constants$root.C_POINTER$LAYOUT
);
static final MethodHandle sdrplay_api_GetLastError_t_DOWN$MH = RuntimeHelper.downcallHandle(
constants$3.sdrplay_api_GetLastError_t_DOWN$FUNC
);
}

View File

@@ -0,0 +1,74 @@
/*
* *****************************************************************************
* 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/>
* ****************************************************************************
*/
// Generated by jextract
package io.github.dsheirer.source.tuner.sdrplay.api.v3_14;
import java.lang.foreign.FunctionDescriptor;
import java.lang.invoke.MethodHandle;
final class constants$4 {
// Suppresses default constructor, ensuring non-instantiability.
private constants$4() {}
static final FunctionDescriptor sdrplay_api_GetLastErrorByType_t$FUNC = FunctionDescriptor.of(Constants$root.C_POINTER$LAYOUT,
Constants$root.C_POINTER$LAYOUT,
Constants$root.C_INT$LAYOUT,
Constants$root.C_POINTER$LAYOUT
);
static final FunctionDescriptor sdrplay_api_GetLastErrorByType_t_UP$FUNC = FunctionDescriptor.of(Constants$root.C_POINTER$LAYOUT,
Constants$root.C_POINTER$LAYOUT,
Constants$root.C_INT$LAYOUT,
Constants$root.C_POINTER$LAYOUT
);
static final MethodHandle sdrplay_api_GetLastErrorByType_t_UP$MH = RuntimeHelper.upcallHandle(sdrplay_api_GetLastErrorByType_t.class, "apply", constants$4.sdrplay_api_GetLastErrorByType_t_UP$FUNC);
static final FunctionDescriptor sdrplay_api_GetLastErrorByType_t_DOWN$FUNC = FunctionDescriptor.of(Constants$root.C_POINTER$LAYOUT,
Constants$root.C_POINTER$LAYOUT,
Constants$root.C_INT$LAYOUT,
Constants$root.C_POINTER$LAYOUT
);
static final MethodHandle sdrplay_api_GetLastErrorByType_t_DOWN$MH = RuntimeHelper.downcallHandle(
constants$4.sdrplay_api_GetLastErrorByType_t_DOWN$FUNC
);
static final FunctionDescriptor sdrplay_api_DisableHeartbeat_t$FUNC = FunctionDescriptor.of(Constants$root.C_INT$LAYOUT);
static final FunctionDescriptor sdrplay_api_DisableHeartbeat_t_UP$FUNC = FunctionDescriptor.of(Constants$root.C_INT$LAYOUT);
static final MethodHandle sdrplay_api_DisableHeartbeat_t_UP$MH = RuntimeHelper.upcallHandle(sdrplay_api_DisableHeartbeat_t.class, "apply", constants$4.sdrplay_api_DisableHeartbeat_t_UP$FUNC);
static final FunctionDescriptor sdrplay_api_DisableHeartbeat_t_DOWN$FUNC = FunctionDescriptor.of(Constants$root.C_INT$LAYOUT);
static final MethodHandle sdrplay_api_DisableHeartbeat_t_DOWN$MH = RuntimeHelper.downcallHandle(
constants$4.sdrplay_api_DisableHeartbeat_t_DOWN$FUNC
);
static final FunctionDescriptor sdrplay_api_DebugEnable_t$FUNC = FunctionDescriptor.of(Constants$root.C_INT$LAYOUT,
Constants$root.C_POINTER$LAYOUT,
Constants$root.C_INT$LAYOUT
);
static final FunctionDescriptor sdrplay_api_DebugEnable_t_UP$FUNC = FunctionDescriptor.of(Constants$root.C_INT$LAYOUT,
Constants$root.C_POINTER$LAYOUT,
Constants$root.C_INT$LAYOUT
);
static final MethodHandle sdrplay_api_DebugEnable_t_UP$MH = RuntimeHelper.upcallHandle(sdrplay_api_DebugEnable_t.class, "apply", constants$4.sdrplay_api_DebugEnable_t_UP$FUNC);
static final FunctionDescriptor sdrplay_api_DebugEnable_t_DOWN$FUNC = FunctionDescriptor.of(Constants$root.C_INT$LAYOUT,
Constants$root.C_POINTER$LAYOUT,
Constants$root.C_INT$LAYOUT
);
static final MethodHandle sdrplay_api_DebugEnable_t_DOWN$MH = RuntimeHelper.downcallHandle(
constants$4.sdrplay_api_DebugEnable_t_DOWN$FUNC
);
}

View File

@@ -0,0 +1,80 @@
/*
* *****************************************************************************
* 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/>
* ****************************************************************************
*/
// Generated by jextract
package io.github.dsheirer.source.tuner.sdrplay.api.v3_14;
import java.lang.foreign.FunctionDescriptor;
import java.lang.invoke.MethodHandle;
final class constants$5 {
// Suppresses default constructor, ensuring non-instantiability.
private constants$5() {}
static final FunctionDescriptor sdrplay_api_GetDeviceParams_t$FUNC = FunctionDescriptor.of(Constants$root.C_INT$LAYOUT,
Constants$root.C_POINTER$LAYOUT,
Constants$root.C_POINTER$LAYOUT
);
static final FunctionDescriptor sdrplay_api_GetDeviceParams_t_UP$FUNC = FunctionDescriptor.of(Constants$root.C_INT$LAYOUT,
Constants$root.C_POINTER$LAYOUT,
Constants$root.C_POINTER$LAYOUT
);
static final MethodHandle sdrplay_api_GetDeviceParams_t_UP$MH = RuntimeHelper.upcallHandle(sdrplay_api_GetDeviceParams_t.class, "apply", constants$5.sdrplay_api_GetDeviceParams_t_UP$FUNC);
static final FunctionDescriptor sdrplay_api_GetDeviceParams_t_DOWN$FUNC = FunctionDescriptor.of(Constants$root.C_INT$LAYOUT,
Constants$root.C_POINTER$LAYOUT,
Constants$root.C_POINTER$LAYOUT
);
static final MethodHandle sdrplay_api_GetDeviceParams_t_DOWN$MH = RuntimeHelper.downcallHandle(
constants$5.sdrplay_api_GetDeviceParams_t_DOWN$FUNC
);
static final FunctionDescriptor sdrplay_api_Init_t$FUNC = FunctionDescriptor.of(Constants$root.C_INT$LAYOUT,
Constants$root.C_POINTER$LAYOUT,
Constants$root.C_POINTER$LAYOUT,
Constants$root.C_POINTER$LAYOUT
);
static final FunctionDescriptor sdrplay_api_Init_t_UP$FUNC = FunctionDescriptor.of(Constants$root.C_INT$LAYOUT,
Constants$root.C_POINTER$LAYOUT,
Constants$root.C_POINTER$LAYOUT,
Constants$root.C_POINTER$LAYOUT
);
static final MethodHandle sdrplay_api_Init_t_UP$MH = RuntimeHelper.upcallHandle(sdrplay_api_Init_t.class, "apply", constants$5.sdrplay_api_Init_t_UP$FUNC);
static final FunctionDescriptor sdrplay_api_Init_t_DOWN$FUNC = FunctionDescriptor.of(Constants$root.C_INT$LAYOUT,
Constants$root.C_POINTER$LAYOUT,
Constants$root.C_POINTER$LAYOUT,
Constants$root.C_POINTER$LAYOUT
);
static final MethodHandle sdrplay_api_Init_t_DOWN$MH = RuntimeHelper.downcallHandle(
constants$5.sdrplay_api_Init_t_DOWN$FUNC
);
static final FunctionDescriptor sdrplay_api_Uninit_t$FUNC = FunctionDescriptor.of(Constants$root.C_INT$LAYOUT,
Constants$root.C_POINTER$LAYOUT
);
static final FunctionDescriptor sdrplay_api_Uninit_t_UP$FUNC = FunctionDescriptor.of(Constants$root.C_INT$LAYOUT,
Constants$root.C_POINTER$LAYOUT
);
static final MethodHandle sdrplay_api_Uninit_t_UP$MH = RuntimeHelper.upcallHandle(sdrplay_api_Uninit_t.class, "apply", constants$5.sdrplay_api_Uninit_t_UP$FUNC);
static final FunctionDescriptor sdrplay_api_Uninit_t_DOWN$FUNC = FunctionDescriptor.of(Constants$root.C_INT$LAYOUT,
Constants$root.C_POINTER$LAYOUT
);
static final MethodHandle sdrplay_api_Uninit_t_DOWN$MH = RuntimeHelper.downcallHandle(
constants$5.sdrplay_api_Uninit_t_DOWN$FUNC
);
}

View File

@@ -0,0 +1,89 @@
/*
* *****************************************************************************
* 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/>
* ****************************************************************************
*/
// Generated by jextract
package io.github.dsheirer.source.tuner.sdrplay.api.v3_14;
import java.lang.foreign.FunctionDescriptor;
import java.lang.invoke.MethodHandle;
final class constants$6 {
// Suppresses default constructor, ensuring non-instantiability.
private constants$6() {}
static final FunctionDescriptor sdrplay_api_Update_t$FUNC = FunctionDescriptor.of(Constants$root.C_INT$LAYOUT,
Constants$root.C_POINTER$LAYOUT,
Constants$root.C_INT$LAYOUT,
Constants$root.C_INT$LAYOUT,
Constants$root.C_INT$LAYOUT
);
static final FunctionDescriptor sdrplay_api_Update_t_UP$FUNC = FunctionDescriptor.of(Constants$root.C_INT$LAYOUT,
Constants$root.C_POINTER$LAYOUT,
Constants$root.C_INT$LAYOUT,
Constants$root.C_INT$LAYOUT,
Constants$root.C_INT$LAYOUT
);
static final MethodHandle sdrplay_api_Update_t_UP$MH = RuntimeHelper.upcallHandle(sdrplay_api_Update_t.class, "apply", constants$6.sdrplay_api_Update_t_UP$FUNC);
static final FunctionDescriptor sdrplay_api_Update_t_DOWN$FUNC = FunctionDescriptor.of(Constants$root.C_INT$LAYOUT,
Constants$root.C_POINTER$LAYOUT,
Constants$root.C_INT$LAYOUT,
Constants$root.C_INT$LAYOUT,
Constants$root.C_INT$LAYOUT
);
static final MethodHandle sdrplay_api_Update_t_DOWN$MH = RuntimeHelper.downcallHandle(
constants$6.sdrplay_api_Update_t_DOWN$FUNC
);
static final FunctionDescriptor sdrplay_api_SwapRspDuoActiveTuner_t$FUNC = FunctionDescriptor.of(Constants$root.C_INT$LAYOUT,
Constants$root.C_POINTER$LAYOUT,
Constants$root.C_POINTER$LAYOUT,
Constants$root.C_INT$LAYOUT
);
static final FunctionDescriptor sdrplay_api_SwapRspDuoActiveTuner_t_UP$FUNC = FunctionDescriptor.of(Constants$root.C_INT$LAYOUT,
Constants$root.C_POINTER$LAYOUT,
Constants$root.C_POINTER$LAYOUT,
Constants$root.C_INT$LAYOUT
);
static final MethodHandle sdrplay_api_SwapRspDuoActiveTuner_t_UP$MH = RuntimeHelper.upcallHandle(sdrplay_api_SwapRspDuoActiveTuner_t.class, "apply", constants$6.sdrplay_api_SwapRspDuoActiveTuner_t_UP$FUNC);
static final FunctionDescriptor sdrplay_api_SwapRspDuoActiveTuner_t_DOWN$FUNC = FunctionDescriptor.of(Constants$root.C_INT$LAYOUT,
Constants$root.C_POINTER$LAYOUT,
Constants$root.C_POINTER$LAYOUT,
Constants$root.C_INT$LAYOUT
);
static final MethodHandle sdrplay_api_SwapRspDuoActiveTuner_t_DOWN$MH = RuntimeHelper.downcallHandle(
constants$6.sdrplay_api_SwapRspDuoActiveTuner_t_DOWN$FUNC
);
static final FunctionDescriptor sdrplay_api_SwapRspDuoDualTunerModeSampleRate_t$FUNC = FunctionDescriptor.of(Constants$root.C_INT$LAYOUT,
Constants$root.C_POINTER$LAYOUT,
Constants$root.C_DOUBLE$LAYOUT
);
static final FunctionDescriptor sdrplay_api_SwapRspDuoDualTunerModeSampleRate_t_UP$FUNC = FunctionDescriptor.of(Constants$root.C_INT$LAYOUT,
Constants$root.C_POINTER$LAYOUT,
Constants$root.C_DOUBLE$LAYOUT
);
static final MethodHandle sdrplay_api_SwapRspDuoDualTunerModeSampleRate_t_UP$MH = RuntimeHelper.upcallHandle(sdrplay_api_SwapRspDuoDualTunerModeSampleRate_t.class, "apply", constants$6.sdrplay_api_SwapRspDuoDualTunerModeSampleRate_t_UP$FUNC);
static final FunctionDescriptor sdrplay_api_SwapRspDuoDualTunerModeSampleRate_t_DOWN$FUNC = FunctionDescriptor.of(Constants$root.C_INT$LAYOUT,
Constants$root.C_POINTER$LAYOUT,
Constants$root.C_DOUBLE$LAYOUT
);
static final MethodHandle sdrplay_api_SwapRspDuoDualTunerModeSampleRate_t_DOWN$MH = RuntimeHelper.downcallHandle(
constants$6.sdrplay_api_SwapRspDuoDualTunerModeSampleRate_t_DOWN$FUNC
);
}

View File

@@ -0,0 +1,88 @@
/*
* *****************************************************************************
* 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/>
* ****************************************************************************
*/
// Generated by jextract
package io.github.dsheirer.source.tuner.sdrplay.api.v3_14;
import java.lang.foreign.FunctionDescriptor;
import java.lang.invoke.MethodHandle;
final class constants$7 {
// Suppresses default constructor, ensuring non-instantiability.
private constants$7() {}
static final FunctionDescriptor sdrplay_api_SwapRspDuoMode_t$FUNC = FunctionDescriptor.of(Constants$root.C_INT$LAYOUT,
Constants$root.C_POINTER$LAYOUT,
Constants$root.C_POINTER$LAYOUT,
Constants$root.C_INT$LAYOUT,
Constants$root.C_DOUBLE$LAYOUT,
Constants$root.C_INT$LAYOUT,
Constants$root.C_INT$LAYOUT,
Constants$root.C_INT$LAYOUT,
Constants$root.C_INT$LAYOUT
);
static final FunctionDescriptor sdrplay_api_SwapRspDuoMode_t_UP$FUNC = FunctionDescriptor.of(Constants$root.C_INT$LAYOUT,
Constants$root.C_POINTER$LAYOUT,
Constants$root.C_POINTER$LAYOUT,
Constants$root.C_INT$LAYOUT,
Constants$root.C_DOUBLE$LAYOUT,
Constants$root.C_INT$LAYOUT,
Constants$root.C_INT$LAYOUT,
Constants$root.C_INT$LAYOUT,
Constants$root.C_INT$LAYOUT
);
static final MethodHandle sdrplay_api_SwapRspDuoMode_t_UP$MH = RuntimeHelper.upcallHandle(sdrplay_api_SwapRspDuoMode_t.class, "apply", constants$7.sdrplay_api_SwapRspDuoMode_t_UP$FUNC);
static final FunctionDescriptor sdrplay_api_SwapRspDuoMode_t_DOWN$FUNC = FunctionDescriptor.of(Constants$root.C_INT$LAYOUT,
Constants$root.C_POINTER$LAYOUT,
Constants$root.C_POINTER$LAYOUT,
Constants$root.C_INT$LAYOUT,
Constants$root.C_DOUBLE$LAYOUT,
Constants$root.C_INT$LAYOUT,
Constants$root.C_INT$LAYOUT,
Constants$root.C_INT$LAYOUT,
Constants$root.C_INT$LAYOUT
);
static final MethodHandle sdrplay_api_SwapRspDuoMode_t_DOWN$MH = RuntimeHelper.downcallHandle(
constants$7.sdrplay_api_SwapRspDuoMode_t_DOWN$FUNC
);
static final FunctionDescriptor sdrplay_api_Open$FUNC = FunctionDescriptor.of(Constants$root.C_INT$LAYOUT);
static final MethodHandle sdrplay_api_Open$MH = RuntimeHelper.downcallHandle(
"sdrplay_api_Open",
constants$7.sdrplay_api_Open$FUNC
);
static final FunctionDescriptor sdrplay_api_Close$FUNC = FunctionDescriptor.of(Constants$root.C_INT$LAYOUT);
static final MethodHandle sdrplay_api_Close$MH = RuntimeHelper.downcallHandle(
"sdrplay_api_Close",
constants$7.sdrplay_api_Close$FUNC
);
static final FunctionDescriptor sdrplay_api_ApiVersion$FUNC = FunctionDescriptor.of(Constants$root.C_INT$LAYOUT,
Constants$root.C_POINTER$LAYOUT
);
static final MethodHandle sdrplay_api_ApiVersion$MH = RuntimeHelper.downcallHandle(
"sdrplay_api_ApiVersion",
constants$7.sdrplay_api_ApiVersion$FUNC
);
static final FunctionDescriptor sdrplay_api_LockDeviceApi$FUNC = FunctionDescriptor.of(Constants$root.C_INT$LAYOUT);
static final MethodHandle sdrplay_api_LockDeviceApi$MH = RuntimeHelper.downcallHandle(
"sdrplay_api_LockDeviceApi",
constants$7.sdrplay_api_LockDeviceApi$FUNC
);
}

View File

@@ -0,0 +1,74 @@
/*
* *****************************************************************************
* 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/>
* ****************************************************************************
*/
// Generated by jextract
package io.github.dsheirer.source.tuner.sdrplay.api.v3_14;
import java.lang.foreign.FunctionDescriptor;
import java.lang.invoke.MethodHandle;
final class constants$8 {
// Suppresses default constructor, ensuring non-instantiability.
private constants$8() {}
static final FunctionDescriptor sdrplay_api_UnlockDeviceApi$FUNC = FunctionDescriptor.of(Constants$root.C_INT$LAYOUT);
static final MethodHandle sdrplay_api_UnlockDeviceApi$MH = RuntimeHelper.downcallHandle(
"sdrplay_api_UnlockDeviceApi",
constants$8.sdrplay_api_UnlockDeviceApi$FUNC
);
static final FunctionDescriptor sdrplay_api_GetDevices$FUNC = FunctionDescriptor.of(Constants$root.C_INT$LAYOUT,
Constants$root.C_POINTER$LAYOUT,
Constants$root.C_POINTER$LAYOUT,
Constants$root.C_INT$LAYOUT
);
static final MethodHandle sdrplay_api_GetDevices$MH = RuntimeHelper.downcallHandle(
"sdrplay_api_GetDevices",
constants$8.sdrplay_api_GetDevices$FUNC
);
static final FunctionDescriptor sdrplay_api_SelectDevice$FUNC = FunctionDescriptor.of(Constants$root.C_INT$LAYOUT,
Constants$root.C_POINTER$LAYOUT
);
static final MethodHandle sdrplay_api_SelectDevice$MH = RuntimeHelper.downcallHandle(
"sdrplay_api_SelectDevice",
constants$8.sdrplay_api_SelectDevice$FUNC
);
static final FunctionDescriptor sdrplay_api_ReleaseDevice$FUNC = FunctionDescriptor.of(Constants$root.C_INT$LAYOUT,
Constants$root.C_POINTER$LAYOUT
);
static final MethodHandle sdrplay_api_ReleaseDevice$MH = RuntimeHelper.downcallHandle(
"sdrplay_api_ReleaseDevice",
constants$8.sdrplay_api_ReleaseDevice$FUNC
);
static final FunctionDescriptor sdrplay_api_GetErrorString$FUNC = FunctionDescriptor.of(Constants$root.C_POINTER$LAYOUT,
Constants$root.C_INT$LAYOUT
);
static final MethodHandle sdrplay_api_GetErrorString$MH = RuntimeHelper.downcallHandle(
"sdrplay_api_GetErrorString",
constants$8.sdrplay_api_GetErrorString$FUNC
);
static final FunctionDescriptor sdrplay_api_GetLastError$FUNC = FunctionDescriptor.of(Constants$root.C_POINTER$LAYOUT,
Constants$root.C_POINTER$LAYOUT
);
static final MethodHandle sdrplay_api_GetLastError$MH = RuntimeHelper.downcallHandle(
"sdrplay_api_GetLastError",
constants$8.sdrplay_api_GetLastError$FUNC
);
}

View File

@@ -0,0 +1,78 @@
/*
* *****************************************************************************
* 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/>
* ****************************************************************************
*/
// Generated by jextract
package io.github.dsheirer.source.tuner.sdrplay.api.v3_14;
import java.lang.foreign.FunctionDescriptor;
import java.lang.invoke.MethodHandle;
final class constants$9 {
// Suppresses default constructor, ensuring non-instantiability.
private constants$9() {}
static final FunctionDescriptor sdrplay_api_GetLastErrorByType$FUNC = FunctionDescriptor.of(Constants$root.C_POINTER$LAYOUT,
Constants$root.C_POINTER$LAYOUT,
Constants$root.C_INT$LAYOUT,
Constants$root.C_POINTER$LAYOUT
);
static final MethodHandle sdrplay_api_GetLastErrorByType$MH = RuntimeHelper.downcallHandle(
"sdrplay_api_GetLastErrorByType",
constants$9.sdrplay_api_GetLastErrorByType$FUNC
);
static final FunctionDescriptor sdrplay_api_DisableHeartbeat$FUNC = FunctionDescriptor.of(Constants$root.C_INT$LAYOUT);
static final MethodHandle sdrplay_api_DisableHeartbeat$MH = RuntimeHelper.downcallHandle(
"sdrplay_api_DisableHeartbeat",
constants$9.sdrplay_api_DisableHeartbeat$FUNC
);
static final FunctionDescriptor sdrplay_api_DebugEnable$FUNC = FunctionDescriptor.of(Constants$root.C_INT$LAYOUT,
Constants$root.C_POINTER$LAYOUT,
Constants$root.C_INT$LAYOUT
);
static final MethodHandle sdrplay_api_DebugEnable$MH = RuntimeHelper.downcallHandle(
"sdrplay_api_DebugEnable",
constants$9.sdrplay_api_DebugEnable$FUNC
);
static final FunctionDescriptor sdrplay_api_GetDeviceParams$FUNC = FunctionDescriptor.of(Constants$root.C_INT$LAYOUT,
Constants$root.C_POINTER$LAYOUT,
Constants$root.C_POINTER$LAYOUT
);
static final MethodHandle sdrplay_api_GetDeviceParams$MH = RuntimeHelper.downcallHandle(
"sdrplay_api_GetDeviceParams",
constants$9.sdrplay_api_GetDeviceParams$FUNC
);
static final FunctionDescriptor sdrplay_api_Init$FUNC = FunctionDescriptor.of(Constants$root.C_INT$LAYOUT,
Constants$root.C_POINTER$LAYOUT,
Constants$root.C_POINTER$LAYOUT,
Constants$root.C_POINTER$LAYOUT
);
static final MethodHandle sdrplay_api_Init$MH = RuntimeHelper.downcallHandle(
"sdrplay_api_Init",
constants$9.sdrplay_api_Init$FUNC
);
static final FunctionDescriptor sdrplay_api_Uninit$FUNC = FunctionDescriptor.of(Constants$root.C_INT$LAYOUT,
Constants$root.C_POINTER$LAYOUT
);
static final MethodHandle sdrplay_api_Uninit$MH = RuntimeHelper.downcallHandle(
"sdrplay_api_Uninit",
constants$9.sdrplay_api_Uninit$FUNC
);
}

View File

@@ -0,0 +1,261 @@
/*
* *****************************************************************************
* 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/>
* ****************************************************************************
*/
// Generated by jextract
package io.github.dsheirer.source.tuner.sdrplay.api.v3_14;
import java.lang.foreign.MemoryLayout;
import java.lang.foreign.MemorySegment;
import java.lang.foreign.SegmentAllocator;
import java.lang.foreign.SegmentScope;
import java.lang.foreign.StructLayout;
import java.lang.invoke.VarHandle;
/**
* {@snippet :
* struct {
* sdrplay_api_AgcControlT enable;
* int setPoint_dBfs;
* unsigned short attack_ms;
* unsigned short decay_ms;
* unsigned short decay_delay_ms;
* unsigned short decay_threshold_dB;
* int syncUpdate;
* };
* }
*/
public class sdrplay_api_AgcT {
static final StructLayout $struct$LAYOUT = MemoryLayout.structLayout(
Constants$root.C_INT$LAYOUT.withName("enable"),
Constants$root.C_INT$LAYOUT.withName("setPoint_dBfs"),
Constants$root.C_SHORT$LAYOUT.withName("attack_ms"),
Constants$root.C_SHORT$LAYOUT.withName("decay_ms"),
Constants$root.C_SHORT$LAYOUT.withName("decay_delay_ms"),
Constants$root.C_SHORT$LAYOUT.withName("decay_threshold_dB"),
Constants$root.C_INT$LAYOUT.withName("syncUpdate")
);
public static MemoryLayout $LAYOUT() {
return sdrplay_api_AgcT.$struct$LAYOUT;
}
static final VarHandle enable$VH = $struct$LAYOUT.varHandle(MemoryLayout.PathElement.groupElement("enable"));
public static VarHandle enable$VH() {
return sdrplay_api_AgcT.enable$VH;
}
/**
* Getter for field:
* {@snippet :
* sdrplay_api_AgcControlT enable;
* }
*/
public static int enable$get(MemorySegment seg) {
return (int)sdrplay_api_AgcT.enable$VH.get(seg);
}
/**
* Setter for field:
* {@snippet :
* sdrplay_api_AgcControlT enable;
* }
*/
public static void enable$set(MemorySegment seg, int x) {
sdrplay_api_AgcT.enable$VH.set(seg, x);
}
public static int enable$get(MemorySegment seg, long index) {
return (int)sdrplay_api_AgcT.enable$VH.get(seg.asSlice(index*sizeof()));
}
public static void enable$set(MemorySegment seg, long index, int x) {
sdrplay_api_AgcT.enable$VH.set(seg.asSlice(index*sizeof()), x);
}
static final VarHandle setPoint_dBfs$VH = $struct$LAYOUT.varHandle(MemoryLayout.PathElement.groupElement("setPoint_dBfs"));
public static VarHandle setPoint_dBfs$VH() {
return sdrplay_api_AgcT.setPoint_dBfs$VH;
}
/**
* Getter for field:
* {@snippet :
* int setPoint_dBfs;
* }
*/
public static int setPoint_dBfs$get(MemorySegment seg) {
return (int)sdrplay_api_AgcT.setPoint_dBfs$VH.get(seg);
}
/**
* Setter for field:
* {@snippet :
* int setPoint_dBfs;
* }
*/
public static void setPoint_dBfs$set(MemorySegment seg, int x) {
sdrplay_api_AgcT.setPoint_dBfs$VH.set(seg, x);
}
public static int setPoint_dBfs$get(MemorySegment seg, long index) {
return (int)sdrplay_api_AgcT.setPoint_dBfs$VH.get(seg.asSlice(index*sizeof()));
}
public static void setPoint_dBfs$set(MemorySegment seg, long index, int x) {
sdrplay_api_AgcT.setPoint_dBfs$VH.set(seg.asSlice(index*sizeof()), x);
}
static final VarHandle attack_ms$VH = $struct$LAYOUT.varHandle(MemoryLayout.PathElement.groupElement("attack_ms"));
public static VarHandle attack_ms$VH() {
return sdrplay_api_AgcT.attack_ms$VH;
}
/**
* Getter for field:
* {@snippet :
* unsigned short attack_ms;
* }
*/
public static short attack_ms$get(MemorySegment seg) {
return (short)sdrplay_api_AgcT.attack_ms$VH.get(seg);
}
/**
* Setter for field:
* {@snippet :
* unsigned short attack_ms;
* }
*/
public static void attack_ms$set(MemorySegment seg, short x) {
sdrplay_api_AgcT.attack_ms$VH.set(seg, x);
}
public static short attack_ms$get(MemorySegment seg, long index) {
return (short)sdrplay_api_AgcT.attack_ms$VH.get(seg.asSlice(index*sizeof()));
}
public static void attack_ms$set(MemorySegment seg, long index, short x) {
sdrplay_api_AgcT.attack_ms$VH.set(seg.asSlice(index*sizeof()), x);
}
static final VarHandle decay_ms$VH = $struct$LAYOUT.varHandle(MemoryLayout.PathElement.groupElement("decay_ms"));
public static VarHandle decay_ms$VH() {
return sdrplay_api_AgcT.decay_ms$VH;
}
/**
* Getter for field:
* {@snippet :
* unsigned short decay_ms;
* }
*/
public static short decay_ms$get(MemorySegment seg) {
return (short)sdrplay_api_AgcT.decay_ms$VH.get(seg);
}
/**
* Setter for field:
* {@snippet :
* unsigned short decay_ms;
* }
*/
public static void decay_ms$set(MemorySegment seg, short x) {
sdrplay_api_AgcT.decay_ms$VH.set(seg, x);
}
public static short decay_ms$get(MemorySegment seg, long index) {
return (short)sdrplay_api_AgcT.decay_ms$VH.get(seg.asSlice(index*sizeof()));
}
public static void decay_ms$set(MemorySegment seg, long index, short x) {
sdrplay_api_AgcT.decay_ms$VH.set(seg.asSlice(index*sizeof()), x);
}
static final VarHandle decay_delay_ms$VH = $struct$LAYOUT.varHandle(MemoryLayout.PathElement.groupElement("decay_delay_ms"));
public static VarHandle decay_delay_ms$VH() {
return sdrplay_api_AgcT.decay_delay_ms$VH;
}
/**
* Getter for field:
* {@snippet :
* unsigned short decay_delay_ms;
* }
*/
public static short decay_delay_ms$get(MemorySegment seg) {
return (short)sdrplay_api_AgcT.decay_delay_ms$VH.get(seg);
}
/**
* Setter for field:
* {@snippet :
* unsigned short decay_delay_ms;
* }
*/
public static void decay_delay_ms$set(MemorySegment seg, short x) {
sdrplay_api_AgcT.decay_delay_ms$VH.set(seg, x);
}
public static short decay_delay_ms$get(MemorySegment seg, long index) {
return (short)sdrplay_api_AgcT.decay_delay_ms$VH.get(seg.asSlice(index*sizeof()));
}
public static void decay_delay_ms$set(MemorySegment seg, long index, short x) {
sdrplay_api_AgcT.decay_delay_ms$VH.set(seg.asSlice(index*sizeof()), x);
}
static final VarHandle decay_threshold_dB$VH = $struct$LAYOUT.varHandle(MemoryLayout.PathElement.groupElement("decay_threshold_dB"));
public static VarHandle decay_threshold_dB$VH() {
return sdrplay_api_AgcT.decay_threshold_dB$VH;
}
/**
* Getter for field:
* {@snippet :
* unsigned short decay_threshold_dB;
* }
*/
public static short decay_threshold_dB$get(MemorySegment seg) {
return (short)sdrplay_api_AgcT.decay_threshold_dB$VH.get(seg);
}
/**
* Setter for field:
* {@snippet :
* unsigned short decay_threshold_dB;
* }
*/
public static void decay_threshold_dB$set(MemorySegment seg, short x) {
sdrplay_api_AgcT.decay_threshold_dB$VH.set(seg, x);
}
public static short decay_threshold_dB$get(MemorySegment seg, long index) {
return (short)sdrplay_api_AgcT.decay_threshold_dB$VH.get(seg.asSlice(index*sizeof()));
}
public static void decay_threshold_dB$set(MemorySegment seg, long index, short x) {
sdrplay_api_AgcT.decay_threshold_dB$VH.set(seg.asSlice(index*sizeof()), x);
}
static final VarHandle syncUpdate$VH = $struct$LAYOUT.varHandle(MemoryLayout.PathElement.groupElement("syncUpdate"));
public static VarHandle syncUpdate$VH() {
return sdrplay_api_AgcT.syncUpdate$VH;
}
/**
* Getter for field:
* {@snippet :
* int syncUpdate;
* }
*/
public static int syncUpdate$get(MemorySegment seg) {
return (int)sdrplay_api_AgcT.syncUpdate$VH.get(seg);
}
/**
* Setter for field:
* {@snippet :
* int syncUpdate;
* }
*/
public static void syncUpdate$set(MemorySegment seg, int x) {
sdrplay_api_AgcT.syncUpdate$VH.set(seg, x);
}
public static int syncUpdate$get(MemorySegment seg, long index) {
return (int)sdrplay_api_AgcT.syncUpdate$VH.get(seg.asSlice(index*sizeof()));
}
public static void syncUpdate$set(MemorySegment seg, long index, int x) {
sdrplay_api_AgcT.syncUpdate$VH.set(seg.asSlice(index*sizeof()), x);
}
public static long sizeof() { return $LAYOUT().byteSize(); }
public static MemorySegment allocate(SegmentAllocator allocator) { return allocator.allocate($LAYOUT()); }
public static MemorySegment allocateArray(long len, SegmentAllocator allocator) {
return allocator.allocate(MemoryLayout.sequenceLayout(len, $LAYOUT()));
}
public static MemorySegment ofAddress(MemorySegment addr, SegmentScope scope) { return RuntimeHelper.asArray(addr, $LAYOUT(), 1, scope); }
}

View File

@@ -0,0 +1,49 @@
/*
* *****************************************************************************
* 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/>
* ****************************************************************************
*/
// Generated by jextract
package io.github.dsheirer.source.tuner.sdrplay.api.v3_14;
import java.lang.foreign.MemorySegment;
import java.lang.foreign.SegmentScope;
/**
* {@snippet :
* enum (*sdrplay_api_ApiVersion_t)(float* apiVer);
* }
*/
public interface sdrplay_api_ApiVersion_t {
int apply(java.lang.foreign.MemorySegment dev);
static MemorySegment allocate(sdrplay_api_ApiVersion_t fi, SegmentScope scope) {
return RuntimeHelper.upcallStub(constants$1.sdrplay_api_ApiVersion_t_UP$MH, fi, constants$1.sdrplay_api_ApiVersion_t$FUNC, scope);
}
static sdrplay_api_ApiVersion_t ofAddress(MemorySegment addr, SegmentScope scope) {
MemorySegment symbol = MemorySegment.ofAddress(addr.address(), 0, scope);
return (java.lang.foreign.MemorySegment _dev) -> {
try {
return (int)constants$1.sdrplay_api_ApiVersion_t_DOWN$MH.invokeExact(symbol, _dev);
} catch (Throwable ex$) {
throw new AssertionError("should not reach here", ex$);
}
};
}
}

View File

@@ -0,0 +1,150 @@
/*
* *****************************************************************************
* 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/>
* ****************************************************************************
*/
// Generated by jextract
package io.github.dsheirer.source.tuner.sdrplay.api.v3_14;
import java.lang.foreign.MemoryLayout;
import java.lang.foreign.MemorySegment;
import java.lang.foreign.SegmentAllocator;
import java.lang.foreign.SegmentScope;
import java.lang.foreign.StructLayout;
import java.lang.invoke.VarHandle;
/**
* {@snippet :
* struct {
* sdrplay_api_StreamCallback_t StreamACbFn;
* sdrplay_api_StreamCallback_t StreamBCbFn;
* sdrplay_api_EventCallback_t EventCbFn;
* };
* }
*/
public class sdrplay_api_CallbackFnsT {
static final StructLayout $struct$LAYOUT = MemoryLayout.structLayout(
Constants$root.C_POINTER$LAYOUT.withName("StreamACbFn"),
Constants$root.C_POINTER$LAYOUT.withName("StreamBCbFn"),
Constants$root.C_POINTER$LAYOUT.withName("EventCbFn")
);
public static MemoryLayout $LAYOUT() {
return sdrplay_api_CallbackFnsT.$struct$LAYOUT;
}
static final VarHandle StreamACbFn$VH = $struct$LAYOUT.varHandle(MemoryLayout.PathElement.groupElement("StreamACbFn"));
public static VarHandle StreamACbFn$VH() {
return sdrplay_api_CallbackFnsT.StreamACbFn$VH;
}
/**
* Getter for field:
* {@snippet :
* sdrplay_api_StreamCallback_t StreamACbFn;
* }
*/
public static MemorySegment StreamACbFn$get(MemorySegment seg) {
return (java.lang.foreign.MemorySegment)sdrplay_api_CallbackFnsT.StreamACbFn$VH.get(seg);
}
/**
* Setter for field:
* {@snippet :
* sdrplay_api_StreamCallback_t StreamACbFn;
* }
*/
public static void StreamACbFn$set(MemorySegment seg, MemorySegment x) {
sdrplay_api_CallbackFnsT.StreamACbFn$VH.set(seg, x);
}
public static MemorySegment StreamACbFn$get(MemorySegment seg, long index) {
return (java.lang.foreign.MemorySegment)sdrplay_api_CallbackFnsT.StreamACbFn$VH.get(seg.asSlice(index*sizeof()));
}
public static void StreamACbFn$set(MemorySegment seg, long index, MemorySegment x) {
sdrplay_api_CallbackFnsT.StreamACbFn$VH.set(seg.asSlice(index*sizeof()), x);
}
public static sdrplay_api_StreamCallback_t StreamACbFn(MemorySegment segment, SegmentScope scope) {
return sdrplay_api_StreamCallback_t.ofAddress(StreamACbFn$get(segment), scope);
}
static final VarHandle StreamBCbFn$VH = $struct$LAYOUT.varHandle(MemoryLayout.PathElement.groupElement("StreamBCbFn"));
public static VarHandle StreamBCbFn$VH() {
return sdrplay_api_CallbackFnsT.StreamBCbFn$VH;
}
/**
* Getter for field:
* {@snippet :
* sdrplay_api_StreamCallback_t StreamBCbFn;
* }
*/
public static MemorySegment StreamBCbFn$get(MemorySegment seg) {
return (java.lang.foreign.MemorySegment)sdrplay_api_CallbackFnsT.StreamBCbFn$VH.get(seg);
}
/**
* Setter for field:
* {@snippet :
* sdrplay_api_StreamCallback_t StreamBCbFn;
* }
*/
public static void StreamBCbFn$set(MemorySegment seg, MemorySegment x) {
sdrplay_api_CallbackFnsT.StreamBCbFn$VH.set(seg, x);
}
public static MemorySegment StreamBCbFn$get(MemorySegment seg, long index) {
return (java.lang.foreign.MemorySegment)sdrplay_api_CallbackFnsT.StreamBCbFn$VH.get(seg.asSlice(index*sizeof()));
}
public static void StreamBCbFn$set(MemorySegment seg, long index, MemorySegment x) {
sdrplay_api_CallbackFnsT.StreamBCbFn$VH.set(seg.asSlice(index*sizeof()), x);
}
public static sdrplay_api_StreamCallback_t StreamBCbFn(MemorySegment segment, SegmentScope scope) {
return sdrplay_api_StreamCallback_t.ofAddress(StreamBCbFn$get(segment), scope);
}
static final VarHandle EventCbFn$VH = $struct$LAYOUT.varHandle(MemoryLayout.PathElement.groupElement("EventCbFn"));
public static VarHandle EventCbFn$VH() {
return sdrplay_api_CallbackFnsT.EventCbFn$VH;
}
/**
* Getter for field:
* {@snippet :
* sdrplay_api_EventCallback_t EventCbFn;
* }
*/
public static MemorySegment EventCbFn$get(MemorySegment seg) {
return (java.lang.foreign.MemorySegment)sdrplay_api_CallbackFnsT.EventCbFn$VH.get(seg);
}
/**
* Setter for field:
* {@snippet :
* sdrplay_api_EventCallback_t EventCbFn;
* }
*/
public static void EventCbFn$set(MemorySegment seg, MemorySegment x) {
sdrplay_api_CallbackFnsT.EventCbFn$VH.set(seg, x);
}
public static MemorySegment EventCbFn$get(MemorySegment seg, long index) {
return (java.lang.foreign.MemorySegment)sdrplay_api_CallbackFnsT.EventCbFn$VH.get(seg.asSlice(index*sizeof()));
}
public static void EventCbFn$set(MemorySegment seg, long index, MemorySegment x) {
sdrplay_api_CallbackFnsT.EventCbFn$VH.set(seg.asSlice(index*sizeof()), x);
}
public static sdrplay_api_EventCallback_t EventCbFn(MemorySegment segment, SegmentScope scope) {
return sdrplay_api_EventCallback_t.ofAddress(EventCbFn$get(segment), scope);
}
public static long sizeof() { return $LAYOUT().byteSize(); }
public static MemorySegment allocate(SegmentAllocator allocator) { return allocator.allocate($LAYOUT()); }
public static MemorySegment allocateArray(long len, SegmentAllocator allocator) {
return allocator.allocate(MemoryLayout.sequenceLayout(len, $LAYOUT()));
}
public static MemorySegment ofAddress(MemorySegment addr, SegmentScope scope) { return RuntimeHelper.asArray(addr, $LAYOUT(), 1, scope); }
}

View File

@@ -0,0 +1,49 @@
/*
* *****************************************************************************
* 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/>
* ****************************************************************************
*/
// Generated by jextract
package io.github.dsheirer.source.tuner.sdrplay.api.v3_14;
import java.lang.foreign.MemorySegment;
import java.lang.foreign.SegmentScope;
/**
* {@snippet :
* enum (*sdrplay_api_Close_t)();
* }
*/
public interface sdrplay_api_Close_t {
int apply();
static MemorySegment allocate(sdrplay_api_Close_t fi, SegmentScope scope) {
return RuntimeHelper.upcallStub(constants$1.sdrplay_api_Close_t_UP$MH, fi, constants$1.sdrplay_api_Close_t$FUNC, scope);
}
static sdrplay_api_Close_t ofAddress(MemorySegment addr, SegmentScope scope) {
MemorySegment symbol = MemorySegment.ofAddress(addr.address(), 0, scope);
return () -> {
try {
return (int)constants$1.sdrplay_api_Close_t_DOWN$MH.invokeExact(symbol);
} catch (Throwable ex$) {
throw new AssertionError("should not reach here", ex$);
}
};
}
}

View File

@@ -0,0 +1,112 @@
/*
* *****************************************************************************
* 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/>
* ****************************************************************************
*/
// Generated by jextract
package io.github.dsheirer.source.tuner.sdrplay.api.v3_14;
import java.lang.foreign.MemoryLayout;
import java.lang.foreign.MemorySegment;
import java.lang.foreign.SegmentAllocator;
import java.lang.foreign.SegmentScope;
import java.lang.foreign.StructLayout;
import java.lang.invoke.VarHandle;
/**
* {@snippet :
* struct {
* sdrplay_api_DcOffsetT dcOffset;
* sdrplay_api_DecimationT decimation;
* sdrplay_api_AgcT agc;
* sdrplay_api_AdsbModeT adsbMode;
* };
* }
*/
public class sdrplay_api_ControlParamsT {
static final StructLayout $struct$LAYOUT = MemoryLayout.structLayout(
MemoryLayout.structLayout(
Constants$root.C_CHAR$LAYOUT.withName("DCenable"),
Constants$root.C_CHAR$LAYOUT.withName("IQenable")
).withName("dcOffset"),
MemoryLayout.structLayout(
Constants$root.C_CHAR$LAYOUT.withName("enable"),
Constants$root.C_CHAR$LAYOUT.withName("decimationFactor"),
Constants$root.C_CHAR$LAYOUT.withName("wideBandSignal")
).withName("decimation"),
MemoryLayout.paddingLayout(24),
MemoryLayout.structLayout(
Constants$root.C_INT$LAYOUT.withName("enable"),
Constants$root.C_INT$LAYOUT.withName("setPoint_dBfs"),
Constants$root.C_SHORT$LAYOUT.withName("attack_ms"),
Constants$root.C_SHORT$LAYOUT.withName("decay_ms"),
Constants$root.C_SHORT$LAYOUT.withName("decay_delay_ms"),
Constants$root.C_SHORT$LAYOUT.withName("decay_threshold_dB"),
Constants$root.C_INT$LAYOUT.withName("syncUpdate")
).withName("agc"),
Constants$root.C_INT$LAYOUT.withName("adsbMode")
);
public static MemoryLayout $LAYOUT() {
return sdrplay_api_ControlParamsT.$struct$LAYOUT;
}
public static MemorySegment dcOffset$slice(MemorySegment seg) {
return seg.asSlice(0, 2);
}
public static MemorySegment decimation$slice(MemorySegment seg) {
return seg.asSlice(2, 3);
}
public static MemorySegment agc$slice(MemorySegment seg) {
return seg.asSlice(8, 20);
}
static final VarHandle adsbMode$VH = $struct$LAYOUT.varHandle(MemoryLayout.PathElement.groupElement("adsbMode"));
public static VarHandle adsbMode$VH() {
return sdrplay_api_ControlParamsT.adsbMode$VH;
}
/**
* Getter for field:
* {@snippet :
* sdrplay_api_AdsbModeT adsbMode;
* }
*/
public static int adsbMode$get(MemorySegment seg) {
return (int)sdrplay_api_ControlParamsT.adsbMode$VH.get(seg);
}
/**
* Setter for field:
* {@snippet :
* sdrplay_api_AdsbModeT adsbMode;
* }
*/
public static void adsbMode$set(MemorySegment seg, int x) {
sdrplay_api_ControlParamsT.adsbMode$VH.set(seg, x);
}
public static int adsbMode$get(MemorySegment seg, long index) {
return (int)sdrplay_api_ControlParamsT.adsbMode$VH.get(seg.asSlice(index*sizeof()));
}
public static void adsbMode$set(MemorySegment seg, long index, int x) {
sdrplay_api_ControlParamsT.adsbMode$VH.set(seg.asSlice(index*sizeof()), x);
}
public static long sizeof() { return $LAYOUT().byteSize(); }
public static MemorySegment allocate(SegmentAllocator allocator) { return allocator.allocate($LAYOUT()); }
public static MemorySegment allocateArray(long len, SegmentAllocator allocator) {
return allocator.allocate(MemoryLayout.sequenceLayout(len, $LAYOUT()));
}
public static MemorySegment ofAddress(MemorySegment addr, SegmentScope scope) { return RuntimeHelper.asArray(addr, $LAYOUT(), 1, scope); }
}

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