diff --git a/CMakeLists.txt b/CMakeLists.txt index 0c76bd2be..03b3e3a10 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -346,6 +346,7 @@ if (BUILD_DEBIAN) add_subdirectory(libmirisdr) add_subdirectory(libperseus) add_subdirectory(libiio) + add_subdirectory(libsoapysdr) endif (BUILD_DEBIAN) add_subdirectory(devices) diff --git a/app/main.cpp b/app/main.cpp index 8d1f8de47..101f06656 100644 --- a/app/main.cpp +++ b/app/main.cpp @@ -35,7 +35,7 @@ static int runQtApplication(int argc, char* argv[], qtwebapp::LoggerWithFile *lo */ QCoreApplication::setOrganizationName("f4exb"); QCoreApplication::setApplicationName("SDRangel"); - QCoreApplication::setApplicationVersion("4.3.0"); + QCoreApplication::setApplicationVersion("4.3.1"); #if QT_VERSION >= 0x050600 QApplication::setAttribute(Qt::AA_EnableHighDpiScaling); // DPI support QCoreApplication::setAttribute(Qt::AA_UseHighDpiPixmaps); //HiDPI pixmaps diff --git a/appbench/main.cpp b/appbench/main.cpp index 1bb7f1f5f..49161a862 100644 --- a/appbench/main.cpp +++ b/appbench/main.cpp @@ -57,7 +57,7 @@ static int runQtApplication(int argc, char* argv[], qtwebapp::LoggerWithFile *lo QCoreApplication::setOrganizationName("f4exb"); QCoreApplication::setApplicationName("SDRangelBench"); - QCoreApplication::setApplicationVersion("4.3.0"); + QCoreApplication::setApplicationVersion("4.3.1"); int catchSignals[] = {SIGQUIT, SIGINT, SIGTERM, SIGHUP}; std::vector vsig(catchSignals, catchSignals + sizeof(catchSignals) / sizeof(int)); diff --git a/appsrv/main.cpp b/appsrv/main.cpp index e11724111..af308e7a3 100644 --- a/appsrv/main.cpp +++ b/appsrv/main.cpp @@ -56,7 +56,7 @@ static int runQtApplication(int argc, char* argv[], qtwebapp::LoggerWithFile *lo QCoreApplication::setOrganizationName("f4exb"); QCoreApplication::setApplicationName("SDRangelSrv"); - QCoreApplication::setApplicationVersion("4.3.0"); + QCoreApplication::setApplicationVersion("4.3.1"); int catchSignals[] = {SIGQUIT, SIGINT, SIGTERM, SIGHUP}; std::vector vsig(catchSignals, catchSignals + sizeof(catchSignals) / sizeof(int)); diff --git a/cm256cc/cm256cc.pro b/cm256cc/cm256cc.pro index 26a533757..67c59ca7a 100644 --- a/cm256cc/cm256cc.pro +++ b/cm256cc/cm256cc.pro @@ -9,8 +9,11 @@ QT += core TEMPLATE = lib TARGET = cm256cc +CONFIG(MSVC):DEFINES += cm256cc_EXPORTS + CONFIG(MINGW32):LIBCM256CCSRC = "C:\softs\cm256cc" CONFIG(MINGW64):LIBCM256CCSRC = "C:\softs\cm256cc" +CONFIG(MSVC):LIBCM256CCSRC = "C:\softs\cm256cc" CONFIG(macx):LIBCM256CCSRC = "../../deps/cm256cc" INCLUDEPATH += $$LIBCM256CCSRC @@ -26,4 +29,5 @@ SOURCES = $$LIBCM256CCSRC/gf256.cpp\ $$LIBCM256CCSRC/cm256.cpp HEADERS = $$LIBCM256CCSRC/gf256.h\ -$$LIBCM256CCSRC/cm256.h +$$LIBCM256CCSRC/cm256.h\ +$$LIBCM256CCSRC/export.h diff --git a/cmake/Modules/FindFFmpeg.cmake b/cmake/Modules/FindFFmpeg.cmake index f97cfbd58..3b0bef249 100644 --- a/cmake/Modules/FindFFmpeg.cmake +++ b/cmake/Modules/FindFFmpeg.cmake @@ -137,7 +137,7 @@ if (NOT FFMPEG_LIBRARIES) endif () # Now set the noncached _FOUND vars for the components. -foreach (_component AVCODEC AVDEVICE AVFORMAT AVUTIL POSTPROCESS SWSCALE) +foreach (_component AVCODEC AVDEVICE AVFORMAT AVUTIL POSTPROC SWSCALE) set_component_found(${_component}) endforeach () diff --git a/debian/changelog b/debian/changelog index 91461fb1d..7bee4db1d 100644 --- a/debian/changelog +++ b/debian/changelog @@ -1,9 +1,19 @@ +sdrangel (4.3.1-1) unstable; urgency=medium + + * RTL-SDR: offset tuning support + * SoapySDR support: 250 ms minimum timeout + * LimeSDR REST API: support GPIO + + -- Edouard Griffiths, F4EXB Fri, 30 Nov 2018 21:14:18 +0100 + sdrangel (4.3.0-1) unstable; urgency=medium * SoapySDR support * BladeRF2 corrections + * Scope fixes possible seg fault and correct memory processing + * FCDPro/FCDProPlus critical fixes to make it work again - -- Edouard Griffiths, F4EXB Sun, 18 Nov 2018 21:14:18 +0100 + -- Edouard Griffiths, F4EXB Thu, 22 Nov 2018 21:14:18 +0100 sdrangel (4.2.4-1) unstable; urgency=medium diff --git a/debian/rules b/debian/rules index 800c02c9d..b78931773 100755 --- a/debian/rules +++ b/debian/rules @@ -21,5 +21,5 @@ # dh_make generated override targets # This is example for Cmake (See https://bugs.debian.org/641051 ) override_dh_auto_configure: - dh_auto_configure -- -DCMAKE_INSTALL_PREFIX=/opt/sdrangel -DDEBUG_OUTPUT=ON -DBUILD_TYPE=DEBIAN -DRX_SAMPLE_24BIT=ON -DLIBCM256CCSRC=/z1/development/cm256cc -DLIBDSDCCSRC=/z1/development/dsdcc -DLIBAIRSPYSRC=/z1/development/libairspy -DLIBAIRSPYHFSRC=/z1/softs/airspyhf -DLIBHACKRFSRC=/z1/development/hackrf/host -DLIBRTLSDRSRC=/z1/development/librtlsdr.f4exb -DLIBMBELIBSRC=/z1/development/mbelib -DLIBSERIALDVSRC=/z1/development/serialDV -DLIBBLADERFSRC=/z1/softs/bladeRF -DLIBBLADERFCOMMONSRC=/z1/softs/bladeRF/host/common -DLIBBLADERFLIBSRC=/z1/softs/bladeRF/host/libraries/libbladeRF -DLIBMIRISDRSRC=/z1/development/libmirisdr-4 -DLIBLIMESUITESRC=/z1/softs/LimeSuite -DLIBIIOSRC=/z1/softs/libiio -DLIBPERSEUSSRC=/z1/softs/libperseus-sdr + dh_auto_configure -- -DCMAKE_INSTALL_PREFIX=/opt/sdrangel -DDEBUG_OUTPUT=ON -DBUILD_TYPE=DEBIAN -DRX_SAMPLE_24BIT=ON -DLIBCM256CCSRC=/z1/development/cm256cc -DLIBDSDCCSRC=/z1/development/dsdcc -DLIBAIRSPYSRC=/z1/development/libairspy -DLIBAIRSPYHFSRC=/z1/softs/airspyhf -DLIBHACKRFSRC=/z1/development/hackrf/host -DLIBRTLSDRSRC=/z1/development/librtlsdr.f4exb -DLIBMBELIBSRC=/z1/development/mbelib -DLIBSERIALDVSRC=/z1/development/serialDV -DLIBBLADERFSRC=/z1/softs/bladeRF -DLIBBLADERFCOMMONSRC=/z1/softs/bladeRF/host/common -DLIBBLADERFLIBSRC=/z1/softs/bladeRF/host/libraries/libbladeRF -DLIBMIRISDRSRC=/z1/development/libmirisdr-4 -DLIBLIMESUITESRC=/z1/softs/LimeSuite -DLIBIIOSRC=/z1/softs/libiio -DLIBPERSEUSSRC=/z1/softs/libperseus-sdr -DSOAPYSDR_SOURCE_DIR=/z1/softs/SoapySDR diff --git a/devices/CMakeLists.txt b/devices/CMakeLists.txt index 9626e5db9..65439fb0d 100644 --- a/devices/CMakeLists.txt +++ b/devices/CMakeLists.txt @@ -1,5 +1,7 @@ project(devices) +set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++11") + find_package(LibUSB) if (BUILD_DEBIAN) diff --git a/devices/bladerf1/devicebladerf1.cpp b/devices/bladerf1/devicebladerf1.cpp index 14ab43374..618c96761 100644 --- a/devices/bladerf1/devicebladerf1.cpp +++ b/devices/bladerf1/devicebladerf1.cpp @@ -14,13 +14,13 @@ // along with this program. If not, see . // /////////////////////////////////////////////////////////////////////////////////// -#include "../bladerf1/devicebladerf1.h" - #include #include #include +#include "devicebladerf1.h" + bool DeviceBladeRF1::open_bladerf(struct bladerf **dev, const char *serial) { int fpga_loaded; diff --git a/devices/bladerf1/devicebladerf1.h b/devices/bladerf1/devicebladerf1.h index f8a9d1cad..41aa5272c 100644 --- a/devices/bladerf1/devicebladerf1.h +++ b/devices/bladerf1/devicebladerf1.h @@ -30,7 +30,7 @@ private: static struct bladerf *open_bladerf_from_serial(const char *serial); }; -class BladerfBandwidths { +class DEVICES_API BladerfBandwidths { public: static unsigned int getBandwidth(unsigned int bandwidth_index); static unsigned int getBandwidthIndex(unsigned int bandwidth); diff --git a/devices/bladerf2/devicebladerf2shared.h b/devices/bladerf2/devicebladerf2shared.h index f4664e6fb..590f7b559 100644 --- a/devices/bladerf2/devicebladerf2shared.h +++ b/devices/bladerf2/devicebladerf2shared.h @@ -31,7 +31,7 @@ class BladeRF2Output; class DEVICES_API DeviceBladeRF2Shared { public: - class MsgReportBuddyChange : public Message { + class DEVICES_API MsgReportBuddyChange : public Message { MESSAGE_CLASS_DECLARATION public: diff --git a/devices/devices.pro b/devices/devices.pro index 0199ff713..c06a7188e 100644 --- a/devices/devices.pro +++ b/devices/devices.pro @@ -61,7 +61,7 @@ MINGW32 || MINGW64 || macx { } MSVC { - INCLUDEPATH += "C:\softs\PothosSDR\include" + INCLUDEPATH += "C:\Program Files\PothosSDR\include" } INCLUDEPATH += $$LIBPERSEUSSRC @@ -136,6 +136,13 @@ macx { } MSVC { + SOURCES += bladerf1/devicebladerf1.cpp\ + bladerf1/devicebladerf1values.cpp\ + bladerf1/devicebladerf1shared.cpp + + SOURCES += bladerf2/devicebladerf2.cpp\ + bladerf2/devicebladerf2shared.cpp + SOURCES += hackrf/devicehackrf.cpp\ hackrf/devicehackrfvalues.cpp\ hackrf/devicehackrfshared.cpp @@ -144,6 +151,25 @@ MSVC { limesdr/devicelimesdrparam.cpp\ limesdr/devicelimesdrshared.cpp + SOURCES += soapysdr/devicesoapysdr.cpp\ + soapysdr/devicesoapysdrparams.cpp\ + soapysdr/devicesoapysdrscan.cpp\ + soapysdr/devicesoapysdrshared.cpp + + SOURCES += plutosdr/deviceplutosdr.cpp\ + plutosdr/deviceplutosdrbox.cpp\ + plutosdr/deviceplutosdrparams.cpp\ + plutosdr/deviceplutosdrscan.cpp\ + plutosdr/deviceplutosdrshared.cpp + + HEADERS += bladerf1/devicebladerf1.h\ + bladerf1/devicebladerf1param.h\ + bladerf1/devicebladerf1values.h\ + bladerf1/devicebladerf1shared.h + + HEADERS += bladerf2/devicebladerf2.h\ + bladerf2/devicebladerf2shared.h + HEADERS += hackrf/devicehackrf.h\ hackrf/devicehackrfparam.h\ hackrf/devicehackrfvalues.h\ @@ -152,6 +178,17 @@ MSVC { HEADERS += limesdr/devicelimesdr.h\ limesdr/devicelimesdrparam.h\ limesdr/devicelimesdrshared.h + + HEADERS += soapysdr/devicesoapysdr.h\ + soapysdr/devicesoapysdrparams.h\ + soapysdr/devicesoapysdrscan.h\ + soapysdr/devicesoapysdrshared.h + + HEADERS += plutosdr/deviceplutosdr.h\ + plutosdr/deviceplutosdrbox.h\ + plutosdr/deviceplutosdrparams.h\ + plutosdr/deviceplutosdrscan.h\ + plutosdr/deviceplutosdrshared.h } LIBS += -L../sdrbase/$${build_subdir} -lsdrbase @@ -171,5 +208,8 @@ macx { MSVC { LIBS += -L../libhackrf/$${build_subdir} -llibhackrf - LIBS += -LC:\softs\PothosSDR\lib -lLimeSuite + LIBS += -L"C:\Program Files\PothosSDR\bin" -L"C:\Program Files\PothosSDR\lib" -lbladeRF + LIBS += -L"C:\Program Files\PothosSDR\bin" -L"C:\Program Files\PothosSDR\lib" -lLimeSuite + LIBS += -L"C:\Program Files\PothosSDR\bin" -L"C:\Program Files\PothosSDR\lib" -lSoapySDR + LIBS += -L"C:\Program Files\PothosSDR\bin" -L"C:\Program Files\PothosSDR\lib" -llibiio } diff --git a/devices/hackrf/devicehackrf.cpp b/devices/hackrf/devicehackrf.cpp index f07f5fc57..9ab2d7ec6 100644 --- a/devices/hackrf/devicehackrf.cpp +++ b/devices/hackrf/devicehackrf.cpp @@ -15,6 +15,7 @@ /////////////////////////////////////////////////////////////////////////////////// #include +#include #include "devicehackrf.h" DeviceHackRF::DeviceHackRF() @@ -22,7 +23,7 @@ DeviceHackRF::DeviceHackRF() hackrf_error rc = (hackrf_error) hackrf_init(); if (rc != HACKRF_SUCCESS) { - fprintf(stderr, "DeviceHackRF::open_hackrf: failed to initiate HackRF library %s\n", hackrf_error_name(rc)); + qCritical("DeviceHackRF::open_hackrf: failed to initiate HackRF library %s", hackrf_error_name(rc)); } } @@ -59,6 +60,7 @@ hackrf_device *DeviceHackRF::open_hackrf(const char * const serial) } else { + qCritical("DeviceHackRF::open_hackrf: error #%d: %s", (int) rc, hackrf_error_name(rc)); return 0; } } @@ -79,6 +81,7 @@ hackrf_device *DeviceHackRF::open_hackrf_from_sequence(int sequence) } else { + qCritical("DeviceHackRF::open_hackrf_from_sequence: error #%d: %s", (int) rc, hackrf_error_name(rc)); return 0; } } diff --git a/devices/hackrf/devicehackrf.h b/devices/hackrf/devicehackrf.h index 291e617b6..51ee822c2 100644 --- a/devices/hackrf/devicehackrf.h +++ b/devices/hackrf/devicehackrf.h @@ -30,11 +30,7 @@ public: protected: DeviceHackRF(); DeviceHackRF(const DeviceHackRF&) {} -#ifdef _MSC_VER - DeviceHackRF& operator=(const DeviceHackRF& other) { return *this; } -#else - DeviceHackRF& operator=(const DeviceHackRF& other __attribute__((unused))) { return *this; } -#endif + DeviceHackRF& operator=(const DeviceHackRF& other) { (void) other; return *this; } ~DeviceHackRF(); private: static hackrf_device *open_hackrf_from_sequence(int sequence); diff --git a/devices/hackrf/devicehackrfshared.h b/devices/hackrf/devicehackrfshared.h index 249c30852..6c392b3c2 100644 --- a/devices/hackrf/devicehackrfshared.h +++ b/devices/hackrf/devicehackrfshared.h @@ -23,7 +23,7 @@ class DEVICES_API DeviceHackRFShared { public: - class MsgConfigureFrequencyDelta : public Message + class DEVICES_API MsgConfigureFrequencyDelta : public Message { MESSAGE_CLASS_DECLARATION diff --git a/devices/limesdr/devicelimesdrparam.cpp b/devices/limesdr/devicelimesdrparam.cpp index 954eee9fa..dd819dfc2 100644 --- a/devices/limesdr/devicelimesdrparam.cpp +++ b/devices/limesdr/devicelimesdrparam.cpp @@ -19,7 +19,9 @@ bool DeviceLimeSDRParams::open(lms_info_str_t deviceStr) { - qDebug("DeviceLimeSDRParams::open: serial: %s", (const char *) deviceStr); + getHardwareType((const char *) deviceStr); + + qDebug("DeviceLimeSDRParams::open: serial: %s type: %d", (const char *) deviceStr, (int) m_type); if (LMS_Open(&m_dev, deviceStr, 0) < 0) { @@ -105,3 +107,18 @@ void DeviceLimeSDRParams::close() } } +void DeviceLimeSDRParams::getHardwareType(const char *device_str) +{ + QString deviceStr(device_str); + + if (deviceStr.contains(QString("LimeSDR Mini"))) { + m_type = LimeMini; + } else if (deviceStr.contains(QString("LimeSDR-USB"))) { + m_type = LimeUSB; + } else if (deviceStr.contains(QString("media=SPI"))) { + m_type = LimeSPI; + } else { + m_type = LimeUndefined; + } +} + diff --git a/devices/limesdr/devicelimesdrparam.h b/devices/limesdr/devicelimesdrparam.h index 353b256e0..3178f21fb 100644 --- a/devices/limesdr/devicelimesdrparam.h +++ b/devices/limesdr/devicelimesdrparam.h @@ -30,6 +30,14 @@ */ struct DEVICES_API DeviceLimeSDRParams { + enum LimeType + { + LimeSPI, + LimeMini, + LimeUSB, + LimeUndefined + }; + lms_device_t *m_dev; //!< device handle uint32_t m_nbRxChannels; //!< number of Rx channels (normally 2, we'll see if we really use it...) uint32_t m_nbTxChannels; //!< number of Tx channels (normally 2, we'll see if we really use it...) @@ -44,6 +52,7 @@ struct DEVICES_API DeviceLimeSDRParams int m_log2OvSRTx; //!< log2 of Tx oversampling (0..5) float m_rxFrequency; //!< Rx frequency float m_txFrequency; //!< Tx frequency + LimeType m_type; //!< Hardware type DeviceLimeSDRParams() : m_dev(0), @@ -53,7 +62,8 @@ struct DEVICES_API DeviceLimeSDRParams m_log2OvSRRx(0), m_log2OvSRTx(0), m_rxFrequency(1e6), - m_txFrequency(1e6) + m_txFrequency(1e6), + m_type(LimeUndefined) { m_lpfRangeRx.max = 0.0f; m_lpfRangeRx.min = 0.0f; @@ -90,6 +100,9 @@ struct DEVICES_API DeviceLimeSDRParams ~DeviceLimeSDRParams() { } + +private: + void getHardwareType(const char *device_str); }; #endif /* DEVICES_LIMESDR_DEVICELIMESDRPARAM_H_ */ diff --git a/devices/limesdr/devicelimesdrshared.cpp b/devices/limesdr/devicelimesdrshared.cpp index ba9f4d6f0..c380ea689 100644 --- a/devices/limesdr/devicelimesdrshared.cpp +++ b/devices/limesdr/devicelimesdrshared.cpp @@ -18,6 +18,7 @@ MESSAGE_CLASS_DEFINITION(DeviceLimeSDRShared::MsgReportBuddyChange, Message) MESSAGE_CLASS_DEFINITION(DeviceLimeSDRShared::MsgReportClockSourceChange, Message) +MESSAGE_CLASS_DEFINITION(DeviceLimeSDRShared::MsgReportGPIOChange, Message) MESSAGE_CLASS_DEFINITION(DeviceLimeSDRShared::MsgReportDeviceInfo, Message) const float DeviceLimeSDRShared::m_sampleFifoLengthInSeconds = 0.25; diff --git a/devices/limesdr/devicelimesdrshared.h b/devices/limesdr/devicelimesdrshared.h index c8df559e2..b4e90fd88 100644 --- a/devices/limesdr/devicelimesdrshared.h +++ b/devices/limesdr/devicelimesdrshared.h @@ -28,7 +28,7 @@ class DEVICES_API DeviceLimeSDRShared { public: - class MsgReportBuddyChange : public Message { + class DEVICES_API MsgReportBuddyChange : public Message { MESSAGE_CLASS_DECLARATION public: @@ -69,7 +69,7 @@ public: { } }; - class MsgReportClockSourceChange : public Message { + class DEVICES_API MsgReportClockSourceChange : public Message { MESSAGE_CLASS_DECLARATION public: @@ -98,27 +98,52 @@ public: { } }; - class MsgReportDeviceInfo : public Message { + class DEVICES_API MsgReportDeviceInfo : public Message { MESSAGE_CLASS_DECLARATION public: float getTemperature() const { return m_temperature; } + uint8_t getGPIOPins() const { return m_gpioPins; } - static MsgReportDeviceInfo* create(float temperature) + static MsgReportDeviceInfo* create(float temperature, uint8_t gpioPins) { - return new MsgReportDeviceInfo(temperature); + return new MsgReportDeviceInfo(temperature, gpioPins); } private: float m_temperature; + uint8_t m_gpioPins; - MsgReportDeviceInfo(float temperature) : + MsgReportDeviceInfo(float temperature, uint8_t gpioPins) : Message(), - m_temperature(temperature) + m_temperature(temperature), + m_gpioPins(gpioPins) { } }; - class ThreadInterface + class DEVICES_API MsgReportGPIOChange : public Message { + MESSAGE_CLASS_DECLARATION + + public: + uint8_t getGPIODir() const { return m_gpioDir; } + uint8_t getGPIOPins() const { return m_gpioPins; } + + static MsgReportGPIOChange* create(uint8_t gpioDir, uint8_t gpioPins) + { + return new MsgReportGPIOChange(gpioDir, gpioPins); + } + + private: + uint8_t m_gpioDir; + uint8_t m_gpioPins; + + MsgReportGPIOChange(uint8_t gpioDir, uint8_t gpioPins) : + m_gpioDir(gpioDir), + m_gpioPins(gpioPins) + {} + }; + + class DEVICES_API ThreadInterface { public: virtual void startWork() = 0; diff --git a/devices/perseus/deviceperseus.h b/devices/perseus/deviceperseus.h index 1ac30fcdb..47d8a38c5 100644 --- a/devices/perseus/deviceperseus.h +++ b/devices/perseus/deviceperseus.h @@ -32,7 +32,7 @@ public: protected: DevicePerseus(); DevicePerseus(const DevicePerseus&) : m_nbDevices(0) {} - DevicePerseus& operator=(const DevicePerseus& other __attribute__((unused))) { return *this; } + DevicePerseus& operator=(const DevicePerseus& other) { (void) other; return *this; } ~DevicePerseus(); private: diff --git a/devices/plutosdr/deviceplutosdrbox.h b/devices/plutosdr/deviceplutosdrbox.h index 4941ff30b..c3487c833 100644 --- a/devices/plutosdr/deviceplutosdrbox.h +++ b/devices/plutosdr/deviceplutosdrbox.h @@ -24,6 +24,11 @@ #include "export.h" +#if defined(_MSC_VER) +#include +typedef SSIZE_T ssize_t; +#endif + class DEVICES_API DevicePlutoSDRBox { public: diff --git a/devices/plutosdr/deviceplutosdrparams.h b/devices/plutosdr/deviceplutosdrparams.h index 113b05752..4ff154cb6 100644 --- a/devices/plutosdr/deviceplutosdrparams.h +++ b/devices/plutosdr/deviceplutosdrparams.h @@ -30,7 +30,7 @@ class DEVICES_API DevicePlutoSDRBox; * There is only one copy that is constructed by the first participant and destroyed by the last. * A participant knows it is the first or last by checking the lists of buddies (Rx + Tx). */ -class DevicePlutoSDRParams +class DEVICES_API DevicePlutoSDRParams { public: DevicePlutoSDRParams(); diff --git a/devices/plutosdr/deviceplutosdrshared.h b/devices/plutosdr/deviceplutosdrshared.h index 9d98c66a0..78657b369 100644 --- a/devices/plutosdr/deviceplutosdrshared.h +++ b/devices/plutosdr/deviceplutosdrshared.h @@ -42,7 +42,7 @@ public: virtual bool isRunning() = 0; }; - class MsgCrossReportToBuddy : public Message { + class DEVICES_API MsgCrossReportToBuddy : public Message { MESSAGE_CLASS_DECLARATION public: uint64_t getDevSampleRate() const { return m_devSampleRate; } diff --git a/devices/soapysdr/CMakeLists.txt b/devices/soapysdr/CMakeLists.txt index 55ef5369b..c7902bdde 100644 --- a/devices/soapysdr/CMakeLists.txt +++ b/devices/soapysdr/CMakeLists.txt @@ -20,7 +20,8 @@ if (BUILD_DEBIAN) include_directories( . ${CMAKE_CURRENT_BINARY_DIR} - ${SOAPYSDRSRC} + ${SOAPYSDR_SOURCE_DIR}/include + ${SOAPYSDR_SOURCE_DIR}/src ) else (BUILD_DEBIAN) include_directories( @@ -39,7 +40,7 @@ add_library(soapysdrdevice SHARED if (BUILD_DEBIAN) target_link_libraries(soapysdrdevice - soapysdr + SoapySDR sdrbase ) else (BUILD_DEBIAN) diff --git a/devices/soapysdr/devicesoapysdr.h b/devices/soapysdr/devicesoapysdr.h index c8be84557..d26e87a4f 100644 --- a/devices/soapysdr/devicesoapysdr.h +++ b/devices/soapysdr/devicesoapysdr.h @@ -38,7 +38,7 @@ public: protected: DeviceSoapySDR(); DeviceSoapySDR(const DeviceSoapySDR&) {} - DeviceSoapySDR& operator=(const DeviceSoapySDR& other __attribute__((unused))) { return *this; } + DeviceSoapySDR& operator=(const DeviceSoapySDR& other) { (void) other; return *this; } ~DeviceSoapySDR(); private: diff --git a/devices/soapysdr/devicesoapysdrparams.h b/devices/soapysdr/devicesoapysdrparams.h index 2489b8f85..74886c147 100644 --- a/devices/soapysdr/devicesoapysdrparams.h +++ b/devices/soapysdr/devicesoapysdrparams.h @@ -68,6 +68,8 @@ public: DeviceSoapySDRParams(SoapySDR::Device *device); ~DeviceSoapySDRParams(); + const SoapySDR::ArgInfoList& getDeviceArgs() const { return m_deviceSettingsArgs; } + const ChannelSettings* getRxChannelSettings(uint32_t index) { if (index < m_nbRx) { diff --git a/devices/soapysdr/devicesoapysdrscan.cpp b/devices/soapysdr/devicesoapysdrscan.cpp index 61b44d0c2..234f6e6ef 100644 --- a/devices/soapysdr/devicesoapysdrscan.cpp +++ b/devices/soapysdr/devicesoapysdrscan.cpp @@ -66,15 +66,17 @@ void DeviceSoapySDRScan::scan() SoapySDR::Kwargs::const_iterator kargIt; - if ((kargIt = kit->find("label")) != kit->end()) - { + if ((kargIt = kit->find("label")) != kit->end()) { m_deviceEnums.back().m_label = QString(kargIt->second.c_str()); - qDebug("DeviceSoapySDRScan::scan: %s #%u %s", - m_deviceEnums.back().m_driverName.toStdString().c_str(), - deviceSeq, - kargIt->second.c_str()); + } else { // if no label is registered for this device then create a label with the driver name and sequence + m_deviceEnums.back().m_label = QString("%1-%2").arg(m_deviceEnums.back().m_driverName).arg(deviceSeq); } + qDebug("DeviceSoapySDRScan::scan: %s #%u %s", + m_deviceEnums.back().m_driverName.toStdString().c_str(), + deviceSeq, + m_deviceEnums.back().m_label.toStdString().c_str()); + if ((kargIt = kit->find("serial")) != kit->end()) { m_deviceEnums.back().m_idKey = QString(kargIt->first.c_str()); diff --git a/devices/soapysdr/devicesoapysdrshared.cpp b/devices/soapysdr/devicesoapysdrshared.cpp index e7ef10f70..a5f04466c 100644 --- a/devices/soapysdr/devicesoapysdrshared.cpp +++ b/devices/soapysdr/devicesoapysdrshared.cpp @@ -17,6 +17,7 @@ #include "devicesoapysdrshared.h" MESSAGE_CLASS_DEFINITION(DeviceSoapySDRShared::MsgReportBuddyChange, Message) +MESSAGE_CLASS_DEFINITION(DeviceSoapySDRShared::MsgReportDeviceArgsChange, Message) const float DeviceSoapySDRShared::m_sampleFifoLengthInSeconds = 0.25; const int DeviceSoapySDRShared::m_sampleFifoMinSize = 75000; // 300 kS/s knee @@ -24,6 +25,7 @@ const int DeviceSoapySDRShared::m_sampleFifoMinSize32 = 150000; // Fixed for DeviceSoapySDRShared::DeviceSoapySDRShared() : m_device(0), + m_deviceParams(0), m_channel(-1), m_source(0), m_sink(0) diff --git a/devices/soapysdr/devicesoapysdrshared.h b/devices/soapysdr/devicesoapysdrshared.h index 85adc878a..f64108692 100644 --- a/devices/soapysdr/devicesoapysdrshared.h +++ b/devices/soapysdr/devicesoapysdrshared.h @@ -17,6 +17,9 @@ #ifndef DEVICES_SOAPYSDR_DEVICESOAPYSDRSHARED_H_ #define DEVICES_SOAPYSDR_DEVICESOAPYSDRSHARED_H_ +#include +#include + #include #include "util/message.h" @@ -32,7 +35,7 @@ class SoapySDROutput; class DEVICES_API DeviceSoapySDRShared { public: - class MsgReportBuddyChange : public Message { + class DEVICES_API MsgReportBuddyChange : public Message { MESSAGE_CLASS_DECLARATION public: @@ -79,6 +82,24 @@ public: { } }; + class DEVICES_API MsgReportDeviceArgsChange : public Message { + MESSAGE_CLASS_DECLARATION + + public: + const QMap& getDeviceArgSettings() const { return m_deviceArgSettings; } + + static MsgReportDeviceArgsChange* create(const QMap& deviceArgSettings) { + return new MsgReportDeviceArgsChange(deviceArgSettings); + } + + private: + QMap m_deviceArgSettings; + + MsgReportDeviceArgsChange(const QMap& deviceArgSettings) : + m_deviceArgSettings(deviceArgSettings) + { } + }; + DeviceSoapySDRShared(); ~DeviceSoapySDRShared(); diff --git a/doc/img/RTLSDR_plugin.png b/doc/img/RTLSDR_plugin.png index d90f96a35..a3db93d9c 100644 Binary files a/doc/img/RTLSDR_plugin.png and b/doc/img/RTLSDR_plugin.png differ diff --git a/doc/img/RTLSDR_plugin.xcf b/doc/img/RTLSDR_plugin.xcf index a1981cf43..ad2016c80 100644 Binary files a/doc/img/RTLSDR_plugin.xcf and b/doc/img/RTLSDR_plugin.xcf differ diff --git a/doc/img/SoapySDRInput_plugin1.png b/doc/img/SoapySDRInput_plugin1.png new file mode 100644 index 000000000..a3f29bdfb Binary files /dev/null and b/doc/img/SoapySDRInput_plugin1.png differ diff --git a/doc/img/SoapySDRInput_plugin1.xcf b/doc/img/SoapySDRInput_plugin1.xcf new file mode 100644 index 000000000..1068f3328 Binary files /dev/null and b/doc/img/SoapySDRInput_plugin1.xcf differ diff --git a/doc/img/SoapySDROutput_plugin1.png b/doc/img/SoapySDROutput_plugin1.png new file mode 100644 index 000000000..c0c10d9c4 Binary files /dev/null and b/doc/img/SoapySDROutput_plugin1.png differ diff --git a/doc/img/SoapySDR_arg_bool1.png b/doc/img/SoapySDR_arg_bool1.png new file mode 100644 index 000000000..813adb017 Binary files /dev/null and b/doc/img/SoapySDR_arg_bool1.png differ diff --git a/doc/img/SoapySDR_arg_bool1.xcf b/doc/img/SoapySDR_arg_bool1.xcf new file mode 100644 index 000000000..7ec5246e9 Binary files /dev/null and b/doc/img/SoapySDR_arg_bool1.xcf differ diff --git a/doc/img/SoapySDR_arg_bool2.png b/doc/img/SoapySDR_arg_bool2.png new file mode 100644 index 000000000..5ce78c973 Binary files /dev/null and b/doc/img/SoapySDR_arg_bool2.png differ diff --git a/doc/img/SoapySDR_arg_bool2.xcf b/doc/img/SoapySDR_arg_bool2.xcf new file mode 100644 index 000000000..f8d61b3d9 Binary files /dev/null and b/doc/img/SoapySDR_arg_bool2.xcf differ diff --git a/doc/img/SoapySDR_arg_bool3.png b/doc/img/SoapySDR_arg_bool3.png new file mode 100644 index 000000000..48995034a Binary files /dev/null and b/doc/img/SoapySDR_arg_bool3.png differ diff --git a/doc/img/SoapySDR_arg_bool3.xcf b/doc/img/SoapySDR_arg_bool3.xcf new file mode 100644 index 000000000..6837bc090 Binary files /dev/null and b/doc/img/SoapySDR_arg_bool3.xcf differ diff --git a/doc/img/SoapySDR_arg_str.png b/doc/img/SoapySDR_arg_str.png new file mode 100644 index 000000000..39b141777 Binary files /dev/null and b/doc/img/SoapySDR_arg_str.png differ diff --git a/doc/img/SoapySDR_arg_str.xcf b/doc/img/SoapySDR_arg_str.xcf new file mode 100644 index 000000000..48eda9768 Binary files /dev/null and b/doc/img/SoapySDR_arg_str.xcf differ diff --git a/doc/img/SoapySDR_arg_strlist.png b/doc/img/SoapySDR_arg_strlist.png new file mode 100644 index 000000000..d71a604bb Binary files /dev/null and b/doc/img/SoapySDR_arg_strlist.png differ diff --git a/doc/img/SoapySDR_arg_strlist.xcf b/doc/img/SoapySDR_arg_strlist.xcf new file mode 100644 index 000000000..2f707a3ef Binary files /dev/null and b/doc/img/SoapySDR_arg_strlist.xcf differ diff --git a/doc/img/SoapySDR_range_discrete.png b/doc/img/SoapySDR_range_discrete.png new file mode 100644 index 000000000..ce31fc1b9 Binary files /dev/null and b/doc/img/SoapySDR_range_discrete.png differ diff --git a/doc/img/SoapySDR_range_discrete.xcf b/doc/img/SoapySDR_range_discrete.xcf new file mode 100644 index 000000000..4411b4735 Binary files /dev/null and b/doc/img/SoapySDR_range_discrete.xcf differ diff --git a/doc/img/SoapySDR_range_gain.png b/doc/img/SoapySDR_range_gain.png new file mode 100644 index 000000000..d62ace47d Binary files /dev/null and b/doc/img/SoapySDR_range_gain.png differ diff --git a/doc/img/SoapySDR_range_gain.xcf b/doc/img/SoapySDR_range_gain.xcf new file mode 100644 index 000000000..749b0e647 Binary files /dev/null and b/doc/img/SoapySDR_range_gain.xcf differ diff --git a/doc/img/SoapySDR_range_list1.png b/doc/img/SoapySDR_range_list1.png new file mode 100644 index 000000000..6f6209f91 Binary files /dev/null and b/doc/img/SoapySDR_range_list1.png differ diff --git a/doc/img/SoapySDR_range_list1.xcf b/doc/img/SoapySDR_range_list1.xcf new file mode 100644 index 000000000..417632a06 Binary files /dev/null and b/doc/img/SoapySDR_range_list1.xcf differ diff --git a/doc/img/SoapySDR_range_neg.png b/doc/img/SoapySDR_range_neg.png new file mode 100644 index 000000000..d25f4e383 Binary files /dev/null and b/doc/img/SoapySDR_range_neg.png differ diff --git a/doc/img/SoapySDR_range_neg.xcf b/doc/img/SoapySDR_range_neg.xcf new file mode 100644 index 000000000..ffdc16135 Binary files /dev/null and b/doc/img/SoapySDR_range_neg.xcf differ diff --git a/doc/img/SoapySDR_range_pos.png b/doc/img/SoapySDR_range_pos.png new file mode 100644 index 000000000..7b42b8ef4 Binary files /dev/null and b/doc/img/SoapySDR_range_pos.png differ diff --git a/doc/img/SoapySDR_range_pos.xcf b/doc/img/SoapySDR_range_pos.xcf new file mode 100644 index 000000000..37c687b23 Binary files /dev/null and b/doc/img/SoapySDR_range_pos.xcf differ diff --git a/dsdcc/CMakeLists.txt b/dsdcc/CMakeLists.txt index 5f5611cae..152efc73e 100644 --- a/dsdcc/CMakeLists.txt +++ b/dsdcc/CMakeLists.txt @@ -1,5 +1,7 @@ project(dsdcc) +set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++11") + set(dsdcc_SOURCES ${LIBDSDCCSRC}/descramble.cpp ${LIBDSDCCSRC}/dmr.cpp diff --git a/dsdcc/dsdcc.pro b/dsdcc/dsdcc.pro index 7cb2add66..89dc3b67a 100644 --- a/dsdcc/dsdcc.pro +++ b/dsdcc/dsdcc.pro @@ -9,12 +9,16 @@ QT += core TEMPLATE = lib TARGET = dsdcc +CONFIG(MSVC):DEFINES += dsdcc_EXPORTS + CONFIG(MINGW32):LIBDSDCCSRC = "C:\softs\dsdcc" CONFIG(MINGW64):LIBDSDCCSRC = "C:\softs\dsdcc" +CONFIG(MSVC):LIBDSDCCSRC = "C:\softs\dsdcc" CONFIG(macx):LIBDSDCCSRC = "../../deps/dsdcc" CONFIG(MINGW32):LIBMBELIBSRC = "C:\softs\mbelib" CONFIG(MINGW64):LIBMBELIBSRC = "C:\softs\mbelib" +CONFIG(MSVC):LIBMBELIBSRC = "C:\softs\mbelib" CONFIG(macx):LIBMBELIBSRC = "../../deps/mbelib" INCLUDEPATH += $$LIBDSDCCSRC @@ -50,7 +54,8 @@ $$LIBDSDCCSRC/viterbi5.cpp\ $$LIBDSDCCSRC/pn.cpp\ $$LIBDSDCCSRC/mbefec.cpp\ $$LIBDSDCCSRC/phaselock.cpp\ -$$LIBDSDCCSRC/locator.cpp +$$LIBDSDCCSRC/locator.cpp\ +$$LIBDSDCCSRC/timeutil.cpp HEADERS = $$LIBDSDCCSRC/descramble.h\ $$LIBDSDCCSRC/dmr.h\ @@ -80,6 +85,8 @@ $$LIBDSDCCSRC/viterbi5.h\ $$LIBDSDCCSRC/pn.h\ $$LIBDSDCCSRC/mbefec.h\ $$LIBDSDCCSRC/phaselock.h\ -$$LIBDSDCCSRC/locator.h +$$LIBDSDCCSRC/locator.h\ +$$LIBDSDCCSRC/timeutil.h\ +$$LIBDSDCCSRC/export.h LIBS += -L../mbelib/$${build_subdir} -lmbelib diff --git a/exports/export.h b/exports/export.h index 10b79fea5..cda4f61f8 100644 --- a/exports/export.h +++ b/exports/export.h @@ -102,6 +102,18 @@ # define QRTPLIB_API #endif +/* the 'SERIALDV_API' controls the import/export of 'serialdv' symbols + */ +#if !defined(sdrangel_STATIC) +# ifdef serialdv_EXPORTS +# define SERIALDV_API __SDR_EXPORT +# else +# define SERIALDV_API __SDR_IMPORT +# endif +#else +# define SERIALDV_API +#endif + /* the 'SWG_API' controls the import/export of 'swagger' symbols */ #if !defined(sdrangel_STATIC) diff --git a/fcdlib/fcdtraits.cpp b/fcdlib/fcdtraits.cpp index 41f8b66a6..ac008da78 100644 --- a/fcdlib/fcdtraits.cpp +++ b/fcdlib/fcdtraits.cpp @@ -1,15 +1,27 @@ -/* - * fcdtraits.cpp - * - * Created on: Sep 5, 2015 - * Author: f4exb - */ +/////////////////////////////////////////////////////////////////////////////////// +// Copyright (C) 2015-2018 Edouard Griffiths, F4EXB // +// // +// This program is free software; you can redistribute it and/or modify // +// it under the terms of the GNU General Public License as published by // +// the Free Software Foundation as version 3 of the License, or // +// // +// This program is distributed in the hope that it will be useful, // +// but WITHOUT ANY WARRANTY; without even the implied warranty of // +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // +// GNU General Public License V3 for more details. // +// // +// You should have received a copy of the GNU General Public License // +// along with this program. If not, see . // +/////////////////////////////////////////////////////////////////////////////////// #include "fcdtraits.h" const char *fcd_traits::alsaDeviceName = "hw:CARD=V10"; const char *fcd_traits::alsaDeviceName = "hw:CARD=V20"; +const char *fcd_traits::qtDeviceName = "FUNcube_Dongle_V1.0"; +const char *fcd_traits::qtDeviceName = "FUNcube_Dongle_V2.0"; + const char *fcd_traits::hardwareID = "FCDPro"; const char *fcd_traits::hardwareID = "FCDPro+"; @@ -22,8 +34,8 @@ const char *fcd_traits::displayedName = "FunCube Dongle Pro+"; const char *fcd_traits::pluginDisplayedName = "FunCube Pro Input"; const char *fcd_traits::pluginDisplayedName = "FunCube Pro+ Input"; -const char *fcd_traits::pluginVersion = "4.0.0"; -const char *fcd_traits::pluginVersion = "4.0.0"; +const char *fcd_traits::pluginVersion = "4.3.0"; +const char *fcd_traits::pluginVersion = "4.3.0"; const int64_t fcd_traits::loLowLimitFreq = 64000000L; const int64_t fcd_traits::loLowLimitFreq = 150000L; diff --git a/fcdlib/fcdtraits.h b/fcdlib/fcdtraits.h index a649edc39..ebdfa20a0 100644 --- a/fcdlib/fcdtraits.h +++ b/fcdlib/fcdtraits.h @@ -1,9 +1,18 @@ -/* - * fcdtraits.h - * - * Created on: 3 Sep 2015 - * Author: egriffiths - */ +/////////////////////////////////////////////////////////////////////////////////// +// Copyright (C) 2015-2018 Edouard Griffiths, F4EXB // +// // +// This program is free software; you can redistribute it and/or modify // +// it under the terms of the GNU General Public License as published by // +// the Free Software Foundation as version 3 of the License, or // +// // +// This program is distributed in the hope that it will be useful, // +// but WITHOUT ANY WARRANTY; without even the implied warranty of // +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // +// GNU General Public License V3 for more details. // +// // +// You should have received a copy of the GNU General Public License // +// along with this program. If not, see . // +/////////////////////////////////////////////////////////////////////////////////// #ifndef FCDLIB_FCDTRAITS_H_ #define FCDLIB_FCDTRAITS_H_ @@ -23,8 +32,8 @@ struct fcd_traits static const uint16_t productId = 0x0; static const int sampleRate = 48000; static const int convBufSize = (1<<11); - static const int fcdBufSize = (1<<12); static const char *alsaDeviceName; + static const char *qtDeviceName; static const char *hardwareID; static const char *interfaceIID; static const char *displayedName; @@ -41,8 +50,8 @@ struct fcd_traits static const uint16_t productId = 0xFB56; static const int sampleRate = 96000; static const int convBufSize = (1<<11); - static const int fcdBufSize = (1<<12); static const char *alsaDeviceName; + static const char *qtDeviceName; static const char *hardwareID; static const char *interfaceIID; static const char *displayedName; @@ -58,9 +67,9 @@ struct fcd_traits static const uint16_t vendorId = 0x04D8; static const uint16_t productId = 0xFB31; static const int sampleRate = 192000; - static const int convBufSize = (1<<12); - static const int fcdBufSize = (1<<18); + static const int convBufSize = (1<<10); static const char *alsaDeviceName; + static const char *qtDeviceName; static const char *hardwareID; static const char *interfaceIID; static const char *displayedName; diff --git a/httpserver/CMakeLists.txt b/httpserver/CMakeLists.txt index 1b8341028..fc1f8e605 100644 --- a/httpserver/CMakeLists.txt +++ b/httpserver/CMakeLists.txt @@ -1,5 +1,7 @@ project(httpserver) +set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++11") + set(httpserver_SOURCES httpglobal.cpp httplistener.cpp diff --git a/httpserver/httpserver.pro b/httpserver/httpserver.pro index 9dd999c07..a3f82fb0b 100644 --- a/httpserver/httpserver.pro +++ b/httpserver/httpserver.pro @@ -17,6 +17,8 @@ QMAKE_CXXFLAGS += -std=c++11 CONFIG(Release):build_subdir = release CONFIG(Debug):build_subdir = debug +CONFIG(MSVC):DEFINES += httpserver_EXPORTS + # Enable very detailed debug messages when compiling the debug version CONFIG(debug, debug|release) { DEFINES += SUPERVERBOSE diff --git a/libairspy/CMakeLists.txt b/libairspy/CMakeLists.txt index e0a8af4c7..bc3a9da48 100644 --- a/libairspy/CMakeLists.txt +++ b/libairspy/CMakeLists.txt @@ -1,5 +1,7 @@ project(airspy) +set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++11") + find_package(LibUSB) remove_definitions(-DUSE_SSE2) diff --git a/libairspyhf/CMakeLists.txt b/libairspyhf/CMakeLists.txt index 645d76fae..5394c4d44 100644 --- a/libairspyhf/CMakeLists.txt +++ b/libairspyhf/CMakeLists.txt @@ -1,5 +1,7 @@ project(airspyhf) +set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++11") + find_package(LibUSB) set(airspyhf_SOURCES diff --git a/libbladerf/CMakeLists.txt b/libbladerf/CMakeLists.txt index 990b09984..8b44ba461 100644 --- a/libbladerf/CMakeLists.txt +++ b/libbladerf/CMakeLists.txt @@ -1,5 +1,7 @@ project(bladerf) +set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++11") + find_package(LibUSB) add_definitions(-DBLADERF_OS_LINUX) diff --git a/libhackrf/CMakeLists.txt b/libhackrf/CMakeLists.txt index 7afa12e96..24473318e 100644 --- a/libhackrf/CMakeLists.txt +++ b/libhackrf/CMakeLists.txt @@ -1,5 +1,7 @@ project(hackrf) +set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++11") + find_package(LibUSB) set(hackrf_SOURCES diff --git a/libiio/CMakeLists.txt b/libiio/CMakeLists.txt index 5d01b71f4..4ef538a2a 100644 --- a/libiio/CMakeLists.txt +++ b/libiio/CMakeLists.txt @@ -1,6 +1,8 @@ cmake_minimum_required(VERSION 2.8.7) project(iio) +set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++11") + set(LIBIIO_VERSION_MAJOR 0) set(LIBIIO_VERSION_MINOR 10) set(VERSION "${LIBIIO_VERSION_MAJOR}.${LIBIIO_VERSION_MINOR}") diff --git a/liblimesuite/CMakeLists.txt b/liblimesuite/CMakeLists.txt index 36f6662f9..6c1a3e616 100644 --- a/liblimesuite/CMakeLists.txt +++ b/liblimesuite/CMakeLists.txt @@ -1,5 +1,7 @@ project(limesuite) +set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++11") + find_package(LibUSB) set(limesuite_SOURCES diff --git a/libmirisdr/CMakeLists.txt b/libmirisdr/CMakeLists.txt index e48d603b5..e2ef09622 100644 --- a/libmirisdr/CMakeLists.txt +++ b/libmirisdr/CMakeLists.txt @@ -1,5 +1,7 @@ project(mirisdr) +set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++11") + add_definitions(-DDETACH_KERNEL_DRIVER=ON) find_package(LibUSB) diff --git a/libperseus/CMakeLists.txt b/libperseus/CMakeLists.txt index 806153dd2..0e9ddfe50 100644 --- a/libperseus/CMakeLists.txt +++ b/libperseus/CMakeLists.txt @@ -1,5 +1,7 @@ project(perseus) +set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++11") + find_package(LibUSB) add_definitions(-DHAVE_CONFIG_H) diff --git a/librtlsdr/CMakeLists.txt b/librtlsdr/CMakeLists.txt index dda9bcdd6..7c3d65bd0 100644 --- a/librtlsdr/CMakeLists.txt +++ b/librtlsdr/CMakeLists.txt @@ -1,5 +1,7 @@ project(rtlsdr) +set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++11") + add_definitions(-DDETACH_KERNEL_DRIVER=ON) find_package(LibUSB) diff --git a/libsoapysdr/CMakeLists.txt b/libsoapysdr/CMakeLists.txt new file mode 100644 index 000000000..a10a0f957 --- /dev/null +++ b/libsoapysdr/CMakeLists.txt @@ -0,0 +1,161 @@ +######################################################################## +# Project setup +######################################################################## +cmake_minimum_required(VERSION 2.8.7) +project(SoapySDR) +enable_language(CXX) +enable_testing() +set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++11") +#set(SOAPYSDR_SOURCE_DIR "/opt/build/SoapySDR") +######################################################################## +# gather version information +# packagers may specify -DSOAPY_SDR_EXTVER="foo" to replace the git hash +######################################################################## +file(READ "${SOAPYSDR_SOURCE_DIR}/Changelog.txt" changelog_txt) +string(REGEX MATCH "Release ([0-9]+\\.[0-9]+\\.[0-9]+) \\(" CHANGELOG_MATCH "${changelog_txt}") +if(NOT CHANGELOG_MATCH) + message(FATAL_ERROR "Failed to extract version number from Changelog.txt") +endif(NOT CHANGELOG_MATCH) +set(SOAPY_SDR_LIBVER "${CMAKE_MATCH_1}") + +if (NOT SOAPY_SDR_EXTVER) + include(${SOAPYSDR_SOURCE_DIR}/cmake/Modules/GetGitRevisionDescription.cmake) + get_git_head_revision(GITREFSPEC GITHASH) + if (GITHASH) + string(SUBSTRING "${GITHASH}" 0 8 GITHASH) + set(SOAPY_SDR_EXTVER "g${GITHASH}") + else (GITHASH) + set(SOAPY_SDR_EXTVER "unknown") + endif (GITHASH) +endif() + +set(SOAPY_SDR_VERSION "${SOAPY_SDR_LIBVER}-${SOAPY_SDR_EXTVER}") + +#SOAPY_SDR_ROOT is compiled into the library to locate the install base. +#By default, the SOAPY_SDR_ROOT is set to the CMAKE_INSTALL_PREFIX. +#However users may overload this by specifying -DSOAPY_SDR_ROOT=. +set(SOAPY_SDR_ROOT "${CMAKE_INSTALL_PREFIX}" CACHE PATH + "Installation root for SoapySDR::getRootPath()") +file(TO_CMAKE_PATH "${SOAPY_SDR_ROOT}" SOAPY_SDR_ROOT) + +#SOAPY_SDR_ROOT_ENV is the name of the environment variable +#which tells SoapySDR where to find the root installation. +#By default, the environment variable SOAPY_SDR_ROOT is used. +#Example: set -DSOAPY_SDR_ROOT_ENV=SNAP for snappy packages. +set(SOAPY_SDR_ROOT_ENV "SOAPY_SDR_ROOT" CACHE STRING + "Environment variable for SoapySDR::getRootPath()") + +######################################################################## +# select the release build type by default to get optimization flags +######################################################################## +if(NOT CMAKE_BUILD_TYPE) + set(CMAKE_BUILD_TYPE "Release") + message(STATUS "Build type not specified: defaulting to release.") +endif(NOT CMAKE_BUILD_TYPE) +set(CMAKE_BUILD_TYPE ${CMAKE_BUILD_TYPE} CACHE STRING "") + +######################################################################## +# rpath setup - http://www.cmake.org/Wiki/CMake_RPATH_handling +######################################################################## +# use, i.e. don't skip the full RPATH for the build tree +option(CMAKE_SKIP_BUILD_RPATH "skip rpath build" FALSE) + +# when building, don't use the install RPATH already +# (but later on when installing) +option(CMAKE_BUILD_WITH_INSTALL_RPATH "build with install rpath" FALSE) + +# the RPATH to be used when installing, but only if it's not a system directory +option(CMAKE_AUTOSET_INSTALL_RPATH TRUE) +if(CMAKE_AUTOSET_INSTALL_RPATH) +LIST(FIND CMAKE_PLATFORM_IMPLICIT_LINK_DIRECTORIES "${CMAKE_INSTALL_PREFIX}/lib${LIB_SUFFIX}" isSystemDir) +IF("${isSystemDir}" STREQUAL "-1") + SET(CMAKE_INSTALL_RPATH "${CMAKE_INSTALL_PREFIX}/lib${LIB_SUFFIX}") +ENDIF("${isSystemDir}" STREQUAL "-1") +endif(CMAKE_AUTOSET_INSTALL_RPATH) + +# add the automatically determined parts of the RPATH +# which point to directories outside the build tree to the install RPATH +option(CMAKE_INSTALL_RPATH_USE_LINK_PATH "build with automatic rpath" TRUE) + +if(APPLE) + set(CMAKE_MACOSX_RPATH ON) +endif() + +######################################################################## +# Allows in-tree module util +######################################################################## +set(SoapySDR_DIR ${SOAPYSDR_SOURCE_DIR}/cmake/Modules) +set(SOAPY_SDR_IN_TREE_SOURCE_DIR ${SOAPYSDR_SOURCE_DIR}) +find_package(SoapySDR NO_MODULE REQUIRED) +include_directories(${SoapySDR_INCLUDE_DIRS}) #local include precedence + +######################################################################## +# Install cmake helper modules +######################################################################## +configure_file( + ${SOAPYSDR_SOURCE_DIR}/cmake/Modules/SoapySDRConfigVersion.in.cmake + ${PROJECT_BINARY_DIR}/SoapySDRConfigVersion.cmake +@ONLY) +set(cmake_files + ${SOAPYSDR_SOURCE_DIR}/cmake/Modules/SoapySDRConfig.cmake + ${SOAPYSDR_SOURCE_DIR}/cmake/Modules/SoapySDRUtil.cmake + ${PROJECT_BINARY_DIR}/SoapySDRConfigVersion.cmake) +if (UNIX) + install(FILES ${cmake_files} DESTINATION share/cmake/${PROJECT_NAME}) +elseif (WIN32) + install(FILES ${cmake_files} DESTINATION cmake) +endif () + +######################################################################## +# Install headers +######################################################################## +#install(DIRECTORY include/SoapySDR DESTINATION include) + +######################################################################## +# Build subdirs +######################################################################## +add_subdirectory(${SOAPYSDR_SOURCE_DIR}/lib ${PROJECT_BINARY_DIR}/lib) +#add_subdirectory(apps) +#add_subdirectory(tests) +#add_subdirectory(docs) + +######################################################################## +# uninstall target +######################################################################## +configure_file( + "${SOAPYSDR_SOURCE_DIR}/cmake_uninstall.cmake.in" + "${SOAPYSDR_SOURCE_DIR}/cmake_uninstall.cmake" + IMMEDIATE @ONLY) + +#only add uninstall target if this is the top project +if(${CMAKE_PROJECT_NAME} STREQUAL ${PROJECT_NAME}) +add_custom_target(uninstall + COMMAND ${CMAKE_COMMAND} -P ${CMAKE_CURRENT_BINARY_DIR}/cmake_uninstall.cmake) +endif() + +######################################################################### +# summary +######################################################################### +include(FeatureSummary) +message(STATUS "") +message(STATUS "######################################################") +message(STATUS "## ${PROJECT_NAME} enabled features") +message(STATUS "######################################################") +feature_summary(WHAT ENABLED_FEATURES) +message(STATUS "######################################################") +message(STATUS "## ${PROJECT_NAME} disabled features") +message(STATUS "######################################################") +feature_summary(WHAT DISABLED_FEATURES) +message(STATUS "SoapySDR version: v${SOAPY_SDR_VERSION}") +message(STATUS "ABI/so version: v${SOAPY_SDR_ABI_VERSION}") +message(STATUS "Install prefix: ${CMAKE_INSTALL_PREFIX}") + +#add_definitions(-DQT_SHARED) +# +#message( STATUS "soapysdr_SOURCES: ${soapysdr_SOURCES}" ) +# +#add_library(soapysdr SHARED +# ${soapysdr_SOURCES} +#) +# +#install(TARGETS soapysdr DESTINATION lib) diff --git a/logging/CMakeLists.txt b/logging/CMakeLists.txt index 5208d4326..6b0fbf998 100644 --- a/logging/CMakeLists.txt +++ b/logging/CMakeLists.txt @@ -1,5 +1,7 @@ project(logging) +set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++11") + set(logging_SOURCES dualfilelogger.cpp loggerwithfile.cpp diff --git a/mbelib/CMakeLists.txt b/mbelib/CMakeLists.txt index a085fa384..2328fec32 100644 --- a/mbelib/CMakeLists.txt +++ b/mbelib/CMakeLists.txt @@ -1,5 +1,7 @@ project(mbelib) +set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++11") + set(mbelib_SOURCES ${LIBMBELIBSRC}/ambe3600x2400.c ${LIBMBELIBSRC}/ambe3600x2450.c diff --git a/mbelib/mbelib.pro b/mbelib/mbelib.pro index 9fa45a02b..57cb623f2 100644 --- a/mbelib/mbelib.pro +++ b/mbelib/mbelib.pro @@ -9,6 +9,8 @@ QT += core TEMPLATE = lib TARGET = mbelib +CONFIG(MSVC):DEFINES += mbelib_EXPORTS + CONFIG(MINGW32):LIBMBELIBSRC = "C:\softs\mbelib" CONFIG(MINGW64):LIBMBELIBSRC = "C:\softs\mbelib" CONFIG(MSVC):LIBMBELIBSRC = "C:\softs\mbelib" @@ -28,4 +30,5 @@ $$LIBMBELIBSRC/ambe3600x2450_const.h\ $$LIBMBELIBSRC/ecc_const.h\ $$LIBMBELIBSRC/imbe7200x4400_const.h\ $$LIBMBELIBSRC/mbelib.h\ +$$LIBMBELIBSRC/export.h\ $$LIBMBELIBSRC/mbelib_const.h diff --git a/plugins/channelrx/chanalyzer/CMakeLists.txt b/plugins/channelrx/chanalyzer/CMakeLists.txt index a33c29a51..e286273dd 100644 --- a/plugins/channelrx/chanalyzer/CMakeLists.txt +++ b/plugins/channelrx/chanalyzer/CMakeLists.txt @@ -1,5 +1,7 @@ project(chanalyzer) +set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++11") + set(chanalyzer_SOURCES chanalyzer.cpp chanalyzergui.cpp diff --git a/plugins/channelrx/chanalyzer/chanalyzer.cpp b/plugins/channelrx/chanalyzer/chanalyzer.cpp index 3299e5ab5..2b6038084 100644 --- a/plugins/channelrx/chanalyzer/chanalyzer.cpp +++ b/plugins/channelrx/chanalyzer/chanalyzer.cpp @@ -89,8 +89,9 @@ void ChannelAnalyzer::configure(MessageQueue* messageQueue, messageQueue->push(cmd); } -void ChannelAnalyzer::feed(const SampleVector::const_iterator& begin, const SampleVector::const_iterator& end, bool positiveOnly __attribute__((unused))) +void ChannelAnalyzer::feed(const SampleVector::const_iterator& begin, const SampleVector::const_iterator& end, bool positiveOnly) { + (void) positiveOnly; fftfilt::cmplx *sideband = 0; Complex ci; diff --git a/plugins/channelrx/chanalyzer/chanalyzer.h b/plugins/channelrx/chanalyzer/chanalyzer.h index 6a56ab486..54be55fd2 100644 --- a/plugins/channelrx/chanalyzer/chanalyzer.h +++ b/plugins/channelrx/chanalyzer/chanalyzer.h @@ -205,7 +205,7 @@ public: virtual qint64 getCenterFrequency() const { return m_settings.m_frequency; } virtual QByteArray serialize() const { return QByteArray(); } - virtual bool deserialize(const QByteArray& data __attribute__((unused))) { return false; } + virtual bool deserialize(const QByteArray& data) { (void) data; return false; } static const QString m_channelIdURI; static const QString m_channelId; diff --git a/plugins/channelrx/chanalyzer/chanalyzer.pro b/plugins/channelrx/chanalyzer/chanalyzer.pro index e2209802a..14377d5b9 100644 --- a/plugins/channelrx/chanalyzer/chanalyzer.pro +++ b/plugins/channelrx/chanalyzer/chanalyzer.pro @@ -25,6 +25,7 @@ INCLUDEPATH += ../../../sdrgui CONFIG(ANDROID):INCLUDEPATH += /opt/softs/boost_1_60_0 CONFIG(MINGW32):INCLUDEPATH += "C:\softs\boost_1_66_0" CONFIG(MINGW64):INCLUDEPATH += "C:\softs\boost_1_66_0" +CONFIG(MSVC):INCLUDEPATH += "C:\softs\boost_1_66_0" CONFIG(macx):INCLUDEPATH += "../../../../../boost_1_64_0" CONFIG(Release):build_subdir = release diff --git a/plugins/channelrx/chanalyzer/chanalyzergui.cpp b/plugins/channelrx/chanalyzer/chanalyzergui.cpp index 4a21d237b..d394b076e 100644 --- a/plugins/channelrx/chanalyzer/chanalyzergui.cpp +++ b/plugins/channelrx/chanalyzer/chanalyzergui.cpp @@ -312,16 +312,18 @@ void ChannelAnalyzerGUI::on_rrcRolloff_valueChanged(int value) applySettings(); } -void ChannelAnalyzerGUI::on_BW_valueChanged(int value __attribute__((unused))) +void ChannelAnalyzerGUI::on_BW_valueChanged(int value) { + (void) value; setFiltersUIBoundaries(); m_settings.m_bandwidth = ui->BW->value() * 100; m_settings.m_lowCutoff = ui->lowCut->value() * 100; applySettings(); } -void ChannelAnalyzerGUI::on_lowCut_valueChanged(int value __attribute__((unused))) +void ChannelAnalyzerGUI::on_lowCut_valueChanged(int value) { + (void) value; setFiltersUIBoundaries(); m_settings.m_bandwidth = ui->BW->value() * 100; m_settings.m_lowCutoff = ui->lowCut->value() * 100; @@ -351,8 +353,10 @@ void ChannelAnalyzerGUI::on_ssb_toggled(bool checked) applySettings(); } -void ChannelAnalyzerGUI::onWidgetRolled(QWidget* widget __attribute__((unused)), bool rollDown __attribute__((unused))) +void ChannelAnalyzerGUI::onWidgetRolled(QWidget* widget, bool rollDown) { + (void) widget; + (void) rollDown; } void ChannelAnalyzerGUI::onMenuDialogCalled(const QPoint& p) diff --git a/plugins/channelrx/chanalyzer/chanalyzerplugin.cpp b/plugins/channelrx/chanalyzer/chanalyzerplugin.cpp index 8dcb43823..60aa4b978 100644 --- a/plugins/channelrx/chanalyzer/chanalyzerplugin.cpp +++ b/plugins/channelrx/chanalyzer/chanalyzerplugin.cpp @@ -23,7 +23,7 @@ const PluginDescriptor ChannelAnalyzerPlugin::m_pluginDescriptor = { QString("Channel Analyzer"), - QString("4.2.4"), + QString("4.3.0"), QString("(c) Edouard Griffiths, F4EXB"), QString("https://github.com/f4exb/sdrangel"), true, diff --git a/plugins/channelrx/daemonsink/daemonsink.cpp b/plugins/channelrx/daemonsink/daemonsink.cpp index ac5dfd02e..797e5b429 100644 --- a/plugins/channelrx/daemonsink/daemonsink.cpp +++ b/plugins/channelrx/daemonsink/daemonsink.cpp @@ -97,8 +97,9 @@ void DaemonSink::setNbBlocksFEC(int nbBlocksFEC) m_nbBlocksFEC = nbBlocksFEC; } -void DaemonSink::feed(const SampleVector::const_iterator& begin, const SampleVector::const_iterator& end, bool firstOfBurst __attribute__((unused))) +void DaemonSink::feed(const SampleVector::const_iterator& begin, const SampleVector::const_iterator& end, bool firstOfBurst) { + (void) firstOfBurst; SampleVector::const_iterator it = begin; while (it != end) @@ -134,7 +135,10 @@ void DaemonSink::feed(const SampleVector::const_iterator& begin, const SampleVec superBlock.m_header.m_blockIndex = m_txBlockIndex; superBlock.m_header.m_sampleBytes = (SDR_RX_SAMP_SZ <= 16 ? 2 : 4); superBlock.m_header.m_sampleBits = SDR_RX_SAMP_SZ; - memcpy((void *) &superBlock.m_protectedBlock, (const void *) &metaData, sizeof(SDRDaemonMetaDataFEC)); + + SDRDaemonMetaDataFEC *destMeta = (SDRDaemonMetaDataFEC *) &superBlock.m_protectedBlock; + *destMeta = metaData; + //memcpy((void *) &superBlock.m_protectedBlock, (const void *) &metaData, sizeof(SDRDaemonMetaDataFEC)); if (!(metaData == m_currentMetaFEC)) { @@ -238,8 +242,9 @@ void DaemonSink::stop() m_running = false; } -bool DaemonSink::handleMessage(const Message& cmd __attribute__((unused))) +bool DaemonSink::handleMessage(const Message& cmd) { + (void) cmd; if (DownChannelizer::MsgChannelizerNotification::match(cmd)) { DownChannelizer::MsgChannelizerNotification& notif = (DownChannelizer::MsgChannelizerNotification&) cmd; @@ -293,8 +298,9 @@ QByteArray DaemonSink::serialize() const return m_settings.serialize(); } -bool DaemonSink::deserialize(const QByteArray& data __attribute__((unused))) +bool DaemonSink::deserialize(const QByteArray& data) { + (void) data; if (m_settings.deserialize(data)) { MsgConfigureDaemonSink *msg = MsgConfigureDaemonSink::create(m_settings, true); @@ -341,8 +347,9 @@ void DaemonSink::applySettings(const DaemonSinkSettings& settings, bool force) int DaemonSink::webapiSettingsGet( SWGSDRangel::SWGChannelSettings& response, - QString& errorMessage __attribute__((unused))) + QString& errorMessage) { + (void) errorMessage; response.setDaemonSinkSettings(new SWGSDRangel::SWGDaemonSinkSettings()); response.getDaemonSinkSettings()->init(); webapiFormatChannelSettings(response, m_settings); @@ -353,8 +360,9 @@ int DaemonSink::webapiSettingsPutPatch( bool force, const QStringList& channelSettingsKeys, SWGSDRangel::SWGChannelSettings& response, - QString& errorMessage __attribute__((unused))) + QString& errorMessage) { + (void) errorMessage; DaemonSinkSettings settings = m_settings; if (channelSettingsKeys.contains("nbFECBlocks")) diff --git a/plugins/channelrx/daemonsink/daemonsinkgui.cpp b/plugins/channelrx/daemonsink/daemonsinkgui.cpp index 83338b822..a77bc9a64 100644 --- a/plugins/channelrx/daemonsink/daemonsinkgui.cpp +++ b/plugins/channelrx/daemonsink/daemonsinkgui.cpp @@ -48,8 +48,9 @@ qint64 DaemonSinkGUI::getCenterFrequency() const { return 0; } -void DaemonSinkGUI::setCenterFrequency(qint64 centerFrequency __attribute__((unused))) +void DaemonSinkGUI::setCenterFrequency(qint64 centerFrequency) { + (void) centerFrequency; } void DaemonSinkGUI::resetToDefaults() @@ -207,8 +208,10 @@ void DaemonSinkGUI::handleSourceMessages() } } -void DaemonSinkGUI::onWidgetRolled(QWidget* widget __attribute__((unused)), bool rollDown __attribute__((unused))) +void DaemonSinkGUI::onWidgetRolled(QWidget* widget, bool rollDown) { + (void) widget; + (void) rollDown; } void DaemonSinkGUI::onMenuDialogCalled(const QPoint &p) @@ -249,8 +252,9 @@ void DaemonSinkGUI::on_dataPort_returnPressed() applySettings(); } -void DaemonSinkGUI::on_dataApplyButton_clicked(bool checked __attribute__((unused))) +void DaemonSinkGUI::on_dataApplyButton_clicked(bool checked) { + (void) checked; m_settings.m_dataAddress = ui->dataAddress->text(); bool dataOk; diff --git a/plugins/channelrx/daemonsink/daemonsinksettings.cpp b/plugins/channelrx/daemonsink/daemonsinksettings.cpp index 9b81702f0..1579bc80f 100644 --- a/plugins/channelrx/daemonsink/daemonsinksettings.cpp +++ b/plugins/channelrx/daemonsink/daemonsinksettings.cpp @@ -39,6 +39,7 @@ void DaemonSinkSettings::resetToDefaults() m_dataPort = 9090; m_rgbColor = QColor(140, 4, 4).rgb(); m_title = "Daemon sink"; + m_channelMarker = nullptr; } QByteArray DaemonSinkSettings::serialize() const diff --git a/plugins/channelrx/daemonsink/daemonsinkthread.h b/plugins/channelrx/daemonsink/daemonsinkthread.h index 5e468f7a9..e4f5cb332 100644 --- a/plugins/channelrx/daemonsink/daemonsinkthread.h +++ b/plugins/channelrx/daemonsink/daemonsinkthread.h @@ -68,7 +68,7 @@ public slots: private: QMutex m_startWaitMutex; QWaitCondition m_startWaiter; - bool m_running; + volatile bool m_running; CM256 m_cm256; CM256 *m_cm256p; diff --git a/plugins/channelrx/demodam/amdemod.cpp b/plugins/channelrx/demodam/amdemod.cpp index 29a01559f..f0f48d562 100644 --- a/plugins/channelrx/demodam/amdemod.cpp +++ b/plugins/channelrx/demodam/amdemod.cpp @@ -98,8 +98,9 @@ AMDemod::~AMDemod() delete SSBFilter; } -void AMDemod::feed(const SampleVector::const_iterator& begin, const SampleVector::const_iterator& end, bool firstOfBurst __attribute__((unused))) +void AMDemod::feed(const SampleVector::const_iterator& begin, const SampleVector::const_iterator& end, bool firstOfBurst) { + (void) firstOfBurst; Complex ci; if (!m_running) { @@ -502,8 +503,9 @@ bool AMDemod::deserialize(const QByteArray& data) int AMDemod::webapiSettingsGet( SWGSDRangel::SWGChannelSettings& response, - QString& errorMessage __attribute__((unused))) + QString& errorMessage) { + (void) errorMessage; response.setAmDemodSettings(new SWGSDRangel::SWGAMDemodSettings()); response.getAmDemodSettings()->init(); webapiFormatChannelSettings(response, m_settings); @@ -514,8 +516,9 @@ int AMDemod::webapiSettingsPutPatch( bool force, const QStringList& channelSettingsKeys, SWGSDRangel::SWGChannelSettings& response, - QString& errorMessage __attribute__((unused))) + QString& errorMessage) { + (void) errorMessage; AMDemodSettings settings = m_settings; bool frequencyOffsetChanged = false; @@ -584,8 +587,9 @@ int AMDemod::webapiSettingsPutPatch( int AMDemod::webapiReportGet( SWGSDRangel::SWGChannelReport& response, - QString& errorMessage __attribute__((unused))) + QString& errorMessage) { + (void) errorMessage; response.setAmDemodReport(new SWGSDRangel::SWGAMDemodReport()); response.getAmDemodReport()->init(); webapiFormatChannelReport(response); diff --git a/plugins/channelrx/demodam/amdemodgui.cpp b/plugins/channelrx/demodam/amdemodgui.cpp index c1a8184d2..2bc57c488 100644 --- a/plugins/channelrx/demodam/amdemodgui.cpp +++ b/plugins/channelrx/demodam/amdemodgui.cpp @@ -92,8 +92,9 @@ bool AMDemodGUI::deserialize(const QByteArray& data) } } -bool AMDemodGUI::handleMessage(const Message& message __attribute__((unused))) +bool AMDemodGUI::handleMessage(const Message& message) { + (void) message; if (AMDemod::MsgConfigureAMDemod::match(message)) { qDebug("AMDemodGUI::handleMessage: AMDemod::MsgConfigureAMDemod"); @@ -192,8 +193,10 @@ void AMDemodGUI::on_audioMute_toggled(bool checked) applySettings(); } -void AMDemodGUI::onWidgetRolled(QWidget* widget __attribute__((unused)), bool rollDown __attribute__((unused))) +void AMDemodGUI::onWidgetRolled(QWidget* widget, bool rollDown) { + (void) widget; + (void) rollDown; /* if((widget == ui->spectrumContainer) && (m_nfmDemod != NULL)) m_nfmDemod->setSpectrum(m_threadedSampleSink->getMessageQueue(), rollDown); diff --git a/plugins/channelrx/demodatv/CMakeLists.txt b/plugins/channelrx/demodatv/CMakeLists.txt index 7665ee799..30e835539 100644 --- a/plugins/channelrx/demodatv/CMakeLists.txt +++ b/plugins/channelrx/demodatv/CMakeLists.txt @@ -1,5 +1,7 @@ project(atv) +set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++11") + set(atv_SOURCES atvdemod.cpp atvdemodsettings.cpp diff --git a/plugins/channelrx/demodatv/atvdemod.cpp b/plugins/channelrx/demodatv/atvdemod.cpp index 68e8feed5..778de4045 100644 --- a/plugins/channelrx/demodatv/atvdemod.cpp +++ b/plugins/channelrx/demodatv/atvdemod.cpp @@ -164,8 +164,9 @@ void ATVDemod::configureRF( objMessageQueue->push(msgCmd); } -void ATVDemod::feed(const SampleVector::const_iterator& begin, const SampleVector::const_iterator& end, bool firstOfBurst __attribute__((unused))) +void ATVDemod::feed(const SampleVector::const_iterator& begin, const SampleVector::const_iterator& end, bool firstOfBurst) { + (void) firstOfBurst; float fltI; float fltQ; Complex ci; diff --git a/plugins/channelrx/demodatv/atvdemod.h b/plugins/channelrx/demodatv/atvdemod.h index dda259740..9d99c09ac 100644 --- a/plugins/channelrx/demodatv/atvdemod.h +++ b/plugins/channelrx/demodatv/atvdemod.h @@ -65,7 +65,8 @@ public: ATV_FM3, //!< Classical frequency modulation with phase derivative discriminator ATV_AM, //!< Classical amplitude modulation ATV_USB, //!< AM with vestigial lower side band (main signal is in the upper side) - ATV_LSB //!< AM with vestigial upper side band (main signal is in the lower side) + ATV_LSB, //!< AM with vestigial upper side band (main signal is in the lower side) + ATV_NONE //!< No modulation just produces zeros }; struct ATVConfig @@ -229,7 +230,7 @@ public: virtual qint64 getCenterFrequency() const { return m_rfRunning.m_intFrequencyOffset; } virtual QByteArray serialize() const { return QByteArray(); } - virtual bool deserialize(const QByteArray& data __attribute__((unused))) { return false; } + virtual bool deserialize(const QByteArray& data) { (void) data; return false; } void setTVScreen(TVScreen *objScreen); //!< set by the GUI int getSampleRate(); diff --git a/plugins/channelrx/demodatv/atvdemodgui.cpp b/plugins/channelrx/demodatv/atvdemodgui.cpp index 4fadfd9b6..a73f05724 100644 --- a/plugins/channelrx/demodatv/atvdemodgui.cpp +++ b/plugins/channelrx/demodatv/atvdemodgui.cpp @@ -263,8 +263,10 @@ void ATVDemodGUI::handleSourceMessages() } } -void ATVDemodGUI::onWidgetRolled(QWidget* widget __attribute__((unused)), bool rollDown __attribute__((unused))) +void ATVDemodGUI::onWidgetRolled(QWidget* widget, bool rollDown) { + (void) widget; + (void) rollDown; } ATVDemodGUI::ATVDemodGUI(PluginAPI* objPluginAPI, DeviceUISet *deviceUISet, BasebandSampleSink *rxChannel, QWidget* objParent) : @@ -534,32 +536,37 @@ void ATVDemodGUI::on_halfImage_clicked() applySettings(); } -void ATVDemodGUI::on_nbLines_currentIndexChanged(int index __attribute__((unused))) +void ATVDemodGUI::on_nbLines_currentIndexChanged(int index) { + (void) index; lineTimeUpdate(); topTimeUpdate(); applySettings(); } -void ATVDemodGUI::on_fps_currentIndexChanged(int index __attribute__((unused))) +void ATVDemodGUI::on_fps_currentIndexChanged(int index) { + (void) index; lineTimeUpdate(); topTimeUpdate(); applySettings(); } -void ATVDemodGUI::on_standard_currentIndexChanged(int index __attribute__((unused))) +void ATVDemodGUI::on_standard_currentIndexChanged(int index) { + (void) index; applySettings(); } -void ATVDemodGUI::on_reset_clicked(bool checked __attribute__((unused))) +void ATVDemodGUI::on_reset_clicked(bool checked) { + (void) checked; resetToDefaults(); } -void ATVDemodGUI::on_modulation_currentIndexChanged(int index __attribute__((unused))) +void ATVDemodGUI::on_modulation_currentIndexChanged(int index) { + (void) index; setRFFiltersSlidersRange(m_atvDemod->getEffectiveSampleRate()); setChannelMarkerBandwidth(); applyRFSettings(); @@ -579,15 +586,17 @@ void ATVDemodGUI::on_rfOppBW_valueChanged(int value) applyRFSettings(); } -void ATVDemodGUI::on_rfFiltering_toggled(bool checked __attribute__((unused))) +void ATVDemodGUI::on_rfFiltering_toggled(bool checked) { + (void) checked; setRFFiltersSlidersRange(m_atvDemod->getEffectiveSampleRate()); setChannelMarkerBandwidth(); applyRFSettings(); } -void ATVDemodGUI::on_decimatorEnable_toggled(bool checked __attribute__((unused))) +void ATVDemodGUI::on_decimatorEnable_toggled(bool checked) { + (void) checked; setChannelMarkerBandwidth(); applyRFSettings(); } @@ -610,8 +619,9 @@ void ATVDemodGUI::on_fmDeviation_valueChanged(int value) applyRFSettings(); } -void ATVDemodGUI::on_screenTabWidget_currentChanged(int index __attribute__((unused))) +void ATVDemodGUI::on_screenTabWidget_currentChanged(int index) { + (void) index; applySettings(); } diff --git a/plugins/channelrx/demodatv/atvdemodplugin.cpp b/plugins/channelrx/demodatv/atvdemodplugin.cpp index f728462f5..bd1efedba 100644 --- a/plugins/channelrx/demodatv/atvdemodplugin.cpp +++ b/plugins/channelrx/demodatv/atvdemodplugin.cpp @@ -27,7 +27,7 @@ const PluginDescriptor ATVDemodPlugin::m_ptrPluginDescriptor = { QString("ATV Demodulator"), - QString("4.2.4"), + QString("4.3.0"), QString("(c) F4HKW for F4EXB / SDRAngel"), QString("https://github.com/f4exb/sdrangel"), true, diff --git a/plugins/channelrx/demodatv/demodatv.pro b/plugins/channelrx/demodatv/demodatv.pro index decef5410..aa5fce3d4 100644 --- a/plugins/channelrx/demodatv/demodatv.pro +++ b/plugins/channelrx/demodatv/demodatv.pro @@ -27,6 +27,7 @@ CONFIG(Debug):build_subdir = debug CONFIG(MINGW32):INCLUDEPATH += "C:\softs\boost_1_66_0" CONFIG(MINGW64):INCLUDEPATH += "C:\softs\boost_1_66_0" +CONFIG(MSVC):INCLUDEPATH += "C:\softs\boost_1_66_0" CONFIG(macx):INCLUDEPATH += "../../../../../boost_1_64_0" SOURCES += atvdemod.cpp\ diff --git a/plugins/channelrx/demodbfm/bfmdemod.cpp b/plugins/channelrx/demodbfm/bfmdemod.cpp index 1d056771d..1ac07377e 100644 --- a/plugins/channelrx/demodbfm/bfmdemod.cpp +++ b/plugins/channelrx/demodbfm/bfmdemod.cpp @@ -113,8 +113,9 @@ BFMDemod::~BFMDemod() delete m_rfFilter; } -void BFMDemod::feed(const SampleVector::const_iterator& begin, const SampleVector::const_iterator& end, bool firstOfBurst __attribute__((unused))) +void BFMDemod::feed(const SampleVector::const_iterator& begin, const SampleVector::const_iterator& end, bool firstOfBurst) { + (void) firstOfBurst; Complex ci, cs, cr; fftfilt::cmplx *rf; int rf_out; @@ -538,8 +539,9 @@ bool BFMDemod::deserialize(const QByteArray& data) int BFMDemod::webapiSettingsGet( SWGSDRangel::SWGChannelSettings& response, - QString& errorMessage __attribute__((unused))) + QString& errorMessage) { + (void) errorMessage; response.setBfmDemodSettings(new SWGSDRangel::SWGBFMDemodSettings()); response.getBfmDemodSettings()->init(); webapiFormatChannelSettings(response, m_settings); @@ -550,8 +552,9 @@ int BFMDemod::webapiSettingsPutPatch( bool force, const QStringList& channelSettingsKeys, SWGSDRangel::SWGChannelSettings& response, - QString& errorMessage __attribute__((unused))) + QString& errorMessage) { + (void) errorMessage; BFMDemodSettings settings = m_settings; bool frequencyOffsetChanged = false; @@ -618,8 +621,9 @@ int BFMDemod::webapiSettingsPutPatch( int BFMDemod::webapiReportGet( SWGSDRangel::SWGChannelReport& response, - QString& errorMessage __attribute__((unused))) + QString& errorMessage) { + (void) errorMessage; response.setBfmDemodReport(new SWGSDRangel::SWGBFMDemodReport()); response.getBfmDemodReport()->init(); webapiFormatChannelReport(response); diff --git a/plugins/channelrx/demodbfm/bfmdemodgui.cpp b/plugins/channelrx/demodbfm/bfmdemodgui.cpp index 2e0f4c42a..a2fded696 100644 --- a/plugins/channelrx/demodbfm/bfmdemodgui.cpp +++ b/plugins/channelrx/demodbfm/bfmdemodgui.cpp @@ -225,8 +225,9 @@ void BFMDemodGUI::on_rds_clicked() applySettings(); } -void BFMDemodGUI::on_clearData_clicked(bool checked __attribute__((unused))) +void BFMDemodGUI::on_clearData_clicked(bool checked) { + (void) checked; if (ui->rds->isChecked()) { m_bfmDemod->getRDSParser().clearAllFields(); @@ -288,26 +289,31 @@ void BFMDemodGUI::on_g14ProgServiceNames_currentIndexChanged(int _index) } } -void BFMDemodGUI::on_g00AltFrequenciesBox_activated(int index __attribute__((unused))) +void BFMDemodGUI::on_g00AltFrequenciesBox_activated(int index) { + (void) index; qint64 f = (qint64) ((ui->g00AltFrequenciesBox->currentText()).toDouble() * 1e6); changeFrequency(f); } -void BFMDemodGUI::on_g14MappedFrequencies_activated(int index __attribute__((unused))) +void BFMDemodGUI::on_g14MappedFrequencies_activated(int index) { + (void) index; qint64 f = (qint64) ((ui->g14MappedFrequencies->currentText()).toDouble() * 1e6); changeFrequency(f); } -void BFMDemodGUI::on_g14AltFrequencies_activated(int index __attribute__((unused))) +void BFMDemodGUI::on_g14AltFrequencies_activated(int index) { + (void) index; qint64 f = (qint64) ((ui->g14AltFrequencies->currentText()).toDouble() * 1e6); changeFrequency(f); } -void BFMDemodGUI::onWidgetRolled(QWidget* widget __attribute__((unused)), bool rollDown __attribute__((unused))) +void BFMDemodGUI::onWidgetRolled(QWidget* widget, bool rollDown) { + (void) widget; + (void) rollDown; } void BFMDemodGUI::onMenuDialogCalled(const QPoint &p) diff --git a/plugins/channelrx/demodbfm/demodbfm.pro b/plugins/channelrx/demodbfm/demodbfm.pro index 8f7d6bea1..efb129f79 100644 --- a/plugins/channelrx/demodbfm/demodbfm.pro +++ b/plugins/channelrx/demodbfm/demodbfm.pro @@ -26,6 +26,7 @@ INCLUDEPATH += ../../../swagger/sdrangel/code/qt5/client CONFIG(ANDROID):INCLUDEPATH += /opt/softs/boost_1_60_0 CONFIG(MINGW32):INCLUDEPATH += "C:\softs\boost_1_66_0" CONFIG(MINGW64):INCLUDEPATH += "C:\softs\boost_1_66_0" +CONFIG(MSVC):INCLUDEPATH += "C:\softs\boost_1_66_0" CONFIG(macx):INCLUDEPATH += "../../../../../boost_1_64_0" CONFIG(Release):build_subdir = release diff --git a/plugins/channelrx/demodbfm/rdsdemod.cpp b/plugins/channelrx/demodbfm/rdsdemod.cpp index c38cccdf8..bdce3ef0e 100644 --- a/plugins/channelrx/demodbfm/rdsdemod.cpp +++ b/plugins/channelrx/demodbfm/rdsdemod.cpp @@ -66,8 +66,9 @@ RDSDemod::~RDSDemod() //delete m_socket; } -void RDSDemod::setSampleRate(int srate __attribute__((unused))) /// FIXME: fix rate for now +void RDSDemod::setSampleRate(int srate) /// FIXME: fix rate for now { + (void) srate; } bool RDSDemod::process(Real demod, bool& bit) diff --git a/plugins/channelrx/demodbfm/rdsparser.cpp b/plugins/channelrx/demodbfm/rdsparser.cpp index eaa95c98e..be40ab821 100644 --- a/plugins/channelrx/demodbfm/rdsparser.cpp +++ b/plugins/channelrx/demodbfm/rdsparser.cpp @@ -532,20 +532,16 @@ void RDSParser::decode_type0(unsigned int *group, bool B) if (af_1) { // @TODO: Find proper header or STL on OSX -#ifndef __APPLE__ - std::pair, bool> res = m_g0_alt_freq.insert(af_1/1e3); - m_g0_af_updated = m_g0_af_updated || res.second; -#endif + auto res = m_g0_alt_freq.insert(af_1/1e3); + m_g0_af_updated = m_g0_af_updated || res.second; no_af += 1; } if (af_2) { // @TODO: Find proper header or STL on OSX -#ifndef __APPLE__ - std::pair, bool> res = m_g0_alt_freq.insert(af_2/1e3); + auto res = m_g0_alt_freq.insert(af_2/1e3); m_g0_af_updated = m_g0_af_updated || res.second; -#endif no_af += 2; } @@ -828,19 +824,25 @@ void RDSParser::decode_type4(unsigned int *group, bool B) //send_message(5,time); } -void RDSParser::decode_type5(unsigned int *group __attribute__((unused)), bool B __attribute__((unused))) { +void RDSParser::decode_type5(unsigned int *group, bool B) { + (void) group; + (void) B; qDebug() << "RDSParser::decode_type5: type5 not implemented yet"; m_g5_updated = true; m_g5_count++; } -void RDSParser::decode_type6(unsigned int *group __attribute__((unused)), bool B __attribute__((unused))) { +void RDSParser::decode_type6(unsigned int *group, bool B) { + (void) group; + (void) B; qDebug() << "RDSParser::decode_type6: type 6 not implemented yet"; m_g6_updated = true; m_g6_count++; } -void RDSParser::decode_type7(unsigned int *group __attribute__((unused)), bool B __attribute__((unused))) { +void RDSParser::decode_type7(unsigned int *group, bool B) { + (void) group; + (void) B; qDebug() << "RDSParser::decode_type7: type 7 not implemented yet"; m_g7_updated = true; m_g7_count++; @@ -971,29 +973,37 @@ void RDSParser::decode_type9(unsigned int *group, bool B){ m_g9_count++; } -void RDSParser::decode_type10(unsigned int *group __attribute__((unused)), bool B __attribute__((unused))) +void RDSParser::decode_type10(unsigned int *group, bool B) { + (void) group; + (void) B; qDebug() << "RDSParser::decode_type10: type 10 not implemented yet"; m_g10_updated = true; m_g10_count++; } -void RDSParser::decode_type11(unsigned int *group __attribute__((unused)), bool B __attribute__((unused))) +void RDSParser::decode_type11(unsigned int *group, bool B) { + (void) group; + (void) B; qDebug() << "RDSParser::decode_type11: type 11 not implemented yet"; m_g11_updated = true; m_g11_count++; } -void RDSParser::decode_type12(unsigned int *group __attribute__((unused)), bool B __attribute__((unused))) +void RDSParser::decode_type12(unsigned int *group, bool B) { + (void) group; + (void) B; qDebug() << "RDSParser::decode_type12: type 12 not implemented yet"; m_g12_updated = true; m_g12_count++; } -void RDSParser::decode_type13(unsigned int *group __attribute__((unused)), bool B __attribute__((unused))) +void RDSParser::decode_type13(unsigned int *group, bool B) { + (void) group; + (void) B; qDebug() << "RDSParser::decode_type13: type 13 not implemented yet"; m_g13_updated = true; m_g13_count++; @@ -1180,8 +1190,10 @@ void RDSParser::decode_type14(unsigned int *group, bool B) }*/ } -void RDSParser::decode_type15(unsigned int *group __attribute__((unused)), bool B __attribute__((unused))) +void RDSParser::decode_type15(unsigned int *group, bool B) { + (void) group; + (void) B; qDebug() << "RDSParser::decode_type5: type 15 not implemented yet"; m_g15_updated = true; m_g15_count++; diff --git a/plugins/channelrx/demoddatv/CMakeLists.txt b/plugins/channelrx/demoddatv/CMakeLists.txt index a4bfb1b0e..b1eedcbcb 100644 --- a/plugins/channelrx/demoddatv/CMakeLists.txt +++ b/plugins/channelrx/demoddatv/CMakeLists.txt @@ -1,5 +1,7 @@ project(datv) +set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++11") + set(datv_SOURCES datvdemod.cpp datvdemodgui.cpp diff --git a/plugins/channelrx/demoddatv/datvconstellation.h b/plugins/channelrx/demoddatv/datvconstellation.h index f3d21b32c..091bed139 100644 --- a/plugins/channelrx/demoddatv/datvconstellation.h +++ b/plugins/channelrx/demoddatv/datvconstellation.h @@ -19,7 +19,6 @@ #ifndef DATVCONSTELLATION_H #define DATVCONSTELLATION_H -#include #include #include "leansdr/framework.h" @@ -69,12 +68,8 @@ template struct datvconstellation: runnable for (; p < pend; ++p) { - if (m_objDATVScreen != 0) - { - m_objDATVScreen->selectRow(256 * (p->re - xymin) / (xymax - xymin)); - m_objDATVScreen->setDataColor(256 - 256 * ((p->im - xymin) / (xymax - xymin)), 255, 0, 255); - } - + m_objDATVScreen->selectRow(256 * (p->re - xymin) / (xymax - xymin)); + m_objDATVScreen->setDataColor(256 - 256 * ((p->im - xymin) / (xymax - xymin)), 255, 0, 255); } if (cstln && (*cstln)) diff --git a/plugins/channelrx/demoddatv/datvdemod.cpp b/plugins/channelrx/demoddatv/datvdemod.cpp index 2023e5c3f..7d22cd8f6 100644 --- a/plugins/channelrx/demoddatv/datvdemod.cpp +++ b/plugins/channelrx/demoddatv/datvdemod.cpp @@ -764,8 +764,9 @@ void DATVDemod::InitDATVFramework() m_blnDVBInitialized=true; } -void DATVDemod::feed(const SampleVector::const_iterator& begin, const SampleVector::const_iterator& end, bool firstOfBurst __attribute__((unused))) +void DATVDemod::feed(const SampleVector::const_iterator& begin, const SampleVector::const_iterator& end, bool firstOfBurst) { + (void) firstOfBurst; float fltI; float fltQ; leansdr::cf32 objIQ; diff --git a/plugins/channelrx/demoddatv/datvdemod.h b/plugins/channelrx/demoddatv/datvdemod.h index a5af83546..8bccb0ca9 100644 --- a/plugins/channelrx/demoddatv/datvdemod.h +++ b/plugins/channelrx/demoddatv/datvdemod.h @@ -185,7 +185,7 @@ public: virtual qint64 getCenterFrequency() const { return m_objRunning.intCenterFrequency; } virtual QByteArray serialize() const { return QByteArray(); } - virtual bool deserialize(const QByteArray& data __attribute__((unused))) { return false; } + virtual bool deserialize(const QByteArray& data) { (void) data; return false; } void configure( MessageQueue* objMessageQueue, diff --git a/plugins/channelrx/demoddatv/datvdemodgui.cpp b/plugins/channelrx/demoddatv/datvdemodgui.cpp index 21c22892e..090a407db 100644 --- a/plugins/channelrx/demoddatv/datvdemodgui.cpp +++ b/plugins/channelrx/demoddatv/datvdemodgui.cpp @@ -219,8 +219,9 @@ bool DATVDemodGUI::deserialize(const QByteArray& arrData) } } -bool DATVDemodGUI::handleMessage(const Message& objMessage __attribute__((unused))) +bool DATVDemodGUI::handleMessage(const Message& objMessage) { + (void) objMessage; return false; } @@ -241,8 +242,10 @@ void DATVDemodGUI::channelMarkerHighlightedByCursor() } -void DATVDemodGUI::onWidgetRolled(QWidget* widget __attribute__((unused)), bool rollDown __attribute__((unused))) +void DATVDemodGUI::onWidgetRolled(QWidget* widget, bool rollDown) { + (void) widget; + (void) rollDown; } void DATVDemodGUI::onMenuDoubleClicked() @@ -526,13 +529,15 @@ void DATVDemodGUI::tick() return; } -void DATVDemodGUI::on_cmbStandard_currentIndexChanged(const QString &arg1 __attribute__((unused))) +void DATVDemodGUI::on_cmbStandard_currentIndexChanged(const QString &arg1) { + (void) arg1; applySettings(); } -void DATVDemodGUI::on_cmbModulation_currentIndexChanged(const QString &arg1 __attribute__((unused))) +void DATVDemodGUI::on_cmbModulation_currentIndexChanged(const QString &arg1) { + (void) arg1; QString strModulation; QString strFEC; @@ -583,8 +588,9 @@ void DATVDemodGUI::on_cmbModulation_currentIndexChanged(const QString &arg1 __at } -void DATVDemodGUI::on_cmbFEC_currentIndexChanged(const QString &arg1 __attribute__((unused))) +void DATVDemodGUI::on_cmbFEC_currentIndexChanged(const QString &arg1) { + (void) arg1; QString strFEC; strFEC = ui->cmbFEC->currentText(); @@ -647,13 +653,15 @@ void DATVDemodGUI::on_pushButton_2_clicked() resetToDefaults(); } -void DATVDemodGUI::on_spiSymbolRate_valueChanged(int arg1 __attribute__((unused))) +void DATVDemodGUI::on_spiSymbolRate_valueChanged(int arg1) { + (void) arg1; applySettings(); } -void DATVDemodGUI::on_spiNotchFilters_valueChanged(int arg1 __attribute__((unused))) +void DATVDemodGUI::on_spiNotchFilters_valueChanged(int arg1) { + (void) arg1; applySettings(); } @@ -680,8 +688,9 @@ void DATVDemodGUI::on_pushButton_4_clicked() } -void DATVDemodGUI::on_mouseEvent(QMouseEvent* obj __attribute__((unused))) +void DATVDemodGUI::on_mouseEvent(QMouseEvent* obj) { + (void) obj; } QString DATVDemodGUI::formatBytes(qint64 intBytes) @@ -703,8 +712,9 @@ QString DATVDemodGUI::formatBytes(qint64 intBytes) } -void DATVDemodGUI::on_StreamDataAvailable(int *intPackets __attribute__((unused)), int *intBytes, int *intPercent, qint64 *intTotalReceived) +void DATVDemodGUI::on_StreamDataAvailable(int *intPackets, int *intBytes, int *intPercent, qint64 *intTotalReceived) { + (void) intPackets; ui->lblStatus->setText(QString("Data: %1B").arg(formatBytes(*intTotalReceived))); m_intLastDecodedData = *intTotalReceived; @@ -721,18 +731,21 @@ void DATVDemodGUI::on_StreamDataAvailable(int *intPackets __attribute__((unused) } -void DATVDemodGUI::on_spiBandwidth_valueChanged(int arg1 __attribute__((unused))) +void DATVDemodGUI::on_spiBandwidth_valueChanged(int arg1) { + (void) arg1; applySettings(); } -void DATVDemodGUI::on_deltaFrequency_changed(qint64 value __attribute__((unused))) +void DATVDemodGUI::on_deltaFrequency_changed(qint64 value) { + (void) value; applySettings(); } -void DATVDemodGUI::on_rfBandwidth_changed(qint64 value __attribute__((unused))) +void DATVDemodGUI::on_rfBandwidth_changed(qint64 value) { + (void) value; applySettings(); } @@ -789,19 +802,22 @@ void DATVDemodGUI::displayRRCParameters(bool blnVisible) ui->label_6->setVisible(blnVisible); } -void DATVDemodGUI::on_cmbFilter_currentIndexChanged(int index __attribute__((unused))) +void DATVDemodGUI::on_cmbFilter_currentIndexChanged(int index) { + (void) index; displayRRCParameters((ui->cmbFilter->currentIndex()==2)); applySettings(); } -void DATVDemodGUI::on_spiRollOff_valueChanged(int arg1 __attribute__((unused))) +void DATVDemodGUI::on_spiRollOff_valueChanged(int arg1) { + (void) arg1; applySettings(); } -void DATVDemodGUI::on_spiExcursion_valueChanged(int arg1 __attribute__((unused))) +void DATVDemodGUI::on_spiExcursion_valueChanged(int arg1) { + (void) arg1; applySettings(); } diff --git a/plugins/channelrx/demoddatv/datvdemodplugin.cpp b/plugins/channelrx/demoddatv/datvdemodplugin.cpp index 346a898ff..0fe293803 100644 --- a/plugins/channelrx/demoddatv/datvdemodplugin.cpp +++ b/plugins/channelrx/demoddatv/datvdemodplugin.cpp @@ -27,7 +27,7 @@ const PluginDescriptor DATVDemodPlugin::m_ptrPluginDescriptor = { QString("DATV Demodulator"), - QString("4.0.1"), + QString("4.3.1"), QString("(c) F4HKW for SDRAngel using LeanSDR framework (c) F4DAV"), QString("https://github.com/f4exb/sdrangel"), true, diff --git a/plugins/channelrx/demoddatv/datvideostream.cpp b/plugins/channelrx/demoddatv/datvideostream.cpp index 53016cb76..fbe644ed5 100644 --- a/plugins/channelrx/demoddatv/datvideostream.cpp +++ b/plugins/channelrx/demoddatv/datvideostream.cpp @@ -49,8 +49,6 @@ void DATVideostream::cleanUp() m_objeventLoop.exit(); } - m_objMutex.unlock(); - m_intBytesAvailable=0; m_intBytesWaiting=0; m_intQueueWaiting=0; @@ -224,12 +222,16 @@ qint64 DATVideostream::readData(char *data, qint64 len) return (qint64)intEffectiveLen; } -qint64 DATVideostream::writeData(const char *data __attribute__((unused)), qint64 len __attribute__((unused))) +qint64 DATVideostream::writeData(const char *data, qint64 len) { + (void) data; + (void) len; return 0; } -qint64 DATVideostream::readLineData(char *data __attribute__((unused)), qint64 maxSize __attribute__((unused))) +qint64 DATVideostream::readLineData(char *data, qint64 maxSize) { + (void) data; + (void) maxSize; return 0; } diff --git a/plugins/channelrx/demoddatv/demoddatv.pro b/plugins/channelrx/demoddatv/demoddatv.pro index c02e89ad5..46c0404d9 100644 --- a/plugins/channelrx/demoddatv/demoddatv.pro +++ b/plugins/channelrx/demoddatv/demoddatv.pro @@ -7,7 +7,7 @@ TEMPLATE = lib CONFIG += plugin -QT += core gui multimedia multimediawidgets widgets opengl +QT += core gui multimedia multimediawidgets widgets opengl qml TARGET = demoddatv @@ -18,25 +18,26 @@ QMAKE_CXXFLAGS += -msse4.1 QMAKE_CXXFLAGS += -std=c++11 INCLUDEPATH += $$PWD +INCLUDEPATH += ../../../exports INCLUDEPATH += ../../../sdrbase INCLUDEPATH += ../../../sdrgui CONFIG(Release):build_subdir = release CONFIG(Debug):build_subdir = debug -CONFIG(MINGW32):INCLUDEPATH += "D:\boost_1_58_0" -CONFIG(MINGW64):INCLUDEPATH += "D:\boost_1_58_0" +CONFIG(MSVC):INCLUDEPATH += "C:\softs\boost_1_66_0" +CONFIG(MSVC):INCLUDEPATH += "C:\softs\ffmpeg-20181127-1035206-win64-dev\include" CONFIG(macx):INCLUDEPATH += "../../../../../boost_1_64_0" SOURCES += datvdemod.cpp\ - datvdemodgui.cpp\ - datvdemodplugin.cpp\ + datvdemodgui.cpp\ + datvdemodplugin.cpp\ datvideostream.cpp \ datvideorender.cpp HEADERS += datvdemod.h\ - datvdemodgui.h\ - datvdemodplugin.h\ + datvdemodgui.h\ + datvdemodplugin.h\ leansdr/convolutional.h \ leansdr/dsp.h \ leansdr/dvb.h \ @@ -58,6 +59,7 @@ FORMS += datvdemodgui.ui LIBS += -L../../../sdrbase/$${build_subdir} -lsdrbase LIBS += -L../../../sdrgui/$${build_subdir} -lsdrgui -LIBS += -lavutil -lswscale -lavdevice -lavformat -lavcodec -lswresample +#LIBS += -lavutil -lswscale -lavdevice -lavformat -lavcodec -lswresample +LIBS += -L"C:\softs\ffmpeg-20181127-1035206-win64-dev\lib" -lavutil -lswscale -lavdevice -lavformat -lavcodec -lswresample RESOURCES = ../../../sdrbase/resources/res.qrc diff --git a/plugins/channelrx/demoddatv/leansdr/dvb.h b/plugins/channelrx/demoddatv/leansdr/dvb.h index da4e44fb8..8cde82b79 100644 --- a/plugins/channelrx/demoddatv/leansdr/dvb.h +++ b/plugins/channelrx/demoddatv/leansdr/dvb.h @@ -404,7 +404,9 @@ private: for (int im_pos = 0; im_pos <= 1; ++im_pos) { int re_neg = !re_pos; +#if 0 int im_neg __attribute__((unused)) = !im_pos; +#endif int I, Q; switch (sync_id) { @@ -666,16 +668,17 @@ static struct fec_spec int bits_in; // Entering the convolutional coder int bits_out; // Exiting the convolutional coder const uint16_t *polys; // [bits_out] -} fec_specs[FEC_MAX] = -{ [FEC12] = -{ 1, 2, polys_fec12 }, [FEC23] = -{ 2, 3, polys_fec23 }, [FEC46] = -{ 4, 6, polys_fec46 }, [FEC34] = -{ 3, 4, polys_fec34 }, [FEC56] = -{ 5, 6, polys_fec56 }, [FEC78] = -{ 7, 8, polys_fec78 }, [FEC45] = -{ 4, 5, polys_fec45 }, // Non-standard - }; +} + +fec_specs[FEC_MAX] = { + { 1, 2, polys_fec12 }, + { 2, 3, polys_fec23 }, + { 4, 6, polys_fec46 }, + { 3, 4, polys_fec34 }, + { 5, 6, polys_fec56 }, + { 7, 8, polys_fec78 }, + { 4, 5, polys_fec45 }, // Non-standard +}; struct dvb_convol: runnable { diff --git a/plugins/channelrx/demoddatv/leansdr/framework.h b/plugins/channelrx/demoddatv/leansdr/framework.h index e705b2db6..d894c74b5 100644 --- a/plugins/channelrx/demoddatv/leansdr/framework.h +++ b/plugins/channelrx/demoddatv/leansdr/framework.h @@ -2,6 +2,8 @@ #define LEANSDR_FRAMEWORK_H #include +#include + #include #include #include @@ -46,8 +48,9 @@ struct pipebuf_common return 0; } - virtual void dump(std::size_t *total_bufs __attribute__((unused))) + virtual void dump(std::size_t *total_bufs) { + (void) total_bufs; } pipebuf_common(const char *_name) : @@ -105,9 +108,10 @@ struct scheduler bool verbose, debug; scheduler() : - npipes(0), nrunnables(0), windows(NULL), verbose(false), debug( - false) + npipes(0), nrunnables(0), windows(nullptr), verbose(false), debug(false) { + std::fill(pipes, pipes + MAX_PIPES, nullptr); + std::fill(runnables, runnables + MAX_RUNNABLES, nullptr); } void add_pipe(pipebuf_common *p) diff --git a/plugins/channelrx/demoddatv/leansdr/generic.h b/plugins/channelrx/demoddatv/leansdr/generic.h index 47577328e..d7e541d28 100644 --- a/plugins/channelrx/demoddatv/leansdr/generic.h +++ b/plugins/channelrx/demoddatv/leansdr/generic.h @@ -2,7 +2,13 @@ #define LEANSDR_GENERIC_H #include + +#ifdef _MSC_VER +#include +#include +#else #include +#endif #include "leansdr/math.h" @@ -29,7 +35,11 @@ struct file_reader: runnable if (!size) return; +#ifdef _MSC_VER + again: ssize_t nr = _read(fdin, out.wr(), size); +#else again: ssize_t nr = read(fdin, out.wr(), size); +#endif if (nr < 0) { fatal("leansdr::file_reader::run: read"); @@ -41,7 +51,11 @@ struct file_reader: runnable return; if (sch->debug) fprintf(stderr, "leansdr::file_reader::run: %s looping\n", name); +#ifdef _MSC_VER + off_t res = _lseek(fdin, 0, SEEK_SET); +#else off_t res = lseek(fdin, 0, SEEK_SET); +#endif if (res == (off_t) -1) { fatal("leansdr::file_reader::run: lseek"); @@ -57,7 +71,11 @@ struct file_reader: runnable { if (sch->debug) fprintf(stderr, "+"); +#ifdef _MSC_VER + ssize_t nr2 = _read(fdin, (char*) out.wr() + nr, remain); +#else ssize_t nr2 = read(fdin, (char*) out.wr() + nr, remain); +#endif if (nr2 <= 0) { fatal("leansdr::file_reader::run: partial read"); @@ -89,7 +107,11 @@ struct file_writer: runnable int size = in.readable() * sizeof(T); if (!size) return; +#ifdef _MSC_VER + int nw = _write(fdout, in.rd(), size); +#else int nw = write(fdout, in.rd(), size); +#endif if (!nw) { fatal("leansdr::file_writer::run: pipe"); @@ -138,7 +160,11 @@ struct file_printer: runnable fatal("leansdr::file_printer::run: obsolete glibc"); return; } +#ifdef _MSC_VER + int nw = _write(fdout, buf, len); +#else int nw = write(fdout, buf, len); +#endif if (nw != len) { fatal("leansdr::file_printer::run: partial write"); @@ -329,9 +355,10 @@ private: template struct serializer: runnable { - serializer(scheduler *sch __attribute__((unused)), pipebuf &_in, pipebuf &_out) : + serializer(scheduler *sch, pipebuf &_in, pipebuf &_out) : nin(max((size_t) 1, sizeof(Tin) / sizeof(Tout))), nout(max((size_t) 1, sizeof(Tout) / sizeof(Tin))), in(_in), out(_out, nout) { + (void) sch; if (nin * sizeof(Tin) != nout * sizeof(Tout)) { fail("serializer::serializer", "incompatible sizes"); diff --git a/plugins/channelrx/demoddatv/leansdr/math.h b/plugins/channelrx/demoddatv/leansdr/math.h index 26a94b250..ada707f17 100644 --- a/plugins/channelrx/demoddatv/leansdr/math.h +++ b/plugins/channelrx/demoddatv/leansdr/math.h @@ -1,6 +1,7 @@ #ifndef LEANSDR_MATH_H #define LEANSDR_MATH_H +#define _USE_MATH_DEFINES #include #include diff --git a/plugins/channelrx/demoddatv/leansdr/rs.h b/plugins/channelrx/demoddatv/leansdr/rs.h index 0df614409..32e5c0a93 100644 --- a/plugins/channelrx/demoddatv/leansdr/rs.h +++ b/plugins/channelrx/demoddatv/leansdr/rs.h @@ -162,7 +162,7 @@ struct rs_engine { // TBD Avoid copying u8 p[204]; - memcpy(p, msg, 188); + memcpy(p, msg, 204); // was 188 but causing underflow (PVS https://www.viva64.com/en/w/v512/) memset(p + 188, 0, 16); // p = msg*X^16 #if DEBUG_RS diff --git a/plugins/channelrx/demoddatv/leansdr/sdr.h b/plugins/channelrx/demoddatv/leansdr/sdr.h index 6d87eb90e..a8da24be9 100644 --- a/plugins/channelrx/demoddatv/leansdr/sdr.h +++ b/plugins/channelrx/demoddatv/leansdr/sdr.h @@ -700,8 +700,9 @@ struct sampler_interface { virtual complex interp(const complex *pin, float mu, float phase) = 0; - virtual void update_freq(float freqw __attribute__((unused))) + virtual void update_freq(float freqw) { + (void) freqw; } // 65536 = 1 Hz virtual int readahead() @@ -725,8 +726,9 @@ struct nearest_sampler: sampler_interface return 0; } - complex interp(const complex *pin, float mu __attribute__((unused)), float phase) + complex interp(const complex *pin, float mu, float phase) { + (void) mu; return pin[0] * trig.expi(-phase); } diff --git a/plugins/channelrx/demoddsd/demoddsd.pro b/plugins/channelrx/demoddsd/demoddsd.pro index 8b8c96bc7..d9e085168 100644 --- a/plugins/channelrx/demoddsd/demoddsd.pro +++ b/plugins/channelrx/demoddsd/demoddsd.pro @@ -19,14 +19,17 @@ QMAKE_CXXFLAGS += -std=c++11 CONFIG(MINGW32):LIBDSDCCSRC = "C:\softs\dsdcc" CONFIG(MINGW64):LIBDSDCCSRC = "C:\softs\dsdcc" +CONFIG(MSVC):LIBDSDCCSRC = "C:\softs\dsdcc" CONFIG(macx):LIBDSDCCSRC = "../../../../deps/dsdcc" CONFIG(MINGW32):LIBMBELIBSRC = "C:\softs\mbelib" CONFIG(MINGW64):LIBMBELIBSRC = "C:\softs\mbelib" +CONFIG(MSVC):LIBMBELIBSRC = "C:\softs\mbelib" CONFIG(macx):LIBMBELIBSRC = "../../../../deps/mbelib" CONFIG(MINGW32):INCLUDEPATH += "C:\softs\boost_1_66_0" CONFIG(MINGW64):INCLUDEPATH += "C:\softs\boost_1_66_0" +CONFIG(MSVC):INCLUDEPATH += "C:\softs\boost_1_66_0" CONFIG(macx):INCLUDEPATH += "../../../../../boost_1_64_0" INCLUDEPATH += $$PWD diff --git a/plugins/channelrx/demoddsd/dsddemod.cpp b/plugins/channelrx/demoddsd/dsddemod.cpp index 04a9169e3..0b63c3c35 100644 --- a/plugins/channelrx/demoddsd/dsddemod.cpp +++ b/plugins/channelrx/demoddsd/dsddemod.cpp @@ -112,8 +112,9 @@ void DSDDemod::configureMyPosition(MessageQueue* messageQueue, float myLatitude, messageQueue->push(cmd); } -void DSDDemod::feed(const SampleVector::const_iterator& begin, const SampleVector::const_iterator& end, bool firstOfBurst __attribute__((unused))) +void DSDDemod::feed(const SampleVector::const_iterator& begin, const SampleVector::const_iterator& end, bool firstOfBurst) { + (void) firstOfBurst; Complex ci; int samplesPerSymbol = m_dsdDecoder.getSamplesPerSymbol(); @@ -767,8 +768,9 @@ void DSDDemod::formatStatusText() int DSDDemod::webapiSettingsGet( SWGSDRangel::SWGChannelSettings& response, - QString& errorMessage __attribute__((unused))) + QString& errorMessage) { + (void) errorMessage; response.setDsdDemodSettings(new SWGSDRangel::SWGDSDDemodSettings()); response.getDsdDemodSettings()->init(); webapiFormatChannelSettings(response, m_settings); @@ -779,8 +781,9 @@ int DSDDemod::webapiSettingsPutPatch( bool force, const QStringList& channelSettingsKeys, SWGSDRangel::SWGChannelSettings& response, - QString& errorMessage __attribute__((unused))) + QString& errorMessage) { + (void) errorMessage; DSDDemodSettings settings = m_settings; bool frequencyOffsetChanged = false; @@ -877,8 +880,9 @@ int DSDDemod::webapiSettingsPutPatch( int DSDDemod::webapiReportGet( SWGSDRangel::SWGChannelReport& response, - QString& errorMessage __attribute__((unused))) + QString& errorMessage) { + (void) errorMessage; response.setDsdDemodReport(new SWGSDRangel::SWGDSDDemodReport()); response.getDsdDemodReport()->init(); webapiFormatChannelReport(response); diff --git a/plugins/channelrx/demoddsd/dsddemodgui.cpp b/plugins/channelrx/demoddsd/dsddemodgui.cpp index 514a3e333..b8dbf0429 100644 --- a/plugins/channelrx/demoddsd/dsddemodgui.cpp +++ b/plugins/channelrx/demoddsd/dsddemodgui.cpp @@ -264,8 +264,10 @@ void DSDDemodGUI::on_symbolPLLLock_toggled(bool checked) applySettings(); } -void DSDDemodGUI::onWidgetRolled(QWidget* widget __attribute__((unused)), bool rollDown __attribute__((unused))) +void DSDDemodGUI::onWidgetRolled(QWidget* widget, bool rollDown) { + (void) widget; + (void) rollDown; } void DSDDemodGUI::onMenuDialogCalled(const QPoint &p) diff --git a/plugins/channelrx/demoddsd/dsddemodplugin.cpp b/plugins/channelrx/demoddsd/dsddemodplugin.cpp index 0d14131da..4f8835841 100644 --- a/plugins/channelrx/demoddsd/dsddemodplugin.cpp +++ b/plugins/channelrx/demoddsd/dsddemodplugin.cpp @@ -27,7 +27,7 @@ const PluginDescriptor DSDDemodPlugin::m_pluginDescriptor = { QString("DSD Demodulator"), - QString("4.2.4"), + QString("4.3.1"), QString("(c) Edouard Griffiths, F4EXB"), QString("https://github.com/f4exb/sdrangel"), true, diff --git a/plugins/channelrx/demodlora/CMakeLists.txt b/plugins/channelrx/demodlora/CMakeLists.txt index a2ced900c..f5d743996 100644 --- a/plugins/channelrx/demodlora/CMakeLists.txt +++ b/plugins/channelrx/demodlora/CMakeLists.txt @@ -1,5 +1,7 @@ project(lora) +set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++11") + set(lora_SOURCES lorademod.cpp lorademodgui.cpp diff --git a/plugins/channelrx/demodlora/lorademod.cpp b/plugins/channelrx/demodlora/lorademod.cpp index 87d9882b3..831997bdd 100644 --- a/plugins/channelrx/demodlora/lorademod.cpp +++ b/plugins/channelrx/demodlora/lorademod.cpp @@ -251,8 +251,9 @@ int LoRaDemod::detect(Complex c, Complex a) return m_result; } -void LoRaDemod::feed(const SampleVector::const_iterator& begin, const SampleVector::const_iterator& end, bool pO __attribute__((unused))) +void LoRaDemod::feed(const SampleVector::const_iterator& begin, const SampleVector::const_iterator& end, bool pO) { + (void) pO; int newangle; Complex ci; diff --git a/plugins/channelrx/demodlora/lorademodgui.cpp b/plugins/channelrx/demodlora/lorademodgui.cpp index f70abc72c..ceb5da5b4 100644 --- a/plugins/channelrx/demodlora/lorademodgui.cpp +++ b/plugins/channelrx/demodlora/lorademodgui.cpp @@ -70,8 +70,9 @@ bool LoRaDemodGUI::deserialize(const QByteArray& data) } } -bool LoRaDemodGUI::handleMessage(const Message& message __attribute__((unused))) +bool LoRaDemodGUI::handleMessage(const Message& message) { + (void) message; return false; } @@ -97,12 +98,15 @@ void LoRaDemodGUI::on_BW_valueChanged(int value) applySettings(); } -void LoRaDemodGUI::on_Spread_valueChanged(int value __attribute__((unused))) +void LoRaDemodGUI::on_Spread_valueChanged(int value) { + (void) value; } -void LoRaDemodGUI::onWidgetRolled(QWidget* widget __attribute__((unused)), bool rollDown __attribute__((unused))) +void LoRaDemodGUI::onWidgetRolled(QWidget* widget, bool rollDown) { + (void) widget; + (void) rollDown; } LoRaDemodGUI::LoRaDemodGUI(PluginAPI* pluginAPI, DeviceUISet *deviceUISet, BasebandSampleSink *rxChannel, QWidget* parent) : diff --git a/plugins/channelrx/demodnfm/nfmdemod.cpp b/plugins/channelrx/demodnfm/nfmdemod.cpp index 2002d2463..69d75bba4 100644 --- a/plugins/channelrx/demodnfm/nfmdemod.cpp +++ b/plugins/channelrx/demodnfm/nfmdemod.cpp @@ -137,8 +137,9 @@ Real angleDist(Real a, Real b) return dist; } -void NFMDemod::feed(const SampleVector::const_iterator& begin, const SampleVector::const_iterator& end, bool firstOfBurst __attribute__((unused))) +void NFMDemod::feed(const SampleVector::const_iterator& begin, const SampleVector::const_iterator& end, bool firstOfBurst) { + (void) firstOfBurst; Complex ci; if (!m_running) { @@ -585,8 +586,9 @@ bool NFMDemod::deserialize(const QByteArray& data) int NFMDemod::webapiSettingsGet( SWGSDRangel::SWGChannelSettings& response, - QString& errorMessage __attribute__((unused))) + QString& errorMessage) { + (void) errorMessage; response.setNfmDemodSettings(new SWGSDRangel::SWGNFMDemodSettings()); response.getNfmDemodSettings()->init(); webapiFormatChannelSettings(response, m_settings); @@ -597,8 +599,9 @@ int NFMDemod::webapiSettingsPutPatch( bool force, const QStringList& channelSettingsKeys, SWGSDRangel::SWGChannelSettings& response, - QString& errorMessage __attribute__((unused))) + QString& errorMessage) { + (void) errorMessage; NFMDemodSettings settings = m_settings; bool frequencyOffsetChanged = false; @@ -670,8 +673,9 @@ int NFMDemod::webapiSettingsPutPatch( int NFMDemod::webapiReportGet( SWGSDRangel::SWGChannelReport& response, - QString& errorMessage __attribute__((unused))) + QString& errorMessage) { + (void) errorMessage; response.setNfmDemodReport(new SWGSDRangel::SWGNFMDemodReport()); response.getNfmDemodReport()->init(); webapiFormatChannelReport(response); diff --git a/plugins/channelrx/demodnfm/nfmdemodgui.cpp b/plugins/channelrx/demodnfm/nfmdemodgui.cpp index 98c2361d4..e3ac5afc5 100644 --- a/plugins/channelrx/demodnfm/nfmdemodgui.cpp +++ b/plugins/channelrx/demodnfm/nfmdemodgui.cpp @@ -214,8 +214,10 @@ void NFMDemodGUI::on_ctcss_currentIndexChanged(int index) applySettings(); } -void NFMDemodGUI::onWidgetRolled(QWidget* widget __attribute__((unused)), bool rollDown __attribute__((unused))) +void NFMDemodGUI::onWidgetRolled(QWidget* widget, bool rollDown) { + (void) widget; + (void) rollDown; /* if((widget == ui->spectrumContainer) && (m_nfmDemod != NULL)) m_nfmDemod->setSpectrum(m_threadedSampleSink->getMessageQueue(), rollDown); diff --git a/plugins/channelrx/demodssb/ssbdemod.cpp b/plugins/channelrx/demodssb/ssbdemod.cpp index 0b0aa6b21..311cca888 100644 --- a/plugins/channelrx/demodssb/ssbdemod.cpp +++ b/plugins/channelrx/demodssb/ssbdemod.cpp @@ -144,8 +144,9 @@ void SSBDemod::configure(MessageQueue* messageQueue, messageQueue->push(cmd); } -void SSBDemod::feed(const SampleVector::const_iterator& begin, const SampleVector::const_iterator& end, bool positiveOnly __attribute__((unused))) +void SSBDemod::feed(const SampleVector::const_iterator& begin, const SampleVector::const_iterator& end, bool positiveOnly) { + (void) positiveOnly; Complex ci; fftfilt::cmplx *sideband; int n_out; @@ -585,8 +586,9 @@ bool SSBDemod::deserialize(const QByteArray& data) int SSBDemod::webapiSettingsGet( SWGSDRangel::SWGChannelSettings& response, - QString& errorMessage __attribute__((unused))) + QString& errorMessage) { + (void) errorMessage; response.setSsbDemodSettings(new SWGSDRangel::SWGSSBDemodSettings()); response.getSsbDemodSettings()->init(); webapiFormatChannelSettings(response, m_settings); @@ -597,8 +599,9 @@ int SSBDemod::webapiSettingsPutPatch( bool force, const QStringList& channelSettingsKeys, SWGSDRangel::SWGChannelSettings& response, - QString& errorMessage __attribute__((unused))) + QString& errorMessage) { + (void) errorMessage; SSBDemodSettings settings = m_settings; bool frequencyOffsetChanged = false; @@ -680,8 +683,9 @@ int SSBDemod::webapiSettingsPutPatch( int SSBDemod::webapiReportGet( SWGSDRangel::SWGChannelReport& response, - QString& errorMessage __attribute__((unused))) + QString& errorMessage) { + (void) errorMessage; response.setSsbDemodReport(new SWGSDRangel::SWGSSBDemodReport()); response.getSsbDemodReport()->init(); webapiFormatChannelReport(response); diff --git a/plugins/channelrx/demodssb/ssbdemodgui.cpp b/plugins/channelrx/demodssb/ssbdemodgui.cpp index 788b1d946..d6b3e2e85 100644 --- a/plugins/channelrx/demodssb/ssbdemodgui.cpp +++ b/plugins/channelrx/demodssb/ssbdemodgui.cpp @@ -156,13 +156,15 @@ void SSBDemodGUI::on_deltaFrequency_changed(qint64 value) applySettings(); } -void SSBDemodGUI::on_BW_valueChanged(int value __attribute__((unused))) +void SSBDemodGUI::on_BW_valueChanged(int value) { + (void) value; applyBandwidths(5 - ui->spanLog2->value()); } -void SSBDemodGUI::on_lowCut_valueChanged(int value __attribute__((unused))) +void SSBDemodGUI::on_lowCut_valueChanged(int value) { + (void) value; applyBandwidths(5 - ui->spanLog2->value()); } @@ -224,8 +226,9 @@ void SSBDemodGUI::on_spanLog2_valueChanged(int value) applyBandwidths(5 - ui->spanLog2->value()); } -void SSBDemodGUI::on_flipSidebands_clicked(bool checked __attribute__((unused))) +void SSBDemodGUI::on_flipSidebands_clicked(bool checked) { + (void) checked; int bwValue = ui->BW->value(); int lcValue = ui->lowCut->value(); ui->BW->setValue(-bwValue); @@ -248,8 +251,10 @@ void SSBDemodGUI::onMenuDialogCalled(const QPoint &p) applySettings(); } -void SSBDemodGUI::onWidgetRolled(QWidget* widget __attribute__((unused)), bool rollDown __attribute__((unused))) +void SSBDemodGUI::onWidgetRolled(QWidget* widget, bool rollDown) { + (void) widget; + (void) rollDown; } SSBDemodGUI::SSBDemodGUI(PluginAPI* pluginAPI, DeviceUISet *deviceUISet, BasebandSampleSink *rxChannel, QWidget* parent) : diff --git a/plugins/channelrx/demodwfm/wfmdemod.cpp b/plugins/channelrx/demodwfm/wfmdemod.cpp index 3b1d49619..b9dbd0547 100644 --- a/plugins/channelrx/demodwfm/wfmdemod.cpp +++ b/plugins/channelrx/demodwfm/wfmdemod.cpp @@ -87,8 +87,9 @@ WFMDemod::~WFMDemod() delete m_rfFilter; } -void WFMDemod::feed(const SampleVector::const_iterator& begin, const SampleVector::const_iterator& end, bool firstOfBurst __attribute__((unused))) +void WFMDemod::feed(const SampleVector::const_iterator& begin, const SampleVector::const_iterator& end, bool firstOfBurst) { + (void) firstOfBurst; Complex ci; fftfilt::cmplx *rf; int rf_out; @@ -382,8 +383,9 @@ bool WFMDemod::deserialize(const QByteArray& data) int WFMDemod::webapiSettingsGet( SWGSDRangel::SWGChannelSettings& response, - QString& errorMessage __attribute__((unused))) + QString& errorMessage) { + (void) errorMessage; response.setWfmDemodSettings(new SWGSDRangel::SWGWFMDemodSettings()); response.getWfmDemodSettings()->init(); webapiFormatChannelSettings(response, m_settings); @@ -394,8 +396,9 @@ int WFMDemod::webapiSettingsPutPatch( bool force, const QStringList& channelSettingsKeys, SWGSDRangel::SWGChannelSettings& response, - QString& errorMessage __attribute__((unused))) + QString& errorMessage) { + (void) errorMessage; WFMDemodSettings settings = m_settings; bool frequencyOffsetChanged = false; @@ -453,8 +456,9 @@ int WFMDemod::webapiSettingsPutPatch( int WFMDemod::webapiReportGet( SWGSDRangel::SWGChannelReport& response, - QString& errorMessage __attribute__((unused))) + QString& errorMessage) { + (void) errorMessage; response.setWfmDemodReport(new SWGSDRangel::SWGWFMDemodReport()); response.getWfmDemodReport()->init(); webapiFormatChannelReport(response); diff --git a/plugins/channelrx/demodwfm/wfmdemodgui.cpp b/plugins/channelrx/demodwfm/wfmdemodgui.cpp index 77ec241dd..b6b6cfc85 100644 --- a/plugins/channelrx/demodwfm/wfmdemodgui.cpp +++ b/plugins/channelrx/demodwfm/wfmdemodgui.cpp @@ -75,8 +75,9 @@ bool WFMDemodGUI::deserialize(const QByteArray& data) } } -bool WFMDemodGUI::handleMessage(const Message& message __attribute__((unused))) +bool WFMDemodGUI::handleMessage(const Message& message) { + (void) message; if (WFMDemod::MsgConfigureWFMDemod::match(message)) { qDebug("WFMDemodGUI::handleMessage: WFMDemod::MsgConfigureWFMDemod"); @@ -159,8 +160,10 @@ void WFMDemodGUI::on_audioMute_toggled(bool checked) applySettings(); } -void WFMDemodGUI::onWidgetRolled(QWidget* widget __attribute__((unused)), bool rollDown __attribute__((unused))) +void WFMDemodGUI::onWidgetRolled(QWidget* widget, bool rollDown) { + (void) widget; + (void) rollDown; } void WFMDemodGUI::onMenuDialogCalled(const QPoint &p) diff --git a/plugins/channelrx/udpsink/udpsink.cpp b/plugins/channelrx/udpsink/udpsink.cpp index 040c054df..ba828f590 100644 --- a/plugins/channelrx/udpsink/udpsink.cpp +++ b/plugins/channelrx/udpsink/udpsink.cpp @@ -644,8 +644,9 @@ bool UDPSink::deserialize(const QByteArray& data) int UDPSink::webapiSettingsGet( SWGSDRangel::SWGChannelSettings& response, - QString& errorMessage __attribute__((unused))) + QString& errorMessage) { + (void) errorMessage; response.setUdpSinkSettings(new SWGSDRangel::SWGUDPSinkSettings()); response.getUdpSinkSettings()->init(); webapiFormatChannelSettings(response, m_settings); @@ -656,8 +657,9 @@ int UDPSink::webapiSettingsPutPatch( bool force, const QStringList& channelSettingsKeys, SWGSDRangel::SWGChannelSettings& response, - QString& errorMessage __attribute__((unused))) + QString& errorMessage) { + (void) errorMessage; UDPSinkSettings settings = m_settings; bool frequencyOffsetChanged = false; @@ -746,8 +748,9 @@ int UDPSink::webapiSettingsPutPatch( int UDPSink::webapiReportGet( SWGSDRangel::SWGChannelReport& response, - QString& errorMessage __attribute__((unused))) + QString& errorMessage) { + (void) errorMessage; response.setUdpSinkReport(new SWGSDRangel::SWGUDPSinkReport()); response.getUdpSinkReport()->init(); webapiFormatChannelReport(response); diff --git a/plugins/channelrx/udpsink/udpsinkgui.cpp b/plugins/channelrx/udpsink/udpsinkgui.cpp index eed9fcb54..c4c8a06bb 100644 --- a/plugins/channelrx/udpsink/udpsinkgui.cpp +++ b/plugins/channelrx/udpsink/udpsinkgui.cpp @@ -472,8 +472,9 @@ void UDPSinkGUI::on_inputUDPAudioPort_editingFinished() ui->applyBtn->setStyleSheet("QPushButton { background-color : green; }"); } -void UDPSinkGUI::on_sampleRate_textEdited(const QString& arg1 __attribute__((unused))) +void UDPSinkGUI::on_sampleRate_textEdited(const QString& arg1) { + (void) arg1; bool ok; Real outputSampleRate = ui->sampleRate->text().toDouble(&ok); @@ -491,8 +492,9 @@ void UDPSinkGUI::on_sampleRate_textEdited(const QString& arg1 __attribute__((unu ui->applyBtn->setStyleSheet("QPushButton { background-color : green; }"); } -void UDPSinkGUI::on_rfBandwidth_textEdited(const QString& arg1 __attribute__((unused))) +void UDPSinkGUI::on_rfBandwidth_textEdited(const QString& arg1) { + (void) arg1; bool ok; Real rfBandwidth = ui->rfBandwidth->text().toDouble(&ok); @@ -512,8 +514,9 @@ void UDPSinkGUI::on_rfBandwidth_textEdited(const QString& arg1 __attribute__((un ui->applyBtn->setStyleSheet("QPushButton { background-color : green; }"); } -void UDPSinkGUI::on_fmDeviation_textEdited(const QString& arg1 __attribute__((unused))) +void UDPSinkGUI::on_fmDeviation_textEdited(const QString& arg1) { + (void) arg1; bool ok; int fmDeviation = ui->fmDeviation->text().toInt(&ok); diff --git a/plugins/channeltx/daemonsource/daemonsource.cpp b/plugins/channeltx/daemonsource/daemonsource.cpp index d23e1e100..bf57d0283 100644 --- a/plugins/channeltx/daemonsource/daemonsource.cpp +++ b/plugins/channeltx/daemonsource/daemonsource.cpp @@ -74,8 +74,9 @@ void DaemonSource::pull(Sample& sample) m_dataReadQueue.readSample(sample, true); // true is scale for Tx } -void DaemonSource::pullAudio(int nbSamples __attribute__((unused))) +void DaemonSource::pullAudio(int nbSamples) { + (void) nbSamples; } void DaemonSource::start() @@ -174,8 +175,9 @@ QByteArray DaemonSource::serialize() const return m_settings.serialize(); } -bool DaemonSource::deserialize(const QByteArray& data __attribute__((unused))) +bool DaemonSource::deserialize(const QByteArray& data) { + (void) data; if (m_settings.deserialize(data)) { MsgConfigureDaemonSource *msg = MsgConfigureDaemonSource::create(m_settings, true); @@ -215,8 +217,9 @@ void DaemonSource::applySettings(const DaemonSourceSettings& settings, bool forc m_settings = settings; } -void DaemonSource::handleDataBlock(SDRDaemonDataBlock* dataBlock __attribute__((unused))) +void DaemonSource::handleDataBlock(SDRDaemonDataBlock* dataBlock) { + (void) dataBlock; if (dataBlock->m_rxControlBlock.m_blockCount < SDRDaemonNbOrginalBlocks) { qWarning("DaemonSource::handleDataBlock: incomplete data block: not processing"); @@ -352,8 +355,9 @@ uint32_t DaemonSource::calculateDataReadQueueSize(int sampleRate) int DaemonSource::webapiSettingsGet( SWGSDRangel::SWGChannelSettings& response, - QString& errorMessage __attribute__((unused))) + QString& errorMessage) { + (void) errorMessage; response.setDaemonSourceSettings(new SWGSDRangel::SWGDaemonSourceSettings()); response.getDaemonSourceSettings()->init(); webapiFormatChannelSettings(response, m_settings); @@ -364,8 +368,9 @@ int DaemonSource::webapiSettingsPutPatch( bool force, const QStringList& channelSettingsKeys, SWGSDRangel::SWGChannelSettings& response, - QString& errorMessage __attribute__((unused))) + QString& errorMessage) { + (void) errorMessage; DaemonSourceSettings settings = m_settings; if (channelSettingsKeys.contains("dataAddress")) { @@ -405,8 +410,9 @@ int DaemonSource::webapiSettingsPutPatch( int DaemonSource::webapiReportGet( SWGSDRangel::SWGChannelReport& response, - QString& errorMessage __attribute__((unused))) + QString& errorMessage) { + (void) errorMessage; response.setDaemonSourceReport(new SWGSDRangel::SWGDaemonSourceReport()); response.getDaemonSourceReport()->init(); webapiFormatChannelReport(response); diff --git a/plugins/channeltx/daemonsource/daemonsourcegui.cpp b/plugins/channeltx/daemonsource/daemonsourcegui.cpp index 10ba93ba5..5a95a4059 100644 --- a/plugins/channeltx/daemonsource/daemonsourcegui.cpp +++ b/plugins/channeltx/daemonsource/daemonsourcegui.cpp @@ -48,8 +48,9 @@ qint64 DaemonSourceGUI::getCenterFrequency() const { return 0; } -void DaemonSourceGUI::setCenterFrequency(qint64 centerFrequency __attribute__((unused))) +void DaemonSourceGUI::setCenterFrequency(qint64 centerFrequency) { + (void) centerFrequency; } void DaemonSourceGUI::resetToDefaults() @@ -152,7 +153,7 @@ bool DaemonSourceGUI::handleMessage(const Message& message) } } -DaemonSourceGUI::DaemonSourceGUI(PluginAPI* pluginAPI, DeviceUISet *deviceUISet, BasebandSampleSource *channelTx __attribute__((unused)), QWidget* parent) : +DaemonSourceGUI::DaemonSourceGUI(PluginAPI* pluginAPI, DeviceUISet *deviceUISet, BasebandSampleSource *channelTx, QWidget* parent) : RollupWidget(parent), ui(new Ui::DaemonSourceGUI), m_pluginAPI(pluginAPI), @@ -166,6 +167,7 @@ DaemonSourceGUI::DaemonSourceGUI(PluginAPI* pluginAPI, DeviceUISet *deviceUISet, m_resetCounts(true), m_tickCount(0) { + (void) channelTx; ui->setupUi(this); setAttribute(Qt::WA_DeleteOnClose, true); connect(this, SIGNAL(widgetRolled(QWidget*,bool)), this, SLOT(onWidgetRolled(QWidget*,bool))); @@ -262,8 +264,10 @@ void DaemonSourceGUI::handleSourceMessages() } } -void DaemonSourceGUI::onWidgetRolled(QWidget* widget __attribute__((unused)), bool rollDown __attribute__((unused))) +void DaemonSourceGUI::onWidgetRolled(QWidget* widget, bool rollDown) { + (void) widget; + (void) rollDown; } void DaemonSourceGUI::onMenuDialogCalled(const QPoint &p) @@ -304,8 +308,9 @@ void DaemonSourceGUI::on_dataPort_returnPressed() applySettings(); } -void DaemonSourceGUI::on_dataApplyButton_clicked(bool checked __attribute__((unused))) +void DaemonSourceGUI::on_dataApplyButton_clicked(bool checked) { + (void) checked; m_settings.m_dataAddress = ui->dataAddress->text(); bool dataOk; @@ -319,8 +324,9 @@ void DaemonSourceGUI::on_dataApplyButton_clicked(bool checked __attribute__((unu applySettings(); } -void DaemonSourceGUI::on_eventCountsReset_clicked(bool checked __attribute__((unused))) +void DaemonSourceGUI::on_eventCountsReset_clicked(bool checked) { + (void) checked; m_countUnrecoverable = 0; m_countRecovered = 0; m_time.start(); diff --git a/plugins/channeltx/daemonsource/daemonsourcesettings.cpp b/plugins/channeltx/daemonsource/daemonsourcesettings.cpp index e55462390..ca0dafbe5 100644 --- a/plugins/channeltx/daemonsource/daemonsourcesettings.cpp +++ b/plugins/channeltx/daemonsource/daemonsourcesettings.cpp @@ -31,6 +31,7 @@ void DaemonSourceSettings::resetToDefaults() m_dataPort = 9090; m_rgbColor = QColor(140, 4, 4).rgb(); m_title = "Daemon source"; + m_channelMarker = nullptr; } QByteArray DaemonSourceSettings::serialize() const diff --git a/plugins/channeltx/daemonsource/daemonsourcethread.h b/plugins/channeltx/daemonsource/daemonsourcethread.h index a5371bed7..690d902a0 100644 --- a/plugins/channeltx/daemonsource/daemonsourcethread.h +++ b/plugins/channeltx/daemonsource/daemonsourcethread.h @@ -83,7 +83,7 @@ public: private: QMutex m_startWaitMutex; QWaitCondition m_startWaiter; - bool m_running; + volatile bool m_running; MessageQueue m_inputMessageQueue; SDRDaemonDataQueue *m_dataQueue; diff --git a/plugins/channeltx/modam/ammod.cpp b/plugins/channeltx/modam/ammod.cpp index 6fe798e1c..8604b001b 100644 --- a/plugins/channeltx/modam/ammod.cpp +++ b/plugins/channeltx/modam/ammod.cpp @@ -513,8 +513,9 @@ bool AMMod::deserialize(const QByteArray& data) int AMMod::webapiSettingsGet( SWGSDRangel::SWGChannelSettings& response, - QString& errorMessage __attribute__((unused))) + QString& errorMessage) { + (void) errorMessage; response.setAmModSettings(new SWGSDRangel::SWGAMModSettings()); response.getAmModSettings()->init(); webapiFormatChannelSettings(response, m_settings); @@ -525,8 +526,9 @@ int AMMod::webapiSettingsPutPatch( bool force, const QStringList& channelSettingsKeys, SWGSDRangel::SWGChannelSettings& response, - QString& errorMessage __attribute__((unused))) + QString& errorMessage) { + (void) errorMessage; AMModSettings settings = m_settings; bool frequencyOffsetChanged = false; @@ -623,8 +625,9 @@ int AMMod::webapiSettingsPutPatch( int AMMod::webapiReportGet( SWGSDRangel::SWGChannelReport& response, - QString& errorMessage __attribute__((unused))) + QString& errorMessage) { + (void) errorMessage; response.setAmModReport(new SWGSDRangel::SWGAMModReport()); response.getAmModReport()->init(); webapiFormatChannelReport(response); diff --git a/plugins/channeltx/modam/ammodgui.cpp b/plugins/channeltx/modam/ammodgui.cpp index 25270da64..e3decf2bc 100644 --- a/plugins/channeltx/modam/ammodgui.cpp +++ b/plugins/channeltx/modam/ammodgui.cpp @@ -248,8 +248,9 @@ void AMModGUI::on_navTimeSlider_valueChanged(int value) } } -void AMModGUI::on_showFileDialog_clicked(bool checked __attribute__((unused))) +void AMModGUI::on_showFileDialog_clicked(bool checked) { + (void) checked; QString fileName = QFileDialog::getOpenFileName(this, tr("Open raw audio file"), ".", tr("Raw audio Files (*.raw)"), 0, QFileDialog::DontUseNativeDialog); @@ -269,8 +270,10 @@ void AMModGUI::configureFileName() m_amMod->getInputMessageQueue()->push(message); } -void AMModGUI::onWidgetRolled(QWidget* widget __attribute__((unused)), bool rollDown __attribute__((unused))) +void AMModGUI::onWidgetRolled(QWidget* widget, bool rollDown) { + (void) widget; + (void) rollDown; } void AMModGUI::onMenuDialogCalled(const QPoint &p) @@ -363,8 +366,9 @@ void AMModGUI::blockApplySettings(bool block) m_doApplySettings = !block; } -void AMModGUI::applySettings(bool force __attribute((unused))) +void AMModGUI::applySettings(bool force) { + (void) force; if (m_doApplySettings) { setTitleColor(m_channelMarker.getColor()); diff --git a/plugins/channeltx/modatv/atvmod.cpp b/plugins/channeltx/modatv/atvmod.cpp index 6c98853dd..bce87b3f6 100644 --- a/plugins/channeltx/modatv/atvmod.cpp +++ b/plugins/channeltx/modatv/atvmod.cpp @@ -116,8 +116,9 @@ ATVMod::~ATVMod() delete[] m_DSBFilterBuffer; } -void ATVMod::pullAudio(int nbSamples __attribute__((unused))) +void ATVMod::pullAudio(int nbSamples) { + (void) nbSamples; } void ATVMod::pull(Sample& sample) @@ -1185,8 +1186,9 @@ bool ATVMod::deserialize(const QByteArray& data) int ATVMod::webapiSettingsGet( SWGSDRangel::SWGChannelSettings& response, - QString& errorMessage __attribute__((unused))) + QString& errorMessage) { + (void) errorMessage; response.setAtvModSettings(new SWGSDRangel::SWGATVModSettings()); response.getAtvModSettings()->init(); webapiFormatChannelSettings(response, m_settings); @@ -1197,8 +1199,9 @@ int ATVMod::webapiSettingsPutPatch( bool force, const QStringList& channelSettingsKeys, SWGSDRangel::SWGChannelSettings& response, - QString& errorMessage __attribute__((unused))) + QString& errorMessage) { + (void) errorMessage; ATVModSettings settings = m_settings; bool frequencyOffsetChanged = false; @@ -1319,8 +1322,9 @@ int ATVMod::webapiSettingsPutPatch( int ATVMod::webapiReportGet( SWGSDRangel::SWGChannelReport& response, - QString& errorMessage __attribute__((unused))) + QString& errorMessage) { + (void) errorMessage; response.setAtvModReport(new SWGSDRangel::SWGATVModReport()); response.getAtvModReport()->init(); webapiFormatChannelReport(response); diff --git a/plugins/channeltx/modatv/atvmodgui.cpp b/plugins/channeltx/modatv/atvmodgui.cpp index 1059423a1..be40013e2 100644 --- a/plugins/channeltx/modatv/atvmodgui.cpp +++ b/plugins/channeltx/modatv/atvmodgui.cpp @@ -444,14 +444,16 @@ void ATVModGUI::setChannelMarkerBandwidth() } } -void ATVModGUI::on_nbLines_currentIndexChanged(int index __attribute__((unused))) +void ATVModGUI::on_nbLines_currentIndexChanged(int index) { + (void) index; m_settings.m_nbLines = getNbLines(); applySettings(); } -void ATVModGUI::on_fps_currentIndexChanged(int index __attribute__((unused))) +void ATVModGUI::on_fps_currentIndexChanged(int index) { + (void) index; m_settings.m_fps = getFPS(); applySettings(); } @@ -494,8 +496,9 @@ void ATVModGUI::on_forceDecimator_toggled(bool checked) applySettings(); } -void ATVModGUI::on_imageFileDialog_clicked(bool checked __attribute__((unused))) +void ATVModGUI::on_imageFileDialog_clicked(bool checked) { + (void) checked; QString fileName = QFileDialog::getOpenFileName(this, tr("Open image file"), ".", tr("Image Files (*.png *.jpg *.bmp *.gif *.tiff)"), 0, QFileDialog::DontUseNativeDialog); @@ -507,8 +510,9 @@ void ATVModGUI::on_imageFileDialog_clicked(bool checked __attribute__((unused))) } } -void ATVModGUI::on_videoFileDialog_clicked(bool checked __attribute__((unused))) +void ATVModGUI::on_videoFileDialog_clicked(bool checked) { + (void) checked; QString fileName = QFileDialog::getOpenFileName(this, tr("Open video file"), ".", tr("Video Files (*.avi *.mpg *.mp4 *.mov *.m4v *.mkv *.vob *.wmv)"), 0, QFileDialog::DontUseNativeDialog); @@ -580,8 +584,9 @@ void ATVModGUI::on_overlayTextShow_toggled(bool checked) applySettings(); } -void ATVModGUI::on_overlayText_textEdited(const QString& arg1 __attribute__((unused))) +void ATVModGUI::on_overlayText_textEdited(const QString& arg1) { + (void) arg1; m_settings.m_overlayText = arg1; applySettings(); } @@ -600,8 +605,10 @@ void ATVModGUI::configureVideoFileName() m_atvMod->getInputMessageQueue()->push(message); } -void ATVModGUI::onWidgetRolled(QWidget* widget __attribute__((unused)), bool rollDown __attribute__((unused))) +void ATVModGUI::onWidgetRolled(QWidget* widget, bool rollDown) { + (void) widget; + (void) rollDown; } void ATVModGUI::onMenuDialogCalled(const QPoint &p) diff --git a/plugins/channeltx/modnfm/nfmmod.cpp b/plugins/channeltx/modnfm/nfmmod.cpp index 894d4ffb5..f51e91276 100644 --- a/plugins/channeltx/modnfm/nfmmod.cpp +++ b/plugins/channeltx/modnfm/nfmmod.cpp @@ -553,8 +553,9 @@ bool NFMMod::deserialize(const QByteArray& data) int NFMMod::webapiSettingsGet( SWGSDRangel::SWGChannelSettings& response, - QString& errorMessage __attribute__((unused))) + QString& errorMessage) { + (void) errorMessage; response.setNfmModSettings(new SWGSDRangel::SWGNFMModSettings()); response.getNfmModSettings()->init(); webapiFormatChannelSettings(response, m_settings); @@ -565,8 +566,9 @@ int NFMMod::webapiSettingsPutPatch( bool force, const QStringList& channelSettingsKeys, SWGSDRangel::SWGChannelSettings& response, - QString& errorMessage __attribute__((unused))) + QString& errorMessage) { + (void) errorMessage; NFMModSettings settings = m_settings; bool frequencyOffsetChanged = false; @@ -673,8 +675,9 @@ int NFMMod::webapiSettingsPutPatch( int NFMMod::webapiReportGet( SWGSDRangel::SWGChannelReport& response, - QString& errorMessage __attribute__((unused))) + QString& errorMessage) { + (void) errorMessage; response.setNfmModReport(new SWGSDRangel::SWGNFMModReport()); response.getNfmModReport()->init(); webapiFormatChannelReport(response); diff --git a/plugins/channeltx/modnfm/nfmmodgui.cpp b/plugins/channeltx/modnfm/nfmmodgui.cpp index 6db1738a8..9d7ec0262 100644 --- a/plugins/channeltx/modnfm/nfmmodgui.cpp +++ b/plugins/channeltx/modnfm/nfmmodgui.cpp @@ -252,8 +252,9 @@ void NFMModGUI::on_navTimeSlider_valueChanged(int value) } } -void NFMModGUI::on_showFileDialog_clicked(bool checked __attribute__((unused))) +void NFMModGUI::on_showFileDialog_clicked(bool checked) { + (void) checked; QString fileName = QFileDialog::getOpenFileName(this, tr("Open raw audio file"), ".", tr("Raw audio Files (*.raw)"), 0, QFileDialog::DontUseNativeDialog); @@ -286,8 +287,10 @@ void NFMModGUI::configureFileName() m_nfmMod->getInputMessageQueue()->push(message); } -void NFMModGUI::onWidgetRolled(QWidget* widget __attribute__((unused)), bool rollDown __attribute__((unused))) +void NFMModGUI::onWidgetRolled(QWidget* widget, bool rollDown) { + (void) widget; + (void) rollDown; } void NFMModGUI::onMenuDialogCalled(const QPoint &p) diff --git a/plugins/channeltx/modssb/ssbmod.cpp b/plugins/channeltx/modssb/ssbmod.cpp index 2efda0df5..b8fcbb357 100644 --- a/plugins/channeltx/modssb/ssbmod.cpp +++ b/plugins/channeltx/modssb/ssbmod.cpp @@ -872,8 +872,9 @@ bool SSBMod::deserialize(const QByteArray& data) int SSBMod::webapiSettingsGet( SWGSDRangel::SWGChannelSettings& response, - QString& errorMessage __attribute__((unused))) + QString& errorMessage) { + (void) errorMessage; response.setSsbModSettings(new SWGSDRangel::SWGSSBModSettings()); response.getSsbModSettings()->init(); webapiFormatChannelSettings(response, m_settings); @@ -884,8 +885,9 @@ int SSBMod::webapiSettingsPutPatch( bool force, const QStringList& channelSettingsKeys, SWGSDRangel::SWGChannelSettings& response, - QString& errorMessage __attribute__((unused))) + QString& errorMessage) { + (void) errorMessage; SSBModSettings settings = m_settings; bool frequencyOffsetChanged = false; @@ -1018,8 +1020,9 @@ int SSBMod::webapiSettingsPutPatch( int SSBMod::webapiReportGet( SWGSDRangel::SWGChannelReport& response, - QString& errorMessage __attribute__((unused))) + QString& errorMessage) { + (void) errorMessage; response.setSsbModReport(new SWGSDRangel::SWGSSBModReport()); response.getSsbModReport()->init(); webapiFormatChannelReport(response); diff --git a/plugins/channeltx/modssb/ssbmodgui.cpp b/plugins/channeltx/modssb/ssbmodgui.cpp index b15818d42..85d13da29 100644 --- a/plugins/channeltx/modssb/ssbmodgui.cpp +++ b/plugins/channeltx/modssb/ssbmodgui.cpp @@ -173,8 +173,9 @@ void SSBModGUI::on_deltaFrequency_changed(qint64 value) applySettings(); } -void SSBModGUI::on_flipSidebands_clicked(bool checked __attribute__((unused))) +void SSBModGUI::on_flipSidebands_clicked(bool checked) { + (void) checked; int bwValue = ui->BW->value(); int lcValue = ui->lowCut->value(); ui->BW->setValue(-bwValue); @@ -208,13 +209,15 @@ void SSBModGUI::on_spanLog2_valueChanged(int value) applyBandwidths(5 - value); } -void SSBModGUI::on_BW_valueChanged(int value __attribute__((unused))) +void SSBModGUI::on_BW_valueChanged(int value) { + (void) value; applyBandwidths(5 - ui->spanLog2->value()); } -void SSBModGUI::on_lowCut_valueChanged(int value __attribute__((unused))) +void SSBModGUI::on_lowCut_valueChanged(int value) { + (void) value; applyBandwidths(5 - ui->spanLog2->value()); } @@ -338,8 +341,9 @@ void SSBModGUI::on_navTimeSlider_valueChanged(int value) } } -void SSBModGUI::on_showFileDialog_clicked(bool checked __attribute__((unused))) +void SSBModGUI::on_showFileDialog_clicked(bool checked) { + (void) checked; QString fileName = QFileDialog::getOpenFileName(this, tr("Open raw audio file"), ".", tr("Raw audio Files (*.raw)"), 0, QFileDialog::DontUseNativeDialog); @@ -359,8 +363,10 @@ void SSBModGUI::configureFileName() m_ssbMod->getInputMessageQueue()->push(message); } -void SSBModGUI::onWidgetRolled(QWidget* widget __attribute__((unused)), bool rollDown __attribute__((unused))) +void SSBModGUI::onWidgetRolled(QWidget* widget, bool rollDown) { + (void) widget; + (void) rollDown; } void SSBModGUI::onMenuDialogCalled(const QPoint &p) diff --git a/plugins/channeltx/modwfm/wfmmod.cpp b/plugins/channeltx/modwfm/wfmmod.cpp index 916781f0d..dcf34a040 100644 --- a/plugins/channeltx/modwfm/wfmmod.cpp +++ b/plugins/channeltx/modwfm/wfmmod.cpp @@ -546,8 +546,9 @@ bool WFMMod::deserialize(const QByteArray& data) int WFMMod::webapiSettingsGet( SWGSDRangel::SWGChannelSettings& response, - QString& errorMessage __attribute__((unused))) + QString& errorMessage) { + (void) errorMessage; response.setWfmModSettings(new SWGSDRangel::SWGWFMModSettings()); response.getWfmModSettings()->init(); webapiFormatChannelSettings(response, m_settings); @@ -558,8 +559,9 @@ int WFMMod::webapiSettingsPutPatch( bool force, const QStringList& channelSettingsKeys, SWGSDRangel::SWGChannelSettings& response, - QString& errorMessage __attribute__((unused))) + QString& errorMessage) { + (void) errorMessage; WFMModSettings settings = m_settings; bool channelizerChange = false; @@ -657,8 +659,9 @@ int WFMMod::webapiSettingsPutPatch( int WFMMod::webapiReportGet( SWGSDRangel::SWGChannelReport& response, - QString& errorMessage __attribute__((unused))) + QString& errorMessage) { + (void) errorMessage; response.setWfmModReport(new SWGSDRangel::SWGWFMModReport()); response.getWfmModReport()->init(); webapiFormatChannelReport(response); diff --git a/plugins/channeltx/modwfm/wfmmodgui.cpp b/plugins/channeltx/modwfm/wfmmodgui.cpp index b5cf6d6c2..eeef938ef 100644 --- a/plugins/channeltx/modwfm/wfmmodgui.cpp +++ b/plugins/channeltx/modwfm/wfmmodgui.cpp @@ -254,8 +254,9 @@ void WFMModGUI::on_navTimeSlider_valueChanged(int value) } } -void WFMModGUI::on_showFileDialog_clicked(bool checked __attribute__((unused))) +void WFMModGUI::on_showFileDialog_clicked(bool checked) { + (void) checked; QString fileName = QFileDialog::getOpenFileName(this, tr("Open raw audio file"), ".", tr("Raw audio Files (*.raw)"), 0, QFileDialog::DontUseNativeDialog); @@ -275,8 +276,10 @@ void WFMModGUI::configureFileName() m_wfmMod->getInputMessageQueue()->push(message); } -void WFMModGUI::onWidgetRolled(QWidget* widget __attribute__((unused)), bool rollDown __attribute__((unused))) +void WFMModGUI::onWidgetRolled(QWidget* widget, bool rollDown) { + (void) widget; + (void) rollDown; } void WFMModGUI::onMenuDialogCalled(const QPoint &p) diff --git a/plugins/channeltx/udpsource/udpsource.cpp b/plugins/channeltx/udpsource/udpsource.cpp index 38b25e946..809919927 100644 --- a/plugins/channeltx/udpsource/udpsource.cpp +++ b/plugins/channeltx/udpsource/udpsource.cpp @@ -599,8 +599,9 @@ bool UDPSource::deserialize(const QByteArray& data) int UDPSource::webapiSettingsGet( SWGSDRangel::SWGChannelSettings& response, - QString& errorMessage __attribute__((unused))) + QString& errorMessage) { + (void) errorMessage; response.setUdpSourceSettings(new SWGSDRangel::SWGUDPSourceSettings()); response.getUdpSourceSettings()->init(); webapiFormatChannelSettings(response, m_settings); @@ -611,8 +612,9 @@ int UDPSource::webapiSettingsPutPatch( bool force, const QStringList& channelSettingsKeys, SWGSDRangel::SWGChannelSettings& response, - QString& errorMessage __attribute__((unused))) + QString& errorMessage) { + (void) errorMessage; UDPSourceSettings settings = m_settings; bool frequencyOffsetChanged = false; @@ -700,8 +702,9 @@ int UDPSource::webapiSettingsPutPatch( int UDPSource::webapiReportGet( SWGSDRangel::SWGChannelReport& response, - QString& errorMessage __attribute__((unused))) + QString& errorMessage) { + (void) errorMessage; response.setUdpSourceReport(new SWGSDRangel::SWGUDPSourceReport()); response.getUdpSourceReport()->init(); webapiFormatChannelReport(response); diff --git a/plugins/channeltx/udpsource/udpsourcegui.cpp b/plugins/channeltx/udpsource/udpsourcegui.cpp index fefa33893..08ad2942a 100644 --- a/plugins/channeltx/udpsource/udpsourcegui.cpp +++ b/plugins/channeltx/udpsource/udpsourcegui.cpp @@ -316,8 +316,9 @@ void UDPSourceGUI::on_localUDPPort_editingFinished() ui->applyBtn->setStyleSheet("QPushButton { background-color : green; }"); } -void UDPSourceGUI::on_sampleRate_textEdited(const QString& arg1 __attribute__((unused))) +void UDPSourceGUI::on_sampleRate_textEdited(const QString& arg1) { + (void) arg1; bool ok; Real inputSampleRate = ui->sampleRate->text().toDouble(&ok); @@ -332,8 +333,9 @@ void UDPSourceGUI::on_sampleRate_textEdited(const QString& arg1 __attribute__((u ui->applyBtn->setStyleSheet("QPushButton { background-color : green; }"); } -void UDPSourceGUI::on_rfBandwidth_textEdited(const QString& arg1 __attribute__((unused))) +void UDPSourceGUI::on_rfBandwidth_textEdited(const QString& arg1) { + (void) arg1; bool ok; Real rfBandwidth = ui->rfBandwidth->text().toDouble(&ok); @@ -353,8 +355,9 @@ void UDPSourceGUI::on_rfBandwidth_textEdited(const QString& arg1 __attribute__(( ui->applyBtn->setStyleSheet("QPushButton { background-color : green; }"); } -void UDPSourceGUI::on_fmDeviation_textEdited(const QString& arg1 __attribute__((unused))) +void UDPSourceGUI::on_fmDeviation_textEdited(const QString& arg1) { + (void) arg1; bool ok; int fmDeviation = ui->fmDeviation->text().toInt(&ok); @@ -369,8 +372,9 @@ void UDPSourceGUI::on_fmDeviation_textEdited(const QString& arg1 __attribute__(( ui->applyBtn->setStyleSheet("QPushButton { background-color : green; }"); } -void UDPSourceGUI::on_amModPercent_textEdited(const QString& arg1 __attribute__((unused))) +void UDPSourceGUI::on_amModPercent_textEdited(const QString& arg1) { + (void) arg1; bool ok; int amModPercent = ui->amModPercent->text().toInt(&ok); diff --git a/plugins/samplesink/bladerf1output/bladerf1output.cpp b/plugins/samplesink/bladerf1output/bladerf1output.cpp index 75d15f593..9255cf3c3 100644 --- a/plugins/samplesink/bladerf1output/bladerf1output.cpp +++ b/plugins/samplesink/bladerf1output/bladerf1output.cpp @@ -321,7 +321,7 @@ bool Bladerf1Output::applySettings(const BladeRF1OutputSettings& settings, bool } else { - fifoSize = std::max( + fifoSize = (std::max)( (int) ((settings.m_devSampleRate/(1<init(); webapiFormatDeviceSettings(response, m_settings); @@ -560,8 +561,9 @@ int Bladerf1Output::webapiSettingsPutPatch( bool force, const QStringList& deviceSettingsKeys, SWGSDRangel::SWGDeviceSettings& response, // query + response - QString& errorMessage __attribute__((unused))) + QString& errorMessage) { + (void) errorMessage; BladeRF1OutputSettings settings = m_settings; if (deviceSettingsKeys.contains("centerFrequency")) { @@ -607,8 +609,9 @@ int Bladerf1Output::webapiSettingsPutPatch( int Bladerf1Output::webapiRunGet( SWGSDRangel::SWGDeviceState& response, - QString& errorMessage __attribute__((unused))) + QString& errorMessage) { + (void) errorMessage; m_deviceAPI->getDeviceEngineStateStr(*response.getState()); return 200; } @@ -616,8 +619,9 @@ int Bladerf1Output::webapiRunGet( int Bladerf1Output::webapiRun( bool run, SWGSDRangel::SWGDeviceState& response, - QString& errorMessage __attribute__((unused))) + QString& errorMessage) { + (void) errorMessage; m_deviceAPI->getDeviceEngineStateStr(*response.getState()); MsgStartStop *message = MsgStartStop::create(run); m_inputMessageQueue.push(message); diff --git a/plugins/samplesink/bladerf1output/bladerf1output.pro b/plugins/samplesink/bladerf1output/bladerf1output.pro index 325942932..a777d371e 100644 --- a/plugins/samplesink/bladerf1output/bladerf1output.pro +++ b/plugins/samplesink/bladerf1output/bladerf1output.pro @@ -25,7 +25,15 @@ INCLUDEPATH += ../../../sdrbase INCLUDEPATH += ../../../sdrgui INCLUDEPATH += ../../../swagger/sdrangel/code/qt5/client INCLUDEPATH += ../../../devices -INCLUDEPATH += $$LIBBLADERF/include + +MINGW32 || MINGW64 { + LIBBLADERF = "C:\Programs\bladeRF" + INCLUDEPATH += $$LIBBLADERF/include +} + +MSVC { + INCLUDEPATH += "C:\Program Files\PothosSDR\include" +} CONFIG(Release):build_subdir = release CONFIG(Debug):build_subdir = debug @@ -47,7 +55,14 @@ FORMS += bladerf1outputgui.ui LIBS += -L../../../sdrbase/$${build_subdir} -lsdrbase LIBS += -L../../../sdrgui/$${build_subdir} -lsdrgui LIBS += -L../../../swagger/$${build_subdir} -lswagger -LIBS += -L$$LIBBLADERF/lib -lbladeRF LIBS += -L../../../devices/$${build_subdir} -ldevices +MINGW32 || MINGW64 { + LIBS += -L$$LIBBLADERF/lib -lbladeRF +} + +MSVC { + LIBS += -L"C:\Program Files\PothosSDR\lib" -L"C:\Program Files\PothosSDR\bin" -lbladeRF +} + RESOURCES = ../../../sdrgui/resources/res.qrc diff --git a/plugins/samplesink/bladerf1output/bladerf1outputgui.cpp b/plugins/samplesink/bladerf1output/bladerf1outputgui.cpp index 76562676f..d94afe77d 100644 --- a/plugins/samplesink/bladerf1output/bladerf1outputgui.cpp +++ b/plugins/samplesink/bladerf1output/bladerf1outputgui.cpp @@ -395,14 +395,10 @@ unsigned int Bladerf1OutputGui::getXb200Index(bool xb_200, bladerf_xb200_path xb { return 6; } - else if (xb200Filter == BLADERF_XB200_222M) + else // xb200Filter == BLADERF_XB200_222M { return 7; } - else - { - return 0; - } } } else diff --git a/plugins/samplesink/bladerf1output/readme.md b/plugins/samplesink/bladerf1output/readme.md index fde65d313..371adebe5 100644 --- a/plugins/samplesink/bladerf1output/readme.md +++ b/plugins/samplesink/bladerf1output/readme.md @@ -6,6 +6,22 @@ This output sample sink plugin sends its samples to a [BladeRF1 device](https:// Warning to Windows users: concurrent use of Rx and Tx does not work correctly hence full duplex is not fully operational. For best results use BladeRF as a half duplex device like HackRF i.e. do not run Tx and Rx concurrently. Anyway from version 4.2.0 using LibbladeRF v.2 this is available in Linux distributions only. +SoapySDR devices appear in the list of available devices in the order they are listed by the API call to SoapySDR. If more than one device controlled by SoapySDR is listed then its sequence number is incremented like: + +
+SoapySDR[0:0] Generic RTL...
+SoapySDR[1:0] Generic RTL... +
+ +If the same device exposes several channels they appear as distinct devices with the channel number incremented like: + +
+SoapySDR[1:0] LimeSDR...
+SoapySDR[1:1] LimeSDR... +
+ +This works similarly to LimeSDR USB or BladeRF 2.0 micro +

Build

The plugin will be built only if the [BladeRF host library](https://github.com/Nuand/bladeRF) is installed in your system. If you build it from source and install it in a custom location say: `/opt/install/libbladeRF` you will have to add `-DLIBBLADERF_INCLUDE_DIR=/opt/install/libbladeRF/include -DLIBBLADERF_LIBRARIES=/opt/install/libbladeRF/lib/libbladeRF.so` to the cmake command line. diff --git a/plugins/samplesink/bladerf2output/bladerf2output.cpp b/plugins/samplesink/bladerf2output/bladerf2output.cpp index 8ebec2a37..caea1d0a5 100644 --- a/plugins/samplesink/bladerf2output/bladerf2output.cpp +++ b/plugins/samplesink/bladerf2output/bladerf2output.cpp @@ -303,6 +303,10 @@ bool BladeRF2Output::start() m_deviceShared.m_dev->closeTx(i); } + // was used as temporary storage: + delete[] fifos; + delete[] log2Interps; + needsStart = true; } else @@ -450,6 +454,10 @@ void BladeRF2Output::stop() bladeRF2OutputThread->startWork(); } + + // was used as temporary storage: + delete[] fifos; + delete[] log2Interps; } else // remove channel from existing thread { @@ -707,7 +715,7 @@ bool BladeRF2Output::applySettings(const BladeRF2OutputSettings& settings, bool } else { - fifoSize = std::max( + fifoSize = (std::max)( (int) ((settings.m_devSampleRate/(1<init(); webapiFormatDeviceSettings(response, m_settings); @@ -912,8 +921,9 @@ int BladeRF2Output::webapiSettingsPutPatch( bool force, const QStringList& deviceSettingsKeys, SWGSDRangel::SWGDeviceSettings& response, // query + response - QString& errorMessage __attribute__((unused))) + QString& errorMessage) { + (void) errorMessage; BladeRF2OutputSettings settings = m_settings; if (deviceSettingsKeys.contains("centerFrequency")) { @@ -957,8 +967,9 @@ int BladeRF2Output::webapiSettingsPutPatch( return 200; } -int BladeRF2Output::webapiReportGet(SWGSDRangel::SWGDeviceReport& response, QString& errorMessage __attribute__((unused))) +int BladeRF2Output::webapiReportGet(SWGSDRangel::SWGDeviceReport& response, QString& errorMessage) { + (void) errorMessage; response.setBladeRf2OutputReport(new SWGSDRangel::SWGBladeRF2OutputReport()); response.getBladeRf2OutputReport()->init(); webapiFormatDeviceReport(response); @@ -1019,8 +1030,9 @@ void BladeRF2Output::webapiFormatDeviceReport(SWGSDRangel::SWGDeviceReport& resp int BladeRF2Output::webapiRunGet( SWGSDRangel::SWGDeviceState& response, - QString& errorMessage __attribute__((unused))) + QString& errorMessage) { + (void) errorMessage; m_deviceAPI->getDeviceEngineStateStr(*response.getState()); return 200; } @@ -1028,8 +1040,9 @@ int BladeRF2Output::webapiRunGet( int BladeRF2Output::webapiRun( bool run, SWGSDRangel::SWGDeviceState& response, - QString& errorMessage __attribute__((unused))) + QString& errorMessage) { + (void) errorMessage; m_deviceAPI->getDeviceEngineStateStr(*response.getState()); MsgStartStop *message = MsgStartStop::create(run); m_inputMessageQueue.push(message); diff --git a/plugins/samplesink/bladerf2output/bladerf2output.pro b/plugins/samplesink/bladerf2output/bladerf2output.pro index 8844d2926..74f0859a2 100644 --- a/plugins/samplesink/bladerf2output/bladerf2output.pro +++ b/plugins/samplesink/bladerf2output/bladerf2output.pro @@ -17,15 +17,21 @@ DEFINES += USE_SSE4_1=1 QMAKE_CXXFLAGS += -msse4.1 QMAKE_CXXFLAGS += -std=c++11 -CONFIG(MINGW32):LIBBLADERF = "C:\Programs\bladeRF" -CONFIG(MINGW64):LIBBLADERF = "C:\Programs\bladeRF" INCLUDEPATH += $$PWD INCLUDEPATH += ../../../exports INCLUDEPATH += ../../../sdrbase INCLUDEPATH += ../../../sdrgui INCLUDEPATH += ../../../swagger/sdrangel/code/qt5/client INCLUDEPATH += ../../../devices -INCLUDEPATH += $$LIBBLADERF/include + +MINGW32 || MINGW64 { + LIBBLADERF = "C:\Programs\bladeRF" + INCLUDEPATH += $$LIBBLADERF/include +} + +MSVC { + INCLUDEPATH += "C:\Program Files\PothosSDR\include" +} CONFIG(Release):build_subdir = release CONFIG(Debug):build_subdir = debug @@ -47,7 +53,14 @@ FORMS += bladerf2outputgui.ui LIBS += -L../../../sdrbase/$${build_subdir} -lsdrbase LIBS += -L../../../sdrgui/$${build_subdir} -lsdrgui LIBS += -L../../../swagger/$${build_subdir} -lswagger -LIBS += -L$$LIBBLADERF/lib -lbladeRF LIBS += -L../../../devices/$${build_subdir} -ldevices +MINGW32 || MINGW64 { + LIBS += -L$$LIBBLADERF/lib -lbladeRF +} + +MSVC { + LIBS += -L"C:\Program Files\PothosSDR\lib" -L"C:\Program Files\PothosSDR\bin" -lbladeRF +} + RESOURCES = ../../../sdrgui/resources/res.qrc diff --git a/plugins/samplesink/filesink/filesinkgui.cpp b/plugins/samplesink/filesink/filesinkgui.cpp index c05d525c0..9e2327276 100644 --- a/plugins/samplesink/filesink/filesinkgui.cpp +++ b/plugins/samplesink/filesink/filesinkgui.cpp @@ -284,8 +284,9 @@ void FileSinkGui::on_startStop_toggled(bool checked) } } -void FileSinkGui::on_showFileDialog_clicked(bool checked __attribute__((unused))) +void FileSinkGui::on_showFileDialog_clicked(bool checked) { + (void) checked; QString fileName = QFileDialog::getSaveFileName(this, tr("Save I/Q record file"), ".", tr("SDR I/Q Files (*.sdriq)"), 0, QFileDialog::DontUseNativeDialog); diff --git a/plugins/samplesink/filesink/filesinkoutput.cpp b/plugins/samplesink/filesink/filesinkoutput.cpp index d73747c1a..602812ec8 100644 --- a/plugins/samplesink/filesink/filesinkoutput.cpp +++ b/plugins/samplesink/filesink/filesinkoutput.cpp @@ -318,8 +318,9 @@ void FileSinkOutput::applySettings(const FileSinkSettings& settings, bool force) int FileSinkOutput::webapiRunGet( SWGSDRangel::SWGDeviceState& response, - QString& errorMessage __attribute__((unused))) + QString& errorMessage) { + (void) errorMessage; m_deviceAPI->getDeviceEngineStateStr(*response.getState()); return 200; } @@ -327,8 +328,9 @@ int FileSinkOutput::webapiRunGet( int FileSinkOutput::webapiRun( bool run, SWGSDRangel::SWGDeviceState& response, - QString& errorMessage __attribute__((unused))) + QString& errorMessage) { + (void) errorMessage; m_deviceAPI->getDeviceEngineStateStr(*response.getState()); MsgStartStop *message = MsgStartStop::create(run); m_inputMessageQueue.push(message); diff --git a/plugins/samplesink/hackrfoutput/hackrfoutput.cpp b/plugins/samplesink/hackrfoutput/hackrfoutput.cpp index 3ae7437b1..00f0137cd 100644 --- a/plugins/samplesink/hackrfoutput/hackrfoutput.cpp +++ b/plugins/samplesink/hackrfoutput/hackrfoutput.cpp @@ -463,8 +463,9 @@ bool HackRFOutput::applySettings(const HackRFOutputSettings& settings, bool forc int HackRFOutput::webapiSettingsGet( SWGSDRangel::SWGDeviceSettings& response, - QString& errorMessage __attribute__((unused))) + QString& errorMessage) { + (void) errorMessage; response.setHackRfOutputSettings(new SWGSDRangel::SWGHackRFOutputSettings()); response.getHackRfOutputSettings()->init(); webapiFormatDeviceSettings(response, m_settings); @@ -475,8 +476,9 @@ int HackRFOutput::webapiSettingsPutPatch( bool force, const QStringList& deviceSettingsKeys, SWGSDRangel::SWGDeviceSettings& response, // query + response - QString& errorMessage __attribute__((unused))) + QString& errorMessage) { + (void) errorMessage; HackRFOutputSettings settings = m_settings; if (deviceSettingsKeys.contains("centerFrequency")) { @@ -531,8 +533,9 @@ void HackRFOutput::webapiFormatDeviceSettings(SWGSDRangel::SWGDeviceSettings& re int HackRFOutput::webapiRunGet( SWGSDRangel::SWGDeviceState& response, - QString& errorMessage __attribute__((unused))) + QString& errorMessage) { + (void) errorMessage; m_deviceAPI->getDeviceEngineStateStr(*response.getState()); return 200; } @@ -540,8 +543,9 @@ int HackRFOutput::webapiRunGet( int HackRFOutput::webapiRun( bool run, SWGSDRangel::SWGDeviceState& response, - QString& errorMessage __attribute__((unused))) + QString& errorMessage) { + (void) errorMessage; m_deviceAPI->getDeviceEngineStateStr(*response.getState()); MsgStartStop *message = MsgStartStop::create(run); m_inputMessageQueue.push(message); diff --git a/plugins/samplesink/hackrfoutput/hackrfoutput.pro b/plugins/samplesink/hackrfoutput/hackrfoutput.pro index 3fe253caf..f8c1f1113 100644 --- a/plugins/samplesink/hackrfoutput/hackrfoutput.pro +++ b/plugins/samplesink/hackrfoutput/hackrfoutput.pro @@ -19,6 +19,8 @@ QMAKE_CXXFLAGS += -std=c++11 CONFIG(MINGW32):LIBHACKRFSRC = "C:\softs\hackrf\host" CONFIG(MINGW64):LIBHACKRFSRC = "C:\softs\hackrf\host" +CONFIG(MSVC):LIBHACKRFSRC = "C:\softs\hackrf\host" + INCLUDEPATH += $$PWD INCLUDEPATH += ../../../exports INCLUDEPATH += ../../../sdrbase diff --git a/plugins/samplesink/hackrfoutput/hackrfoutputthread.cpp b/plugins/samplesink/hackrfoutput/hackrfoutputthread.cpp index 0223c33b8..4ed07ec3f 100644 --- a/plugins/samplesink/hackrfoutput/hackrfoutputthread.cpp +++ b/plugins/samplesink/hackrfoutput/hackrfoutputthread.cpp @@ -18,7 +18,6 @@ #include #include -#include #include "dsp/samplesourcefifo.h" diff --git a/plugins/samplesink/limesdroutput/limesdroutput.cpp b/plugins/samplesink/limesdroutput/limesdroutput.cpp index a166d488c..d0b82ee5d 100644 --- a/plugins/samplesink/limesdroutput/limesdroutput.cpp +++ b/plugins/samplesink/limesdroutput/limesdroutput.cpp @@ -599,6 +599,17 @@ bool LimeSDROutput::handleMessage(const Message& message) return true; } + else if (DeviceLimeSDRShared::MsgReportGPIOChange::match(message)) + { + DeviceLimeSDRShared::MsgReportGPIOChange& report = (DeviceLimeSDRShared::MsgReportGPIOChange&) message; + + m_settings.m_gpioDir = report.getGPIODir(); + m_settings.m_gpioPins = report.getGPIOPins(); + + // no GUI for the moment only REST API + + return true; + } else if (MsgGetStreamInfo::match(message)) { // qDebug() << "LimeSDROutput::handleMessage: MsgGetStreamInfo"; @@ -644,19 +655,24 @@ bool LimeSDROutput::handleMessage(const Message& message) else if (MsgGetDeviceInfo::match(message)) { double temp = 0.0; + uint8_t gpioPins = 0; - if (m_deviceShared.m_deviceParams->getDevice() && (LMS_GetChipTemperature(m_deviceShared.m_deviceParams->getDevice(), 0, &temp) == 0)) - { - //qDebug("LimeSDROutput::handleMessage: MsgGetDeviceInfo: temperature: %f", temp); - } - else - { + if (m_deviceShared.m_deviceParams->getDevice() && (LMS_GetChipTemperature(m_deviceShared.m_deviceParams->getDevice(), 0, &temp) != 0)) { qDebug("LimeSDROutput::handleMessage: MsgGetDeviceInfo: cannot get temperature"); } + if ((m_deviceShared.m_deviceParams->m_type != DeviceLimeSDRParams::LimeMini) + && (m_deviceShared.m_deviceParams->m_type != DeviceLimeSDRParams::LimeUndefined)) + { + if (m_deviceShared.m_deviceParams->getDevice() && (LMS_GPIORead(m_deviceShared.m_deviceParams->getDevice(), &gpioPins, 1) != 0)) { + qDebug("LimeSDROutput::handleMessage: MsgGetDeviceInfo: cannot get GPIO pins values"); + } + } + // send to oneself - if (getMessageQueueToGUI()) { - DeviceLimeSDRShared::MsgReportDeviceInfo *report = DeviceLimeSDRShared::MsgReportDeviceInfo::create(temp); + if (getMessageQueueToGUI()) + { + DeviceLimeSDRShared::MsgReportDeviceInfo *report = DeviceLimeSDRShared::MsgReportDeviceInfo::create(temp, gpioPins); getMessageQueueToGUI()->push(report); } @@ -668,7 +684,7 @@ bool LimeSDROutput::handleMessage(const Message& message) { if ((*itSource)->getSampleSourceGUIMessageQueue()) { - DeviceLimeSDRShared::MsgReportDeviceInfo *report = DeviceLimeSDRShared::MsgReportDeviceInfo::create(temp); + DeviceLimeSDRShared::MsgReportDeviceInfo *report = DeviceLimeSDRShared::MsgReportDeviceInfo::create(temp, gpioPins); (*itSource)->getSampleSourceGUIMessageQueue()->push(report); } } @@ -681,7 +697,7 @@ bool LimeSDROutput::handleMessage(const Message& message) { if ((*itSink)->getSampleSinkGUIMessageQueue()) { - DeviceLimeSDRShared::MsgReportDeviceInfo *report = DeviceLimeSDRShared::MsgReportDeviceInfo::create(temp); + DeviceLimeSDRShared::MsgReportDeviceInfo *report = DeviceLimeSDRShared::MsgReportDeviceInfo::create(temp, gpioPins); (*itSink)->getSampleSinkGUIMessageQueue()->push(report); } } @@ -700,6 +716,7 @@ bool LimeSDROutput::applySettings(const LimeSDROutputSettings& settings, bool fo bool forwardChangeTxDSP = false; bool forwardChangeAllDSP = false; bool forwardClockSource = false; + bool forwardGPIOChange = false; bool ownThreadWasRunning = false; bool doCalibration = false; bool doLPCalibration = false; @@ -772,7 +789,7 @@ bool LimeSDROutput::applySettings(const LimeSDROutputSettings& settings, bool fo if ((m_settings.m_devSampleRate != settings.m_devSampleRate) || (m_settings.m_log2SoftInterp != settings.m_log2SoftInterp) || force) { - int fifoSize = std::max( + int fifoSize = (std::max)( (int) ((settings.m_devSampleRate/(1<m_type != DeviceLimeSDRParams::LimeMini) + && (m_deviceShared.m_deviceParams->m_type != DeviceLimeSDRParams::LimeUndefined)) + { + if ((m_settings.m_gpioDir != settings.m_gpioDir) || force) + { + if (LMS_GPIODirWrite(m_deviceShared.m_deviceParams->getDevice(), &settings.m_gpioDir, 1) != 0) + { + qCritical("LimeSDROutput::applySettings: could not set GPIO directions to %u", settings.m_gpioDir); + } + else + { + forwardGPIOChange = true; + qDebug("LimeSDROutput::applySettings: GPIO directions set to %u", settings.m_gpioDir); + } + } + + if ((m_settings.m_gpioPins != settings.m_gpioPins) || force) + { + if (LMS_GPIOWrite(m_deviceShared.m_deviceParams->getDevice(), &settings.m_gpioPins, 1) != 0) + { + qCritical("LimeSDROutput::applySettings: could not set GPIO pins to %u", settings.m_gpioPins); + } + else + { + forwardGPIOChange = true; + qDebug("LimeSDROutput::applySettings: GPIO pins set to %u", settings.m_gpioPins); + } + } + } + m_settings = settings; double clockGenFreqAfter; @@ -1072,6 +1119,30 @@ bool LimeSDROutput::applySettings(const LimeSDROutputSettings& settings, bool fo } } + if (forwardGPIOChange) + { + const std::vector& sourceBuddies = m_deviceAPI->getSourceBuddies(); + std::vector::const_iterator itSource = sourceBuddies.begin(); + + for (; itSource != sourceBuddies.end(); ++itSource) + { + DeviceLimeSDRShared::MsgReportGPIOChange *report = DeviceLimeSDRShared::MsgReportGPIOChange::create( + m_settings.m_gpioDir, m_settings.m_gpioPins); + (*itSource)->getSampleSourceInputMessageQueue()->push(report); + } + + // send to sink buddies + const std::vector& sinkBuddies = m_deviceAPI->getSinkBuddies(); + std::vector::const_iterator itSink = sinkBuddies.begin(); + + for (; itSink != sinkBuddies.end(); ++itSink) + { + DeviceLimeSDRShared::MsgReportGPIOChange *report = DeviceLimeSDRShared::MsgReportGPIOChange::create( + m_settings.m_gpioDir, m_settings.m_gpioPins); + (*itSink)->getSampleSinkInputMessageQueue()->push(report); + } + } + QLocale loc; qDebug().noquote() << "LimeSDROutput::applySettings: center freq: " << m_settings.m_centerFrequency << " Hz" @@ -1092,6 +1163,8 @@ bool LimeSDROutput::applySettings(const LimeSDROutputSettings& settings, bool fo << " m_antennaPath: " << m_settings.m_antennaPath << " m_extClock: " << m_settings.m_extClock << " m_extClockFreq: " << loc.toString(m_settings.m_extClockFreq) + << " m_gpioDir: " << m_settings.m_gpioDir + << " m_gpioPins: " << m_settings.m_gpioPins << " force: " << force << " forceNCOFrequency: " << forceNCOFrequency << " doCalibration: " << doCalibration @@ -1102,8 +1175,9 @@ bool LimeSDROutput::applySettings(const LimeSDROutputSettings& settings, bool fo int LimeSDROutput::webapiSettingsGet( SWGSDRangel::SWGDeviceSettings& response, - QString& errorMessage __attribute__((unused))) + QString& errorMessage) { + (void) errorMessage; response.setLimeSdrOutputSettings(new SWGSDRangel::SWGLimeSdrOutputSettings()); response.getLimeSdrOutputSettings()->init(); webapiFormatDeviceSettings(response, m_settings); @@ -1114,8 +1188,9 @@ int LimeSDROutput::webapiSettingsPutPatch( bool force, const QStringList& deviceSettingsKeys, SWGSDRangel::SWGDeviceSettings& response, // query + response - QString& errorMessage __attribute__((unused))) + QString& errorMessage) { + (void) errorMessage; LimeSDROutputSettings settings = m_settings; if (deviceSettingsKeys.contains("antennaPath")) { @@ -1163,6 +1238,12 @@ int LimeSDROutput::webapiSettingsPutPatch( if (deviceSettingsKeys.contains("transverterMode")) { settings.m_transverterMode = response.getLimeSdrOutputSettings()->getTransverterMode() != 0; } + if (deviceSettingsKeys.contains("gpioDir")) { + settings.m_gpioDir = response.getLimeSdrOutputSettings()->getGpioDir() & 0xFF; + } + if (deviceSettingsKeys.contains("gpioPins")) { + settings.m_gpioPins = response.getLimeSdrOutputSettings()->getGpioPins() & 0xFF; + } MsgConfigureLimeSDR *msg = MsgConfigureLimeSDR::create(settings, force); m_inputMessageQueue.push(msg); @@ -1179,8 +1260,9 @@ int LimeSDROutput::webapiSettingsPutPatch( int LimeSDROutput::webapiReportGet( SWGSDRangel::SWGDeviceReport& response, - QString& errorMessage __attribute__((unused))) + QString& errorMessage) { + (void) errorMessage; response.setLimeSdrOutputReport(new SWGSDRangel::SWGLimeSdrOutputReport()); response.getLimeSdrOutputReport()->init(); webapiFormatDeviceReport(response); @@ -1203,12 +1285,15 @@ void LimeSDROutput::webapiFormatDeviceSettings(SWGSDRangel::SWGDeviceSettings& r response.getLimeSdrOutputSettings()->setNcoFrequency(settings.m_ncoFrequency); response.getLimeSdrOutputSettings()->setTransverterDeltaFrequency(settings.m_transverterDeltaFrequency); response.getLimeSdrOutputSettings()->setTransverterMode(settings.m_transverterMode ? 1 : 0); + response.getLimeSdrOutputSettings()->setGpioDir(settings.m_gpioDir); + response.getLimeSdrOutputSettings()->setGpioPins(settings.m_gpioPins); } int LimeSDROutput::webapiRunGet( SWGSDRangel::SWGDeviceState& response, - QString& errorMessage __attribute__((unused))) + QString& errorMessage) { + (void) errorMessage; m_deviceAPI->getDeviceEngineStateStr(*response.getState()); return 200; } @@ -1216,8 +1301,9 @@ int LimeSDROutput::webapiRunGet( int LimeSDROutput::webapiRun( bool run, SWGSDRangel::SWGDeviceState& response, - QString& errorMessage __attribute__((unused))) + QString& errorMessage) { + (void) errorMessage; m_deviceAPI->getDeviceEngineStateStr(*response.getState()); MsgStartStop *message = MsgStartStop::create(run); m_inputMessageQueue.push(message); @@ -1235,6 +1321,8 @@ void LimeSDROutput::webapiFormatDeviceReport(SWGSDRangel::SWGDeviceReport& respo { bool success = false; double temp = 0.0; + uint8_t gpioDir = 0; + uint8_t gpioPins = 0; lms_stream_status_t status; status.active = false; status.fifoFilledCount = 0; @@ -1257,9 +1345,14 @@ void LimeSDROutput::webapiFormatDeviceReport(SWGSDRangel::SWGDeviceReport& respo response.getLimeSdrOutputReport()->setLinkRate(status.linkRate); response.getLimeSdrOutputReport()->setHwTimestamp(status.timestamp); - if (m_deviceShared.m_deviceParams->getDevice()) { + if (m_deviceShared.m_deviceParams->getDevice()) + { LMS_GetChipTemperature(m_deviceShared.m_deviceParams->getDevice(), 0, &temp); + LMS_GPIODirRead(m_deviceShared.m_deviceParams->getDevice(), &gpioDir, 1); + LMS_GPIORead(m_deviceShared.m_deviceParams->getDevice(), &gpioPins, 1); } response.getLimeSdrOutputReport()->setTemperature(temp); + response.getLimeSdrOutputReport()->setGpioDir(gpioDir); + response.getLimeSdrOutputReport()->setGpioPins(gpioPins); } diff --git a/plugins/samplesink/limesdroutput/limesdroutput.pro b/plugins/samplesink/limesdroutput/limesdroutput.pro index e296a3e6c..8f4f60b51 100644 --- a/plugins/samplesink/limesdroutput/limesdroutput.pro +++ b/plugins/samplesink/limesdroutput/limesdroutput.pro @@ -26,17 +26,24 @@ INCLUDEPATH += ../../../sdrbase INCLUDEPATH += ../../../sdrgui INCLUDEPATH += ../../../swagger/sdrangel/code/qt5/client INCLUDEPATH += ../../../devices -INCLUDEPATH += ../../../liblimesuite/srcmw -INCLUDEPATH += $$LIBLIMESUITESRC/src -INCLUDEPATH += $$LIBLIMESUITESRC/src/ADF4002 -INCLUDEPATH += $$LIBLIMESUITESRC/src/ConnectionRegistry -INCLUDEPATH += $$LIBLIMESUITESRC/src/FPGA_common -INCLUDEPATH += $$LIBLIMESUITESRC/src/GFIR -INCLUDEPATH += $$LIBLIMESUITESRC/src/lms7002m -INCLUDEPATH += $$LIBLIMESUITESRC/src/lms7002m_mcu -INCLUDEPATH += $$LIBLIMESUITESRC/src/Si5351C -INCLUDEPATH += $$LIBLIMESUITESRC/src/protocols -INCLUDEPATH += $$LIBLIMESUITESRC/external/cpp-feather-ini-parser + +MINGW32 || MINGW64 || macx { + INCLUDEPATH += ../../../liblimesuite/srcmw + INCLUDEPATH += $$LIBLIMESUITESRC/src + INCLUDEPATH += $$LIBLIMESUITESRC/src/ADF4002 + INCLUDEPATH += $$LIBLIMESUITESRC/src/ConnectionRegistry + INCLUDEPATH += $$LIBLIMESUITESRC/src/FPGA_common + INCLUDEPATH += $$LIBLIMESUITESRC/src/GFIR + INCLUDEPATH += $$LIBLIMESUITESRC/src/lms7002m + INCLUDEPATH += $$LIBLIMESUITESRC/src/lms7002m_mcu + INCLUDEPATH += $$LIBLIMESUITESRC/src/Si5351C + INCLUDEPATH += $$LIBLIMESUITESRC/src/protocols + INCLUDEPATH += $$LIBLIMESUITESRC/external/cpp-feather-ini-parser +} + +MSVC { + INCLUDEPATH += "C:\Program Files\PothosSDR\include" +} CONFIG(Release):build_subdir = release CONFIG(Debug):build_subdir = debug @@ -58,7 +65,13 @@ FORMS += limesdroutputgui.ui LIBS += -L../../../sdrbase/$${build_subdir} -lsdrbase LIBS += -L../../../sdrgui/$${build_subdir} -lsdrgui LIBS += -L../../../swagger/$${build_subdir} -lswagger -LIBS += -L../../../liblimesuite/$${build_subdir} -lliblimesuite LIBS += -L../../../devices/$${build_subdir} -ldevices +MINGW32 || MINGW64 || macx { + LIBS += -L../../../liblimesuite/$${build_subdir} -lliblimesuite +} +MSVC { + LIBS += -L"C:\Program Files\PothosSDR\bin" -L"C:\Program Files\PothosSDR\lib" -lLimeSuite +} + RESOURCES = ../../../sdrgui/resources/res.qrc diff --git a/plugins/samplesink/limesdroutput/limesdroutputgui.cpp b/plugins/samplesink/limesdroutput/limesdroutputgui.cpp index f904360d9..f5aa0b9c6 100644 --- a/plugins/samplesink/limesdroutput/limesdroutputgui.cpp +++ b/plugins/samplesink/limesdroutput/limesdroutputgui.cpp @@ -244,6 +244,7 @@ bool LimeSDROutputGUI::handleMessage(const Message& message) { DeviceLimeSDRShared::MsgReportDeviceInfo& report = (DeviceLimeSDRShared::MsgReportDeviceInfo&) message; ui->temperatureText->setText(tr("%1C").arg(QString::number(report.getTemperature(), 'f', 0))); + ui->gpioText->setText(tr("%1").arg(report.getGPIOPins(), 2, 16, QChar('0')).toUpper()); return true; } diff --git a/plugins/samplesink/limesdroutput/limesdroutputgui.ui b/plugins/samplesink/limesdroutput/limesdroutputgui.ui index 19d8d00e4..3e7197e9a 100644 --- a/plugins/samplesink/limesdroutput/limesdroutputgui.ui +++ b/plugins/samplesink/limesdroutput/limesdroutputgui.ui @@ -880,6 +880,23 @@ QToolTip{background-color: white; color: black;} + + + + Qt::Vertical + + + + + + + GPIO bits as hex value (LSB first) + + + 00 + + + @@ -952,6 +969,39 @@ QToolTip{background-color: white; color: black;} + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/plugins/samplesink/limesdroutput/limesdroutputplugin.cpp b/plugins/samplesink/limesdroutput/limesdroutputplugin.cpp index 1c4d765e9..4764834d6 100644 --- a/plugins/samplesink/limesdroutput/limesdroutputplugin.cpp +++ b/plugins/samplesink/limesdroutput/limesdroutputplugin.cpp @@ -34,7 +34,7 @@ const PluginDescriptor LimeSDROutputPlugin::m_pluginDescriptor = { QString("LimeSDR Output"), - QString("4.2.4"), + QString("4.3.1"), QString("(c) Edouard Griffiths, F4EXB"), QString("https://github.com/f4exb/sdrangel"), true, diff --git a/plugins/samplesink/limesdroutput/limesdroutputsettings.cpp b/plugins/samplesink/limesdroutput/limesdroutputsettings.cpp index 96270d375..3983126af 100644 --- a/plugins/samplesink/limesdroutput/limesdroutputsettings.cpp +++ b/plugins/samplesink/limesdroutput/limesdroutputsettings.cpp @@ -40,6 +40,8 @@ void LimeSDROutputSettings::resetToDefaults() m_extClockFreq = 10000000; // 10 MHz m_transverterMode = false; m_transverterDeltaFrequency = 0; + m_gpioDir = 0; + m_gpioPins = 0; } QByteArray LimeSDROutputSettings::serialize() const @@ -60,6 +62,8 @@ QByteArray LimeSDROutputSettings::serialize() const s.writeU32(15, m_extClockFreq); s.writeBool(16, m_transverterMode); s.writeS64(17, m_transverterDeltaFrequency); + s.writeU32(18, m_gpioDir); + s.writeU32(19, m_gpioPins); return s.final(); } @@ -77,6 +81,7 @@ bool LimeSDROutputSettings::deserialize(const QByteArray& data) if (d.getVersion() == 1) { int intval; + uint32_t uintval; d.readS32(1, &m_devSampleRate, 5000000); d.readU32(2, &m_log2HardInterp, 2); @@ -93,6 +98,10 @@ bool LimeSDROutputSettings::deserialize(const QByteArray& data) d.readU32(15, &m_extClockFreq, 10000000); d.readBool(16, &m_transverterMode, false); d.readS64(17, &m_transverterDeltaFrequency, 0); + d.readU32(18, &uintval, 0); + m_gpioDir = uintval & 0xFF; + d.readU32(19, &uintval, 0); + m_gpioPins = uintval & 0xFF; return true; } diff --git a/plugins/samplesink/limesdroutput/limesdroutputsettings.h b/plugins/samplesink/limesdroutput/limesdroutputsettings.h index 2fe21b054..f29ac63ba 100644 --- a/plugins/samplesink/limesdroutput/limesdroutputsettings.h +++ b/plugins/samplesink/limesdroutput/limesdroutputsettings.h @@ -56,6 +56,8 @@ struct LimeSDROutputSettings uint32_t m_extClockFreq; //!< Frequency (Hz) of external clock source bool m_transverterMode; qint64 m_transverterDeltaFrequency; + uint8_t m_gpioDir; //!< GPIO pin direction LSB first; 0 input, 1 output + uint8_t m_gpioPins; //!< GPIO pins to write; LSB first LimeSDROutputSettings(); void resetToDefaults(); diff --git a/plugins/samplesink/limesdroutput/limesdroutputthread.h b/plugins/samplesink/limesdroutput/limesdroutputthread.h index 2761f45d5..ec5c4a5c8 100644 --- a/plugins/samplesink/limesdroutput/limesdroutputthread.h +++ b/plugins/samplesink/limesdroutput/limesdroutputthread.h @@ -39,7 +39,7 @@ public: virtual void startWork(); virtual void stopWork(); - virtual void setDeviceSampleRate(int __attribute__((unused)) sampleRate) {} + virtual void setDeviceSampleRate(int sampleRate) { (void) sampleRate; } virtual bool isRunning() { return m_running; } void setLog2Interpolation(unsigned int log2_ioterp); diff --git a/plugins/samplesink/plutosdroutput/plutosdroutput.cpp b/plugins/samplesink/plutosdroutput/plutosdroutput.cpp index 3c81a79a2..54157a930 100644 --- a/plugins/samplesink/plutosdroutput/plutosdroutput.cpp +++ b/plugins/samplesink/plutosdroutput/plutosdroutput.cpp @@ -549,8 +549,9 @@ float PlutoSDROutput::getTemperature() int PlutoSDROutput::webapiRunGet( SWGSDRangel::SWGDeviceState& response, - QString& errorMessage __attribute__((unused))) + QString& errorMessage) { + (void) errorMessage; m_deviceAPI->getDeviceEngineStateStr(*response.getState()); return 200; } @@ -558,8 +559,9 @@ int PlutoSDROutput::webapiRunGet( int PlutoSDROutput::webapiRun( bool run, SWGSDRangel::SWGDeviceState& response, - QString& errorMessage __attribute__((unused))) + QString& errorMessage) { + (void) errorMessage; m_deviceAPI->getDeviceEngineStateStr(*response.getState()); MsgStartStop *message = MsgStartStop::create(run); m_inputMessageQueue.push(message); @@ -575,8 +577,9 @@ int PlutoSDROutput::webapiRun( int PlutoSDROutput::webapiSettingsGet( SWGSDRangel::SWGDeviceSettings& response, - QString& errorMessage __attribute__((unused))) + QString& errorMessage) { + (void) errorMessage; response.setPlutoSdrOutputSettings(new SWGSDRangel::SWGPlutoSdrOutputSettings()); response.getPlutoSdrOutputSettings()->init(); webapiFormatDeviceSettings(response, m_settings); @@ -587,8 +590,9 @@ int PlutoSDROutput::webapiSettingsPutPatch( bool force, const QStringList& deviceSettingsKeys, SWGSDRangel::SWGDeviceSettings& response, // query + response - QString& errorMessage __attribute__((unused))) + QString& errorMessage) { + (void) errorMessage; PlutoSDROutputSettings settings = m_settings; if (deviceSettingsKeys.contains("centerFrequency")) { @@ -648,8 +652,9 @@ int PlutoSDROutput::webapiSettingsPutPatch( int PlutoSDROutput::webapiReportGet( SWGSDRangel::SWGDeviceReport& response, - QString& errorMessage __attribute__((unused))) + QString& errorMessage) { + (void) errorMessage; response.setPlutoSdrOutputReport(new SWGSDRangel::SWGPlutoSdrOutputReport()); response.getPlutoSdrOutputReport()->init(); webapiFormatDeviceReport(response); diff --git a/plugins/samplesink/plutosdroutput/plutosdroutput.pro b/plugins/samplesink/plutosdroutput/plutosdroutput.pro index 2d1fd03e4..1cee810e4 100644 --- a/plugins/samplesink/plutosdroutput/plutosdroutput.pro +++ b/plugins/samplesink/plutosdroutput/plutosdroutput.pro @@ -17,17 +17,22 @@ DEFINES += USE_SSE4_1=1 QMAKE_CXXFLAGS += -msse4.1 QMAKE_CXXFLAGS += -std=c++11 -CONFIG(MINGW32):LIBIIOSRC = "C:\softs\libiio" -CONFIG(MINGW64):LIBIIOSRC = "C:\softs\libiio" - INCLUDEPATH += $$PWD INCLUDEPATH += ../../../exports INCLUDEPATH += ../../../sdrbase INCLUDEPATH += ../../../sdrgui INCLUDEPATH += ../../../swagger/sdrangel/code/qt5/client INCLUDEPATH += ../../../devices -INCLUDEPATH += ../../../libiio/includemw -INCLUDEPATH += $$LIBIIOSRC + +MINGW32 || MINGW64 { + LIBIIOSRC = "C:\softs\libiio" + INCLUDEPATH += ../../../libiio/includemw + INCLUDEPATH += $$LIBIIOSRC +} + +MSVC { + INCLUDEPATH += "C:\Program Files\PothosSDR\include" +} CONFIG(Release):build_subdir = release CONFIG(Debug):build_subdir = debug @@ -49,7 +54,14 @@ FORMS += plutosdroutputgui.ui LIBS += -L../../../sdrbase/$${build_subdir} -lsdrbase LIBS += -L../../../sdrgui/$${build_subdir} -lsdrgui LIBS += -L../../../swagger/$${build_subdir} -lswagger -LIBS += -L../../../libiio/$${build_subdir} -llibiio LIBS += -L../../../devices/$${build_subdir} -ldevices +MINGW32 || MINGW64 { + LIBS += -L../../../libiio/$${build_subdir} -llibiio +} + +MSVC { + LIBS += -L"C:\Program Files\PothosSDR\bin" -L"C:\Program Files\PothosSDR\lib" -llibiio +} + RESOURCES = ../../../sdrgui/resources/res.qrc diff --git a/plugins/samplesink/plutosdroutput/plutosdroutputgui.cpp b/plugins/samplesink/plutosdroutput/plutosdroutputgui.cpp index 731240c46..4d96665e6 100644 --- a/plugins/samplesink/plutosdroutput/plutosdroutputgui.cpp +++ b/plugins/samplesink/plutosdroutput/plutosdroutputgui.cpp @@ -129,8 +129,9 @@ bool PlutoSDROutputGUI::deserialize(const QByteArray& data) } } -bool PlutoSDROutputGUI::handleMessage(const Message& message __attribute__((unused))) +bool PlutoSDROutputGUI::handleMessage(const Message& message) { + (void) message; if (PlutoSDROutput::MsgConfigurePlutoSDR::match(message)) { const PlutoSDROutput::MsgConfigurePlutoSDR& cfg = (PlutoSDROutput::MsgConfigurePlutoSDR&) message; diff --git a/plugins/samplesink/plutosdroutput/plutosdroutputplugin.cpp b/plugins/samplesink/plutosdroutput/plutosdroutputplugin.cpp index fd5469c99..99d3b4259 100644 --- a/plugins/samplesink/plutosdroutput/plutosdroutputplugin.cpp +++ b/plugins/samplesink/plutosdroutput/plutosdroutputplugin.cpp @@ -30,7 +30,7 @@ class DeviceSourceAPI; const PluginDescriptor PlutoSDROutputPlugin::m_pluginDescriptor = { QString("PlutoSDR Output"), - QString("4.0.4"), + QString("4.3.1"), QString("(c) Edouard Griffiths, F4EXB"), QString("https://github.com/f4exb/sdrangel"), true, diff --git a/plugins/samplesink/plutosdroutput/plutosdroutputthread.cpp b/plugins/samplesink/plutosdroutput/plutosdroutputthread.cpp index 88a10bc7a..fd51f6b07 100644 --- a/plugins/samplesink/plutosdroutput/plutosdroutputthread.cpp +++ b/plugins/samplesink/plutosdroutput/plutosdroutputthread.cpp @@ -14,8 +14,6 @@ // along with this program. If not, see . // /////////////////////////////////////////////////////////////////////////////////// -#include - #include "plutosdr/deviceplutosdrbox.h" #include "plutosdroutputsettings.h" #include "iio.h" diff --git a/plugins/samplesink/plutosdroutput/plutosdroutputthread.h b/plugins/samplesink/plutosdroutput/plutosdroutputthread.h index 45f80e218..080b093bb 100644 --- a/plugins/samplesink/plutosdroutput/plutosdroutputthread.h +++ b/plugins/samplesink/plutosdroutput/plutosdroutputthread.h @@ -37,7 +37,7 @@ public: virtual void startWork(); virtual void stopWork(); - virtual void setDeviceSampleRate(int sampleRate __attribute__((unused))) {} + virtual void setDeviceSampleRate(int sampleRate) { (void) sampleRate; } virtual bool isRunning() { return m_running; } void setLog2Interpolation(unsigned int log2_interp); diff --git a/plugins/samplesink/sdrdaemonsink/sdrdaemonsink.pro b/plugins/samplesink/sdrdaemonsink/sdrdaemonsink.pro index 51a2d307a..b70d7a122 100644 --- a/plugins/samplesink/sdrdaemonsink/sdrdaemonsink.pro +++ b/plugins/samplesink/sdrdaemonsink/sdrdaemonsink.pro @@ -13,6 +13,7 @@ TARGET = outputsdrdaemonsink CONFIG(MINGW32):LIBCM256CCSRC = "C:\softs\cm256cc" CONFIG(MINGW64):LIBCM256CCSRC = "C:\softs\cm256cc" +CONFIG(MSVC):LIBCM256CCSRC = "C:\softs\cm256cc" CONFIG(macx):LIBCM256CCSRC = "../../../../deps/cm256cc" INCLUDEPATH += $$PWD @@ -36,6 +37,7 @@ CONFIG(Debug):build_subdir = debug CONFIG(MINGW32):INCLUDEPATH += "C:\softs\boost_1_66_0" CONFIG(MINGW64):INCLUDEPATH += "C:\softs\boost_1_66_0" +CONFIG(MSVC):INCLUDEPATH += "C:\softs\boost_1_66_0" CONFIG(macx):INCLUDEPATH += "../../../boost_1_64_0" SOURCES += sdrdaemonsinkthread.cpp\ diff --git a/plugins/samplesink/sdrdaemonsink/sdrdaemonsinkgui.cpp b/plugins/samplesink/sdrdaemonsink/sdrdaemonsinkgui.cpp index c2607530f..b7eb7e9ff 100644 --- a/plugins/samplesink/sdrdaemonsink/sdrdaemonsinkgui.cpp +++ b/plugins/samplesink/sdrdaemonsink/sdrdaemonsinkgui.cpp @@ -391,8 +391,9 @@ void SDRdaemonSinkGui::on_dataPort_returnPressed() sendSettings(); } -void SDRdaemonSinkGui::on_apiApplyButton_clicked(bool checked __attribute__((unused))) +void SDRdaemonSinkGui::on_apiApplyButton_clicked(bool checked) { + (void) checked; m_settings.m_apiAddress = ui->apiAddress->text(); bool apiOk; @@ -410,8 +411,9 @@ void SDRdaemonSinkGui::on_apiApplyButton_clicked(bool checked __attribute__((unu m_networkManager->get(m_networkRequest); } -void SDRdaemonSinkGui::on_dataApplyButton_clicked(bool checked __attribute__((unused))) +void SDRdaemonSinkGui::on_dataApplyButton_clicked(bool checked) { + (void) checked; m_settings.m_dataAddress = ui->dataAddress->text(); bool dataOk; @@ -434,8 +436,9 @@ void SDRdaemonSinkGui::on_startStop_toggled(bool checked) } } -void SDRdaemonSinkGui::on_eventCountsReset_clicked(bool checked __attribute__((unused))) +void SDRdaemonSinkGui::on_eventCountsReset_clicked(bool checked) { + (void) checked; m_countUnrecoverable = 0; m_countRecovered = 0; m_time.start(); diff --git a/plugins/samplesink/sdrdaemonsink/sdrdaemonsinkgui.h b/plugins/samplesink/sdrdaemonsink/sdrdaemonsinkgui.h index 314be9314..4204dfc16 100644 --- a/plugins/samplesink/sdrdaemonsink/sdrdaemonsinkgui.h +++ b/plugins/samplesink/sdrdaemonsink/sdrdaemonsinkgui.h @@ -81,7 +81,7 @@ public: void resetToDefaults(); virtual qint64 getCenterFrequency() const { return m_deviceCenterFrequency; } - virtual void setCenterFrequency(qint64 centerFrequency __attribute__((unused))) {} + virtual void setCenterFrequency(qint64 centerFrequency) { (void) centerFrequency; } QByteArray serialize() const; bool deserialize(const QByteArray& data); virtual MessageQueue *getInputMessageQueue() { return &m_inputMessageQueue; } diff --git a/plugins/samplesink/sdrdaemonsink/sdrdaemonsinkoutput.cpp b/plugins/samplesink/sdrdaemonsink/sdrdaemonsinkoutput.cpp index 0403c80c2..7f9c9ab62 100644 --- a/plugins/samplesink/sdrdaemonsink/sdrdaemonsinkoutput.cpp +++ b/plugins/samplesink/sdrdaemonsink/sdrdaemonsinkoutput.cpp @@ -14,7 +14,6 @@ // along with this program. If not, see . // /////////////////////////////////////////////////////////////////////////////////// -#include #include #include #include @@ -306,8 +305,9 @@ void SDRdaemonSinkOutput::applySettings(const SDRdaemonSinkSettings& settings, b int SDRdaemonSinkOutput::webapiRunGet( SWGSDRangel::SWGDeviceState& response, - QString& errorMessage __attribute__((unused))) + QString& errorMessage) { + (void) errorMessage; m_deviceAPI->getDeviceEngineStateStr(*response.getState()); return 200; } @@ -315,8 +315,9 @@ int SDRdaemonSinkOutput::webapiRunGet( int SDRdaemonSinkOutput::webapiRun( bool run, SWGSDRangel::SWGDeviceState& response, - QString& errorMessage __attribute__((unused))) + QString& errorMessage) { + (void) errorMessage; m_deviceAPI->getDeviceEngineStateStr(*response.getState()); MsgStartStop *message = MsgStartStop::create(run); m_inputMessageQueue.push(message); @@ -332,8 +333,9 @@ int SDRdaemonSinkOutput::webapiRun( int SDRdaemonSinkOutput::webapiSettingsGet( SWGSDRangel::SWGDeviceSettings& response, - QString& errorMessage __attribute__((unused))) + QString& errorMessage) { + (void) errorMessage; response.setSdrDaemonSinkSettings(new SWGSDRangel::SWGSDRdaemonSinkSettings()); response.getSdrDaemonSinkSettings()->init(); webapiFormatDeviceSettings(response, m_settings); @@ -344,8 +346,9 @@ int SDRdaemonSinkOutput::webapiSettingsPutPatch( bool force, const QStringList& deviceSettingsKeys, SWGSDRangel::SWGDeviceSettings& response, // query + response - QString& errorMessage __attribute__((unused))) + QString& errorMessage) { + (void) errorMessage; SDRdaemonSinkSettings settings = m_settings; if (deviceSettingsKeys.contains("sampleRate")) { @@ -391,8 +394,9 @@ int SDRdaemonSinkOutput::webapiSettingsPutPatch( int SDRdaemonSinkOutput::webapiReportGet( SWGSDRangel::SWGDeviceReport& response, - QString& errorMessage __attribute__((unused))) + QString& errorMessage) { + (void) errorMessage; response.setSdrDaemonSinkReport(new SWGSDRangel::SWGSDRdaemonSinkReport()); response.getSdrDaemonSinkReport()->init(); webapiFormatDeviceReport(response); @@ -415,9 +419,9 @@ void SDRdaemonSinkOutput::webapiFormatDeviceSettings(SWGSDRangel::SWGDeviceSetti void SDRdaemonSinkOutput::webapiFormatDeviceReport(SWGSDRangel::SWGDeviceReport& response) { - struct timeval tv; + uint64_t ts_usecs; response.getSdrDaemonSinkReport()->setBufferRwBalance(m_sampleSourceFifo.getRWBalance()); - response.getSdrDaemonSinkReport()->setSampleCount(m_sdrDaemonSinkThread ? (int) m_sdrDaemonSinkThread->getSamplesCount(tv) : 0); + response.getSdrDaemonSinkReport()->setSampleCount(m_sdrDaemonSinkThread ? (int) m_sdrDaemonSinkThread->getSamplesCount(ts_usecs) : 0); } void SDRdaemonSinkOutput::tick() @@ -499,8 +503,8 @@ void SDRdaemonSinkOutput::analyzeApiReply(const QJsonObject& jsonObject) } uint32_t sampleCountDelta, sampleCount; - struct timeval tv; - sampleCount = m_sdrDaemonSinkThread->getSamplesCount(tv); + uint64_t timestampUs; + sampleCount = m_sdrDaemonSinkThread->getSamplesCount(timestampUs); if (sampleCount < m_lastSampleCount) { sampleCountDelta = (0xFFFFFFFFU - m_lastSampleCount) + sampleCount + 1; @@ -508,8 +512,6 @@ void SDRdaemonSinkOutput::analyzeApiReply(const QJsonObject& jsonObject) sampleCountDelta = sampleCount - m_lastSampleCount; } - uint64_t timestampUs = tv.tv_sec*1000000ULL + tv.tv_usec; - // on initial state wait for queue stabilization if ((m_lastRemoteTimestampRateCorrection == 0) && (queueLength >= m_lastQueueLength-1) && (queueLength <= m_lastQueueLength+1)) { diff --git a/plugins/samplesink/sdrdaemonsink/sdrdaemonsinkoutput.h b/plugins/samplesink/sdrdaemonsink/sdrdaemonsinkoutput.h index 741c6d1bd..93ce45d5e 100644 --- a/plugins/samplesink/sdrdaemonsink/sdrdaemonsinkoutput.h +++ b/plugins/samplesink/sdrdaemonsink/sdrdaemonsinkoutput.h @@ -136,7 +136,7 @@ public: virtual const QString& getDeviceDescription() const; virtual int getSampleRate() const; virtual quint64 getCenterFrequency() const; - virtual void setCenterFrequency(qint64 centerFrequency __attribute__((unused))) {} + virtual void setCenterFrequency(qint64 centerFrequency) { (void) centerFrequency; } std::time_t getStartingTimeStamp() const; virtual bool handleMessage(const Message& message); diff --git a/plugins/samplesink/sdrdaemonsink/sdrdaemonsinkthread.cpp b/plugins/samplesink/sdrdaemonsink/sdrdaemonsinkthread.cpp index bbe966cb8..a412b7efb 100644 --- a/plugins/samplesink/sdrdaemonsink/sdrdaemonsinkthread.cpp +++ b/plugins/samplesink/sdrdaemonsink/sdrdaemonsinkthread.cpp @@ -14,7 +14,6 @@ // along with this program. If not, see . // /////////////////////////////////////////////////////////////////////////////////// -#include #include #include #include @@ -22,6 +21,7 @@ #include #include "dsp/samplesourcefifo.h" +#include "util/timeutil.h" #include "sdrdaemonsinkthread.h" SDRdaemonSinkThread::SDRdaemonSinkThread(SampleSourceFifo* sampleFifo, QObject* parent) : @@ -140,8 +140,8 @@ void SDRdaemonSinkThread::tick() } } -uint32_t SDRdaemonSinkThread::getSamplesCount(struct timeval& tv) const +uint32_t SDRdaemonSinkThread::getSamplesCount(uint64_t& ts_usecs) const { - gettimeofday(&tv, 0); + ts_usecs = TimeUtil::nowus(); return m_samplesCount; } diff --git a/plugins/samplesink/sdrdaemonsink/sdrdaemonsinkthread.h b/plugins/samplesink/sdrdaemonsink/sdrdaemonsinkthread.h index e6a2fd91a..af6f09440 100644 --- a/plugins/samplesink/sdrdaemonsink/sdrdaemonsinkthread.h +++ b/plugins/samplesink/sdrdaemonsink/sdrdaemonsinkthread.h @@ -55,7 +55,7 @@ public: bool isRunning() const { return m_running; } - uint32_t getSamplesCount(struct timeval& tv) const; + uint32_t getSamplesCount(uint64_t& ts_usecs) const; void setSamplesCount(int samplesCount) { m_samplesCount = samplesCount; } void setChunkCorrection(int chunkCorrection) { m_chunkCorrection = chunkCorrection; } diff --git a/plugins/samplesink/sdrdaemonsink/udpsinkfec.cpp b/plugins/samplesink/sdrdaemonsink/udpsinkfec.cpp index cd1b6fb0f..1013f2bde 100644 --- a/plugins/samplesink/sdrdaemonsink/udpsinkfec.cpp +++ b/plugins/samplesink/sdrdaemonsink/udpsinkfec.cpp @@ -16,11 +16,10 @@ #include -#include -#include #include #include +#include "util/timeutil.h" #include "udpsinkfec.h" #include "udpsinkfecworker.h" @@ -118,10 +117,9 @@ void UDPSinkFEC::write(const SampleVector::iterator& begin, uint32_t sampleChunk if (m_txBlockIndex == 0) // Tx block index 0 is a block with only meta data { - struct timeval tv; SDRDaemonMetaDataFEC metaData; - gettimeofday(&tv, 0); + uint64_t ts_usecs = TimeUtil::nowus(); metaData.m_centerFrequency = 0; // frequency not set by stream metaData.m_sampleRate = m_sampleRate; @@ -129,8 +127,8 @@ void UDPSinkFEC::write(const SampleVector::iterator& begin, uint32_t sampleChunk metaData.m_sampleBits = SDR_RX_SAMP_SZ; metaData.m_nbOriginalBlocks = m_nbOriginalBlocks; metaData.m_nbFECBlocks = m_nbBlocksFEC; - metaData.m_tv_sec = tv.tv_sec; - metaData.m_tv_usec = tv.tv_usec; + metaData.m_tv_sec = ts_usecs / 1000000UL; + metaData.m_tv_usec = ts_usecs % 1000000UL; boost::crc_32_type crc32; crc32.process_bytes(&metaData, 20); @@ -143,7 +141,10 @@ void UDPSinkFEC::write(const SampleVector::iterator& begin, uint32_t sampleChunk m_superBlock.m_header.m_blockIndex = m_txBlockIndex; m_superBlock.m_header.m_sampleBytes = (SDR_RX_SAMP_SZ <= 16 ? 2 : 4); m_superBlock.m_header.m_sampleBits = SDR_RX_SAMP_SZ; - memcpy((char *) &m_superBlock.m_protectedBlock, (const char *) &metaData, sizeof(SDRDaemonMetaDataFEC)); + + SDRDaemonMetaDataFEC *destMeta = (SDRDaemonMetaDataFEC *) &m_superBlock.m_protectedBlock; + *destMeta = metaData; + //memcpy((char *) &m_superBlock.m_protectedBlock, (const char *) &metaData, sizeof(SDRDaemonMetaDataFEC)); if (!(metaData == m_currentMetaFEC)) { diff --git a/plugins/samplesink/sdrdaemonsink/udpsinkfecworker.cpp b/plugins/samplesink/sdrdaemonsink/udpsinkfecworker.cpp index 7618c4421..29f2c14c4 100644 --- a/plugins/samplesink/sdrdaemonsink/udpsinkfecworker.cpp +++ b/plugins/samplesink/sdrdaemonsink/udpsinkfecworker.cpp @@ -46,9 +46,13 @@ void UDPSinkFECWorker::startWork() qDebug("UDPSinkFECWorker::startWork"); m_startWaitMutex.lock(); m_udpSocket = new QUdpSocket(this); + start(); - while(!m_running) + + while(!m_running) { m_startWaiter.wait(&m_startWaitMutex, 100); + } + m_startWaitMutex.unlock(); } diff --git a/plugins/samplesink/sdrdaemonsink/udpsinkfecworker.h b/plugins/samplesink/sdrdaemonsink/udpsinkfecworker.h index 32580aa3f..fb61b602c 100644 --- a/plugins/samplesink/sdrdaemonsink/udpsinkfecworker.h +++ b/plugins/samplesink/sdrdaemonsink/udpsinkfecworker.h @@ -135,7 +135,7 @@ private: QMutex m_startWaitMutex; QWaitCondition m_startWaiter; - bool m_running; + volatile bool m_running; CM256 m_cm256; //!< CM256 library object bool m_cm256Valid; //!< true if CM256 library is initialized correctly QUdpSocket *m_udpSocket; diff --git a/plugins/samplesink/soapysdroutput/CMakeLists.txt b/plugins/samplesink/soapysdroutput/CMakeLists.txt index 95011bb52..b1b1db381 100644 --- a/plugins/samplesink/soapysdroutput/CMakeLists.txt +++ b/plugins/samplesink/soapysdroutput/CMakeLists.txt @@ -28,8 +28,8 @@ include_directories( ${CMAKE_CURRENT_BINARY_DIR} ${CMAKE_SOURCE_DIR}/swagger/sdrangel/code/qt5/client ${CMAKE_SOURCE_DIR}/devices - ${SOAPYSDRSRC}/include - ${SOAPYSDRSRC}/src + ${SOAPYSDR_SOURCE_DIR}/include + ${SOAPYSDR_SOURCE_DIR}/src ) else (BUILD_DEBIAN) include_directories( @@ -56,7 +56,7 @@ add_library(outputsoapysdr SHARED if (BUILD_DEBIAN) target_link_libraries(outputsoapysdr ${QT_LIBRARIES} - bladerf + SoapySDR sdrbase sdrgui swagger diff --git a/plugins/samplesink/soapysdroutput/readme.md b/plugins/samplesink/soapysdroutput/readme.md new file mode 100644 index 000000000..5eb020cf2 --- /dev/null +++ b/plugins/samplesink/soapysdroutput/readme.md @@ -0,0 +1,188 @@ +

SoapySDR output plugin

+ +

Introduction

+ +This output sample sink plugin sends its samples to a device interfaced with [SoapySDR](https://github.com/pothosware/SoapySDR/wiki). + +SoapySDR is a [C/C++ API](https://github.com/pothosware/SoapySDR/blob/master/include/SoapySDR/Device.hpp) that interfaces SDR hardware on one side and application software on the other. Due to its very generic nature it was fairly difficult to implement and specific UI widgets were developped to handle specific types of parameters. The level of control depends on how the device API was implemented by the vendors. On application side some parts of the API have not been implemented and can be left as possible enhancements (see next). In any case it is recommended to use the native plugins if they are available. + +SoapySDR devices appear in the list of available devices in the order they are listed in the API call to SoapySDR. If more than one device controlled by SoapySDR is listed then its sequence number is incremented like: + + - SoapySDR[0:0] HackRF One... + - SoapySDR[1:0] HackRF One... + +If the same device exposes several channels they appear as distinct devices with the channel number incremented like: + + - SoapySDR[1:0] LimeSDR... + - SoapySDR[1:1] LimeSDR... + +This works similarly to LimeSDR USB or BladeRF 2.0 micro + +

Binary distributions

+ +The binary distributions provide only the SoapySDR base library. It is your responsibility to install SoapySDR in your system with the SoapySDR plugins suitable for your hardware. + +

SoapySDR API implementation

+ +Not all parts are implemented. Currently the following have been left out: + + - Frequency API tuning arguments. The tuning elements are of course supported. + - Clocking API + - Time API + - Sensor API + - Register API + - GPIO API + - I2C API + - SPI API + - UART API + +

Particular considerations concerning hardware

+ +In general as previously stated you should choose the native plugins if they are available. These are: + + - BladeRF + - HackRF + - LimeSDR + - PlutoSDR + +The following paragraphs list the known issues or oddities. + +

BladeRF

+ +It is very important NOT to use SoapySDR. The default parameters are set to flash the FPGA but as this does not suceeds it results in a FPGA image wipe out and the device returns in "Cypress" mode. It is not too difficult to recover but there is no point risking the hassle. + +

Red Pitaya

+ +When installed the Red Pitaya SoapySDR plugin lists a Red Pitaya device even if there is no Red Pitaya attached. Trying to select and start it when there is no Red Pitaya will result in program crash. + +

Interface

+ +![SoapySDR input plugin GUI](../../../doc/img/SoapySDROutput_plugin1.png) + +The top part described by number tags is common for all devices. The bottom part under the "A" tag depends on the SoapySDR device implementation. The corresponding widgets are stacked vertically inside a scrollable area as there may be many controls depending on how the device interface is implemented in SoapySDR. Move the slider on the right to see all parameters available. + +

1: Start/Stop

+ +Device start / stop button. + + - Blue triangle icon: device is ready and can be started + - Red square icon: device is running and can be stopped + - Magenta (or pink) square icon: an error occurred. In the case the device was accidentally disconnected you may click on the icon, plug back in and start again. + +

2: Stream sample rate

+ +Baseband I/Q sample rate in kS/s. This is the device sample rate (the "SR" SoapySDR control) divided by the interpolation factor (4). + +

3: Frequency

+ +This is the center frequency of transmission in kHz. The center frequency is usually the same for all Tx channels. The GUI of the sibling channel if present is adjusted automatically if necessary. This control corresponds to the first SoapySDR tuning element usually labeled as "RF" and would generally control the main local oscillator (LO). + +Use the wheels to adjust the value. Left click on a digit sets the cursor position at this digit. Right click on a digit sets all digits on the right to zero. This effectively floors value at the digit position. Wheels are moved with the mousewheel while pointing at the wheel or by selecting the wheel with the left mouse click and using the keyboard arrows. Pressing shift simultaneously moves digit by 5 and pressing control moves it by 2. + +

4: Interpolation factor

+ +The I/Q stream from the application is upsampled by a power of two before being sent to the the SoapySDR controlled device. Possible values are increasing powers of two: 1 (no interpolation), 2, 4, 8, 16, 32, 64. + +

5: Transverter mode open dialog

+ +This button opens a dialog to set the transverter mode frequency translation options: + +![Input stream transverter dialog](../../../doc/img/RTLSDR_plugin_xvrt.png) + +Note that if you mouse over the button a tooltip appears that displays the translating frequency and if translation is enabled or disabled. When the frequency translation is enabled the button is lit. + +

5.1: Translating frequency

+ +You can set the translating frequency in Hz with this dial. The manipulation of the dial is described in (3: Frequency). + +The frequency set in the device is the frequency on the main dial (1) minus this frequency. Thus it is positive for down converters and negative for up converters. + +For example a mixer at 120 MHz for HF operation you would set the value to -120,000,000 Hz so that if the main dial frequency is set at 7,130 kHz the PlutoSDR will be set to 127.130 MHz. + +If you use a down converter to receive the 6 cm band narrowband center frequency of 5670 MHz at 432 MHz you would set the translating frequency to 5760 - 432 = 5328 MHz thus dial +5,328,000,000 Hz. + +For bands even higher in the frequency spectrum the GHz digits are not really significant so you can have them set at 1 GHz. Thus to receive the 10368 MHz frequency at 432 MHz you would set the translating frequency to 1368 - 432 = 936 MHz. Note that in this case the frequency of the LO used in the mixer of the transverter is set at 9936 MHz. + +The Hz precision allows a fine tuning of the transverter LO offset + +

5.2: Translating frequency enable/disable

+ +Use this toggle button to activate or deactivate the frequency translation + +

5.3: Confirmation buttons

+ +Use these buttons to confirm ("OK") or dismiss ("Cancel") your changes. + +

6: Software LO ppm correction

+ +Use this slider to adjust SDRangel internal LO correction in ppm. It can be varied from -100.0 to 100.0 in 0.1 steps and is applied in software when calculating the frequency at which the LO should be set. + +

A: SoapySDR variable interface

+ +The form of widgets is closely related to the type of setting defined in the [SoapySDR interface](https://github.com/pothosware/SoapySDR/blob/master/include/SoapySDR/Types.hpp). These are: + + - Ranges + - Continuous range when maximum and minimum are different + - Discrete value when maximum and minimum are equal. Usually this appears in a range list to define a set of values + - List of ranges: more than one range applies to the same setting + - Arguments defined by + - type: boolean, integer, floating point, string + - nature: continuous or discrete + - String list + +

A.1: Continuous range

+ +If the range is all in the positive domain the unsigned variation is used: + +![SoapySDR input plugin GUI](../../../doc/img/SoapySDR_range_pos.png) + +Note that the same widget is used for single ranges and ranges list. In this case the range selection combo on the right is disabled. The manipulation of the dial is described in (3: Frequency) + +If the range is in both the positive and negative domains the signed variation is used: + +![SoapySDR input plugin GUI](../../../doc/img/SoapySDR_range_neg.png) + +If the range applies to a gain a slider is used: + +![SoapySDR input plugin GUI](../../../doc/img/SoapySDR_range_gain.png) + +

A.2: Discrete range

+ +Appears with a combo box to select a discrete value: + +![SoapySDR input plugin GUI](../../../doc/img/SoapySDR_range_discrete.png) + +

A.3: List of ranges

+ +In this case the range selection combo on the right is enabled: + +![SoapySDR input plugin GUI](../../../doc/img/SoapySDR_range_list1.png) + +

A.4: Boolean argument

+ +A checkbox is used to control boolean values: + +![SoapySDR input plugin GUI](../../../doc/img/SoapySDR_arg_bool2.png) + +For AGC, Auto DC and Auto IQ corrections the checkbox has its text label on the right: + +![SoapySDR input plugin GUI](../../../doc/img/SoapySDR_arg_bool1.png) + +When set (true) a checkbox is lit in orange: + +![SoapySDR input plugin GUI](../../../doc/img/SoapySDR_arg_bool3.png) + +

A.5: Int, Float and String arguments

+ +For all these types of values a line editor is used. Numerical values are parsed from string: + +![SoapySDR input plugin GUI](../../../doc/img/SoapySDR_arg_str.png) + +

A.6 String lists

+ +Some parameters like the antenna ports are expressed as a list of possible string values. These are presented in a combo box: + +![SoapySDR input plugin GUI](../../../doc/img/SoapySDR_arg_strlist.png) + + + diff --git a/plugins/samplesink/soapysdroutput/soapysdroutput.cpp b/plugins/samplesink/soapysdroutput/soapysdroutput.cpp index d3642adc4..d6effe288 100644 --- a/plugins/samplesink/soapysdroutput/soapysdroutput.cpp +++ b/plugins/samplesink/soapysdroutput/soapysdroutput.cpp @@ -16,6 +16,12 @@ #include +#include "SWGDeviceSettings.h" +#include "SWGSoapySDROutputSettings.h" +#include "SWGDeviceState.h" +#include "SWGDeviceReport.h" +#include "SWGSoapySDRReport.h" + #include "util/simpleserializer.h" #include "dsp/dspcommands.h" #include "dsp/dspengine.h" @@ -38,6 +44,9 @@ SoapySDROutput::SoapySDROutput(DeviceSinkAPI *deviceAPI) : { openDevice(); initGainSettings(m_settings); + initTunableElementsSettings(m_settings); + initStreamArgSettings(m_settings); + initDeviceArgSettings(m_settings); } SoapySDROutput::~SoapySDROutput() @@ -237,6 +246,11 @@ const std::vector& SoapySDROutput::getIndivid return channelSettings->m_gainSettings; } +const SoapySDR::ArgInfoList& SoapySDROutput::getDeviceArgInfoList() +{ + return m_deviceShared.m_deviceParams->getDeviceArgs(); +} + void SoapySDROutput::initGainSettings(SoapySDROutputSettings& settings) { const DeviceSoapySDRParams::ChannelSettings* channelSettings = m_deviceShared.m_deviceParams->getTxChannelSettings(m_deviceShared.m_channel); @@ -250,6 +264,69 @@ void SoapySDROutput::initGainSettings(SoapySDROutputSettings& settings) updateGains(m_deviceShared.m_device, m_deviceShared.m_channel, settings); } +void SoapySDROutput::initTunableElementsSettings(SoapySDROutputSettings& settings) +{ + const DeviceSoapySDRParams::ChannelSettings* channelSettings = m_deviceShared.m_deviceParams->getTxChannelSettings(m_deviceShared.m_channel); + settings.m_tunableElements.clear(); + bool first = true; + + for (const auto &it : channelSettings->m_frequencySettings) + { + if (first) + { + first = false; + continue; + } + + settings.m_tunableElements[QString(it.m_name.c_str())] = 0.0; + } + + updateTunableElements(m_deviceShared.m_device, m_deviceShared.m_channel, settings); +} + +const SoapySDR::ArgInfoList& SoapySDROutput::getStreamArgInfoList() +{ + const DeviceSoapySDRParams::ChannelSettings* channelSettings = m_deviceShared.m_deviceParams->getTxChannelSettings(m_deviceShared.m_channel); + return channelSettings->m_streamSettingsArgs; +} + +void SoapySDROutput::initStreamArgSettings(SoapySDROutputSettings& settings) +{ + const DeviceSoapySDRParams::ChannelSettings* channelSettings = m_deviceShared.m_deviceParams->getTxChannelSettings(m_deviceShared.m_channel); + settings.m_streamArgSettings.clear(); + + for (const auto &it : channelSettings->m_streamSettingsArgs) + { + if (it.type == SoapySDR::ArgInfo::BOOL) { + settings.m_streamArgSettings[QString(it.key.c_str())] = QVariant(it.value == "true"); + } else if (it.type == SoapySDR::ArgInfo::INT) { + settings.m_streamArgSettings[QString(it.key.c_str())] = QVariant(atoi(it.value.c_str())); + } else if (it.type == SoapySDR::ArgInfo::FLOAT) { + settings.m_streamArgSettings[QString(it.key.c_str())] = QVariant(atof(it.value.c_str())); + } else if (it.type == SoapySDR::ArgInfo::STRING) { + settings.m_streamArgSettings[QString(it.key.c_str())] = QVariant(it.value.c_str()); + } + } +} + +void SoapySDROutput::initDeviceArgSettings(SoapySDROutputSettings& settings) +{ + settings.m_deviceArgSettings.clear(); + + for (const auto &it : m_deviceShared.m_deviceParams->getDeviceArgs()) + { + if (it.type == SoapySDR::ArgInfo::BOOL) { + settings.m_deviceArgSettings[QString(it.key.c_str())] = QVariant(it.value == "true"); + } else if (it.type == SoapySDR::ArgInfo::INT) { + settings.m_deviceArgSettings[QString(it.key.c_str())] = QVariant(atoi(it.value.c_str())); + } else if (it.type == SoapySDR::ArgInfo::FLOAT) { + settings.m_deviceArgSettings[QString(it.key.c_str())] = QVariant(atof(it.value.c_str())); + } else if (it.type == SoapySDR::ArgInfo::STRING) { + settings.m_deviceArgSettings[QString(it.key.c_str())] = QVariant(it.value.c_str()); + } + } +} + bool SoapySDROutput::hasDCAutoCorrection() { const DeviceSoapySDRParams::ChannelSettings* channelSettings = m_deviceShared.m_deviceParams->getTxChannelSettings(m_deviceShared.m_channel); @@ -549,7 +626,7 @@ QByteArray SoapySDROutput::serialize() const return m_settings.serialize(); } -bool SoapySDROutput::deserialize(const QByteArray& data __attribute__((unused))) +bool SoapySDROutput::deserialize(const QByteArray& data) { bool success = true; @@ -636,6 +713,17 @@ void SoapySDROutput::updateGains(SoapySDR::Device *dev, int requestedChannel, So } } +void SoapySDROutput::updateTunableElements(SoapySDR::Device *dev, int requestedChannel, SoapySDROutputSettings& settings) +{ + if (dev == 0) { + return; + } + + for (const auto &name : settings.m_tunableElements.keys()) { + settings.m_tunableElements[name] = dev->getFrequency(SOAPY_SDR_TX, requestedChannel, name.toStdString()); + } +} + bool SoapySDROutput::handleMessage(const Message& message) { if (MsgConfigureSoapySDROutput::match(message)) @@ -697,6 +785,33 @@ bool SoapySDROutput::handleMessage(const Message& message) return true; } + else if (DeviceSoapySDRShared::MsgReportDeviceArgsChange::match(message)) + { + DeviceSoapySDRShared::MsgReportDeviceArgsChange& report = (DeviceSoapySDRShared::MsgReportDeviceArgsChange&) message; + QMap deviceArgSettings = report.getDeviceArgSettings(); + + for (const auto &oname : m_settings.m_deviceArgSettings.keys()) + { + auto nvalue = deviceArgSettings.find(oname); + + if (nvalue != deviceArgSettings.end() && (m_settings.m_deviceArgSettings[oname] != *nvalue)) + { + m_settings.m_deviceArgSettings[oname] = *nvalue; + qDebug("SoapySDROutput::handleMessage: MsgReportDeviceArgsChange: device argument %s set to %s", + oname.toStdString().c_str(), nvalue->toString().toStdString().c_str()); + } + } + + // propagate settings to GUI if any + if (getMessageQueueToGUI()) + { + DeviceSoapySDRShared::MsgReportDeviceArgsChange *reportToGUI = DeviceSoapySDRShared::MsgReportDeviceArgsChange::create( + m_settings.m_deviceArgSettings); + getMessageQueueToGUI()->push(reportToGUI); + } + + return true; + } else { return false; @@ -709,6 +824,7 @@ bool SoapySDROutput::applySettings(const SoapySDROutputSettings& settings, bool bool forwardChangeToBuddies = false; bool globalGainChanged = false; bool individualGainsChanged = false; + bool deviceArgsChanged = false; SoapySDR::Device *dev = m_deviceShared.m_device; SoapySDROutputThread *outputThread = findThread(); @@ -846,7 +962,7 @@ bool SoapySDROutput::applySettings(const SoapySDROutputSettings& settings, bool { auto nvalue = settings.m_tunableElements.find(oname); - if (nvalue != settings.m_tunableElements.end() && (m_settings.m_tunableElements[oname] != *nvalue)) + if (nvalue != settings.m_tunableElements.end() && ((m_settings.m_tunableElements[oname] != *nvalue) || force)) { if (dev != 0) { @@ -975,6 +1091,57 @@ bool SoapySDROutput::applySettings(const SoapySDROutputSettings& settings, bool } } + for (const auto &oname : m_settings.m_streamArgSettings.keys()) + { + auto nvalue = settings.m_streamArgSettings.find(oname); + + if (nvalue != settings.m_streamArgSettings.end() && ((m_settings.m_streamArgSettings[oname] != *nvalue) || force)) + { + if (dev != 0) + { + try + { + dev->writeSetting(SOAPY_SDR_TX, requestedChannel, oname.toStdString(), nvalue->toString().toStdString()); + qDebug("SoapySDROutput::applySettings: stream argument %s set to %s", + oname.toStdString().c_str(), nvalue->toString().toStdString().c_str()); + } + catch (const std::exception &ex) + { + qCritical("SoapySDROutput::applySettings: cannot set stream argument %s to %s: %s", + oname.toStdString().c_str(), nvalue->toString().toStdString().c_str(), ex.what()); + } + } + + m_settings.m_streamArgSettings[oname] = *nvalue; + } + } + + for (const auto &oname : m_settings.m_deviceArgSettings.keys()) + { + auto nvalue = settings.m_deviceArgSettings.find(oname); + + if (nvalue != settings.m_deviceArgSettings.end() && ((m_settings.m_deviceArgSettings[oname] != *nvalue) || force)) + { + if (dev != 0) + { + try + { + dev->writeSetting(oname.toStdString(), nvalue->toString().toStdString()); + qDebug("SoapySDROutput::applySettings: device argument %s set to %s", + oname.toStdString().c_str(), nvalue->toString().toStdString().c_str()); + } + catch (const std::exception &ex) + { + qCritical("SoapySDRInput::applySettings: cannot set device argument %s to %s: %s", + oname.toStdString().c_str(), nvalue->toString().toStdString().c_str(), ex.what()); + } + } + + m_settings.m_deviceArgSettings[oname] = *nvalue; + deviceArgsChanged = true; + } + } + if (forwardChangeOwnDSP) { int sampleRate = settings.m_devSampleRate/(1<& sourceBuddies = m_deviceAPI->getSourceBuddies(); const std::vector& sinkBuddies = m_deviceAPI->getSinkBuddies(); @@ -1011,6 +1178,27 @@ bool SoapySDROutput::applySettings(const SoapySDROutputSettings& settings, bool } } + if (deviceArgsChanged) + { + // send to buddies + const std::vector& sourceBuddies = m_deviceAPI->getSourceBuddies(); + const std::vector& sinkBuddies = m_deviceAPI->getSinkBuddies(); + + for (const auto &itSource : sourceBuddies) + { + DeviceSoapySDRShared::MsgReportDeviceArgsChange *report = DeviceSoapySDRShared::MsgReportDeviceArgsChange::create( + settings.m_deviceArgSettings); + itSource->getSampleSourceInputMessageQueue()->push(report); + } + + for (const auto &itSink : sinkBuddies) + { + DeviceSoapySDRShared::MsgReportDeviceArgsChange *report = DeviceSoapySDRShared::MsgReportDeviceArgsChange::create( + settings.m_deviceArgSettings); + itSink->getSampleSinkInputMessageQueue()->push(report); + } + } + m_settings = settings; if (globalGainChanged || individualGainsChanged) @@ -1034,7 +1222,499 @@ bool SoapySDROutput::applySettings(const SoapySDROutputSettings& settings, bool << " m_log2Interp: " << m_settings.m_log2Interp << " m_devSampleRate: " << m_settings.m_devSampleRate << " m_bandwidth: " << m_settings.m_bandwidth - << " m_globalGain: " << m_settings.m_globalGain; + << " m_globalGain: " << m_settings.m_globalGain + << " force: " << force; + + QMap::const_iterator doubleIt = m_settings.m_individualGains.begin(); + + for(; doubleIt != m_settings.m_individualGains.end(); ++doubleIt) { + qDebug("SoapySDROutput::applySettings: m_individualGains[%s]: %lf", doubleIt.key().toStdString().c_str(), doubleIt.value()); + } + + doubleIt = m_settings.m_tunableElements.begin(); + + for(; doubleIt != m_settings.m_tunableElements.end(); ++doubleIt) { + qDebug("SoapySDROutput::applySettings: m_tunableElements[%s]: %lf", doubleIt.key().toStdString().c_str(), doubleIt.value()); + } + + QMap::const_iterator varIt = m_settings.m_deviceArgSettings.begin(); + + for(; varIt != m_settings.m_deviceArgSettings.end(); ++varIt) + { + qDebug("SoapySDROutput::applySettings: m_deviceArgSettings[%s] (type %d): %s", + varIt.key().toStdString().c_str(), + (int) varIt.value().type(), // bool: 1, int: 2, double: 6, string: 10 (http://doc.qt.io/archives/qt-4.8/qvariant.html) + varIt.value().toString().toStdString().c_str()); + } + + varIt = m_settings.m_streamArgSettings.begin(); + + for(; varIt != m_settings.m_streamArgSettings.end(); ++varIt) + { + qDebug("SoapySDROutput::applySettings: m_streamArgSettings[%s] (type %d): %s", + varIt.key().toStdString().c_str(), + (int) varIt.value().type(), + varIt.value().toString().toStdString().c_str()); + } return true; } + +int SoapySDROutput::webapiSettingsGet( + SWGSDRangel::SWGDeviceSettings& response, + QString& errorMessage) +{ + (void) errorMessage; + response.setSoapySdrOutputSettings(new SWGSDRangel::SWGSoapySDROutputSettings()); + response.getSoapySdrOutputSettings()->init(); + webapiFormatDeviceSettings(response, m_settings); + return 200; +} + +int SoapySDROutput::webapiSettingsPutPatch( + bool force, + const QStringList& deviceSettingsKeys, + SWGSDRangel::SWGDeviceSettings& response, // query + response + QString& errorMessage) +{ + (void) errorMessage; + SoapySDROutputSettings settings = m_settings; + + if (deviceSettingsKeys.contains("centerFrequency")) { + settings.m_centerFrequency = response.getSoapySdrOutputSettings()->getCenterFrequency(); + } + if (deviceSettingsKeys.contains("LOppmTenths")) { + settings.m_LOppmTenths = response.getSoapySdrOutputSettings()->getLOppmTenths(); + } + if (deviceSettingsKeys.contains("devSampleRate")) { + settings.m_devSampleRate = response.getSoapySdrOutputSettings()->getDevSampleRate(); + } + if (deviceSettingsKeys.contains("bandwidth")) { + settings.m_bandwidth = response.getSoapySdrOutputSettings()->getBandwidth(); + } + if (deviceSettingsKeys.contains("log2Interp")) { + settings.m_log2Interp = response.getSoapySdrOutputSettings()->getLog2Interp(); + } + if (deviceSettingsKeys.contains("transverterDeltaFrequency")) { + settings.m_transverterDeltaFrequency = response.getSoapySdrOutputSettings()->getTransverterDeltaFrequency(); + } + if (deviceSettingsKeys.contains("transverterMode")) { + settings.m_transverterMode = response.getSoapySdrOutputSettings()->getTransverterMode() != 0; + } + if (deviceSettingsKeys.contains("antenna")) { + settings.m_antenna = *response.getSoapySdrOutputSettings()->getAntenna(); + } + + if (deviceSettingsKeys.contains("tunableElements")) + { + QList *tunableElements = response.getSoapySdrOutputSettings()->getTunableElements(); + + for (const auto &itArg : *tunableElements) + { + QMap::iterator itSettings = settings.m_tunableElements.find(*(itArg->getKey())); + + if (itSettings != settings.m_tunableElements.end()) + { + QVariant v = webapiVariantFromArgValue(itArg); + itSettings.value() = v.toDouble(); + } + } + } + + if (deviceSettingsKeys.contains("globalGain")) { + settings.m_globalGain = response.getSoapySdrOutputSettings()->getGlobalGain(); + } + + if (deviceSettingsKeys.contains("individualGains")) + { + QList *individualGains = response.getSoapySdrOutputSettings()->getIndividualGains(); + + for (const auto &itArg : *individualGains) + { + QMap::iterator itSettings = settings.m_individualGains.find(*(itArg->getKey())); + + if (itSettings != settings.m_individualGains.end()) + { + QVariant v = webapiVariantFromArgValue(itArg); + itSettings.value() = v.toDouble(); + } + } + } + + if (deviceSettingsKeys.contains("autoGain")) { + settings.m_autoGain = response.getSoapySdrOutputSettings()->getAutoGain() != 0; + } + if (deviceSettingsKeys.contains("autoDCCorrection")) { + settings.m_autoDCCorrection = response.getSoapySdrOutputSettings()->getAutoDcCorrection() != 0; + } + if (deviceSettingsKeys.contains("autoIQCorrection")) { + settings.m_autoIQCorrection = response.getSoapySdrOutputSettings()->getAutoIqCorrection() != 0; + } + if (deviceSettingsKeys.contains("dcCorrection")) + { + settings.m_dcCorrection.real(response.getSoapySdrOutputSettings()->getDcCorrection()->getReal()); + settings.m_dcCorrection.imag(response.getSoapySdrOutputSettings()->getDcCorrection()->getImag()); + } + if (deviceSettingsKeys.contains("iqCorrection")) + { + settings.m_iqCorrection.real(response.getSoapySdrOutputSettings()->getIqCorrection()->getReal()); + settings.m_iqCorrection.imag(response.getSoapySdrOutputSettings()->getIqCorrection()->getImag()); + } + + if (deviceSettingsKeys.contains("streamArgSettings")) + { + QList *streamArgSettings = response.getSoapySdrOutputSettings()->getStreamArgSettings(); + + for (const auto itArg : *streamArgSettings) + { + QMap::iterator itSettings = settings.m_streamArgSettings.find(*itArg->getKey()); + + if (itSettings != settings.m_streamArgSettings.end()) { + itSettings.value() = webapiVariantFromArgValue(itArg); + } + } + } + + if (deviceSettingsKeys.contains("deviceArgSettings")) + { + QList *deviceArgSettings = response.getSoapySdrOutputSettings()->getDeviceArgSettings(); + + for (const auto itArg : *deviceArgSettings) + { + QMap::iterator itSettings = settings.m_deviceArgSettings.find(*itArg->getKey()); + + if (itSettings != settings.m_deviceArgSettings.end()) { + itSettings.value() = webapiVariantFromArgValue(itArg); + } + } + } + + MsgConfigureSoapySDROutput *msg = MsgConfigureSoapySDROutput::create(settings, force); + m_inputMessageQueue.push(msg); + + if (m_guiMessageQueue) // forward to GUI if any + { + MsgConfigureSoapySDROutput *msgToGUI = MsgConfigureSoapySDROutput::create(settings, force); + m_guiMessageQueue->push(msgToGUI); + } + + webapiFormatDeviceSettings(response, settings); + return 200; +} + +int SoapySDROutput::webapiReportGet(SWGSDRangel::SWGDeviceReport& response, QString& errorMessage) +{ + (void) errorMessage; + response.setSoapySdrOutputReport(new SWGSDRangel::SWGSoapySDRReport()); + response.getSoapySdrOutputReport()->init(); + webapiFormatDeviceReport(response); + return 200; +} + +int SoapySDROutput::webapiRunGet( + SWGSDRangel::SWGDeviceState& response, + QString& errorMessage) +{ + (void) errorMessage; + m_deviceAPI->getDeviceEngineStateStr(*response.getState()); + return 200; +} + +int SoapySDROutput::webapiRun( + bool run, + SWGSDRangel::SWGDeviceState& response, + QString& errorMessage) +{ + (void) errorMessage; + m_deviceAPI->getDeviceEngineStateStr(*response.getState()); + MsgStartStop *message = MsgStartStop::create(run); + m_inputMessageQueue.push(message); + + if (m_guiMessageQueue) // forward to GUI if any + { + MsgStartStop *msgToGUI = MsgStartStop::create(run); + m_guiMessageQueue->push(msgToGUI); + } + + return 200; +} + +void SoapySDROutput::webapiFormatDeviceSettings(SWGSDRangel::SWGDeviceSettings& response, const SoapySDROutputSettings& settings) +{ + response.getSoapySdrOutputSettings()->setCenterFrequency(settings.m_centerFrequency); + response.getSoapySdrOutputSettings()->setLOppmTenths(settings.m_LOppmTenths); + response.getSoapySdrOutputSettings()->setDevSampleRate(settings.m_devSampleRate); + response.getSoapySdrOutputSettings()->setLog2Interp(settings.m_log2Interp); + response.getSoapySdrOutputSettings()->setTransverterDeltaFrequency(settings.m_transverterDeltaFrequency); + response.getSoapySdrOutputSettings()->setTransverterMode(settings.m_transverterMode ? 1 : 0); + + if (response.getSoapySdrOutputSettings()->getAntenna()) { + *response.getSoapySdrOutputSettings()->getAntenna() = settings.m_antenna; + } else { + response.getSoapySdrOutputSettings()->setAntenna(new QString(settings.m_antenna)); + } + + if (response.getSoapySdrOutputSettings()->getTunableElements()) { + response.getSoapySdrOutputSettings()->getTunableElements()->clear(); + } else { + response.getSoapySdrOutputSettings()->setTunableElements(new QList); + } + + for (const auto itName : settings.m_tunableElements.keys()) + { + response.getSoapySdrOutputSettings()->getTunableElements()->append(new SWGSDRangel::SWGArgValue); + response.getSoapySdrOutputSettings()->getTunableElements()->back()->setKey(new QString( itName)); + double value = settings.m_tunableElements.value(itName); + response.getSoapySdrOutputSettings()->getTunableElements()->back()->setValueString(new QString(tr("%1").arg(value))); + response.getSoapySdrOutputSettings()->getTunableElements()->back()->setValueType(new QString("float")); + } + + response.getSoapySdrOutputSettings()->setBandwidth(settings.m_bandwidth); + response.getSoapySdrOutputSettings()->setGlobalGain(settings.m_globalGain); + + if (response.getSoapySdrOutputSettings()->getIndividualGains()) { + response.getSoapySdrOutputSettings()->getIndividualGains()->clear(); + } else { + response.getSoapySdrOutputSettings()->setIndividualGains(new QList); + } + + for (const auto itName : settings.m_individualGains.keys()) + { + response.getSoapySdrOutputSettings()->getIndividualGains()->append(new SWGSDRangel::SWGArgValue); + response.getSoapySdrOutputSettings()->getIndividualGains()->back()->setKey(new QString(itName)); + double value = settings.m_individualGains.value(itName); + response.getSoapySdrOutputSettings()->getIndividualGains()->back()->setValueString(new QString(tr("%1").arg(value))); + response.getSoapySdrOutputSettings()->getIndividualGains()->back()->setValueType(new QString("float")); + } + + response.getSoapySdrOutputSettings()->setAutoGain(settings.m_autoGain ? 1 : 0); + response.getSoapySdrOutputSettings()->setAutoDcCorrection(settings.m_autoDCCorrection ? 1 : 0); + response.getSoapySdrOutputSettings()->setAutoIqCorrection(settings.m_autoIQCorrection ? 1 : 0); + + if (!response.getSoapySdrOutputSettings()->getDcCorrection()) { + response.getSoapySdrOutputSettings()->setDcCorrection(new SWGSDRangel::SWGComplex()); + } + + response.getSoapySdrOutputSettings()->getDcCorrection()->setReal(settings.m_dcCorrection.real()); + response.getSoapySdrOutputSettings()->getDcCorrection()->setImag(settings.m_dcCorrection.imag()); + + if (!response.getSoapySdrOutputSettings()->getIqCorrection()) { + response.getSoapySdrOutputSettings()->setIqCorrection(new SWGSDRangel::SWGComplex()); + } + + response.getSoapySdrOutputSettings()->getIqCorrection()->setReal(settings.m_iqCorrection.real()); + response.getSoapySdrOutputSettings()->getIqCorrection()->setImag(settings.m_iqCorrection.imag()); + + if (response.getSoapySdrOutputSettings()->getStreamArgSettings()) { + response.getSoapySdrOutputSettings()->getStreamArgSettings()->clear(); + } else { + response.getSoapySdrOutputSettings()->setStreamArgSettings(new QList); + } + + for (const auto itName : settings.m_streamArgSettings.keys()) + { + response.getSoapySdrOutputSettings()->getStreamArgSettings()->append(new SWGSDRangel::SWGArgValue); + response.getSoapySdrOutputSettings()->getStreamArgSettings()->back()->setKey(new QString(itName)); + const QVariant& v = settings.m_streamArgSettings.value(itName); + webapiFormatArgValue(v, response.getSoapySdrOutputSettings()->getStreamArgSettings()->back()); + } + + if (response.getSoapySdrOutputSettings()->getDeviceArgSettings()) { + response.getSoapySdrOutputSettings()->getDeviceArgSettings()->clear(); + } else { + response.getSoapySdrOutputSettings()->setDeviceArgSettings(new QList); + } + + for (const auto itName : settings.m_deviceArgSettings.keys()) + { + response.getSoapySdrOutputSettings()->getDeviceArgSettings()->append(new SWGSDRangel::SWGArgValue); + response.getSoapySdrOutputSettings()->getDeviceArgSettings()->back()->setKey(new QString(itName)); + const QVariant& v = settings.m_deviceArgSettings.value(itName); + webapiFormatArgValue(v, response.getSoapySdrOutputSettings()->getDeviceArgSettings()->back()); + } +} + +void SoapySDROutput::webapiFormatDeviceReport(SWGSDRangel::SWGDeviceReport& response) +{ + const DeviceSoapySDRParams::ChannelSettings* channelSettings = m_deviceShared.m_deviceParams->getTxChannelSettings(m_deviceShared.m_channel); + + response.getSoapySdrOutputReport()->setDeviceSettingsArgs(new QList); + + for (const auto itArg : m_deviceShared.m_deviceParams->getDeviceArgs()) + { + response.getSoapySdrOutputReport()->getDeviceSettingsArgs()->append(new SWGSDRangel::SWGArgInfo); + webapiFormatArgInfo(itArg, response.getSoapySdrOutputReport()->getDeviceSettingsArgs()->back()); + } + + response.getSoapySdrOutputReport()->setStreamSettingsArgs(new QList); + + for (const auto itArg : channelSettings->m_streamSettingsArgs) + { + response.getSoapySdrOutputReport()->getStreamSettingsArgs()->append(new SWGSDRangel::SWGArgInfo); + webapiFormatArgInfo(itArg, response.getSoapySdrOutputReport()->getStreamSettingsArgs()->back()); + } + + response.getSoapySdrOutputReport()->setFrequencySettingsArgs(new QList); + + for (const auto itArg : channelSettings->m_frequencySettingsArgs) + { + response.getSoapySdrOutputReport()->getFrequencySettingsArgs()->append(new SWGSDRangel::SWGArgInfo); + webapiFormatArgInfo(itArg, response.getSoapySdrOutputReport()->getFrequencySettingsArgs()->back()); + } + + response.getSoapySdrOutputReport()->setHasAgc(channelSettings->m_hasAGC ? 1 : 0); + response.getSoapySdrOutputReport()->setHasDcAutoCorrection(channelSettings->m_hasDCAutoCorrection ? 1 : 0); + response.getSoapySdrOutputReport()->setHasDcOffsetValue(channelSettings->m_hasDCOffsetValue ? 1 : 0); + response.getSoapySdrOutputReport()->setHasFrequencyCorrectionValue(channelSettings->m_hasFrequencyCorrectionValue ? 1 : 0); + response.getSoapySdrOutputReport()->setHasIqBalanceValue(channelSettings->m_hasIQBalanceValue ? 1 : 0); + + if (channelSettings->m_antennas.size() != 0) + { + response.getSoapySdrOutputReport()->setAntennas(new QList); + + for (const auto itAntenna : channelSettings->m_antennas) { + response.getSoapySdrOutputReport()->getAntennas()->append(new QString(itAntenna.c_str())); + } + } + + if ((channelSettings->m_gainRange.maximum() != 0.0) || (channelSettings->m_gainRange.minimum() != 0.0)) + { + response.getSoapySdrOutputReport()->setGainRange(new SWGSDRangel::SWGRangeFloat()); + response.getSoapySdrOutputReport()->getGainRange()->setMin(channelSettings->m_gainRange.minimum()); + response.getSoapySdrOutputReport()->getGainRange()->setMax(channelSettings->m_gainRange.maximum()); + } + + if (channelSettings->m_gainSettings.size() != 0) + { + response.getSoapySdrOutputReport()->setGainSettings(new QList); + + for (const auto itGain : channelSettings->m_gainSettings) + { + response.getSoapySdrOutputReport()->getGainSettings()->append(new SWGSDRangel::SWGSoapySDRGainSetting()); + response.getSoapySdrOutputReport()->getGainSettings()->back()->setRange(new SWGSDRangel::SWGRangeFloat()); + response.getSoapySdrOutputReport()->getGainSettings()->back()->getRange()->setMin(itGain.m_range.minimum()); + response.getSoapySdrOutputReport()->getGainSettings()->back()->getRange()->setMax(itGain.m_range.maximum()); + response.getSoapySdrOutputReport()->getGainSettings()->back()->setName(new QString(itGain.m_name.c_str())); + } + } + + if (channelSettings->m_frequencySettings.size() != 0) + { + response.getSoapySdrOutputReport()->setFrequencySettings(new QList); + + for (const auto itFreq : channelSettings->m_frequencySettings) + { + response.getSoapySdrOutputReport()->getFrequencySettings()->append(new SWGSDRangel::SWGSoapySDRFrequencySetting()); + response.getSoapySdrOutputReport()->getFrequencySettings()->back()->setRanges(new QList); + + for (const auto itRange : itFreq.m_ranges) + { + response.getSoapySdrOutputReport()->getFrequencySettings()->back()->getRanges()->append(new SWGSDRangel::SWGRangeFloat()); + response.getSoapySdrOutputReport()->getFrequencySettings()->back()->getRanges()->back()->setMin(itRange.minimum()); + response.getSoapySdrOutputReport()->getFrequencySettings()->back()->getRanges()->back()->setMax(itRange.maximum()); + } + + response.getSoapySdrOutputReport()->getFrequencySettings()->back()->setName(new QString(itFreq.m_name.c_str())); + } + } + + if (channelSettings->m_ratesRanges.size() != 0) + { + response.getSoapySdrOutputReport()->setRatesRanges(new QList); + + for (const auto itRange : channelSettings->m_ratesRanges) + { + response.getSoapySdrOutputReport()->getRatesRanges()->append(new SWGSDRangel::SWGRangeFloat()); + response.getSoapySdrOutputReport()->getRatesRanges()->back()->setMin(itRange.minimum()); + response.getSoapySdrOutputReport()->getRatesRanges()->back()->setMax(itRange.maximum()); + } + } + + if (channelSettings->m_bandwidthsRanges.size() != 0) + { + response.getSoapySdrOutputReport()->setBandwidthsRanges(new QList); + + for (const auto itBandwidth : channelSettings->m_bandwidthsRanges) + { + response.getSoapySdrOutputReport()->getBandwidthsRanges()->append(new SWGSDRangel::SWGRangeFloat()); + response.getSoapySdrOutputReport()->getBandwidthsRanges()->back()->setMin(itBandwidth.minimum()); + response.getSoapySdrOutputReport()->getBandwidthsRanges()->back()->setMax(itBandwidth.maximum()); + } + } +} + +QVariant SoapySDROutput::webapiVariantFromArgValue(SWGSDRangel::SWGArgValue *argValue) +{ + if (*argValue->getValueType() == "bool") { + return QVariant((bool) (*argValue->getValueString() == "1")); + } else if (*argValue->getValueType() == "int") { + return QVariant((int) (atoi(argValue->getValueString()->toStdString().c_str()))); + } else if (*argValue->getValueType() == "float") { + return QVariant((double) (atof(argValue->getValueString()->toStdString().c_str()))); + } else { + return QVariant(QString(*argValue->getValueString())); + } +} + +void SoapySDROutput::webapiFormatArgValue(const QVariant& v, SWGSDRangel::SWGArgValue *argValue) +{ + if (v.type() == QVariant::Bool) + { + argValue->setValueType(new QString("bool")); + argValue->setValueString(new QString(v.toBool() ? "1" : "0")); + } + else if (v.type() == QVariant::Int) + { + argValue->setValueType(new QString("int")); + argValue->setValueString(new QString(tr("%1").arg(v.toInt()))); + } + else if (v.type() == QVariant::Double) + { + argValue->setValueType(new QString("float")); + argValue->setValueString(new QString(tr("%1").arg(v.toDouble()))); + } + else + { + argValue->setValueType(new QString("string")); + argValue->setValueString(new QString(v.toString())); + } +} + +void SoapySDROutput::webapiFormatArgInfo(const SoapySDR::ArgInfo& arg, SWGSDRangel::SWGArgInfo *argInfo) +{ + argInfo->setKey(new QString(arg.key.c_str())); + + if (arg.type == SoapySDR::ArgInfo::BOOL) { + argInfo->setValueType(new QString("bool")); + } else if (arg.type == SoapySDR::ArgInfo::INT) { + argInfo->setValueType(new QString("int")); + } else if (arg.type == SoapySDR::ArgInfo::FLOAT) { + argInfo->setValueType(new QString("float")); + } else { + argInfo->setValueType(new QString("string")); + } + + argInfo->setValueString(new QString(arg.value.c_str())); + argInfo->setName(new QString(arg.name.c_str())); + argInfo->setDescription(new QString(arg.description.c_str())); + argInfo->setUnits(new QString(arg.units.c_str())); + + if ((arg.range.minimum() != 0.0) || (arg.range.maximum() != 0.0)) + { + argInfo->setRange(new SWGSDRangel::SWGRangeFloat()); + argInfo->getRange()->setMin(arg.range.minimum()); + argInfo->getRange()->setMax(arg.range.maximum()); + } + + argInfo->setValueOptions(new QList); + + for (const auto itOpt : arg.options) { + argInfo->getValueOptions()->append(new QString(itOpt.c_str())); + } + + argInfo->setOptionNames(new QList); + + for (const auto itOpt : arg.optionNames) { + argInfo->getOptionNames()->append(new QString(itOpt.c_str())); + } +} diff --git a/plugins/samplesink/soapysdroutput/soapysdroutput.h b/plugins/samplesink/soapysdroutput/soapysdroutput.h index 5fb9cc3f2..7be726329 100644 --- a/plugins/samplesink/soapysdroutput/soapysdroutput.h +++ b/plugins/samplesink/soapysdroutput/soapysdroutput.h @@ -32,6 +32,13 @@ class SoapySDROutputThread; namespace SoapySDR { class Device; + class ArgInfo; +} + +namespace SWGSDRangel +{ + class SWGArgValue; + class SWGArgInfo; } class SoapySDROutput : public DeviceSampleSink { @@ -133,12 +140,40 @@ public: const SoapySDR::RangeList& getBandwidthRanges(); const std::vector& getTunableElements(); const std::vector& getIndividualGainsRanges(); + const SoapySDR::ArgInfoList& getStreamArgInfoList(); + const SoapySDR::ArgInfoList& getDeviceArgInfoList(); void initGainSettings(SoapySDROutputSettings& settings); + void initTunableElementsSettings(SoapySDROutputSettings& settings); + void initStreamArgSettings(SoapySDROutputSettings& settings); + void initDeviceArgSettings(SoapySDROutputSettings& settings); bool hasDCAutoCorrection(); bool hasDCCorrectionValue(); bool hasIQAutoCorrection() { return false; } // not in SoapySDR interface bool hasIQCorrectionValue(); + virtual int webapiSettingsGet( + SWGSDRangel::SWGDeviceSettings& response, + QString& errorMessage); + + virtual int webapiSettingsPutPatch( + bool force, + const QStringList& deviceSettingsKeys, + SWGSDRangel::SWGDeviceSettings& response, // query + response + QString& errorMessage); + + virtual int webapiReportGet( + SWGSDRangel::SWGDeviceReport& response, + QString& errorMessage); + + virtual int webapiRunGet( + SWGSDRangel::SWGDeviceState& response, + QString& errorMessage); + + virtual int webapiRun( + bool run, + SWGSDRangel::SWGDeviceState& response, + QString& errorMessage); + private: DeviceSinkAPI *m_deviceAPI; QMutex m_mutex; @@ -155,6 +190,12 @@ private: bool applySettings(const SoapySDROutputSettings& settings, bool force = false); bool setDeviceCenterFrequency(SoapySDR::Device *dev, int requestedChannel, quint64 freq_hz, int loPpmTenths); void updateGains(SoapySDR::Device *dev, int requestedChannel, SoapySDROutputSettings& settings); + void updateTunableElements(SoapySDR::Device *dev, int requestedChannel, SoapySDROutputSettings& settings); + void webapiFormatDeviceSettings(SWGSDRangel::SWGDeviceSettings& response, const SoapySDROutputSettings& settings); + void webapiFormatDeviceReport(SWGSDRangel::SWGDeviceReport& response); + QVariant webapiVariantFromArgValue(SWGSDRangel::SWGArgValue *argValue); + void webapiFormatArgValue(const QVariant& v, SWGSDRangel::SWGArgValue *argValue); + void webapiFormatArgInfo(const SoapySDR::ArgInfo& arg, SWGSDRangel::SWGArgInfo *argInfo); }; diff --git a/plugins/samplesink/soapysdroutput/soapysdroutput.pro b/plugins/samplesink/soapysdroutput/soapysdroutput.pro new file mode 100644 index 000000000..83b0e42ee --- /dev/null +++ b/plugins/samplesink/soapysdroutput/soapysdroutput.pro @@ -0,0 +1,43 @@ +#------------------------------------------------- +# +# Pro file for Windows MSVC builds with Qt Creator +# +#------------------------------------------------- + +TEMPLATE = lib +CONFIG += plugin + +QT += core gui multimedia opengl + +TARGET = outputsoapysdr + +INCLUDEPATH += $$PWD +INCLUDEPATH += ../../../exports +INCLUDEPATH += ../../../sdrbase +INCLUDEPATH += ../../../sdrgui +INCLUDEPATH += ../../../devices +INCLUDEPATH += ../../../swagger/sdrangel/code/qt5/client +INCLUDEPATH += "C:\Program Files\PothosSDR\include" + +CONFIG(Release):build_subdir = release +CONFIG(Debug):build_subdir = debug + +SOURCES += soapysdroutput.cpp\ + soapysdroutputgui.cpp\ + soapysdroutputplugin.cpp\ + soapysdroutputsettings.cpp\ + soapysdroutputthread.cpp + +HEADERS += soapysdroutput.h\ + soapysdroutputgui.h\ + soapysdroutputplugin.h\ + soapysdroutputsettings.h\ + soapysdroutputthread.h + +FORMS += soapysdroutputgui.ui + +LIBS += -L../../../sdrbase/$${build_subdir} -lsdrbase +LIBS += -L../../../sdrgui/$${build_subdir} -lsdrgui +LIBS += -L../../../swagger/$${build_subdir} -lswagger +LIBS += -L../../../devices/$${build_subdir} -ldevices +LIBS += -L"C:\Program Files\PothosSDR\bin" -L"C:\Program Files\PothosSDR\lib" -lSoapySDR diff --git a/plugins/samplesink/soapysdroutput/soapysdroutputgui.cpp b/plugins/samplesink/soapysdroutput/soapysdroutputgui.cpp index dbee2b4d4..07d67a66a 100644 --- a/plugins/samplesink/soapysdroutput/soapysdroutputgui.cpp +++ b/plugins/samplesink/soapysdroutput/soapysdroutputgui.cpp @@ -30,6 +30,8 @@ #include "soapygui/dynamicitemsettinggui.h" #include "soapygui/intervalslidergui.h" #include "soapygui/complexfactorgui.h" +#include "soapygui/arginfogui.h" +#include "soapygui/dynamicargsettinggui.h" #include "soapysdroutputgui.h" @@ -67,7 +69,12 @@ SoapySDROutputGui::SoapySDROutputGui(DeviceUISet *deviceUISet, QWidget* parent) createTunableElementsControl(m_sampleSink->getTunableElements()); createGlobalGainControl(); createIndividualGainsControl(m_sampleSink->getIndividualGainsRanges()); + createArgumentsControl(m_sampleSink->getDeviceArgInfoList(), true); + createArgumentsControl(m_sampleSink->getStreamArgInfoList(), false); m_sampleSink->initGainSettings(m_settings); + m_sampleSink->initTunableElementsSettings(m_settings); + m_sampleSink->initStreamArgSettings(m_settings); + m_sampleSink->initDeviceArgSettings(m_settings); if (m_sampleRateGUI) { connect(m_sampleRateGUI, SIGNAL(valueChanged(double)), this, SLOT(sampleRateChanged(double))); @@ -218,6 +225,7 @@ void SoapySDROutputGui::createGlobalGainControl() { m_autoGain = new QCheckBox(this); m_autoGain->setText(QString("AGC")); + m_autoGain->setStyleSheet("QCheckBox::indicator::unchecked {background: rgb(79,79,79);} QCheckBox::indicator::checked {background: rgb(255, 157, 38);}"); layout->addWidget(m_autoGain); connect(m_autoGain, SIGNAL(toggled(bool)), this, SLOT(autoGainChanged(bool))); @@ -273,6 +281,7 @@ void SoapySDROutputGui::createCorrectionsControl() m_autoDCCorrection = new QCheckBox(this); m_autoDCCorrection->setText(QString("Auto DC corr")); m_autoDCCorrection->setToolTip(QString("Automatic hardware DC offset correction")); + m_autoDCCorrection->setStyleSheet("QCheckBox::indicator::unchecked {background: rgb(79,79,79);} QCheckBox::indicator::checked {background: rgb(255, 157, 38);}"); layout->addWidget(m_autoDCCorrection); connect(m_autoDCCorrection, SIGNAL(toggled(bool)), this, SLOT(autoDCCorrectionChanged(bool))); @@ -297,12 +306,106 @@ void SoapySDROutputGui::createCorrectionsControl() m_autoIQCorrection = new QCheckBox(this); m_autoIQCorrection->setText(QString("Auto IQ corr")); m_autoIQCorrection->setToolTip(QString("Automatic hardware IQ imbalance correction")); + m_autoIQCorrection->setStyleSheet("QCheckBox::indicator::unchecked {background: rgb(79,79,79);} QCheckBox::indicator::checked {background: rgb(255, 157, 38);}"); layout->addWidget(m_autoIQCorrection); connect(m_autoIQCorrection, SIGNAL(toggled(bool)), this, SLOT(autoIQCorrectionChanged(bool))); } } +void SoapySDROutputGui::createArgumentsControl(const SoapySDR::ArgInfoList& argInfoList, bool deviceArguments) +{ + if (argInfoList.size() == 0) { // return early if list is empty + return; + } + + QVBoxLayout *layout = (QVBoxLayout *) ui->scrollAreaWidgetContents->layout(); + + QFrame *line = new QFrame(this); + line->setFrameShape(QFrame::HLine); + line->setFrameShadow(QFrame::Sunken); + layout->addWidget(line); + + std::vector::const_iterator it = argInfoList.begin(); + + for (; it != argInfoList.end(); ++it) + { + ArgInfoGUI::ArgInfoValueType valueType; + ArgInfoGUI *argGUI; + + if (it->type == SoapySDR::ArgInfo::BOOL) { + valueType = ArgInfoGUI::ArgInfoValueBool; + } else if (it->type == SoapySDR::ArgInfo::INT) { + valueType = ArgInfoGUI::ArgInfoValueInt; + } else if (it->type == SoapySDR::ArgInfo::FLOAT) { + valueType = ArgInfoGUI::ArgInfoValueFloat; + } else if (it->type == SoapySDR::ArgInfo::STRING) { + valueType = ArgInfoGUI::ArgInfoValueString; + } else { + continue; + } + + if (valueType == ArgInfoGUI::ArgInfoValueBool) + { + argGUI = new ArgInfoGUI(ArgInfoGUI::ArgInfoBinary, ArgInfoGUI::ArgInfoValueBool, this); + } + else if (it->options.size() == 0) + { + argGUI = new ArgInfoGUI(ArgInfoGUI::ArgInfoContinuous, valueType, this); + } + else + { + argGUI = new ArgInfoGUI(ArgInfoGUI::ArgInfoDiscrete, valueType, this); + std::vector::const_iterator optionIt = it->options.begin(); + std::vector::const_iterator optionNameIt = it->optionNames.begin(); + + for (int i = 0; optionIt != it->options.end(); ++optionIt, i++) + { + QString name(optionNameIt == it->optionNames.end() ? optionIt->c_str() : optionNameIt->c_str()); + + if (optionNameIt != it->optionNames.end()) { + ++optionNameIt; + } + + if (valueType == ArgInfoGUI::ArgInfoValueInt) { + argGUI->addIntValue(name, atoi(optionIt->c_str())); + } else if (valueType == ArgInfoGUI::ArgInfoValueFloat) { + argGUI->addFloatValue(name, atof(optionIt->c_str())); + } else if (valueType == ArgInfoGUI::ArgInfoValueString) { + argGUI->addStringValue(name, QString(optionIt->c_str())); + } + } + } + + if ((it->range.minimum() != 0) || (it->range.maximum() != 0)) { + argGUI->setRange(it->range.minimum(), it->range.maximum()); + } + + argGUI->setLabel(QString(it->name.size() == 0 ? it->key.c_str() : it->name.c_str())); + argGUI->setUnits(QString(it->units.c_str())); + + if (it->description.size() != 0) { + argGUI->setToolTip(QString(it->description.c_str())); + } + + layout->addWidget(argGUI); + + DynamicArgSettingGUI *gui = new DynamicArgSettingGUI(argGUI, QString(it->key.c_str())); + + // This could be made more elegant but let's make it more simple + if (deviceArguments) + { + m_deviceArgsGUIs.push_back(gui); + connect(gui, SIGNAL(valueChanged(QString, QVariant)), this, SLOT(deviceArgChanged(QString, QVariant))); + } + else + { + m_streamArgsGUIs.push_back(gui); + connect(gui, SIGNAL(valueChanged(QString, QVariant)), this, SLOT(streamArgChanged(QString, QVariant))); + } + } +} + void SoapySDROutputGui::setName(const QString& name) { setObjectName(name); @@ -339,12 +442,15 @@ QByteArray SoapySDROutputGui::serialize() const bool SoapySDROutputGui::deserialize(const QByteArray& data) { - if(m_settings.deserialize(data)) { + if(m_settings.deserialize(data)) + { displaySettings(); m_forceSettings = true; sendSettings(); return true; - } else { + } + else + { resetToDefaults(); return false; } @@ -381,6 +487,14 @@ bool SoapySDROutputGui::handleMessage(const Message& message) return true; } + else if (DeviceSoapySDRShared::MsgReportDeviceArgsChange::match(message)) + { + DeviceSoapySDRShared::MsgReportDeviceArgsChange& notif = (DeviceSoapySDRShared::MsgReportDeviceArgsChange&) message; + m_settings.m_deviceArgSettings = notif.getDeviceArgSettings(); + displayDeviceArgsSettings(); + + return true; + } else if (SoapySDROutput::MsgStartStop::match(message)) { SoapySDROutput::MsgStartStop& notif = (SoapySDROutput::MsgStartStop&) message; @@ -426,7 +540,7 @@ void SoapySDROutputGui::handleInputMessages() void SoapySDROutputGui::sampleRateChanged(double sampleRate) { - m_settings.m_devSampleRate = sampleRate; + m_settings.m_devSampleRate = round(sampleRate); sendSettings(); } @@ -439,7 +553,7 @@ void SoapySDROutputGui::antennasChanged() void SoapySDROutputGui::bandwidthChanged(double bandwidth) { - m_settings.m_bandwidth = bandwidth; + m_settings.m_bandwidth = round(bandwidth); sendSettings(); } @@ -509,6 +623,18 @@ void SoapySDROutputGui::iqCorrectionArgumentChanged(double value) sendSettings(); } +void SoapySDROutputGui::streamArgChanged(QString itemName, QVariant value) +{ + m_settings.m_streamArgSettings[itemName] = value; + sendSettings(); +} + +void SoapySDROutputGui::deviceArgChanged(QString itemName, QVariant value) +{ + m_settings.m_deviceArgSettings[itemName] = value; + sendSettings(); +} + void SoapySDROutputGui::on_centerFrequency_changed(quint64 value) { m_settings.m_centerFrequency = value * 1000; @@ -558,14 +684,20 @@ void SoapySDROutputGui::displaySettings() if (m_antennas) { m_antennas->setValue(m_settings.m_antenna.toStdString()); } - if (m_sampleRateGUI) { + if (m_sampleRateGUI) + { m_sampleRateGUI->setValue(m_settings.m_devSampleRate); + m_settings.m_devSampleRate = m_sampleRateGUI->getCurrentValue(); } - if (m_bandwidthGUI) { + if (m_bandwidthGUI) + { m_bandwidthGUI->setValue(m_settings.m_bandwidth); + m_settings.m_bandwidth = m_bandwidthGUI->getCurrentValue(); } - if (m_gainSliderGUI) { + if (m_gainSliderGUI) + { m_gainSliderGUI->setValue(m_settings.m_globalGain); + m_settings.m_globalGain = m_gainSliderGUI->getCurrentValue(); } if (m_autoGain) { m_autoGain->setChecked(m_settings.m_autoGain); @@ -579,6 +711,8 @@ void SoapySDROutputGui::displaySettings() displayTunableElementsControlSettings(); displayIndividualGainsControlSettings(); displayCorrectionsSettings(); + displayStreamArgsSettings(); + displayDeviceArgsSettings(); blockApplySettings(false); } @@ -599,10 +733,12 @@ void SoapySDROutputGui::displayIndividualGainsControlSettings() { for (const auto &it : m_individualGainsGUIs) { - QMap::const_iterator elIt = m_settings.m_individualGains.find(it->getName()); + QMap::iterator elIt = m_settings.m_individualGains.find(it->getName()); - if (elIt != m_settings.m_individualGains.end()) { + if (elIt != m_settings.m_individualGains.end()) + { it->setValue(*elIt); + *elIt = it->getValue(); } } } @@ -632,6 +768,34 @@ void SoapySDROutputGui::displayCorrectionsSettings() } } +void SoapySDROutputGui::displayStreamArgsSettings() +{ + for (const auto &it : m_streamArgsGUIs) + { + QMap::iterator elIt = m_settings.m_streamArgSettings.find(it->getName()); + + if (elIt != m_settings.m_streamArgSettings.end()) + { + it->setValue(elIt.value()); + *elIt = it->getValue(); + } + } +} + +void SoapySDROutputGui::displayDeviceArgsSettings() +{ + for (const auto &it : m_deviceArgsGUIs) + { + QMap::iterator elIt = m_settings.m_deviceArgSettings.find(it->getName()); + + if (elIt != m_settings.m_deviceArgSettings.end()) + { + it->setValue(elIt.value()); + *elIt = it->getValue(); + } + } +} + void SoapySDROutputGui::sendSettings() { if (!m_updateTimer.isActive()) { diff --git a/plugins/samplesink/soapysdroutput/soapysdroutputgui.h b/plugins/samplesink/soapysdroutput/soapysdroutputgui.h index 1ac196323..655c25df2 100644 --- a/plugins/samplesink/soapysdroutput/soapysdroutputgui.h +++ b/plugins/samplesink/soapysdroutput/soapysdroutputgui.h @@ -31,6 +31,7 @@ class DeviceUISet; class ItemSettingGUI; class StringRangeGUI; class DynamicItemSettingGUI; +class DynamicArgSettingGUI; class IntervalSliderGUI; class QCheckBox; class ComplexFactorGUI; @@ -69,6 +70,7 @@ private: void createGlobalGainControl(); void createIndividualGainsControl(const std::vector& individualGainsList); void createCorrectionsControl(); + void createArgumentsControl(const SoapySDR::ArgInfoList& argInfoList, bool deviceArguments); Ui::SoapySDROutputGui* ui; @@ -95,12 +97,16 @@ private: ComplexFactorGUI *m_iqCorrectionGUI; QCheckBox *m_autoDCCorrection; QCheckBox *m_autoIQCorrection; + std::vector m_streamArgsGUIs; + std::vector m_deviceArgsGUIs; void blockApplySettings(bool block) { m_doApplySettings = !block; } void displaySettings(); void displayTunableElementsControlSettings(); void displayIndividualGainsControlSettings(); void displayCorrectionsSettings(); + void displayStreamArgsSettings(); + void displayDeviceArgsSettings(); void sendSettings(); void updateSampleRateAndFrequency(); void updateFrequencyLimits(); @@ -122,6 +128,8 @@ private slots: void dcCorrectionArgumentChanged(double value); void iqCorrectionModuleChanged(double value); void iqCorrectionArgumentChanged(double value); + void streamArgChanged(QString itemName, QVariant value); + void deviceArgChanged(QString itemName, QVariant value); void on_centerFrequency_changed(quint64 value); void on_LOppm_valueChanged(int value); diff --git a/plugins/samplesink/soapysdroutput/soapysdroutputplugin.cpp b/plugins/samplesink/soapysdroutput/soapysdroutputplugin.cpp index cdb6def6d..87a641ed3 100644 --- a/plugins/samplesink/soapysdroutput/soapysdroutputplugin.cpp +++ b/plugins/samplesink/soapysdroutput/soapysdroutputplugin.cpp @@ -31,7 +31,7 @@ const PluginDescriptor SoapySDROutputPlugin::m_pluginDescriptor = { QString("SoapySDR Output"), - QString("4.3.0"), + QString("4.3.1"), QString("(c) Edouard Griffiths, F4EXB"), QString("https://github.com/f4exb/sdrangel"), true, diff --git a/plugins/samplesink/soapysdroutput/soapysdroutputsettings.cpp b/plugins/samplesink/soapysdroutput/soapysdroutputsettings.cpp index 9abc87b96..5e95ddb8b 100644 --- a/plugins/samplesink/soapysdroutput/soapysdroutputsettings.cpp +++ b/plugins/samplesink/soapysdroutput/soapysdroutputsettings.cpp @@ -65,6 +65,8 @@ QByteArray SoapySDROutputSettings::serialize() const s.writeDouble(18, m_dcCorrection.imag()); s.writeDouble(19, m_iqCorrection.real()); s.writeDouble(20, m_iqCorrection.imag()); + s.writeBlob(21, serializeArgumentMap(m_streamArgSettings)); + s.writeBlob(22, serializeArgumentMap(m_deviceArgSettings)); return s.final(); } @@ -105,6 +107,10 @@ bool SoapySDROutputSettings::deserialize(const QByteArray& data) d.readDouble(19, &realval, 0); d.readDouble(20, &imagval, 0); m_iqCorrection = std::complex{realval, imagval}; + d.readBlob(21, &blob); + deserializeArgumentMap(blob, m_streamArgSettings); + d.readBlob(22, &blob); + deserializeArgumentMap(blob, m_deviceArgSettings); return true; } @@ -131,3 +137,21 @@ void SoapySDROutputSettings::deserializeNamedElementMap(const QByteArray& data, (*stream) >> map; delete stream; } + +QByteArray SoapySDROutputSettings::serializeArgumentMap(const QMap& map) const +{ + QByteArray data; + QDataStream *stream = new QDataStream(&data, QIODevice::WriteOnly); + (*stream) << map; + delete stream; + + return data; +} + +void SoapySDROutputSettings::deserializeArgumentMap(const QByteArray& data, QMap& map) +{ + QDataStream *stream = new QDataStream(data); + (*stream) >> map; + delete stream; +} + diff --git a/plugins/samplesink/soapysdroutput/soapysdroutputsettings.h b/plugins/samplesink/soapysdroutput/soapysdroutputsettings.h index d0cf8f448..110b38910 100644 --- a/plugins/samplesink/soapysdroutput/soapysdroutputsettings.h +++ b/plugins/samplesink/soapysdroutput/soapysdroutputsettings.h @@ -18,6 +18,7 @@ #define PLUGINS_SAMPLESINK_SOAPYSDROUTPUT_SOAPYSDROUTPUTSETTINGS_H_ #include +#include #include struct SoapySDROutputSettings { @@ -37,6 +38,8 @@ struct SoapySDROutputSettings { bool m_autoIQCorrection; std::complex m_dcCorrection; std::complex m_iqCorrection; + QMap m_streamArgSettings; + QMap m_deviceArgSettings; SoapySDROutputSettings(); void resetToDefaults(); @@ -46,6 +49,9 @@ struct SoapySDROutputSettings { private: QByteArray serializeNamedElementMap(const QMap& map) const; void deserializeNamedElementMap(const QByteArray& data, QMap& map); + QByteArray serializeArgumentMap(const QMap& map) const; + void deserializeArgumentMap(const QByteArray& data, QMap& map); + }; #endif /* PLUGINS_SAMPLESINK_SOAPYSDROUTPUT_SOAPYSDROUTPUTSETTINGS_H_ */ diff --git a/plugins/samplesink/soapysdroutput/soapysdroutputthread.cpp b/plugins/samplesink/soapysdroutput/soapysdroutputthread.cpp index b7303d401..50df22745 100644 --- a/plugins/samplesink/soapysdroutput/soapysdroutputthread.cpp +++ b/plugins/samplesink/soapysdroutput/soapysdroutputthread.cpp @@ -124,9 +124,11 @@ void SoapySDROutputThread::run() int flags(0); long long timeNs(0); float blockTime = ((float) numElems) / (m_sampleRate <= 0 ? 1024000 : m_sampleRate); - long timeoutUs = 2000000 * blockTime; // 10 times the block time + long initialTtimeoutUs = 10000000 * blockTime; // 10 times the block time + long timeoutUs = initialTtimeoutUs < 250000 ? 250000 : initialTtimeoutUs; // 250ms minimum - qDebug("SoapySDROutputThread::run: numElems: %u elemSize: %u timeoutUs: %ld", numElems, elemSize, timeoutUs); + qDebug("SoapySDROutputThread::run: numElems: %u elemSize: %u initialTtimeoutUs: %ld timeoutUs: %ld", + numElems, elemSize, initialTtimeoutUs, timeoutUs); qDebug("SoapySDROutputThread::run: start running loop"); while (m_running) @@ -137,6 +139,10 @@ void SoapySDROutputThread::run() { qWarning("SoapySDROutputThread::run: timeout: flags: %d timeNs: %lld timeoutUs: %ld", flags, timeNs, timeoutUs); } + else if (ret == SOAPY_SDR_OVERFLOW) + { + qWarning("SoapySDROutputThread::run: overflow: flags: %d timeNs: %lld timeoutUs: %ld", flags, timeNs, timeoutUs); + } else if (ret < 0) { qCritical("SoapySDROutputThread::run: Unexpected write stream error: %s", SoapySDR::errToStr(ret)); diff --git a/plugins/samplesource/airspy/airspy.pro b/plugins/samplesource/airspy/airspy.pro index 5ba6d7050..600b51672 100644 --- a/plugins/samplesource/airspy/airspy.pro +++ b/plugins/samplesource/airspy/airspy.pro @@ -13,6 +13,8 @@ TARGET = inputairspy CONFIG(MINGW32):LIBAIRSPYSRC = "C:\softs\libairspy" CONFIG(MINGW64):LIBAIRSPYSRC = "C:\softs\libairspy" +CONFIG(MSVC):LIBAIRSPYSRC = "C:\softs\libairspy" + INCLUDEPATH += $$PWD INCLUDEPATH += ../../../exports INCLUDEPATH += ../../../sdrbase diff --git a/plugins/samplesource/airspy/airspyinput.cpp b/plugins/samplesource/airspy/airspyinput.cpp index 7ec2f68f3..111ea4dcc 100644 --- a/plugins/samplesource/airspy/airspyinput.cpp +++ b/plugins/samplesource/airspy/airspyinput.cpp @@ -594,8 +594,9 @@ struct airspy_device *AirspyInput::open_airspy_from_sequence(int sequence) int AirspyInput::webapiRunGet( SWGSDRangel::SWGDeviceState& response, - QString& errorMessage __attribute__((unused))) + QString& errorMessage) { + (void) errorMessage; m_deviceAPI->getDeviceEngineStateStr(*response.getState()); return 200; } @@ -603,8 +604,9 @@ int AirspyInput::webapiRunGet( int AirspyInput::webapiRun( bool run, SWGSDRangel::SWGDeviceState& response, - QString& errorMessage __attribute__((unused))) + QString& errorMessage) { + (void) errorMessage; m_deviceAPI->getDeviceEngineStateStr(*response.getState()); MsgStartStop *message = MsgStartStop::create(run); m_inputMessageQueue.push(message); @@ -620,8 +622,9 @@ int AirspyInput::webapiRun( int AirspyInput::webapiSettingsGet( SWGSDRangel::SWGDeviceSettings& response, - QString& errorMessage __attribute__((unused))) + QString& errorMessage) { + (void) errorMessage; response.setAirspySettings(new SWGSDRangel::SWGAirspySettings()); response.getAirspySettings()->init(); webapiFormatDeviceSettings(response, m_settings); @@ -632,8 +635,9 @@ int AirspyInput::webapiSettingsPutPatch( bool force, const QStringList& deviceSettingsKeys, SWGSDRangel::SWGDeviceSettings& response, // query + response - QString& errorMessage __attribute__((unused))) + QString& errorMessage) { + (void) errorMessage; AirspySettings settings = m_settings; if (deviceSettingsKeys.contains("centerFrequency")) { @@ -702,8 +706,9 @@ int AirspyInput::webapiSettingsPutPatch( int AirspyInput::webapiReportGet( SWGSDRangel::SWGDeviceReport& response, - QString& errorMessage __attribute__((unused))) + QString& errorMessage) { + (void) errorMessage; response.setAirspyReport(new SWGSDRangel::SWGAirspyReport()); response.getAirspyReport()->init(); webapiFormatDeviceReport(response); diff --git a/plugins/samplesource/airspyhf/airspyhf.pro b/plugins/samplesource/airspyhf/airspyhf.pro index 6f95b2485..9c611a347 100644 --- a/plugins/samplesource/airspyhf/airspyhf.pro +++ b/plugins/samplesource/airspyhf/airspyhf.pro @@ -13,6 +13,8 @@ TARGET = inputairspyhf CONFIG(MINGW32):LIBAIRSPYHFSRC = "C:\softs\airspyhf" CONFIG(MINGW64):LIBAIRSPYHFSRC = "C:\softs\airspyhf" +CONFIG(MSVC):LIBAIRSPYHFSRC = "C:\softs\airspyhf" + INCLUDEPATH += $$PWD INCLUDEPATH += ../../../exports INCLUDEPATH += ../../../sdrbase diff --git a/plugins/samplesource/airspyhf/airspyhfinput.cpp b/plugins/samplesource/airspyhf/airspyhfinput.cpp index 1cadfcc39..25b16b437 100644 --- a/plugins/samplesource/airspyhf/airspyhfinput.cpp +++ b/plugins/samplesource/airspyhf/airspyhfinput.cpp @@ -486,8 +486,9 @@ airspyhf_device_t *AirspyHFInput::open_airspyhf_from_serial(const QString& seria int AirspyHFInput::webapiSettingsGet( SWGSDRangel::SWGDeviceSettings& response, - QString& errorMessage __attribute__((unused))) + QString& errorMessage) { + (void) errorMessage; response.setAirspyHfSettings(new SWGSDRangel::SWGAirspyHFSettings()); response.getAirspyHfSettings()->init(); webapiFormatDeviceSettings(response, m_settings); @@ -498,8 +499,9 @@ int AirspyHFInput::webapiSettingsPutPatch( bool force, const QStringList& deviceSettingsKeys, SWGSDRangel::SWGDeviceSettings& response, // query + response - QString& errorMessage __attribute__((unused))) + QString& errorMessage) { + (void) errorMessage; AirspyHFSettings settings = m_settings; if (deviceSettingsKeys.contains("centerFrequency")) { @@ -570,8 +572,9 @@ void AirspyHFInput::webapiFormatDeviceReport(SWGSDRangel::SWGDeviceReport& respo int AirspyHFInput::webapiReportGet( SWGSDRangel::SWGDeviceReport& response, - QString& errorMessage __attribute__((unused))) + QString& errorMessage) { + (void) errorMessage; response.setAirspyHfReport(new SWGSDRangel::SWGAirspyHFReport()); response.getAirspyHfReport()->init(); webapiFormatDeviceReport(response); @@ -580,8 +583,9 @@ int AirspyHFInput::webapiReportGet( int AirspyHFInput::webapiRunGet( SWGSDRangel::SWGDeviceState& response, - QString& errorMessage __attribute__((unused))) + QString& errorMessage) { + (void) errorMessage; m_deviceAPI->getDeviceEngineStateStr(*response.getState()); return 200; } @@ -589,8 +593,9 @@ int AirspyHFInput::webapiRunGet( int AirspyHFInput::webapiRun( bool run, SWGSDRangel::SWGDeviceState& response, - QString& errorMessage __attribute__((unused))) + QString& errorMessage) { + (void) errorMessage; m_deviceAPI->getDeviceEngineStateStr(*response.getState()); MsgStartStop *message = MsgStartStop::create(run); m_inputMessageQueue.push(message); diff --git a/plugins/samplesource/bladerf1input/bladerf1input.cpp b/plugins/samplesource/bladerf1input/bladerf1input.cpp index 1791772c9..f21349624 100644 --- a/plugins/samplesource/bladerf1input/bladerf1input.cpp +++ b/plugins/samplesource/bladerf1input/bladerf1input.cpp @@ -609,8 +609,9 @@ bladerf_lna_gain Bladerf1Input::getLnaGain(int lnaGain) int Bladerf1Input::webapiSettingsGet( SWGSDRangel::SWGDeviceSettings& response, - QString& errorMessage __attribute__((unused))) + QString& errorMessage) { + (void) errorMessage; response.setBladeRf1InputSettings(new SWGSDRangel::SWGBladeRF1InputSettings()); response.getBladeRf1InputSettings()->init(); webapiFormatDeviceSettings(response, m_settings); @@ -644,8 +645,9 @@ int Bladerf1Input::webapiSettingsPutPatch( bool force, const QStringList& deviceSettingsKeys, SWGSDRangel::SWGDeviceSettings& response, // query + response - QString& errorMessage __attribute__((unused))) + QString& errorMessage) { + (void) errorMessage; BladeRF1InputSettings settings = m_settings; if (deviceSettingsKeys.contains("centerFrequency")) { @@ -706,8 +708,9 @@ int Bladerf1Input::webapiSettingsPutPatch( int Bladerf1Input::webapiRunGet( SWGSDRangel::SWGDeviceState& response, - QString& errorMessage __attribute__((unused))) + QString& errorMessage) { + (void) errorMessage; m_deviceAPI->getDeviceEngineStateStr(*response.getState()); return 200; } @@ -715,8 +718,9 @@ int Bladerf1Input::webapiRunGet( int Bladerf1Input::webapiRun( bool run, SWGSDRangel::SWGDeviceState& response, - QString& errorMessage __attribute__((unused))) + QString& errorMessage) { + (void) errorMessage; m_deviceAPI->getDeviceEngineStateStr(*response.getState()); MsgStartStop *message = MsgStartStop::create(run); m_inputMessageQueue.push(message); diff --git a/plugins/samplesource/bladerf1input/bladerf1input.pro b/plugins/samplesource/bladerf1input/bladerf1input.pro index 035afb49f..8bfda4fb1 100644 --- a/plugins/samplesource/bladerf1input/bladerf1input.pro +++ b/plugins/samplesource/bladerf1input/bladerf1input.pro @@ -17,15 +17,21 @@ DEFINES += USE_SSE4_1=1 QMAKE_CXXFLAGS += -msse4.1 QMAKE_CXXFLAGS += -std=c++11 -CONFIG(MINGW32):LIBBLADERF = "C:\Programs\bladeRF" -CONFIG(MINGW64):LIBBLADERF = "C:\Programs\bladeRF" INCLUDEPATH += $$PWD INCLUDEPATH += ../../../exports INCLUDEPATH += ../../../sdrbase INCLUDEPATH += ../../../sdrgui INCLUDEPATH += ../../../swagger/sdrangel/code/qt5/client INCLUDEPATH += ../../../devices -INCLUDEPATH += $$LIBBLADERF/include + +MINGW32 || MINGW64 { + LIBBLADERF = "C:\Programs\bladeRF" + INCLUDEPATH += $$LIBBLADERF/include +} + +MSVC { + INCLUDEPATH += "C:\Program Files\PothosSDR\include" +} CONFIG(Release):build_subdir = release CONFIG(Debug):build_subdir = debug @@ -47,7 +53,14 @@ FORMS += bladerf1inputgui.ui LIBS += -L../../../sdrbase/$${build_subdir} -lsdrbase LIBS += -L../../../sdrgui/$${build_subdir} -lsdrgui LIBS += -L../../../swagger/$${build_subdir} -lswagger -LIBS += -L$$LIBBLADERF/lib -lbladeRF LIBS += -L../../../devices/$${build_subdir} -ldevices +MINGW32 || MINGW64 { + LIBS += -L$$LIBBLADERF/lib -lbladeRF +} + +MSVC { + LIBS += -L"C:\Program Files\PothosSDR\lib" -L"C:\Program Files\PothosSDR\bin" -lbladeRF +} + RESOURCES = ../../../sdrgui/resources/res.qrc diff --git a/plugins/samplesource/bladerf1input/bladerf1inputgui.cpp b/plugins/samplesource/bladerf1input/bladerf1inputgui.cpp index 3865fedce..3978c3f6e 100644 --- a/plugins/samplesource/bladerf1input/bladerf1inputgui.cpp +++ b/plugins/samplesource/bladerf1input/bladerf1inputgui.cpp @@ -463,14 +463,10 @@ unsigned int Bladerf1InputGui::getXb200Index(bool xb_200, bladerf_xb200_path xb2 { return 6; } - else if (xb200Filter == BLADERF_XB200_222M) + else // xb200Filter == BLADERF_XB200_222M { return 7; } - else - { - return 0; - } } } else diff --git a/plugins/samplesource/bladerf2input/bladerf2input.cpp b/plugins/samplesource/bladerf2input/bladerf2input.cpp index 577c4a323..2f3faa600 100644 --- a/plugins/samplesource/bladerf2input/bladerf2input.cpp +++ b/plugins/samplesource/bladerf2input/bladerf2input.cpp @@ -329,6 +329,11 @@ bool BladeRF2Input::start() ((DeviceBladeRF2Shared*) (*it)->getBuddySharedPtr())->m_source->setThread(0); } + // was used as temporary storage: + delete[] fifos; + delete[] log2Decims; + delete[] fcPoss; + needsStart = true; } else @@ -470,6 +475,11 @@ void BladeRF2Input::stop() if (stillActiveFIFO) { bladerf2InputThread->startWork(); } + + // was used as temporary storage: + delete[] fifos; + delete[] log2Decims; + delete[] fcPoss; } else // remove channel from existing thread { @@ -967,8 +977,9 @@ bool BladeRF2Input::applySettings(const BladeRF2InputSettings& settings, bool fo int BladeRF2Input::webapiSettingsGet( SWGSDRangel::SWGDeviceSettings& response, - QString& errorMessage __attribute__((unused))) + QString& errorMessage) { + (void) errorMessage; response.setBladeRf2InputSettings(new SWGSDRangel::SWGBladeRF2InputSettings()); response.getBladeRf2InputSettings()->init(); webapiFormatDeviceSettings(response, m_settings); @@ -979,8 +990,9 @@ int BladeRF2Input::webapiSettingsPutPatch( bool force, const QStringList& deviceSettingsKeys, SWGSDRangel::SWGDeviceSettings& response, // query + response - QString& errorMessage __attribute__((unused))) + QString& errorMessage) { + (void) errorMessage; BladeRF2InputSettings settings = m_settings; if (deviceSettingsKeys.contains("centerFrequency")) { @@ -1039,8 +1051,9 @@ int BladeRF2Input::webapiSettingsPutPatch( return 200; } -int BladeRF2Input::webapiReportGet(SWGSDRangel::SWGDeviceReport& response, QString& errorMessage __attribute__((unused))) +int BladeRF2Input::webapiReportGet(SWGSDRangel::SWGDeviceReport& response, QString& errorMessage) { + (void) errorMessage; response.setBladeRf2InputReport(new SWGSDRangel::SWGBladeRF2InputReport()); response.getBladeRf2InputReport()->init(); webapiFormatDeviceReport(response); @@ -1123,8 +1136,9 @@ void BladeRF2Input::webapiFormatDeviceReport(SWGSDRangel::SWGDeviceReport& respo int BladeRF2Input::webapiRunGet( SWGSDRangel::SWGDeviceState& response, - QString& errorMessage __attribute__((unused))) + QString& errorMessage) { + (void) errorMessage; m_deviceAPI->getDeviceEngineStateStr(*response.getState()); return 200; } @@ -1132,8 +1146,9 @@ int BladeRF2Input::webapiRunGet( int BladeRF2Input::webapiRun( bool run, SWGSDRangel::SWGDeviceState& response, - QString& errorMessage __attribute__((unused))) + QString& errorMessage) { + (void) errorMessage; m_deviceAPI->getDeviceEngineStateStr(*response.getState()); MsgStartStop *message = MsgStartStop::create(run); m_inputMessageQueue.push(message); diff --git a/plugins/samplesource/bladerf2input/bladerf2input.pro b/plugins/samplesource/bladerf2input/bladerf2input.pro index e474a41ca..fe47be190 100644 --- a/plugins/samplesource/bladerf2input/bladerf2input.pro +++ b/plugins/samplesource/bladerf2input/bladerf2input.pro @@ -17,15 +17,21 @@ DEFINES += USE_SSE4_1=1 QMAKE_CXXFLAGS += -msse4.1 QMAKE_CXXFLAGS += -std=c++11 -CONFIG(MINGW32):LIBBLADERF = "C:\Programs\bladeRF" -CONFIG(MINGW64):LIBBLADERF = "C:\Programs\bladeRF" INCLUDEPATH += $$PWD INCLUDEPATH += ../../../exports INCLUDEPATH += ../../../sdrbase INCLUDEPATH += ../../../sdrgui INCLUDEPATH += ../../../swagger/sdrangel/code/qt5/client INCLUDEPATH += ../../../devices -INCLUDEPATH += $$LIBBLADERF/include + +MINGW32 || MINGW64 { + LIBBLADERF = "C:\Programs\bladeRF" + INCLUDEPATH += $$LIBBLADERF/include +} + +MSVC { + INCLUDEPATH += "C:\Program Files\PothosSDR\include" +} CONFIG(Release):build_subdir = release CONFIG(Debug):build_subdir = debug @@ -47,7 +53,14 @@ FORMS += bladerf2inputgui.ui LIBS += -L../../../sdrbase/$${build_subdir} -lsdrbase LIBS += -L../../../sdrgui/$${build_subdir} -lsdrgui LIBS += -L../../../swagger/$${build_subdir} -lswagger -LIBS += -L$$LIBBLADERF/lib -lbladeRF LIBS += -L../../../devices/$${build_subdir} -ldevices +MINGW32 || MINGW64 { + LIBS += -L$$LIBBLADERF/lib -lbladeRF +} + +MSVC { + LIBS += -L"C:\Program Files\PothosSDR\lib" -L"C:\Program Files\PothosSDR\bin" -lbladeRF +} + RESOURCES = ../../../sdrgui/resources/res.qrc diff --git a/plugins/samplesource/fcdpro/fcdprogui.cpp b/plugins/samplesource/fcdpro/fcdprogui.cpp index 20920db13..6928742b1 100644 --- a/plugins/samplesource/fcdpro/fcdprogui.cpp +++ b/plugins/samplesource/fcdpro/fcdprogui.cpp @@ -209,7 +209,7 @@ bool FCDProGui::deserialize(const QByteArray& data) } } -bool FCDProGui::handleMessage(const Message& message __attribute__((unused))) +bool FCDProGui::handleMessage(const Message& message) { if (FCDProInput::MsgConfigureFCDPro::match(message)) { @@ -434,8 +434,9 @@ void FCDProGui::on_gain6_currentIndexChanged(int index) sendSettings(); } -void FCDProGui::on_setDefaults_clicked(bool checked __attribute__((unused))) +void FCDProGui::on_setDefaults_clicked(bool checked) { + (void) checked; m_settings.m_lnaGainIndex = 8; // +15 dB //m_settings.rfFilterIndex = 0; m_settings.m_mixerGainIndex = 1; // +12 dB diff --git a/plugins/samplesource/fcdpro/fcdprogui.ui b/plugins/samplesource/fcdpro/fcdprogui.ui index 5e3d747d7..ad9e7c918 100644 --- a/plugins/samplesource/fcdpro/fcdprogui.ui +++ b/plugins/samplesource/fcdpro/fcdprogui.ui @@ -31,9 +31,6 @@ FunCubeDongle - - start/stop acquisition - 3 @@ -61,6 +58,9 @@ + + start/stop acquisition + @@ -287,7 +287,11 @@ - + + + LNA enhancement + + @@ -297,7 +301,11 @@ - + + + Band optimizations + +
@@ -311,7 +319,11 @@ - + + + Band bias + + @@ -321,7 +333,11 @@ - + + + Mode ? + + @@ -335,7 +351,11 @@ - + + + LNA gain + + @@ -345,7 +365,11 @@ - + + + RF filter selection + + @@ -359,7 +383,11 @@ - + + + Mixer gain + + @@ -369,7 +397,11 @@ - + + + Mixer filter selection + + @@ -383,7 +415,11 @@ - + + + Gain block #1 + + @@ -393,7 +429,11 @@ - + + + Baseband RC filter selection + + @@ -407,7 +447,11 @@ - + + + Gain block #2 + + @@ -417,7 +461,11 @@ - + + + Gain block #3 + + @@ -431,7 +479,11 @@ - + + + Gain block #4 + + @@ -441,7 +493,11 @@ - + + + IF filter selection + + @@ -455,7 +511,11 @@ - + + + Gain block #5 + + @@ -465,7 +525,11 @@ - + + + Gain block #6 + + diff --git a/plugins/samplesource/fcdpro/fcdproinput.cpp b/plugins/samplesource/fcdpro/fcdproinput.cpp index 5059a79fd..2ba8b52c0 100644 --- a/plugins/samplesource/fcdpro/fcdproinput.cpp +++ b/plugins/samplesource/fcdpro/fcdproinput.cpp @@ -1,6 +1,5 @@ /////////////////////////////////////////////////////////////////////////////////// -// Copyright (C) 2012 maintech GmbH, Otto-Hahn-Str. 15, 97204 Hoechberg, Germany // -// written by Christian Daniel // +// Copyright (C) 2015-2018 Edouard Griffiths, F4EXB // // // // This 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,8 +14,6 @@ // along with this program. If not, see . // /////////////////////////////////////////////////////////////////////////////////// -// FIXME: FCD is handled very badly! - #include #include #include @@ -27,10 +24,9 @@ #include "dsp/dspcommands.h" #include "dsp/dspengine.h" #include "dsp/filerecord.h" +#include "device/devicesourceapi.h" + #include "fcdproinput.h" - -#include - #include "fcdprothread.h" #include "fcdtraits.h" #include "fcdproconst.h" @@ -47,6 +43,7 @@ FCDProInput::FCDProInput(DeviceSourceAPI *deviceAPI) : m_deviceDescription(fcd_traits::displayedName), m_running(false) { + m_fcdFIFO.setSize(20*fcd_traits::convBufSize); openDevice(); m_fileSink = new FileRecord(QString("test_%1.sdriq").arg(m_deviceAPI->getDeviceUID())); m_deviceAPI->addSink(m_fileSink); @@ -54,9 +51,13 @@ FCDProInput::FCDProInput(DeviceSourceAPI *deviceAPI) : FCDProInput::~FCDProInput() { - if (m_running) stop(); + if (m_running) { + stop(); + } + m_deviceAPI->removeSink(m_fileSink); delete m_fileSink; + closeDevice(); } @@ -67,15 +68,12 @@ void FCDProInput::destroy() bool FCDProInput::openDevice() { - int device = m_deviceAPI->getSampleSourceSequence(); - - if (m_dev != 0) - { + if (m_dev != 0) { closeDevice(); } + int device = m_deviceAPI->getSampleSourceSequence(); qDebug() << "FCDProInput::openDevice with device #" << device; - m_dev = fcdOpen(fcd_traits::vendorId, fcd_traits::productId, device); if (m_dev == 0) @@ -117,7 +115,17 @@ bool FCDProInput::start() return false; } - m_FCDThread = new FCDProThread(&m_sampleFifo); + if (!openFCDAudio(fcd_traits::qtDeviceName)) + { + qCritical("FCDProInput::start: could not open FCD audio source"); + return false; + } + else + { + qDebug("FCDProInput::start: FCD audio source opened"); + } + + m_FCDThread = new FCDProThread(&m_sampleFifo, &m_fcdFIFO); m_FCDThread->startWork(); // mutexLocker.unlock(); @@ -139,6 +147,35 @@ void FCDProInput::closeDevice() m_dev = 0; } +bool FCDProInput::openFCDAudio(const char* cardname) +{ + AudioDeviceManager *audioDeviceManager = DSPEngine::instance()->getAudioDeviceManager(); + const QList& audioList = audioDeviceManager->getInputDevices(); + + for (const auto &itAudio : audioList) + { + if (itAudio.deviceName().contains(QString(cardname))) + { + int fcdDeviceIndex = audioDeviceManager->getInputDeviceIndex(itAudio.deviceName()); + m_fcdAudioInput.start(fcdDeviceIndex, fcd_traits::sampleRate); + int fcdSampleRate = m_fcdAudioInput.getRate(); + qDebug("FCDProPlusInput::openFCDAudio: %s index %d at %d S/s", + itAudio.deviceName().toStdString().c_str(), fcdDeviceIndex, fcdSampleRate); + m_fcdAudioInput.addFifo(&m_fcdFIFO); + return true; + } + } + + qCritical("FCDProInput::openFCDAudio: device with name %s not found", cardname); + return false; +} + +void FCDProInput::closeFCDAudio() +{ + m_fcdAudioInput.removeFifo(&m_fcdFIFO); + m_fcdAudioInput.stop(); +} + void FCDProInput::stop() { // QMutexLocker mutexLocker(&m_mutex); @@ -148,7 +185,8 @@ void FCDProInput::stop() m_FCDThread->stopWork(); // wait for thread to quit ? delete m_FCDThread; - m_FCDThread = 0; + m_FCDThread = nullptr; + closeFCDAudio(); } m_running = false; @@ -493,8 +531,9 @@ void FCDProInput::set_center_freq(double freq) } -void FCDProInput::set_bias_t(bool on __attribute__((unused))) +void FCDProInput::set_bias_t(bool on) { + (void) on; //quint8 cmd = on ? 1 : 0; // TODO: use FCD Pro controls @@ -749,8 +788,9 @@ void FCDProInput::set_lo_ppm() int FCDProInput::webapiRunGet( SWGSDRangel::SWGDeviceState& response, - QString& errorMessage __attribute__((unused))) + QString& errorMessage) { + (void) errorMessage; m_deviceAPI->getDeviceEngineStateStr(*response.getState()); return 200; } @@ -758,8 +798,9 @@ int FCDProInput::webapiRunGet( int FCDProInput::webapiRun( bool run, SWGSDRangel::SWGDeviceState& response, - QString& errorMessage __attribute__((unused))) + QString& errorMessage) { + (void) errorMessage; m_deviceAPI->getDeviceEngineStateStr(*response.getState()); MsgStartStop *message = MsgStartStop::create(run); m_inputMessageQueue.push(message); @@ -775,8 +816,9 @@ int FCDProInput::webapiRun( int FCDProInput::webapiSettingsGet( SWGSDRangel::SWGDeviceSettings& response, - QString& errorMessage __attribute__((unused))) + QString& errorMessage) { + (void) errorMessage; response.setFcdProSettings(new SWGSDRangel::SWGFCDProSettings()); response.getFcdProSettings()->init(); webapiFormatDeviceSettings(response, m_settings); @@ -787,8 +829,9 @@ int FCDProInput::webapiSettingsPutPatch( bool force, const QStringList& deviceSettingsKeys, SWGSDRangel::SWGDeviceSettings& response, // query + response - QString& errorMessage __attribute__((unused))) + QString& errorMessage) { + (void) errorMessage; FCDProSettings settings = m_settings; if (deviceSettingsKeys.contains("centerFrequency")) { diff --git a/plugins/samplesource/fcdpro/fcdproinput.h b/plugins/samplesource/fcdpro/fcdproinput.h index dfdbabe0d..aa0c7240f 100644 --- a/plugins/samplesource/fcdpro/fcdproinput.h +++ b/plugins/samplesource/fcdpro/fcdproinput.h @@ -1,6 +1,5 @@ /////////////////////////////////////////////////////////////////////////////////// -// Copyright (C) 2012 maintech GmbH, Otto-Hahn-Str. 15, 97204 Hoechberg, Germany // -// written by Christian Daniel // +// Copyright (C) 2015-2018 Edouard Griffiths, F4EXB // // // // This program is free software; you can redistribute it and/or modify // // it under the terms of the GNU General Public License as published by // @@ -22,7 +21,10 @@ #include #include -#include +#include "dsp/devicesamplesource.h" +#include "audio/audioinput.h" +#include "audio/audiofifo.h" + #include "fcdprosettings.h" #include "fcdhid.h" @@ -158,6 +160,8 @@ public: private: bool openDevice(); void closeDevice(); + bool openFCDAudio(const char *filename); + void closeFCDAudio(); void applySettings(const FCDProSettings& settings, bool force); void set_lo_ppm(); @@ -165,6 +169,8 @@ private: DeviceSourceAPI *m_deviceAPI; hid_device *m_dev; + AudioInput m_fcdAudioInput; + AudioFifo m_fcdFIFO; QMutex m_mutex; FCDProSettings m_settings; FCDProThread* m_FCDThread; diff --git a/plugins/samplesource/fcdpro/fcdprothread.cpp b/plugins/samplesource/fcdpro/fcdprothread.cpp index e1fbbb721..7b4152b2e 100644 --- a/plugins/samplesource/fcdpro/fcdprothread.cpp +++ b/plugins/samplesource/fcdpro/fcdprothread.cpp @@ -18,16 +18,19 @@ #include #include #include -#include "fcdprothread.h" +#include +#include #include "dsp/samplesinkfifo.h" -#include "fcdtraits.h" +#include "audio/audiofifo.h" -FCDProThread::FCDProThread(SampleSinkFifo* sampleFifo, QObject* parent) : +#include "fcdprothread.h" + +FCDProThread::FCDProThread(SampleSinkFifo* sampleFifo, AudioFifo *fcdFIFO, QObject* parent) : QThread(parent), - fcd_handle(NULL), + m_fcdFIFO(fcdFIFO), m_running(false), - m_convertBuffer(fcd_traits::convBufSize), + m_convertBuffer(fcd_traits::convBufSize), // nb samples m_sampleFifo(sampleFifo) { start(); @@ -59,107 +62,23 @@ void FCDProThread::stopWork() void FCDProThread::run() { - if ( !OpenSource(fcd_traits::alsaDeviceName) ) - { - qCritical() << "FCDThread::run: cannot open FCD sound card"; - return; - } - // TODO: fallback to original fcd + m_running = true; + qDebug("FCDProThread::run: start running loop"); - m_running = true; + while (m_running) + { + work(fcd_traits::convBufSize); + std::this_thread::sleep_for(std::chrono::microseconds(200)); + } - while(m_running) - { - if (work(fcd_traits::convBufSize) < 0) - { - break; - } - } - - CloseSource(); + qDebug("FCDProThread::run: running loop stopped"); + m_running = false; } -bool FCDProThread::OpenSource(const char* cardname) +void FCDProThread::work(unsigned int n_items) { - bool fail = false; - snd_pcm_hw_params_t* params; - //fcd_rate = FCDPP_RATE; - //fcd_channels =2; - //fcd_format = SND_PCM_SFMT_U16_LE; - snd_pcm_stream_t fcd_stream = SND_PCM_STREAM_CAPTURE; - - if (fcd_handle) - { - return false; - } - - if (snd_pcm_open(&fcd_handle, cardname, fcd_stream, 0) < 0) - { - qCritical("FCDThread::OpenSource: cannot open %s", cardname); - return false; - } - - snd_pcm_hw_params_alloca(¶ms); - - if (snd_pcm_hw_params_any(fcd_handle, params) < 0) - { - qCritical("FCDThread::OpenSource: snd_pcm_hw_params_any failed"); - fail = true; - } - else if (snd_pcm_hw_params(fcd_handle, params) < 0) - { - qCritical("FCDThread::OpenSource: snd_pcm_hw_params failed"); - fail = true; - // TODO: check actual samplerate, may be crippled firmware - } - else - { - if (snd_pcm_start(fcd_handle) < 0) - { - qCritical("FCDThread::OpenSource: snd_pcm_start failed"); - fail = true; - } - } - - if (fail) - { - snd_pcm_close( fcd_handle ); - return false; - } - else - { - qDebug("FCDThread::OpenSource: Funcube stream started"); - } - - return true; + uint32_t nbRead = m_fcdFIFO->read((unsigned char *) m_buf, n_items); // number of samples + SampleVector::iterator it = m_convertBuffer.begin(); + m_decimators.decimate1(&it, m_buf, 2*nbRead); + m_sampleFifo->write(m_convertBuffer.begin(), it); } - -void FCDProThread::CloseSource() -{ - if (fcd_handle) - { - snd_pcm_close( fcd_handle ); - } - - fcd_handle = NULL; -} - -int FCDProThread::work(int n_items) -{ - int l; - SampleVector::iterator it; - void *out; - - it = m_convertBuffer.begin(); - out = (void *)&it[0]; - l = snd_pcm_mmap_readi(fcd_handle, out, (snd_pcm_uframes_t)n_items); - if (l > 0) - m_sampleFifo->write(it, it + l); - if (l == -EPIPE) { - qDebug("FCD: Overrun detected"); - return 0; - } - return l; -} - - diff --git a/plugins/samplesource/fcdpro/fcdprothread.h b/plugins/samplesource/fcdpro/fcdprothread.h index ce3e47da5..05891cd92 100644 --- a/plugins/samplesource/fcdpro/fcdprothread.h +++ b/plugins/samplesource/fcdpro/fcdprothread.h @@ -1,5 +1,5 @@ /////////////////////////////////////////////////////////////////////////////////// -// Copyright (C) 2015 Edouard Griffiths, F4EXB // +// Copyright (C) 2015-2018 Edouard Griffiths, F4EXB // // // // This program is free software; you can redistribute it and/or modify // // it under the terms of the GNU General Public License as published by // @@ -20,33 +20,37 @@ #include #include #include -#include "dsp/inthalfbandfilter.h" -#include + #include "dsp/samplesinkfifo.h" +#include "dsp/decimators.h" +#include "fcdtraits.h" + +class AudioFifo; class FCDProThread : public QThread { Q_OBJECT public: - FCDProThread(SampleSinkFifo* sampleFifo, QObject* parent = NULL); + FCDProThread(SampleSinkFifo* sampleFifo, AudioFifo *fcdFIFO, QObject* parent = nullptr); ~FCDProThread(); void startWork(); void stopWork(); - bool OpenSource(const char *filename); - void CloseSource(); private: - snd_pcm_t* fcd_handle; + AudioFifo* m_fcdFIFO; QMutex m_startWaitMutex; QWaitCondition m_startWaiter; bool m_running; + qint16 m_buf[fcd_traits::convBufSize*2]; // stereo (I, Q) SampleVector m_convertBuffer; SampleSinkFifo* m_sampleFifo; + Decimators m_decimators; void run(); - int work(int n_items); + void work(unsigned int n_items); }; + #endif // INCLUDE_FCDPROTHREAD_H diff --git a/plugins/samplesource/fcdproplus/fcdproplusgui.cpp b/plugins/samplesource/fcdproplus/fcdproplusgui.cpp index 210bb4752..7b261a9ca 100644 --- a/plugins/samplesource/fcdproplus/fcdproplusgui.cpp +++ b/plugins/samplesource/fcdproplus/fcdproplusgui.cpp @@ -127,7 +127,7 @@ bool FCDProPlusGui::deserialize(const QByteArray& data) } } -bool FCDProPlusGui::handleMessage(const Message& message __attribute__((unused))) +bool FCDProPlusGui::handleMessage(const Message& message) { if (FCDProPlusInput::MsgConfigureFCDProPlus::match(message)) { @@ -159,18 +159,20 @@ void FCDProPlusGui::handleInputMessages() while ((message = m_inputMessageQueue.pop()) != 0) { - qDebug("RTLSDRGui::handleInputMessages: message: %s", message->getIdentifier()); - if (DSPSignalNotification::match(*message)) { DSPSignalNotification* notif = (DSPSignalNotification*) message; m_sampleRate = notif->getSampleRate(); m_deviceCenterFrequency = notif->getCenterFrequency(); - qDebug("RTLSDRGui::handleInputMessages: DSPSignalNotification: SampleRate:%d, CenterFrequency:%llu", notif->getSampleRate(), notif->getCenterFrequency()); + qDebug("FCDProPlusGui::handleInputMessages: DSPSignalNotification: SampleRate:%d, CenterFrequency:%llu", notif->getSampleRate(), notif->getCenterFrequency()); updateSampleRateAndFrequency(); delete message; } + else + { + qWarning("FCDProPlusGui::handleInputMessages: message: %s. No action.", message->getIdentifier()); + } } } @@ -322,11 +324,8 @@ void FCDProPlusGui::on_ppm_valueChanged(int value) void FCDProPlusGui::on_startStop_toggled(bool checked) { - if (m_doApplySettings) - { - FCDProPlusInput::MsgStartStop *message = FCDProPlusInput::MsgStartStop::create(checked); - m_sampleSource->getInputMessageQueue()->push(message); - } + FCDProPlusInput::MsgStartStop *message = FCDProPlusInput::MsgStartStop::create(checked); + m_sampleSource->getInputMessageQueue()->push(message); } void FCDProPlusGui::on_record_toggled(bool checked) diff --git a/plugins/samplesource/fcdproplus/fcdproplusinput.cpp b/plugins/samplesource/fcdproplus/fcdproplusinput.cpp index a15a0819e..4c9776e13 100644 --- a/plugins/samplesource/fcdproplus/fcdproplusinput.cpp +++ b/plugins/samplesource/fcdproplus/fcdproplusinput.cpp @@ -1,5 +1,5 @@ /////////////////////////////////////////////////////////////////////////////////// -// Copyright (C) 2016 Edouard Griffiths, F4EXB // +// Copyright (C) 2016-2018 Edouard Griffiths, F4EXB // // // // This program is free software; you can redistribute it and/or modify // // it under the terms of the GNU General Public License as published by // @@ -14,8 +14,6 @@ // along with this program. If not, see . // /////////////////////////////////////////////////////////////////////////////////// -// FIXME: FCD is handled very badly! - #include #include #include @@ -25,11 +23,10 @@ #include "dsp/dspcommands.h" #include "dsp/dspengine.h" -#include +#include "dsp/filerecord.h" +#include "device/devicesourceapi.h" + #include "fcdproplusinput.h" - -#include - #include "fcdproplusthread.h" #include "fcdtraits.h" #include "fcdproplusconst.h" @@ -46,6 +43,7 @@ FCDProPlusInput::FCDProPlusInput(DeviceSourceAPI *deviceAPI) : m_deviceDescription(fcd_traits::displayedName), m_running(false) { + m_fcdFIFO.setSize(20*fcd_traits::convBufSize); openDevice(); m_fileSink = new FileRecord(QString("test_%1.sdriq").arg(m_deviceAPI->getDeviceUID())); m_deviceAPI->addSink(m_fileSink); @@ -53,9 +51,13 @@ FCDProPlusInput::FCDProPlusInput(DeviceSourceAPI *deviceAPI) : FCDProPlusInput::~FCDProPlusInput() { - if (m_running) stop(); + if (m_running) { + stop(); + } + m_deviceAPI->removeSink(m_fileSink); delete m_fileSink; + closeDevice(); } @@ -66,9 +68,12 @@ void FCDProPlusInput::destroy() bool FCDProPlusInput::openDevice() { + if (m_dev != 0) { + closeDevice(); + } + int device = m_deviceAPI->getSampleSourceSequence(); qDebug() << "FCDProPlusInput::openDevice with device #" << device; - m_dev = fcdOpen(fcd_traits::vendorId, fcd_traits::productId, device); if (m_dev == 0) @@ -87,14 +92,15 @@ void FCDProPlusInput::init() bool FCDProPlusInput::start() { - // QMutexLocker mutexLocker(&m_mutex); if (!m_dev) { return false; } - if (m_running) stop(); + if (m_running) { + stop(); + } qDebug() << "FCDProPlusInput::start"; @@ -105,13 +111,23 @@ bool FCDProPlusInput::start() //applySettings(m_settings, true); - if(!m_sampleFifo.setSize(96000*4)) + if (!m_sampleFifo.setSize(96000*4)) { - qCritical("Could not allocate SampleFifo"); + qCritical("FCDProPlusInput::start: could not allocate SampleFifo"); return false; } - m_FCDThread = new FCDProPlusThread(&m_sampleFifo); + if (!openFCDAudio(fcd_traits::qtDeviceName)) + { + qCritical("FCDProPlusInput::start: could not open FCD audio source"); + return false; + } + else + { + qDebug("FCDProPlusInput::start: FCD audio source opened"); + } + + m_FCDThread = new FCDProPlusThread(&m_sampleFifo, &m_fcdFIFO); m_FCDThread->startWork(); // mutexLocker.unlock(); @@ -133,6 +149,35 @@ void FCDProPlusInput::closeDevice() m_dev = 0; } +bool FCDProPlusInput::openFCDAudio(const char* cardname) +{ + AudioDeviceManager *audioDeviceManager = DSPEngine::instance()->getAudioDeviceManager(); + const QList& audioList = audioDeviceManager->getInputDevices(); + + for (const auto &itAudio : audioList) + { + if (itAudio.deviceName().contains(QString(cardname))) + { + int fcdDeviceIndex = audioDeviceManager->getInputDeviceIndex(itAudio.deviceName()); + m_fcdAudioInput.start(fcdDeviceIndex, fcd_traits::sampleRate); + int fcdSampleRate = m_fcdAudioInput.getRate(); + qDebug("FCDProPlusInput::openFCDAudio: %s index %d at %d S/s", + itAudio.deviceName().toStdString().c_str(), fcdDeviceIndex, fcdSampleRate); + m_fcdAudioInput.addFifo(&m_fcdFIFO); + return true; + } + } + + qCritical("FCDProPlusInput::openFCDAudio: device with name %s not found", cardname); + return false; +} + +void FCDProPlusInput::closeFCDAudio() +{ + m_fcdAudioInput.removeFifo(&m_fcdFIFO); + m_fcdAudioInput.stop(); +} + void FCDProPlusInput::stop() { QMutexLocker mutexLocker(&m_mutex); @@ -142,7 +187,8 @@ void FCDProPlusInput::stop() m_FCDThread->stopWork(); // wait for thread to quit ? delete m_FCDThread; - m_FCDThread = 0; + m_FCDThread = nullptr; + closeFCDAudio(); } m_running = false; @@ -217,7 +263,7 @@ bool FCDProPlusInput::handleMessage(const Message& message) else if (MsgStartStop::match(message)) { MsgStartStop& cmd = (MsgStartStop&) message; - qDebug() << "BladerfInput::handleMessage: MsgStartStop: " << (cmd.getStartStop() ? "start" : "stop"); + qDebug() << "FCDProPlusInput::handleMessage: MsgStartStop: " << (cmd.getStartStop() ? "start" : "stop"); if (cmd.getStartStop()) { @@ -460,8 +506,9 @@ void FCDProPlusInput::set_lo_ppm() int FCDProPlusInput::webapiRunGet( SWGSDRangel::SWGDeviceState& response, - QString& errorMessage __attribute__((unused))) + QString& errorMessage) { + (void) errorMessage; m_deviceAPI->getDeviceEngineStateStr(*response.getState()); return 200; } @@ -469,8 +516,9 @@ int FCDProPlusInput::webapiRunGet( int FCDProPlusInput::webapiRun( bool run, SWGSDRangel::SWGDeviceState& response, - QString& errorMessage __attribute__((unused))) + QString& errorMessage) { + (void) errorMessage; m_deviceAPI->getDeviceEngineStateStr(*response.getState()); MsgStartStop *message = MsgStartStop::create(run); m_inputMessageQueue.push(message); @@ -486,8 +534,9 @@ int FCDProPlusInput::webapiRun( int FCDProPlusInput::webapiSettingsGet( SWGSDRangel::SWGDeviceSettings& response, - QString& errorMessage __attribute__((unused))) + QString& errorMessage) { + (void) errorMessage; response.setFcdProPlusSettings(new SWGSDRangel::SWGFCDProPlusSettings()); response.getFcdProPlusSettings()->init(); webapiFormatDeviceSettings(response, m_settings); @@ -498,8 +547,9 @@ int FCDProPlusInput::webapiSettingsPutPatch( bool force, const QStringList& deviceSettingsKeys, SWGSDRangel::SWGDeviceSettings& response, // query + response - QString& errorMessage __attribute__((unused))) + QString& errorMessage) { + (void) errorMessage; FCDProPlusSettings settings = m_settings; if (deviceSettingsKeys.contains("centerFrequency")) { diff --git a/plugins/samplesource/fcdproplus/fcdproplusinput.h b/plugins/samplesource/fcdproplus/fcdproplusinput.h index 38c4cac11..94206cd61 100644 --- a/plugins/samplesource/fcdproplus/fcdproplusinput.h +++ b/plugins/samplesource/fcdproplus/fcdproplusinput.h @@ -1,5 +1,5 @@ /////////////////////////////////////////////////////////////////////////////////// -// Copyright (C) 2016 Edouard Griffiths, F4EXB // +// Copyright (C) 2016-2018 Edouard Griffiths, F4EXB // // // // This program is free software; you can redistribute it and/or modify // // it under the terms of the GNU General Public License as published by // @@ -21,7 +21,10 @@ #include #include -#include +#include "dsp/devicesamplesource.h" +#include "audio/audioinput.h" +#include "audio/audiofifo.h" + #include "fcdproplussettings.h" #include "fcdhid.h" @@ -147,11 +150,15 @@ public: private: bool openDevice(); void closeDevice(); + bool openFCDAudio(const char *filename); + void closeFCDAudio(); void applySettings(const FCDProPlusSettings& settings, bool force); void webapiFormatDeviceSettings(SWGSDRangel::SWGDeviceSettings& response, const FCDProPlusSettings& settings); DeviceSourceAPI *m_deviceAPI; hid_device *m_dev; + AudioInput m_fcdAudioInput; + AudioFifo m_fcdFIFO; QMutex m_mutex; FCDProPlusSettings m_settings; FCDProPlusThread* m_FCDThread; diff --git a/plugins/samplesource/fcdproplus/fcdproplusinputqt.cpp b/plugins/samplesource/fcdproplus/fcdproplusinputqt.cpp deleted file mode 100644 index 391a4f0ef..000000000 --- a/plugins/samplesource/fcdproplus/fcdproplusinputqt.cpp +++ /dev/null @@ -1,321 +0,0 @@ -/////////////////////////////////////////////////////////////////////////////////// -// Copyright (C) 2016 Edouard Griffiths, F4EXB // -// // -// This is a pure Qt (non ALSA) FCD sound card reader for Windows build // -// // -// This program is free software; you can redistribute it and/or modify // -// it under the terms of the GNU General Public License as published by // -// the Free Software Foundation as version 3 of the License, or // -// // -// This program is distributed in the hope that it will be useful, // -// but WITHOUT ANY WARRANTY; without even the implied warranty of // -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // -// GNU General Public License V3 for more details. // -// // -// You should have received a copy of the GNU General Public License // -// along with this program. If not, see . // -/////////////////////////////////////////////////////////////////////////////////// - -#include -#include -#include -#include "dsp/dspcommands.h" -#include "dsp/dspengine.h" -#include "fcdproplusinputqt.h" - -#include "fcdproplusgui.h" -#include "fcdproplusreader.h" -#include "fcdtraits.h" -#include "fcdproplusconst.h" - -MESSAGE_CLASS_DEFINITION(FCDProPlusInput::MsgConfigureFCDProPlus, Message) - -FCDProPlusInput::FCDProPlusInput() : - m_dev(0), - m_settings(), - m_deviceDescription(fcd_traits::displayedName), - m_FCDThread(0), - m_running(false), - m_deviceAPI(0) -{ - m_FCDReader = new FCDProPlusReader(&m_sampleFifo); -} - -FCDProPlusInput::~FCDProPlusInput() -{ - stop(); - delete m_FCDReader; -} - -bool FCDProPlusInput::init(const Message& cmd) -{ - return false; -} - -bool FCDProPlusInput::start(int device) -{ - qDebug() << "FCDProPlusInput::start with device #" << device; - - QMutexLocker mutexLocker(&m_mutex); - - m_dev = fcdOpen(fcd_traits::vendorId, fcd_traits::productId, device); - - if (m_dev == 0) - { - qCritical("FCDProPlusInput::start: could not open FCD"); - return false; - } - - /* Apply settings before streaming to avoid bus contention; - * there is very little spare bandwidth on a full speed USB device. - * Failure is harmless if no device is found - * ... This is rubbish...*/ - - //applySettings(m_settings, true); - - if(!m_sampleFifo.setSize(96000*4)) - { - qCritical("Could not allocate SampleFifo"); - return false; - } - - m_FCDReader->startWork(); - - mutexLocker.unlock(); - applySettings(m_settings, true); - - qDebug("FCDProPlusInput::started"); - return true; -} - -void FCDProPlusInput::stop() -{ - QMutexLocker mutexLocker(&m_mutex); - - m_FCDReader->stopWork(); - - fcdClose(m_dev); - m_dev = 0; -} - -const QString& FCDProPlusInput::getDeviceDescription() const -{ - return m_deviceDescription; -} - -int FCDProPlusInput::getSampleRate() const -{ - return fcd_traits::sampleRate; -} - -quint64 FCDProPlusInput::getCenterFrequency() const -{ - return m_settings.m_centerFrequency; -} - -bool FCDProPlusInput::handleMessage(const Message& message) -{ - if(MsgConfigureFCDProPlus::match(message)) - { - qDebug() << "FCDProPlusInput::handleMessage: MsgConfigureFCD"; - MsgConfigureFCDProPlus& conf = (MsgConfigureFCDProPlus&) message; - applySettings(conf.getSettings(), false); - return true; - } - else - { - return false; - } -} - -void FCDProPlusInput::applySettings(const FCDProPlusSettings& settings, bool force) -{ - bool signalChange = false; - - if ((m_settings.m_centerFrequency != settings.m_centerFrequency) || force) - { - qDebug() << "FCDProPlusInput::applySettings: fc: " << settings.m_centerFrequency; - m_settings.m_centerFrequency = settings.m_centerFrequency; - - if (m_dev != 0) - { - set_center_freq((double) m_settings.m_centerFrequency); - } - - signalChange = true; - } - - if ((m_settings.m_lnaGain != settings.m_lnaGain) || force) - { - m_settings.m_lnaGain = settings.m_lnaGain; - - if (m_dev != 0) - { - set_lna_gain(settings.m_lnaGain); - } - } - - if ((m_settings.m_biasT != settings.m_biasT) || force) - { - m_settings.m_biasT = settings.m_biasT; - - if (m_dev != 0) - { - set_bias_t(settings.m_biasT); - } - } - - if ((m_settings.m_mixGain != settings.m_mixGain) || force) - { - m_settings.m_mixGain = settings.m_mixGain; - - if (m_dev != 0) - { - set_mixer_gain(settings.m_mixGain); - } - } - - if ((m_settings.m_ifGain != settings.m_ifGain) || force) - { - m_settings.m_ifGain = settings.m_ifGain; - - if (m_dev != 0) - { - set_if_gain(settings.m_ifGain); - } - } - - if ((m_settings.m_ifFilterIndex != settings.m_ifFilterIndex) || force) - { - m_settings.m_ifFilterIndex = settings.m_ifFilterIndex; - - if (m_dev != 0) - { - set_if_filter(settings.m_ifFilterIndex); - } - } - - if ((m_settings.m_rfFilterIndex != settings.m_rfFilterIndex) || force) - { - m_settings.m_rfFilterIndex = settings.m_rfFilterIndex; - - if (m_dev != 0) - { - set_rf_filter(settings.m_rfFilterIndex); - } - } - - if ((m_settings.m_LOppmTenths != settings.m_LOppmTenths) || force) - { - m_settings.m_LOppmTenths = settings.m_LOppmTenths; - - if (m_dev != 0) - { - set_lo_ppm(); - } - } - - if ((m_settings.m_dcBlock != settings.m_dcBlock) || force) - { - m_settings.m_dcBlock = settings.m_dcBlock; - DSPEngine::instance()->configureCorrections(m_settings.m_dcBlock, m_settings.m_iqImbalance); - } - - if ((m_settings.m_iqImbalance != settings.m_iqImbalance) || force) - { - m_settings.m_iqImbalance = settings.m_iqImbalance; - DSPEngine::instance()->configureCorrections(m_settings.m_dcBlock, m_settings.m_iqImbalance); - } - - if (signalChange) - { - DSPSignalNotification *notif = new DSPSignalNotification(fcd_traits::sampleRate, m_settings.m_centerFrequency); - DSPEngine::instance()->getInputMessageQueue()->push(notif); - } -} - -void FCDProPlusInput::set_center_freq(double freq) -{ - freq += freq*(((double) m_settings.m_LOppmTenths)/10000000.0); - - if (fcdAppSetFreq(m_dev, freq) == FCD_MODE_NONE) - { - qDebug("No FCD HID found for frquency change"); - } -} - -void FCDProPlusInput::set_bias_t(bool on) -{ - quint8 cmd = on ? 1 : 0; - - fcdAppSetParam(m_dev, FCDPROPLUS_HID_CMD_SET_BIAS_TEE, &cmd, 1); -} - -void FCDProPlusInput::set_lna_gain(bool on) -{ - quint8 cmd = on ? 1 : 0; - - fcdAppSetParam(m_dev, FCDPROPLUS_HID_CMD_SET_LNA_GAIN, &cmd, 1); -} - -void FCDProPlusInput::set_mixer_gain(bool on) -{ - quint8 cmd = on ? 1 : 0; - - fcdAppSetParam(m_dev, FCDPROPLUS_HID_CMD_SET_MIXER_GAIN, &cmd, 1); -} - -void FCDProPlusInput::set_if_gain(int gain) -{ - if (gain < 0) - { - return; - } - - quint8 cmd_value = gain; - - if (fcdAppSetParam(m_dev, FCDPROPLUS_HID_CMD_SET_IF_GAIN, &cmd_value, 1) != FCD_MODE_APP) - { - qWarning() << "FCDProPlusInput::set_if_gain: failed to set at " << cmd_value; - } -} - -void FCDProPlusInput::set_if_filter(int filterIndex) -{ - if ((filterIndex < 0) || (filterIndex >= FCDProPlusConstants::fcdproplus_if_filter_nb_values())) - { - return; - } - - quint8 cmd_value = FCDProPlusConstants::if_filters[filterIndex].value; - - if (fcdAppSetParam(m_dev, FCDPROPLUS_HID_CMD_SET_IF_FILTER, &cmd_value, 1) != FCD_MODE_APP) - { - qWarning() << "FCDProPlusInput::set_if_filter: failed to set at " << cmd_value; - } -} - - -void FCDProPlusInput::set_rf_filter(int filterIndex) -{ - if ((filterIndex < 0) || (filterIndex >= FCDProPlusConstants::fcdproplus_rf_filter_nb_values())) - { - return; - } - - quint8 cmd_value = FCDProPlusConstants::rf_filters[filterIndex].value; - - if (fcdAppSetParam(m_dev, FCDPROPLUS_HID_CMD_SET_RF_FILTER, &cmd_value, 1) != FCD_MODE_APP) - { - qWarning() << "FCDProPlusInput::set_rf_filter: failed to set at " << cmd_value; - } -} - -void FCDProPlusInput::set_lo_ppm() -{ - set_center_freq((double) m_settings.m_centerFrequency); -} - - - - diff --git a/plugins/samplesource/fcdproplus/fcdproplusinputqt.h b/plugins/samplesource/fcdproplus/fcdproplusinputqt.h deleted file mode 100644 index af974e582..000000000 --- a/plugins/samplesource/fcdproplus/fcdproplusinputqt.h +++ /dev/null @@ -1,90 +0,0 @@ -/////////////////////////////////////////////////////////////////////////////////// -// Copyright (C) 2016 Edouard Griffiths, F4EXB // -// // -// This is a pure Qt (non ALSA) FCD sound card reader for Windows build // -// // -// This program is free software; you can redistribute it and/or modify // -// it under the terms of the GNU General Public License as published by // -// the Free Software Foundation as version 3 of the License, or // -// // -// This program is distributed in the hope that it will be useful, // -// but WITHOUT ANY WARRANTY; without even the implied warranty of // -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // -// GNU General Public License V3 for more details. // -// // -// You should have received a copy of the GNU General Public License // -// along with this program. If not, see . // -/////////////////////////////////////////////////////////////////////////////////// - -#ifndef INCLUDE_FCDINPUT_H -#define INCLUDE_FCDINPUT_H - -#include - -#include "fcdproplussettings.h" -#include "fcdhid.h" -#include -#include - -struct fcd_buffer { - void *start; - std::size_t length; -}; - -class FCDProPlusReader; - -class FCDProPlusInput : public DeviceSampleSource { -public: - class MsgConfigureFCDProPlus : public Message { - MESSAGE_CLASS_DECLARATION - - public: - const FCDProPlusSettings& getSettings() const { return m_settings; } - - static MsgConfigureFCDProPlus* create(const FCDProPlusSettings& settings) - { - return new MsgConfigureFCDProPlus(settings); - } - - private: - FCDProPlusSettings m_settings; - - MsgConfigureFCD(const FCDProPlusSettings& settings) : - Message(), - m_settings(settings) - { } - }; - - FCDProPlusInput(); - virtual ~FCDProPlusInput(); - - virtual bool init(const Message& cmd); - virtual bool start(int device); - virtual void stop(); - - virtual const QString& getDeviceDescription() const; - virtual int getSampleRate() const; - virtual quint64 getCenterFrequency() const; - - virtual bool handleMessage(const Message& message); - - void set_center_freq(double freq); - void set_bias_t(bool on); - void set_lna_gain(bool on); - void set_mixer_gain(bool on); - void set_if_gain(int gain); - void set_rf_filter(int filterIndex); - void set_if_filter(int filterIndex); - void set_lo_ppm(); - -private: - void applySettings(const FCDProPlusSettings& settings, bool force); - - hid_device *m_dev; - QMutex m_mutex; - FCDProPlusSettings m_settings; - FCDProPlusReader* m_FCDReader; - QString m_deviceDescription; -}; - -#endif // INCLUDE_FCD_H diff --git a/plugins/samplesource/fcdproplus/fcdproplusreader.cpp b/plugins/samplesource/fcdproplus/fcdproplusreader.cpp deleted file mode 100644 index c12366a5c..000000000 --- a/plugins/samplesource/fcdproplus/fcdproplusreader.cpp +++ /dev/null @@ -1,146 +0,0 @@ -/////////////////////////////////////////////////////////////////////////////////// -// Copyright (C) 2016 Edouard Griffiths, F4EXB // -// // -// This program is free software; you can redistribute it and/or modify // -// it under the terms of the GNU General Public License as published by // -// the Free Software Foundation as version 3 of the License, or // -// // -// This program is distributed in the hope that it will be useful, // -// but WITHOUT ANY WARRANTY; without even the implied warranty of // -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // -// GNU General Public License V3 for more details. // -// // -// You should have received a copy of the GNU General Public License // -// along with this program. If not, see . // -/////////////////////////////////////////////////////////////////////////////////// - -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include "fcdproplusreader.h" - -#include "dsp/samplesinkfifo.h" -#include "fcdtraits.h" - -FCDProPlusReader::FCDProPlusReader(SampleSinkFifo* sampleFifo, QObject* parent) : - QObject(parent), - m_fcdAudioInput(0), - m_fcdInput(0), - m_running(false), - m_convertBuffer(fcd_traits::convBufSize), - m_fcdBuffer(fcd_traits::fcdBufSize, 0), - m_sampleFifo(sampleFifo) -{ -} - -FCDProPlusReader::~FCDProPlusReader() -{ - if (m_fcdAudioInput) { - delete m_fcdAudioInput; - } -} - -void FCDProPlusReader::startWork() -{ - QList audioDevices = QAudioDeviceInfo::availableDevices(QAudio::AudioInput); - - QList::iterator audioDeviceIt, fcdDeviceIt = audioDevices.end(); - - for (audioDeviceIt = audioDevices.begin(); audioDeviceIt != audioDevices.end(); ++audioDeviceIt) - { - QAudioFormat fcdAudioFormat = audioDeviceIt->preferredFormat(); - int sampleRate = fcdAudioFormat.sampleRate(); - int sampleBits = fcdAudioFormat.sampleSize(); - - if ((sampleRate == 192000) && (sampleBits == 16)) - { - qDebug() << "FCDProPlusReader::startWork: found: " << audioDeviceIt->deviceName() - << " sampleRate: " << fcdAudioFormat.sampleRate() - << " sampleBits: " << fcdAudioFormat.sampleSize(); - fcdDeviceIt = audioDeviceIt; - break; - } - } - - if (fcdDeviceIt == audioDevices.end()) - { - qCritical() << "FCDProPlusReader::startWork: FCD Pro+ sound card not found"; - return; - } - - openFcdAudio(*fcdDeviceIt); - - if (!m_fcdAudioInput) - { - qCritical() << "FCDProPlusReader::startWork: cannot open FCD Pro+ sound card"; - return; - } - - m_fcdAudioInput->stop(); - m_fcdInput = m_fcdAudioInput->start(); - - if (!m_fcdInput) - { - qCritical() << "FCDProPlusReader::startWork: cannot start FCD Pro+ sound card"; - return; - } - - connect(m_fcdInput, SIGNAL(readyRead()), this, SLOT(readFcdAudio())); - m_running = true; - - qDebug() << "FCDProPlusReader::startWork: started"; -} - -void FCDProPlusReader::stopWork() -{ - m_running = false; - disconnect(m_fcdInput, SIGNAL(readyRead()), this, SLOT(readFcdAudio())); - m_fcdAudioInput->stop(); - - qDebug() << "FCDProPlusReader::stopWork: stopped"; -} - -void FCDProPlusReader::openFcdAudio(const QAudioDeviceInfo& fcdAudioDeviceInfo) -{ - QAudioFormat fcdAudioFormat = fcdAudioDeviceInfo.preferredFormat(); - - qDebug() << "FCDProPlusReader::openFcdAudio: device: " << fcdAudioDeviceInfo.deviceName() - << " sampleRate: " << fcdAudioFormat.sampleRate() - << " sampleBits: " << fcdAudioFormat.sampleSize(); - - m_fcdAudioInput = new QAudioInput(fcdAudioDeviceInfo, fcdAudioFormat, this); - //m_fcdAudioInput->setBufferSize(1<<14); - //m_fcdAudioInput->setNotifyInterval(50); -} - -void FCDProPlusReader::readFcdAudio() -{ - if (!m_fcdAudioInput) { - return; - } - - int len = m_fcdAudioInput->bytesReady(); - -// qDebug() << "FCDProPlusReader::readFcdAudio:" -// << " buffer size: " << m_fcdAudioInput->bufferSize() -// << " interval: " << m_fcdAudioInput->notifyInterval() -// << " len: " << len; - - if (len > fcd_traits::fcdBufSize) { - len = fcd_traits::fcdBufSize; - } - - int readLen = m_fcdInput->read(m_fcdBuffer.data(), len); - - if (readLen > 0) { - m_sampleFifo->write((const quint8*) m_fcdBuffer.constData(), (uint) readLen); - } -} - diff --git a/plugins/samplesource/fcdproplus/fcdproplusthread.cpp b/plugins/samplesource/fcdproplus/fcdproplusthread.cpp index a29ca1411..4a6f27f2a 100644 --- a/plugins/samplesource/fcdproplus/fcdproplusthread.cpp +++ b/plugins/samplesource/fcdproplus/fcdproplusthread.cpp @@ -1,6 +1,5 @@ /////////////////////////////////////////////////////////////////////////////////// -// Copyright (C) 2012 maintech GmbH, Otto-Hahn-Str. 15, 97204 Hoechberg, Germany // -// written by Christian Daniel // +// Copyright (C) 2016-2018 Edouard Griffiths, F4EXB // // // // This program is free software; you can redistribute it and/or modify // // it under the terms of the GNU General Public License as published by // @@ -18,16 +17,19 @@ #include #include #include -#include "fcdproplusthread.h" +#include +#include #include "dsp/samplesinkfifo.h" -#include "fcdtraits.h" +#include "audio/audiofifo.h" -FCDProPlusThread::FCDProPlusThread(SampleSinkFifo* sampleFifo, QObject* parent) : +#include "fcdproplusthread.h" + +FCDProPlusThread::FCDProPlusThread(SampleSinkFifo* sampleFifo, AudioFifo *fcdFIFO, QObject* parent) : QThread(parent), - fcd_handle(NULL), + m_fcdFIFO(fcdFIFO), m_running(false), - m_convertBuffer(fcd_traits::convBufSize), + m_convertBuffer(fcd_traits::convBufSize), // nb samples m_sampleFifo(sampleFifo) { start(); @@ -59,107 +61,23 @@ void FCDProPlusThread::stopWork() void FCDProPlusThread::run() { - if ( !OpenSource(fcd_traits::alsaDeviceName) ) - { - qCritical() << "FCDThread::run: cannot open FCD sound card"; - return; - } - // TODO: fallback to original fcd - m_running = true; + qDebug("FCDThread::run: start running loop"); - while(m_running) + while (m_running) { - if (work(fcd_traits::convBufSize) < 0) - { - break; - } + work(fcd_traits::convBufSize); + std::this_thread::sleep_for(std::chrono::microseconds(100)); } - CloseSource(); + qDebug("FCDThread::run: running loop stopped"); + m_running = false; } -bool FCDProPlusThread::OpenSource(const char* cardname) +void FCDProPlusThread::work(unsigned int n_items) { - bool fail = false; - snd_pcm_hw_params_t* params; - //fcd_rate = FCDPP_RATE; - //fcd_channels =2; - //fcd_format = SND_PCM_SFMT_U16_LE; - snd_pcm_stream_t fcd_stream = SND_PCM_STREAM_CAPTURE; - - if (fcd_handle) - { - return false; - } - - if (snd_pcm_open(&fcd_handle, cardname, fcd_stream, 0) < 0) - { - qCritical("FCDThread::OpenSource: cannot open %s", cardname); - return false; - } - - snd_pcm_hw_params_alloca(¶ms); - - if (snd_pcm_hw_params_any(fcd_handle, params) < 0) - { - qCritical("FCDProPlusThread::OpenSource: snd_pcm_hw_params_any failed"); - fail = true; - } - else if (snd_pcm_hw_params(fcd_handle, params) < 0) - { - qCritical("FCDProPlusThread::OpenSource: snd_pcm_hw_params failed"); - fail = true; - // TODO: check actual samplerate, may be crippled firmware - } - else - { - if (snd_pcm_start(fcd_handle) < 0) - { - qCritical("FCDProPlusThread::OpenSource: snd_pcm_start failed"); - fail = true; - } - } - - if (fail) - { - snd_pcm_close( fcd_handle ); - return false; - } - else - { - qDebug("FCDProPlusThread::OpenSource: Funcube stream started"); - } - - return true; + uint32_t nbRead = m_fcdFIFO->read((unsigned char *) m_buf, n_items); // number of samples + SampleVector::iterator it = m_convertBuffer.begin(); + m_decimators.decimate1(&it, m_buf, 2*nbRead); + m_sampleFifo->write(m_convertBuffer.begin(), it); } - -void FCDProPlusThread::CloseSource() -{ - if (fcd_handle) - { - snd_pcm_close( fcd_handle ); - } - - fcd_handle = NULL; -} - -int FCDProPlusThread::work(int n_items) -{ - int l; - SampleVector::iterator it; - void *out; - - it = m_convertBuffer.begin(); - out = (void *)&it[0]; - l = snd_pcm_mmap_readi(fcd_handle, out, (snd_pcm_uframes_t)n_items); - if (l > 0) - m_sampleFifo->write(it, it + l); - if (l == -EPIPE) { - qDebug("FCDProPlusThread::work: Overrun detected"); - return 0; - } - return l; -} - - diff --git a/plugins/samplesource/fcdproplus/fcdproplusthread.h b/plugins/samplesource/fcdproplus/fcdproplusthread.h index 74e7f6d75..d8b7a7961 100644 --- a/plugins/samplesource/fcdproplus/fcdproplusthread.h +++ b/plugins/samplesource/fcdproplus/fcdproplusthread.h @@ -21,33 +21,36 @@ #include #include #include -#include "dsp/inthalfbandfilter.h" -#include + #include "dsp/samplesinkfifo.h" +#include "dsp/decimators.h" +#include "fcdtraits.h" + +class AudioFifo; class FCDProPlusThread : public QThread { Q_OBJECT public: - FCDProPlusThread(SampleSinkFifo* sampleFifo, QObject* parent = NULL); + FCDProPlusThread(SampleSinkFifo* sampleFifo, AudioFifo *fcdFIFO, QObject* parent = nullptr); ~FCDProPlusThread(); void startWork(); void stopWork(); - bool OpenSource(const char *filename); - void CloseSource(); private: - snd_pcm_t* fcd_handle; + AudioFifo* m_fcdFIFO; QMutex m_startWaitMutex; QWaitCondition m_startWaiter; bool m_running; + qint16 m_buf[fcd_traits::convBufSize*2]; // stereo (I, Q) SampleVector m_convertBuffer; SampleSinkFifo* m_sampleFifo; + Decimators m_decimators; void run(); - int work(int n_items); + void work(unsigned int n_items); }; #endif // INCLUDE_FCDTHREAD_H diff --git a/plugins/samplesource/filesource/filesourcegui.cpp b/plugins/samplesource/filesource/filesourcegui.cpp index f19e500dd..700065a27 100644 --- a/plugins/samplesource/filesource/filesourcegui.cpp +++ b/plugins/samplesource/filesource/filesourcegui.cpp @@ -310,8 +310,9 @@ void FileSourceGui::on_navTimeSlider_valueChanged(int value) } } -void FileSourceGui::on_showFileDialog_clicked(bool checked __attribute__((unused))) +void FileSourceGui::on_showFileDialog_clicked(bool checked) { + (void) checked; QString fileName = QFileDialog::getOpenFileName(this, tr("Open I/Q record file"), ".", tr("SDR I/Q Files (*.sdriq)"), 0, QFileDialog::DontUseNativeDialog); diff --git a/plugins/samplesource/filesource/filesourceinput.cpp b/plugins/samplesource/filesource/filesourceinput.cpp index 74f0b4c26..c68d3bbd1 100644 --- a/plugins/samplesource/filesource/filesourceinput.cpp +++ b/plugins/samplesource/filesource/filesourceinput.cpp @@ -409,8 +409,9 @@ bool FileSourceInput::applySettings(const FileSourceSettings& settings, bool for int FileSourceInput::webapiSettingsGet( SWGSDRangel::SWGDeviceSettings& response, - QString& errorMessage __attribute__((unused))) + QString& errorMessage) { + (void) errorMessage; response.setFileSourceSettings(new SWGSDRangel::SWGFileSourceSettings()); response.getFileSourceSettings()->init(); webapiFormatDeviceSettings(response, m_settings); @@ -421,8 +422,9 @@ int FileSourceInput::webapiSettingsPutPatch( bool force, const QStringList& deviceSettingsKeys, SWGSDRangel::SWGDeviceSettings& response, // query + response - QString& errorMessage __attribute__((unused))) + QString& errorMessage) { + (void) errorMessage; FileSourceSettings settings = m_settings; if (deviceSettingsKeys.contains("fileName")) { @@ -450,8 +452,9 @@ int FileSourceInput::webapiSettingsPutPatch( int FileSourceInput::webapiRunGet( SWGSDRangel::SWGDeviceState& response, - QString& errorMessage __attribute__((unused))) + QString& errorMessage) { + (void) errorMessage; m_deviceAPI->getDeviceEngineStateStr(*response.getState()); return 200; } @@ -459,8 +462,9 @@ int FileSourceInput::webapiRunGet( int FileSourceInput::webapiRun( bool run, SWGSDRangel::SWGDeviceState& response, - QString& errorMessage __attribute__((unused))) + QString& errorMessage) { + (void) errorMessage; m_deviceAPI->getDeviceEngineStateStr(*response.getState()); MsgStartStop *message = MsgStartStop::create(run); m_inputMessageQueue.push(message); @@ -476,8 +480,9 @@ int FileSourceInput::webapiRun( int FileSourceInput::webapiReportGet( SWGSDRangel::SWGDeviceReport& response, - QString& errorMessage __attribute__((unused))) + QString& errorMessage) { + (void) errorMessage; response.setFileSourceReport(new SWGSDRangel::SWGFileSourceReport()); response.getFileSourceReport()->init(); webapiFormatDeviceReport(response); diff --git a/plugins/samplesource/filesource/filesourcesettings.cpp b/plugins/samplesource/filesource/filesourcesettings.cpp index 950f1c1af..f8a6b370a 100644 --- a/plugins/samplesource/filesource/filesourcesettings.cpp +++ b/plugins/samplesource/filesource/filesourcesettings.cpp @@ -103,7 +103,7 @@ int FileSourceSettings::getAccelerationValue(int accelerationIndex) unsigned int v = accelerationIndex - 1; int m = pow(10.0, v/3 > m_accelerationMaxScale ? m_accelerationMaxScale : v/3); - int x; + int x = 1; if (v % 3 == 0) { x = 2; diff --git a/plugins/samplesource/hackrfinput/hackrfinput.cpp b/plugins/samplesource/hackrfinput/hackrfinput.cpp index 744119e0c..2e0dc8dc9 100644 --- a/plugins/samplesource/hackrfinput/hackrfinput.cpp +++ b/plugins/samplesource/hackrfinput/hackrfinput.cpp @@ -528,8 +528,9 @@ bool HackRFInput::applySettings(const HackRFInputSettings& settings, bool force) int HackRFInput::webapiSettingsGet( SWGSDRangel::SWGDeviceSettings& response, - QString& errorMessage __attribute__((unused))) + QString& errorMessage) { + (void) errorMessage; response.setHackRfInputSettings(new SWGSDRangel::SWGHackRFInputSettings()); response.getHackRfInputSettings()->init(); webapiFormatDeviceSettings(response, m_settings); @@ -540,8 +541,9 @@ int HackRFInput::webapiSettingsPutPatch( bool force, const QStringList& deviceSettingsKeys, SWGSDRangel::SWGDeviceSettings& response, // query + response - QString& errorMessage __attribute__((unused))) + QString& errorMessage) { + (void) errorMessage; HackRFInputSettings settings = m_settings; if (deviceSettingsKeys.contains("centerFrequency")) { @@ -628,8 +630,9 @@ void HackRFInput::webapiFormatDeviceSettings(SWGSDRangel::SWGDeviceSettings& res int HackRFInput::webapiRunGet( SWGSDRangel::SWGDeviceState& response, - QString& errorMessage __attribute__((unused))) + QString& errorMessage) { + (void) errorMessage; m_deviceAPI->getDeviceEngineStateStr(*response.getState()); return 200; } @@ -637,8 +640,9 @@ int HackRFInput::webapiRunGet( int HackRFInput::webapiRun( bool run, SWGSDRangel::SWGDeviceState& response, - QString& errorMessage __attribute__((unused))) + QString& errorMessage) { + (void) errorMessage; m_deviceAPI->getDeviceEngineStateStr(*response.getState()); MsgStartStop *message = MsgStartStop::create(run); m_inputMessageQueue.push(message); diff --git a/plugins/samplesource/hackrfinput/hackrfinput.pro b/plugins/samplesource/hackrfinput/hackrfinput.pro index ea5511dc7..573d81165 100644 --- a/plugins/samplesource/hackrfinput/hackrfinput.pro +++ b/plugins/samplesource/hackrfinput/hackrfinput.pro @@ -19,6 +19,8 @@ QMAKE_CXXFLAGS += -std=c++11 CONFIG(MINGW32):LIBHACKRFSRC = "C:\softs\hackrf\host" CONFIG(MINGW64):LIBHACKRFSRC = "C:\softs\hackrf\host" +CONFIG(MSVC):LIBHACKRFSRC = "C:\softs\hackrf\host" + INCLUDEPATH += $$PWD INCLUDEPATH += ../../../exports INCLUDEPATH += ../../../sdrbase diff --git a/plugins/samplesource/hackrfinput/hackrfinputthread.cpp b/plugins/samplesource/hackrfinput/hackrfinputthread.cpp index c0a9dfc57..af3baa502 100644 --- a/plugins/samplesource/hackrfinput/hackrfinputthread.cpp +++ b/plugins/samplesource/hackrfinput/hackrfinputthread.cpp @@ -18,7 +18,6 @@ #include #include -#include #include #include "dsp/samplesinkfifo.h" diff --git a/plugins/samplesource/limesdrinput/limesdrinput.cpp b/plugins/samplesource/limesdrinput/limesdrinput.cpp index 45add7cdd..ab08e7c3e 100644 --- a/plugins/samplesource/limesdrinput/limesdrinput.cpp +++ b/plugins/samplesource/limesdrinput/limesdrinput.cpp @@ -615,6 +615,17 @@ bool LimeSDRInput::handleMessage(const Message& message) return true; } + else if (DeviceLimeSDRShared::MsgReportGPIOChange::match(message)) + { + DeviceLimeSDRShared::MsgReportGPIOChange& report = (DeviceLimeSDRShared::MsgReportGPIOChange&) message; + + m_settings.m_gpioDir = report.getGPIODir(); + m_settings.m_gpioPins = report.getGPIOPins(); + + // no GUI for the moment only REST API + + return true; + } else if (MsgGetStreamInfo::match(message)) { // qDebug() << "LimeSDRInput::handleMessage: MsgGetStreamInfo"; @@ -660,19 +671,24 @@ bool LimeSDRInput::handleMessage(const Message& message) else if (MsgGetDeviceInfo::match(message)) { double temp = 0.0; + uint8_t gpioPins = 0; - if (m_deviceShared.m_deviceParams->getDevice() && (LMS_GetChipTemperature(m_deviceShared.m_deviceParams->getDevice(), 0, &temp) == 0)) - { - //qDebug("LimeSDRInput::handleMessage: MsgGetDeviceInfo: temperature: %f", temp); - } - else - { + if (m_deviceShared.m_deviceParams->getDevice() && (LMS_GetChipTemperature(m_deviceShared.m_deviceParams->getDevice(), 0, &temp) != 0)) { qDebug("LimeSDRInput::handleMessage: MsgGetDeviceInfo: cannot get temperature"); } + if ((m_deviceShared.m_deviceParams->m_type != DeviceLimeSDRParams::LimeMini) + && (m_deviceShared.m_deviceParams->m_type != DeviceLimeSDRParams::LimeUndefined)) + { + if (m_deviceShared.m_deviceParams->getDevice() && (LMS_GPIORead(m_deviceShared.m_deviceParams->getDevice(), &gpioPins, 1) != 0)) { + qDebug("LimeSDROutput::handleMessage: MsgGetDeviceInfo: cannot get GPIO pins values"); + } + } + // send to oneself - if (m_deviceAPI->getSampleSourceGUIMessageQueue()) { - DeviceLimeSDRShared::MsgReportDeviceInfo *report = DeviceLimeSDRShared::MsgReportDeviceInfo::create(temp); + if (m_deviceAPI->getSampleSourceGUIMessageQueue()) + { + DeviceLimeSDRShared::MsgReportDeviceInfo *report = DeviceLimeSDRShared::MsgReportDeviceInfo::create(temp, gpioPins); m_deviceAPI->getSampleSourceGUIMessageQueue()->push(report); } @@ -684,7 +700,7 @@ bool LimeSDRInput::handleMessage(const Message& message) { if ((*itSource)->getSampleSourceGUIMessageQueue()) { - DeviceLimeSDRShared::MsgReportDeviceInfo *report = DeviceLimeSDRShared::MsgReportDeviceInfo::create(temp); + DeviceLimeSDRShared::MsgReportDeviceInfo *report = DeviceLimeSDRShared::MsgReportDeviceInfo::create(temp, gpioPins); (*itSource)->getSampleSourceGUIMessageQueue()->push(report); } } @@ -697,7 +713,7 @@ bool LimeSDRInput::handleMessage(const Message& message) { if ((*itSink)->getSampleSinkGUIMessageQueue()) { - DeviceLimeSDRShared::MsgReportDeviceInfo *report = DeviceLimeSDRShared::MsgReportDeviceInfo::create(temp); + DeviceLimeSDRShared::MsgReportDeviceInfo *report = DeviceLimeSDRShared::MsgReportDeviceInfo::create(temp, gpioPins); (*itSink)->getSampleSinkGUIMessageQueue()->push(report); } } @@ -757,6 +773,7 @@ bool LimeSDRInput::applySettings(const LimeSDRInputSettings& settings, bool forc bool forwardChangeRxDSP = false; bool forwardChangeAllDSP = false; bool forwardClockSource = false; + bool forwardGPIOChange = false; bool ownThreadWasRunning = false; bool doCalibration = false; bool doLPCalibration = false; @@ -1093,6 +1110,36 @@ bool LimeSDRInput::applySettings(const LimeSDRInputSettings& settings, bool forc } } + if ((m_deviceShared.m_deviceParams->m_type != DeviceLimeSDRParams::LimeMini) + && (m_deviceShared.m_deviceParams->m_type != DeviceLimeSDRParams::LimeUndefined)) + { + if ((m_settings.m_gpioDir != settings.m_gpioDir) || force) + { + if (LMS_GPIODirWrite(m_deviceShared.m_deviceParams->getDevice(), &settings.m_gpioDir, 1) != 0) + { + qCritical("LimeSDROutput::applySettings: could not set GPIO directions to %u", settings.m_gpioDir); + } + else + { + forwardGPIOChange = true; + qDebug("LimeSDROutput::applySettings: GPIO directions set to %u", settings.m_gpioDir); + } + } + + if ((m_settings.m_gpioPins != settings.m_gpioPins) || force) + { + if (LMS_GPIOWrite(m_deviceShared.m_deviceParams->getDevice(), &settings.m_gpioPins, 1) != 0) + { + qCritical("LimeSDROutput::applySettings: could not set GPIO pins to %u", settings.m_gpioPins); + } + else + { + forwardGPIOChange = true; + qDebug("LimeSDROutput::applySettings: GPIO pins set to %u", settings.m_gpioPins); + } + } + } + m_settings = settings; double clockGenFreqAfter; @@ -1250,6 +1297,31 @@ bool LimeSDRInput::applySettings(const LimeSDRInputSettings& settings, bool forc } } + if (forwardGPIOChange) + { + // send to source buddies + const std::vector& sourceBuddies = m_deviceAPI->getSourceBuddies(); + std::vector::const_iterator itSource = sourceBuddies.begin(); + + for (; itSource != sourceBuddies.end(); ++itSource) + { + DeviceLimeSDRShared::MsgReportClockSourceChange *report = DeviceLimeSDRShared::MsgReportClockSourceChange::create( + m_settings.m_extClock, m_settings.m_extClockFreq); + (*itSource)->getSampleSourceInputMessageQueue()->push(report); + } + + // send to sink buddies + const std::vector& sinkBuddies = m_deviceAPI->getSinkBuddies(); + std::vector::const_iterator itSink = sinkBuddies.begin(); + + for (; itSink != sinkBuddies.end(); ++itSink) + { + DeviceLimeSDRShared::MsgReportClockSourceChange *report = DeviceLimeSDRShared::MsgReportClockSourceChange::create( + m_settings.m_extClock, m_settings.m_extClockFreq); + (*itSink)->getSampleSinkInputMessageQueue()->push(report); + } + } + QLocale loc; qDebug().noquote() << "LimeSDRInput::applySettings: center freq: " << m_settings.m_centerFrequency << " Hz" @@ -1270,6 +1342,8 @@ bool LimeSDRInput::applySettings(const LimeSDRInputSettings& settings, bool forc << " m_antennaPath: " << m_settings.m_antennaPath << " m_extClock: " << m_settings.m_extClock << " m_extClockFreq: " << loc.toString(m_settings.m_extClockFreq) + << " m_gpioDir: " << m_settings.m_gpioDir + << " m_gpioPins: " << m_settings.m_gpioPins << " force: " << force << " forceNCOFrequency: " << forceNCOFrequency << " doCalibration: " << doCalibration @@ -1280,8 +1354,9 @@ bool LimeSDRInput::applySettings(const LimeSDRInputSettings& settings, bool forc int LimeSDRInput::webapiSettingsGet( SWGSDRangel::SWGDeviceSettings& response, - QString& errorMessage __attribute__((unused))) + QString& errorMessage) { + (void) errorMessage; response.setLimeSdrInputSettings(new SWGSDRangel::SWGLimeSdrInputSettings()); response.getLimeSdrInputSettings()->init(); webapiFormatDeviceSettings(response, m_settings); @@ -1292,8 +1367,9 @@ int LimeSDRInput::webapiSettingsPutPatch( bool force, const QStringList& deviceSettingsKeys, SWGSDRangel::SWGDeviceSettings& response, // query + response - QString& errorMessage __attribute__((unused))) + QString& errorMessage) { + (void) errorMessage; LimeSDRInputSettings settings = m_settings; if (deviceSettingsKeys.contains("antennaPath")) { @@ -1362,6 +1438,12 @@ int LimeSDRInput::webapiSettingsPutPatch( if (deviceSettingsKeys.contains("fileRecordName")) { settings.m_fileRecordName = *response.getLimeSdrInputSettings()->getFileRecordName(); } + if (deviceSettingsKeys.contains("gpioDir")) { + settings.m_gpioDir = response.getLimeSdrInputSettings()->getGpioDir() & 0xFF; + } + if (deviceSettingsKeys.contains("gpioPins")) { + settings.m_gpioPins = response.getLimeSdrInputSettings()->getGpioPins() & 0xFF; + } MsgConfigureLimeSDR *msg = MsgConfigureLimeSDR::create(settings, force); m_inputMessageQueue.push(msg); @@ -1405,12 +1487,16 @@ void LimeSDRInput::webapiFormatDeviceSettings(SWGSDRangel::SWGDeviceSettings& re } else { response.getLimeSdrInputSettings()->setFileRecordName(new QString(settings.m_fileRecordName)); } + + response.getLimeSdrInputSettings()->setGpioDir(settings.m_gpioDir); + response.getLimeSdrInputSettings()->setGpioPins(settings.m_gpioPins); } int LimeSDRInput::webapiReportGet( SWGSDRangel::SWGDeviceReport& response, - QString& errorMessage __attribute__((unused))) + QString& errorMessage) { + (void) errorMessage; response.setLimeSdrInputReport(new SWGSDRangel::SWGLimeSdrInputReport()); response.getLimeSdrInputReport()->init(); webapiFormatDeviceReport(response); @@ -1419,8 +1505,9 @@ int LimeSDRInput::webapiReportGet( int LimeSDRInput::webapiRunGet( SWGSDRangel::SWGDeviceState& response, - QString& errorMessage __attribute__((unused))) + QString& errorMessage) { + (void) errorMessage; m_deviceAPI->getDeviceEngineStateStr(*response.getState()); return 200; } @@ -1428,8 +1515,9 @@ int LimeSDRInput::webapiRunGet( int LimeSDRInput::webapiRun( bool run, SWGSDRangel::SWGDeviceState& response, - QString& errorMessage __attribute__((unused))) + QString& errorMessage) { + (void) errorMessage; m_deviceAPI->getDeviceEngineStateStr(*response.getState()); MsgStartStop *message = MsgStartStop::create(run); m_inputMessageQueue.push(message); @@ -1447,6 +1535,8 @@ void LimeSDRInput::webapiFormatDeviceReport(SWGSDRangel::SWGDeviceReport& respon { bool success = false; double temp = 0.0; + uint8_t gpioDir = 0; + uint8_t gpioPins = 0; lms_stream_status_t status; status.active = false; status.fifoFilledCount = 0; @@ -1469,9 +1559,14 @@ void LimeSDRInput::webapiFormatDeviceReport(SWGSDRangel::SWGDeviceReport& respon response.getLimeSdrInputReport()->setLinkRate(status.linkRate); response.getLimeSdrInputReport()->setHwTimestamp(status.timestamp); - if (m_deviceShared.m_deviceParams->getDevice()) { + if (m_deviceShared.m_deviceParams->getDevice()) + { LMS_GetChipTemperature(m_deviceShared.m_deviceParams->getDevice(), 0, &temp); + LMS_GPIODirRead(m_deviceShared.m_deviceParams->getDevice(), &gpioDir, 1); + LMS_GPIORead(m_deviceShared.m_deviceParams->getDevice(), &gpioPins, 1); } response.getLimeSdrInputReport()->setTemperature(temp); + response.getLimeSdrInputReport()->setGpioDir(gpioDir); + response.getLimeSdrInputReport()->setGpioPins(gpioPins); } diff --git a/plugins/samplesource/limesdrinput/limesdrinput.pro b/plugins/samplesource/limesdrinput/limesdrinput.pro index f8fc5db5b..8c6ec1fe0 100644 --- a/plugins/samplesource/limesdrinput/limesdrinput.pro +++ b/plugins/samplesource/limesdrinput/limesdrinput.pro @@ -28,17 +28,24 @@ INCLUDEPATH += ../../../sdrbase INCLUDEPATH += ../../../sdrgui INCLUDEPATH += ../../../swagger/sdrangel/code/qt5/client INCLUDEPATH += ../../../devices -INCLUDEPATH += ../../../liblimesuite/srcmw -INCLUDEPATH += $$LIBLIMESUITESRC/src -INCLUDEPATH += $$LIBLIMESUITESRC/src/ADF4002 -INCLUDEPATH += $$LIBLIMESUITESRC/src/ConnectionRegistry -INCLUDEPATH += $$LIBLIMESUITESRC/src/FPGA_common -INCLUDEPATH += $$LIBLIMESUITESRC/src/GFIR -INCLUDEPATH += $$LIBLIMESUITESRC/src/lms7002m -INCLUDEPATH += $$LIBLIMESUITESRC/src/lms7002m_mcu -INCLUDEPATH += $$LIBLIMESUITESRC/src/Si5351C -INCLUDEPATH += $$LIBLIMESUITESRC/src/protocols -INCLUDEPATH += $$LIBLIMESUITESRC/external/cpp-feather-ini-parser + +MINGW32 || MINGW64 || macx { + INCLUDEPATH += ../../../liblimesuite/srcmw + INCLUDEPATH += $$LIBLIMESUITESRC/src + INCLUDEPATH += $$LIBLIMESUITESRC/src/ADF4002 + INCLUDEPATH += $$LIBLIMESUITESRC/src/ConnectionRegistry + INCLUDEPATH += $$LIBLIMESUITESRC/src/FPGA_common + INCLUDEPATH += $$LIBLIMESUITESRC/src/GFIR + INCLUDEPATH += $$LIBLIMESUITESRC/src/lms7002m + INCLUDEPATH += $$LIBLIMESUITESRC/src/lms7002m_mcu + INCLUDEPATH += $$LIBLIMESUITESRC/src/Si5351C + INCLUDEPATH += $$LIBLIMESUITESRC/src/protocols + INCLUDEPATH += $$LIBLIMESUITESRC/external/cpp-feather-ini-parser +} + +MSVC { + INCLUDEPATH += "C:\Program Files\PothosSDR\include" +} CONFIG(Release):build_subdir = release CONFIG(Debug):build_subdir = debug @@ -60,7 +67,12 @@ FORMS += limesdrinputgui.ui LIBS += -L../../../sdrbase/$${build_subdir} -lsdrbase LIBS += -L../../../sdrgui/$${build_subdir} -lsdrgui LIBS += -L../../../swagger/$${build_subdir} -lswagger -LIBS += -L../../../liblimesuite/$${build_subdir} -lliblimesuite LIBS += -L../../../devices/$${build_subdir} -ldevices +MINGW32 || MINGW64 || macx { + LIBS += -L../../../liblimesuite/$${build_subdir} -lliblimesuite +} +MSVC { + LIBS += -L"C:\Program Files\PothosSDR\bin" -L"C:\Program Files\PothosSDR\lib" -lLimeSuite +} RESOURCES = ../../../sdrgui/resources/res.qrc diff --git a/plugins/samplesource/limesdrinput/limesdrinputgui.cpp b/plugins/samplesource/limesdrinput/limesdrinputgui.cpp index 8693eb7e1..ff0f60ea9 100644 --- a/plugins/samplesource/limesdrinput/limesdrinputgui.cpp +++ b/plugins/samplesource/limesdrinput/limesdrinputgui.cpp @@ -226,6 +226,7 @@ bool LimeSDRInputGUI::handleMessage(const Message& message) { DeviceLimeSDRShared::MsgReportDeviceInfo& report = (DeviceLimeSDRShared::MsgReportDeviceInfo&) message; ui->temperatureText->setText(tr("%1C").arg(QString::number(report.getTemperature(), 'f', 0))); + ui->gpioText->setText(tr("%1").arg(report.getGPIOPins(), 2, 16, QChar('0')).toUpper()); return true; } else if (LimeSDRInput::MsgStartStop::match(message)) diff --git a/plugins/samplesource/limesdrinput/limesdrinputgui.ui b/plugins/samplesource/limesdrinput/limesdrinputgui.ui index a41f0c50e..669475c97 100644 --- a/plugins/samplesource/limesdrinput/limesdrinputgui.ui +++ b/plugins/samplesource/limesdrinput/limesdrinputgui.ui @@ -1121,6 +1121,23 @@ QToolTip{background-color: white; color: black;} + + + + Qt::Vertical + + + + + + + GPIO bits as hex value (LSB first) + + + 00 + + + @@ -1193,6 +1210,39 @@ QToolTip{background-color: white; color: black;} + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/plugins/samplesource/limesdrinput/limesdrinputplugin.cpp b/plugins/samplesource/limesdrinput/limesdrinputplugin.cpp index a61ed225c..b1abed6d4 100644 --- a/plugins/samplesource/limesdrinput/limesdrinputplugin.cpp +++ b/plugins/samplesource/limesdrinput/limesdrinputplugin.cpp @@ -33,7 +33,7 @@ const PluginDescriptor LimeSDRInputPlugin::m_pluginDescriptor = { QString("LimeSDR Input"), - QString("4.2.4"), + QString("4.3.1"), QString("(c) Edouard Griffiths, F4EXB"), QString("https://github.com/f4exb/sdrangel"), true, diff --git a/plugins/samplesource/limesdrinput/limesdrinputsettings.cpp b/plugins/samplesource/limesdrinput/limesdrinputsettings.cpp index 88383e328..736069ea0 100644 --- a/plugins/samplesource/limesdrinput/limesdrinputsettings.cpp +++ b/plugins/samplesource/limesdrinput/limesdrinputsettings.cpp @@ -46,6 +46,8 @@ void LimeSDRInputSettings::resetToDefaults() m_transverterMode = false; m_transverterDeltaFrequency = 0; m_fileRecordName = ""; + m_gpioDir = 0; + m_gpioPins = 0; } QByteArray LimeSDRInputSettings::serialize() const @@ -72,6 +74,8 @@ QByteArray LimeSDRInputSettings::serialize() const s.writeU32(19, m_extClockFreq); s.writeBool(20, m_transverterMode); s.writeS64(21, m_transverterDeltaFrequency); + s.writeU32(22, m_gpioDir); + s.writeU32(23, m_gpioPins); return s.final(); } @@ -89,6 +93,7 @@ bool LimeSDRInputSettings::deserialize(const QByteArray& data) if (d.getVersion() == 1) { int intval; + uint32_t uintval; d.readS32(1, &m_devSampleRate, 5000000); d.readU32(2, &m_log2HardDecim, 2); @@ -112,6 +117,10 @@ bool LimeSDRInputSettings::deserialize(const QByteArray& data) d.readU32(19, &m_extClockFreq, 10000000); d.readBool(20, &m_transverterMode, false); d.readS64(21, &m_transverterDeltaFrequency, 0); + d.readU32(22, &uintval, 0); + m_gpioDir = uintval & 0xFF; + d.readU32(23, &uintval, 0); + m_gpioPins = uintval & 0xFF; return true; } diff --git a/plugins/samplesource/limesdrinput/limesdrinputsettings.h b/plugins/samplesource/limesdrinput/limesdrinputsettings.h index 9287589a2..cade58966 100644 --- a/plugins/samplesource/limesdrinput/limesdrinputsettings.h +++ b/plugins/samplesource/limesdrinput/limesdrinputsettings.h @@ -66,6 +66,8 @@ struct LimeSDRInputSettings bool m_transverterMode; qint64 m_transverterDeltaFrequency; QString m_fileRecordName; + uint8_t m_gpioDir; //!< GPIO pin direction LSB first; 0 input, 1 output + uint8_t m_gpioPins; //!< GPIO pins to write; LSB first LimeSDRInputSettings(); void resetToDefaults(); diff --git a/plugins/samplesource/limesdrinput/limesdrinputthread.h b/plugins/samplesource/limesdrinput/limesdrinputthread.h index ddf671047..90b09b611 100644 --- a/plugins/samplesource/limesdrinput/limesdrinputthread.h +++ b/plugins/samplesource/limesdrinput/limesdrinputthread.h @@ -39,7 +39,7 @@ public: virtual void startWork(); virtual void stopWork(); - virtual void setDeviceSampleRate(int sampleRate __attribute__((unused))) {} + virtual void setDeviceSampleRate(int sampleRate) { (void) sampleRate; } virtual bool isRunning() { return m_running; } void setLog2Decimation(unsigned int log2_decim); diff --git a/plugins/samplesource/perseus/perseusinput.cpp b/plugins/samplesource/perseus/perseusinput.cpp index aaf431566..67632131e 100644 --- a/plugins/samplesource/perseus/perseusinput.cpp +++ b/plugins/samplesource/perseus/perseusinput.cpp @@ -402,8 +402,9 @@ bool PerseusInput::applySettings(const PerseusSettings& settings, bool force) int PerseusInput::webapiRunGet( SWGSDRangel::SWGDeviceState& response, - QString& errorMessage __attribute__((unused))) + QString& errorMessage) { + (void) errorMessage; m_deviceAPI->getDeviceEngineStateStr(*response.getState()); return 200; } @@ -411,8 +412,9 @@ int PerseusInput::webapiRunGet( int PerseusInput::webapiRun( bool run, SWGSDRangel::SWGDeviceState& response, - QString& errorMessage __attribute__((unused))) + QString& errorMessage) { + (void) errorMessage; m_deviceAPI->getDeviceEngineStateStr(*response.getState()); MsgStartStop *message = MsgStartStop::create(run); m_inputMessageQueue.push(message); @@ -428,8 +430,9 @@ int PerseusInput::webapiRun( int PerseusInput::webapiSettingsGet( SWGSDRangel::SWGDeviceSettings& response, - QString& errorMessage __attribute__((unused))) + QString& errorMessage) { + (void) errorMessage; response.setPerseusSettings(new SWGSDRangel::SWGPerseusSettings()); response.getPerseusSettings()->init(); webapiFormatDeviceSettings(response, m_settings); @@ -440,8 +443,9 @@ int PerseusInput::webapiSettingsPutPatch( bool force, const QStringList& deviceSettingsKeys, SWGSDRangel::SWGDeviceSettings& response, // query + response - QString& errorMessage __attribute__((unused))) + QString& errorMessage) { + (void) errorMessage; PerseusSettings settings = m_settings; if (deviceSettingsKeys.contains("centerFrequency")) { @@ -495,8 +499,9 @@ int PerseusInput::webapiSettingsPutPatch( int PerseusInput::webapiReportGet( SWGSDRangel::SWGDeviceReport& response, - QString& errorMessage __attribute__((unused))) + QString& errorMessage) { + (void) errorMessage; response.setPerseusReport(new SWGSDRangel::SWGPerseusReport()); response.getPerseusReport()->init(); webapiFormatDeviceReport(response); diff --git a/plugins/samplesource/perseus/perseusthread.cpp b/plugins/samplesource/perseus/perseusthread.cpp index ec0441a78..217dd6643 100644 --- a/plugins/samplesource/perseus/perseusthread.cpp +++ b/plugins/samplesource/perseus/perseusthread.cpp @@ -111,8 +111,9 @@ void PerseusThread::callback(const uint8_t* buf, qint32 len) m_sampleFifo->write(m_convertBuffer.begin(), it); } -int PerseusThread::rx_callback(void *buf, int buf_size, void *extra __attribute__((unused))) +int PerseusThread::rx_callback(void *buf, int buf_size, void *extra) { + (void) extra; qint32 nbIAndQ = buf_size / 3; // 3 bytes per I or Q m_this->callback((uint8_t*) buf, nbIAndQ); return 0; diff --git a/plugins/samplesource/plutosdrinput/plutosdrinput.cpp b/plugins/samplesource/plutosdrinput/plutosdrinput.cpp index 09c2317fc..c56c35a36 100644 --- a/plugins/samplesource/plutosdrinput/plutosdrinput.cpp +++ b/plugins/samplesource/plutosdrinput/plutosdrinput.cpp @@ -619,8 +619,9 @@ float PlutoSDRInput::getTemperature() int PlutoSDRInput::webapiRunGet( SWGSDRangel::SWGDeviceState& response, - QString& errorMessage __attribute__((unused))) + QString& errorMessage) { + (void) errorMessage; m_deviceAPI->getDeviceEngineStateStr(*response.getState()); return 200; } @@ -628,8 +629,9 @@ int PlutoSDRInput::webapiRunGet( int PlutoSDRInput::webapiRun( bool run, SWGSDRangel::SWGDeviceState& response, - QString& errorMessage __attribute__((unused))) + QString& errorMessage) { + (void) errorMessage; m_deviceAPI->getDeviceEngineStateStr(*response.getState()); MsgStartStop *message = MsgStartStop::create(run); m_inputMessageQueue.push(message); @@ -645,8 +647,9 @@ int PlutoSDRInput::webapiRun( int PlutoSDRInput::webapiSettingsGet( SWGSDRangel::SWGDeviceSettings& response, - QString& errorMessage __attribute__((unused))) + QString& errorMessage) { + (void) errorMessage; response.setPlutoSdrInputSettings(new SWGSDRangel::SWGPlutoSdrInputSettings()); response.getPlutoSdrInputSettings()->init(); webapiFormatDeviceSettings(response, m_settings); @@ -657,8 +660,9 @@ int PlutoSDRInput::webapiSettingsPutPatch( bool force, const QStringList& deviceSettingsKeys, SWGSDRangel::SWGDeviceSettings& response, // query + response - QString& errorMessage __attribute__((unused))) + QString& errorMessage) { + (void) errorMessage; PlutoSDRInputSettings settings = m_settings; if (deviceSettingsKeys.contains("centerFrequency")) { @@ -737,8 +741,9 @@ int PlutoSDRInput::webapiSettingsPutPatch( int PlutoSDRInput::webapiReportGet( SWGSDRangel::SWGDeviceReport& response, - QString& errorMessage __attribute__((unused))) + QString& errorMessage) { + (void) errorMessage; response.setPlutoSdrInputReport(new SWGSDRangel::SWGPlutoSdrInputReport()); response.getPlutoSdrInputReport()->init(); webapiFormatDeviceReport(response); diff --git a/plugins/samplesource/plutosdrinput/plutosdrinput.pro b/plugins/samplesource/plutosdrinput/plutosdrinput.pro index f18fe1bb4..74999834f 100644 --- a/plugins/samplesource/plutosdrinput/plutosdrinput.pro +++ b/plugins/samplesource/plutosdrinput/plutosdrinput.pro @@ -17,17 +17,22 @@ DEFINES += USE_SSE4_1=1 QMAKE_CXXFLAGS += -msse4.1 QMAKE_CXXFLAGS += -std=c++11 -CONFIG(MINGW32):LIBIIOSRC = "C:\softs\libiio" -CONFIG(MINGW64):LIBIIOSRC = "C:\softs\libiio" - INCLUDEPATH += $$PWD INCLUDEPATH += ../../../exports INCLUDEPATH += ../../../sdrbase INCLUDEPATH += ../../../sdrgui INCLUDEPATH += ../../../swagger/sdrangel/code/qt5/client INCLUDEPATH += ../../../devices -INCLUDEPATH += ../../../libiio/includemw -INCLUDEPATH += $$LIBIIOSRC + +MINGW32 || MINGW64 { + LIBIIOSRC = "C:\softs\libiio" + INCLUDEPATH += ../../../libiio/includemw + INCLUDEPATH += $$LIBIIOSRC +} + +MSVC { + INCLUDEPATH += "C:\Program Files\PothosSDR\include" +} CONFIG(Release):build_subdir = release CONFIG(Debug):build_subdir = debug @@ -49,7 +54,14 @@ FORMS += plutosdrinputgui.ui LIBS += -L../../../sdrbase/$${build_subdir} -lsdrbase LIBS += -L../../../sdrgui/$${build_subdir} -lsdrgui LIBS += -L../../../swagger/$${build_subdir} -lswagger -LIBS += -L../../../libiio/$${build_subdir} -llibiio LIBS += -L../../../devices/$${build_subdir} -ldevices +MINGW32 || MINGW64 { + LIBS += -L../../../libiio/$${build_subdir} -llibiio +} + +MSVC { + LIBS += -L"C:\Program Files\PothosSDR\bin" -L"C:\Program Files\PothosSDR\lib" -llibiio +} + RESOURCES = ../../../sdrgui/resources/res.qrc diff --git a/plugins/samplesource/plutosdrinput/plutosdrinputgui.cpp b/plugins/samplesource/plutosdrinput/plutosdrinputgui.cpp index 441413b0d..9121a91a0 100644 --- a/plugins/samplesource/plutosdrinput/plutosdrinputgui.cpp +++ b/plugins/samplesource/plutosdrinput/plutosdrinputgui.cpp @@ -130,7 +130,7 @@ bool PlutoSDRInputGui::deserialize(const QByteArray& data) } } -bool PlutoSDRInputGui::handleMessage(const Message& message __attribute__((unused))) +bool PlutoSDRInputGui::handleMessage(const Message& message) { if (PlutoSDRInput::MsgConfigurePlutoSDR::match(message)) { diff --git a/plugins/samplesource/plutosdrinput/plutosdrinputplugin.cpp b/plugins/samplesource/plutosdrinput/plutosdrinputplugin.cpp index 1fb15bfc6..e840a6db1 100644 --- a/plugins/samplesource/plutosdrinput/plutosdrinputplugin.cpp +++ b/plugins/samplesource/plutosdrinput/plutosdrinputplugin.cpp @@ -30,7 +30,7 @@ class DeviceSourceAPI; const PluginDescriptor PlutoSDRInputPlugin::m_pluginDescriptor = { QString("PlutoSDR Input"), - QString("4.0.0"), + QString("4.3.1"), QString("(c) Edouard Griffiths, F4EXB"), QString("https://github.com/f4exb/sdrangel"), true, diff --git a/plugins/samplesource/plutosdrinput/plutosdrinputthread.cpp b/plugins/samplesource/plutosdrinput/plutosdrinputthread.cpp index a85a078a3..5c0f90c28 100644 --- a/plugins/samplesource/plutosdrinput/plutosdrinputthread.cpp +++ b/plugins/samplesource/plutosdrinput/plutosdrinputthread.cpp @@ -14,8 +14,6 @@ // along with this program. If not, see . // /////////////////////////////////////////////////////////////////////////////////// -#include - #include "plutosdr/deviceplutosdrbox.h" #include "plutosdrinputsettings.h" #include "plutosdrinputthread.h" diff --git a/plugins/samplesource/plutosdrinput/plutosdrinputthread.h b/plugins/samplesource/plutosdrinput/plutosdrinputthread.h index 4bd285aee..68d2f9bc8 100644 --- a/plugins/samplesource/plutosdrinput/plutosdrinputthread.h +++ b/plugins/samplesource/plutosdrinput/plutosdrinputthread.h @@ -37,7 +37,7 @@ public: virtual void startWork(); virtual void stopWork(); - virtual void setDeviceSampleRate(int sampleRate __attribute__((unused))) {} + virtual void setDeviceSampleRate(int sampleRate) { (void) sampleRate; } virtual bool isRunning() { return m_running; } void setLog2Decimation(unsigned int log2_decim); void setFcPos(int fcPos); diff --git a/plugins/samplesource/rtlsdr/readme.md b/plugins/samplesource/rtlsdr/readme.md index ebe304077..284219b47 100644 --- a/plugins/samplesource/rtlsdr/readme.md +++ b/plugins/samplesource/rtlsdr/readme.md @@ -109,11 +109,15 @@ The I/Q stream from the RTLSDR ADC is downsampled by a power of two before being Use this checkbox to activate the special RTLSDR direct sampling. This can be used to tune to HF frequencies. -

9: RF bandwidth

+

9: Offset tuning

+ +This controls the offset tuning. Some RF frontends like the obsolete E4000 implement this feature and it can seriously reduce the central DC peak without digital correction. This does not work for the R820T and R820T2 that are very popular on which it will produce no effect. However these RF frontends exhibit a central DC peak much smaller than on the E4000 and can be easly corrected digitally via control (3). + +

10: RF bandwidth

This controls the tuner filter bandwidth and can be varied from 350 kHz to 8 MHz. In practice depending on the value this appears to be larger and the filter center is slightly offset above the center frequency. This can still be very useful to eliminate or attenuate large signals outside the device to host I/Q stream passband. -

10: RF gain and AGC

+

11: RF gain and AGC

The slider sets RF gain in dB. The values are defined in the RTLSDR device and generally are: 0.0, 0.9, 1.4, 2.7, 3.7, 7.7, 8.7, 12.5, 14.4, 15.7, 16.6, 19.7, 20.7, 22.9, 25.4, 28.0, 29.7, 32.8, 33.8, 36.4, 37.2, 38.6, 40.2, 42.1, 43.4, 43.9, 44.5, 48.0, 49.6 diff --git a/plugins/samplesource/rtlsdr/rtlsdrgui.cpp b/plugins/samplesource/rtlsdr/rtlsdrgui.cpp index 381a2b053..92cd317f7 100644 --- a/plugins/samplesource/rtlsdr/rtlsdrgui.cpp +++ b/plugins/samplesource/rtlsdr/rtlsdrgui.cpp @@ -261,6 +261,7 @@ void RTLSDRGui::displaySettings() ui->checkBox->setChecked(m_settings.m_noModMode); ui->agc->setChecked(m_settings.m_agc); ui->lowSampleRate->setChecked(m_settings.m_lowSampleRate); + ui->offsetTuning->setChecked(m_settings.m_offsetTuning); } void RTLSDRGui::sendSettings() @@ -441,6 +442,12 @@ void RTLSDRGui::on_sampleRate_changed(quint64 value) sendSettings(); } +void RTLSDRGui::on_offsetTuning_toggled(bool checked) +{ + m_settings.m_offsetTuning = checked; + sendSettings(); +} + void RTLSDRGui::on_rfBW_changed(quint64 value) { m_settings.m_rfBandwidth = value * 1000; diff --git a/plugins/samplesource/rtlsdr/rtlsdrgui.h b/plugins/samplesource/rtlsdr/rtlsdrgui.h index f2c838618..69e010f68 100644 --- a/plugins/samplesource/rtlsdr/rtlsdrgui.h +++ b/plugins/samplesource/rtlsdr/rtlsdrgui.h @@ -78,6 +78,7 @@ private slots: void handleInputMessages(); void on_centerFrequency_changed(quint64 value); void on_sampleRate_changed(quint64 value); + void on_offsetTuning_toggled(bool checked); void on_rfBW_changed(quint64 value); void on_lowSampleRate_toggled(bool checked); void on_dcOffset_toggled(bool checked); diff --git a/plugins/samplesource/rtlsdr/rtlsdrgui.ui b/plugins/samplesource/rtlsdr/rtlsdrgui.ui index 79b0dd127..dcf3a8a25 100644 --- a/plugins/samplesource/rtlsdr/rtlsdrgui.ui +++ b/plugins/samplesource/rtlsdr/rtlsdrgui.ui @@ -493,6 +493,16 @@
+ + + + Offset tuning (applies to some tuners only incl. E4000) + + + Ofs + + + diff --git a/plugins/samplesource/rtlsdr/rtlsdrinput.cpp b/plugins/samplesource/rtlsdr/rtlsdrinput.cpp index 406f104ba..01d3265b9 100644 --- a/plugins/samplesource/rtlsdr/rtlsdrinput.cpp +++ b/plugins/samplesource/rtlsdr/rtlsdrinput.cpp @@ -507,17 +507,28 @@ bool RTLSDRInput::applySettings(const RTLSDRSettings& settings, bool force) if (m_dev != 0) { - if (rtlsdr_set_tuner_bandwidth( m_dev, m_settings.m_rfBandwidth) != 0) - { + if (rtlsdr_set_tuner_bandwidth( m_dev, m_settings.m_rfBandwidth) != 0) { qCritical("RTLSDRInput::applySettings: could not set RF bandwidth to %u", m_settings.m_rfBandwidth); - } - else - { + } else { qDebug() << "RTLSDRInput::applySettings: set RF bandwidth to " << m_settings.m_rfBandwidth; } } } + if ((m_settings.m_offsetTuning != settings.m_offsetTuning) || force) + { + m_settings.m_offsetTuning = settings.m_offsetTuning; + + if (m_dev != 0) + { + if (rtlsdr_set_offset_tuning(m_dev, m_settings.m_offsetTuning ? 0 : 1) != 0) { + qCritical("RTLSDRInput::applySettings: could not set offset tuning to %s", m_settings.m_offsetTuning ? "on" : "off"); + } else { + qDebug("RTLSDRInput::applySettings: offset tuning set to %s", m_settings.m_offsetTuning ? "on" : "off"); + } + } + } + if (forwardChange) { int sampleRate = m_settings.m_devSampleRate/(1<init(); webapiFormatDeviceSettings(response, m_settings); @@ -548,8 +560,9 @@ int RTLSDRInput::webapiSettingsPutPatch( bool force, const QStringList& deviceSettingsKeys, SWGSDRangel::SWGDeviceSettings& response, // query + response - QString& errorMessage __attribute__((unused))) + QString& errorMessage) { + (void) errorMessage; RTLSDRSettings settings = m_settings; if (deviceSettingsKeys.contains("agc")) { @@ -585,6 +598,9 @@ int RTLSDRInput::webapiSettingsPutPatch( if (deviceSettingsKeys.contains("noModMode")) { settings.m_noModMode = response.getRtlSdrSettings()->getNoModMode() != 0; } + if (deviceSettingsKeys.contains("offsetTuning")) { + settings.m_offsetTuning = response.getRtlSdrSettings()->getOffsetTuning() != 0; + } if (deviceSettingsKeys.contains("transverterDeltaFrequency")) { settings.m_transverterDeltaFrequency = response.getRtlSdrSettings()->getTransverterDeltaFrequency(); } @@ -625,6 +641,7 @@ void RTLSDRInput::webapiFormatDeviceSettings(SWGSDRangel::SWGDeviceSettings& res response.getRtlSdrSettings()->setLog2Decim(settings.m_log2Decim); response.getRtlSdrSettings()->setLowSampleRate(settings.m_lowSampleRate ? 1 : 0); response.getRtlSdrSettings()->setNoModMode(settings.m_noModMode ? 1 : 0); + response.getRtlSdrSettings()->setOffsetTuning(settings.m_offsetTuning ? 1 : 0); response.getRtlSdrSettings()->setTransverterDeltaFrequency(settings.m_transverterDeltaFrequency); response.getRtlSdrSettings()->setTransverterMode(settings.m_transverterMode ? 1 : 0); response.getRtlSdrSettings()->setRfBandwidth(settings.m_rfBandwidth); @@ -638,8 +655,9 @@ void RTLSDRInput::webapiFormatDeviceSettings(SWGSDRangel::SWGDeviceSettings& res int RTLSDRInput::webapiRunGet( SWGSDRangel::SWGDeviceState& response, - QString& errorMessage __attribute__((unused))) + QString& errorMessage) { + (void) errorMessage; m_deviceAPI->getDeviceEngineStateStr(*response.getState()); return 200; } @@ -647,8 +665,9 @@ int RTLSDRInput::webapiRunGet( int RTLSDRInput::webapiRun( bool run, SWGSDRangel::SWGDeviceState& response, - QString& errorMessage __attribute__((unused))) + QString& errorMessage) { + (void) errorMessage; m_deviceAPI->getDeviceEngineStateStr(*response.getState()); MsgStartStop *message = MsgStartStop::create(run); m_inputMessageQueue.push(message); @@ -664,8 +683,9 @@ int RTLSDRInput::webapiRun( int RTLSDRInput::webapiReportGet( SWGSDRangel::SWGDeviceReport& response, - QString& errorMessage __attribute__((unused))) + QString& errorMessage) { + (void) errorMessage; response.setRtlSdrReport(new SWGSDRangel::SWGRtlSdrReport()); response.getRtlSdrReport()->init(); webapiFormatDeviceReport(response); diff --git a/plugins/samplesource/rtlsdr/rtlsdrplugin.cpp b/plugins/samplesource/rtlsdr/rtlsdrplugin.cpp index e4d4c5959..ebde7cd55 100644 --- a/plugins/samplesource/rtlsdr/rtlsdrplugin.cpp +++ b/plugins/samplesource/rtlsdr/rtlsdrplugin.cpp @@ -14,7 +14,7 @@ const PluginDescriptor RTLSDRPlugin::m_pluginDescriptor = { QString("RTL-SDR Input"), - QString("4.0.6"), + QString("4.3.1"), QString("(c) Edouard Griffiths, F4EXB"), QString("https://github.com/f4exb/sdrangel"), true, diff --git a/plugins/samplesource/rtlsdr/rtlsdrsettings.cpp b/plugins/samplesource/rtlsdr/rtlsdrsettings.cpp index 6b5fd6ead..95494b820 100644 --- a/plugins/samplesource/rtlsdr/rtlsdrsettings.cpp +++ b/plugins/samplesource/rtlsdr/rtlsdrsettings.cpp @@ -40,6 +40,7 @@ void RTLSDRSettings::resetToDefaults() m_transverterDeltaFrequency = 0; m_rfBandwidth = 2500 * 1000; // Hz m_fileRecordName = ""; + m_offsetTuning = false; } QByteArray RTLSDRSettings::serialize() const @@ -59,6 +60,7 @@ QByteArray RTLSDRSettings::serialize() const s.writeBool(12, m_transverterMode); s.writeS64(13, m_transverterDeltaFrequency); s.writeU32(14, m_rfBandwidth); + s.writeBool(15, m_offsetTuning); return s.final(); } @@ -91,6 +93,7 @@ bool RTLSDRSettings::deserialize(const QByteArray& data) d.readBool(12, &m_transverterMode, false); d.readS64(13, &m_transverterDeltaFrequency, 0); d.readU32(4, &m_rfBandwidth, 2500 * 1000); + d.readBool(15, &m_offsetTuning, false); return true; } diff --git a/plugins/samplesource/rtlsdr/rtlsdrsettings.h b/plugins/samplesource/rtlsdr/rtlsdrsettings.h index bf2ad2c60..e42b92616 100644 --- a/plugins/samplesource/rtlsdr/rtlsdrsettings.h +++ b/plugins/samplesource/rtlsdr/rtlsdrsettings.h @@ -41,6 +41,7 @@ struct RTLSDRSettings { qint64 m_transverterDeltaFrequency; quint32 m_rfBandwidth; //!< RF filter bandwidth in Hz QString m_fileRecordName; + bool m_offsetTuning; RTLSDRSettings(); void resetToDefaults(); diff --git a/plugins/samplesource/sdrdaemonsource/sdrdaemonsource.pro b/plugins/samplesource/sdrdaemonsource/sdrdaemonsource.pro index 27270562d..3b2d766dd 100644 --- a/plugins/samplesource/sdrdaemonsource/sdrdaemonsource.pro +++ b/plugins/samplesource/sdrdaemonsource/sdrdaemonsource.pro @@ -13,6 +13,7 @@ TARGET = inputsdrdaemonsource CONFIG(MINGW32):LIBCM256CCSRC = "C:\softs\cm256cc" CONFIG(MINGW64):LIBCM256CCSRC = "C:\softs\cm256cc" +CONFIG(MSVC):LIBCM256CCSRC = "C:\softs\cm256cc" CONFIG(macx):LIBCM256CCSRC = "../../../../deps/cm256cc" INCLUDEPATH += $$PWD @@ -36,6 +37,7 @@ CONFIG(Debug):build_subdir = debug CONFIG(MINGW32):INCLUDEPATH += "C:\softs\boost_1_66_0" CONFIG(MINGW64):INCLUDEPATH += "C:\softs\boost_1_66_0" +CONFIG(MSVC):INCLUDEPATH += "C:\softs\boost_1_66_0" CONFIG(macx):INCLUDEPATH += "../../../boost_1_64_0" SOURCES += sdrdaemonsourcebuffer.cpp\ diff --git a/plugins/samplesource/sdrdaemonsource/sdrdaemonsourcebuffer.h b/plugins/samplesource/sdrdaemonsource/sdrdaemonsourcebuffer.h index 405ad38ce..6c660d5e3 100644 --- a/plugins/samplesource/sdrdaemonsource/sdrdaemonsourcebuffer.h +++ b/plugins/samplesource/sdrdaemonsource/sdrdaemonsourcebuffer.h @@ -45,6 +45,7 @@ public: // samples timestamp uint32_t getTVOutSec() const { return m_tvOut_sec; } uint32_t getTVOutUsec() const { return m_tvOut_usec; } + uint64_t getTVOutMSec() const { return (m_tvOut_sec * 1000LL) + (m_tvOut_usec/ 1000LL); } // stats diff --git a/plugins/samplesource/sdrdaemonsource/sdrdaemonsourcegui.cpp b/plugins/samplesource/sdrdaemonsource/sdrdaemonsourcegui.cpp index 2607ff590..4b05bbc0c 100644 --- a/plugins/samplesource/sdrdaemonsource/sdrdaemonsourcegui.cpp +++ b/plugins/samplesource/sdrdaemonsource/sdrdaemonsourcegui.cpp @@ -71,8 +71,7 @@ SDRdaemonSourceGui::SDRdaemonSourceGui(DeviceUISet *deviceUISet, QWidget* parent m_paletteGreenText.setColor(QPalette::WindowText, Qt::green); m_paletteWhiteText.setColor(QPalette::WindowText, Qt::white); - m_startingTimeStamp.tv_sec = 0; - m_startingTimeStamp.tv_usec = 0; + m_startingTimeStampms = 0; ui->setupUi(this); ui->centerFrequency->setColorMapper(ColorMapper(ColorMapper::GrayGold)); @@ -163,8 +162,9 @@ qint64 SDRdaemonSourceGui::getCenterFrequency() const return m_streamCenterFrequency; } -void SDRdaemonSourceGui::setCenterFrequency(qint64 centerFrequency __attribute__((unused))) +void SDRdaemonSourceGui::setCenterFrequency(qint64 centerFrequency) { + (void) centerFrequency; } bool SDRdaemonSourceGui::handleMessage(const Message& message) @@ -186,20 +186,17 @@ bool SDRdaemonSourceGui::handleMessage(const Message& message) } else if (SDRdaemonSourceInput::MsgReportSDRdaemonSourceStreamData::match(message)) { - m_startingTimeStamp.tv_sec = ((SDRdaemonSourceInput::MsgReportSDRdaemonSourceStreamData&)message).get_tv_sec(); - m_startingTimeStamp.tv_usec = ((SDRdaemonSourceInput::MsgReportSDRdaemonSourceStreamData&)message).get_tv_usec(); + m_startingTimeStampms = ((SDRdaemonSourceInput::MsgReportSDRdaemonSourceStreamData&)message).get_tv_msec(); qDebug() << "SDRdaemonSourceGui::handleMessage: SDRdaemonSourceInput::MsgReportSDRdaemonSourceStreamData: " - << " : " << m_startingTimeStamp.tv_sec - << " : " << m_startingTimeStamp.tv_usec; + << " : " << m_startingTimeStampms << " ms"; updateWithStreamTime(); return true; } else if (SDRdaemonSourceInput::MsgReportSDRdaemonSourceStreamTiming::match(message)) { - m_startingTimeStamp.tv_sec = ((SDRdaemonSourceInput::MsgReportSDRdaemonSourceStreamTiming&)message).get_tv_sec(); - m_startingTimeStamp.tv_usec = ((SDRdaemonSourceInput::MsgReportSDRdaemonSourceStreamTiming&)message).get_tv_usec(); + m_startingTimeStampms = ((SDRdaemonSourceInput::MsgReportSDRdaemonSourceStreamTiming&)message).get_tv_msec(); m_framesDecodingStatus = ((SDRdaemonSourceInput::MsgReportSDRdaemonSourceStreamTiming&)message).getFramesDecodingStatus(); m_allBlocksReceived = ((SDRdaemonSourceInput::MsgReportSDRdaemonSourceStreamTiming&)message).allBlocksReceived(); m_bufferLengthInSecs = ((SDRdaemonSourceInput::MsgReportSDRdaemonSourceStreamTiming&)message).getBufferLengthInSecs(); @@ -308,8 +305,9 @@ void SDRdaemonSourceGui::sendSettings() m_updateTimer.start(100); } -void SDRdaemonSourceGui::on_apiApplyButton_clicked(bool checked __attribute__((unused))) +void SDRdaemonSourceGui::on_apiApplyButton_clicked(bool checked) { + (void) checked; m_settings.m_apiAddress = ui->apiAddress->text(); bool ctlOk; @@ -326,8 +324,9 @@ void SDRdaemonSourceGui::on_apiApplyButton_clicked(bool checked __attribute__((u m_networkManager->get(m_networkRequest); } -void SDRdaemonSourceGui::on_dataApplyButton_clicked(bool checked __attribute__((unused))) +void SDRdaemonSourceGui::on_dataApplyButton_clicked(bool checked) { + (void) checked; m_settings.m_dataAddress = ui->dataAddress->text(); bool dataOk; @@ -427,8 +426,9 @@ void SDRdaemonSourceGui::on_record_toggled(bool checked) m_sampleSource->getInputMessageQueue()->push(message); } -void SDRdaemonSourceGui::on_eventCountsReset_clicked(bool checked __attribute__((unused))) +void SDRdaemonSourceGui::on_eventCountsReset_clicked(bool checked) { + (void) checked; m_countUnrecoverable = 0; m_countRecovered = 0; m_eventsTime.start(); @@ -460,8 +460,7 @@ void SDRdaemonSourceGui::updateWithAcquisition() void SDRdaemonSourceGui::updateWithStreamTime() { bool updateEventCounts = false; - quint64 startingTimeStampMsec = ((quint64) m_startingTimeStamp.tv_sec * 1000LL) + ((quint64) m_startingTimeStamp.tv_usec / 1000LL); - QDateTime dt = QDateTime::fromMSecsSinceEpoch(startingTimeStampMsec); + QDateTime dt = QDateTime::fromMSecsSinceEpoch(m_startingTimeStampms); QString s_date = dt.toString("yyyy-MM-dd HH:mm:ss.zzz"); ui->absTimeText->setText(s_date); diff --git a/plugins/samplesource/sdrdaemonsource/sdrdaemonsourcegui.h b/plugins/samplesource/sdrdaemonsource/sdrdaemonsourcegui.h index 457705f5a..92d6a8147 100644 --- a/plugins/samplesource/sdrdaemonsource/sdrdaemonsourcegui.h +++ b/plugins/samplesource/sdrdaemonsource/sdrdaemonsourcegui.h @@ -17,8 +17,6 @@ #ifndef INCLUDE_SDRDAEMONSOURCEGUI_H #define INCLUDE_SDRDAEMONSOURCEGUI_H -#include - #include #include #include @@ -72,7 +70,7 @@ private: // int m_sampleRate; // quint64 m_centerFrequency; - struct timeval m_startingTimeStamp; + uint64_t m_startingTimeStampms; int m_framesDecodingStatus; bool m_allBlocksReceived; float m_bufferLengthInSecs; diff --git a/plugins/samplesource/sdrdaemonsource/sdrdaemonsourceinput.cpp b/plugins/samplesource/sdrdaemonsource/sdrdaemonsourceinput.cpp index 2718bed46..566130e8b 100644 --- a/plugins/samplesource/sdrdaemonsource/sdrdaemonsourceinput.cpp +++ b/plugins/samplesource/sdrdaemonsource/sdrdaemonsourceinput.cpp @@ -16,7 +16,6 @@ #include #include -#include #include #include "SWGDeviceSettings.h" @@ -134,8 +133,9 @@ quint64 SDRdaemonSourceInput::getCenterFrequency() const return m_SDRdaemonUDPHandler->getCenterFrequency(); } -void SDRdaemonSourceInput::setCenterFrequency(qint64 centerFrequency __attribute__((unused))) +void SDRdaemonSourceInput::setCenterFrequency(qint64 centerFrequency) { + (void) centerFrequency; } std::time_t SDRdaemonSourceInput::getStartingTimeStamp() const @@ -241,8 +241,9 @@ void SDRdaemonSourceInput::applySettings(const SDRdaemonSourceSettings& settings int SDRdaemonSourceInput::webapiRunGet( SWGSDRangel::SWGDeviceState& response, - QString& errorMessage __attribute__((unused))) + QString& errorMessage) { + (void) errorMessage; m_deviceAPI->getDeviceEngineStateStr(*response.getState()); return 200; } @@ -250,8 +251,9 @@ int SDRdaemonSourceInput::webapiRunGet( int SDRdaemonSourceInput::webapiRun( bool run, SWGSDRangel::SWGDeviceState& response, - QString& errorMessage __attribute__((unused))) + QString& errorMessage) { + (void) errorMessage; m_deviceAPI->getDeviceEngineStateStr(*response.getState()); MsgStartStop *message = MsgStartStop::create(run); m_inputMessageQueue.push(message); @@ -267,8 +269,9 @@ int SDRdaemonSourceInput::webapiRun( int SDRdaemonSourceInput::webapiSettingsGet( SWGSDRangel::SWGDeviceSettings& response, - QString& errorMessage __attribute__((unused))) + QString& errorMessage) { + (void) errorMessage; response.setSdrDaemonSourceSettings(new SWGSDRangel::SWGSDRdaemonSourceSettings()); response.getSdrDaemonSourceSettings()->init(); webapiFormatDeviceSettings(response, m_settings); @@ -279,8 +282,9 @@ int SDRdaemonSourceInput::webapiSettingsPutPatch( bool force, const QStringList& deviceSettingsKeys, SWGSDRangel::SWGDeviceSettings& response, // query + response - QString& errorMessage __attribute__((unused))) + QString& errorMessage) { + (void) errorMessage; SDRdaemonSourceSettings settings = m_settings; if (deviceSettingsKeys.contains("apiAddress")) { @@ -336,8 +340,9 @@ void SDRdaemonSourceInput::webapiFormatDeviceSettings(SWGSDRangel::SWGDeviceSett int SDRdaemonSourceInput::webapiReportGet( SWGSDRangel::SWGDeviceReport& response, - QString& errorMessage __attribute__((unused))) + QString& errorMessage) { + (void) errorMessage; response.setSdrDaemonSourceReport(new SWGSDRangel::SWGSDRdaemonSourceReport()); response.getSdrDaemonSourceReport()->init(); webapiFormatDeviceReport(response); @@ -350,8 +355,7 @@ void SDRdaemonSourceInput::webapiFormatDeviceReport(SWGSDRangel::SWGDeviceReport response.getSdrDaemonSourceReport()->setSampleRate(m_SDRdaemonUDPHandler->getSampleRate()); response.getSdrDaemonSourceReport()->setBufferRwBalance(m_SDRdaemonUDPHandler->getBufferGauge()); - quint64 startingTimeStampMsec = ((quint64) m_SDRdaemonUDPHandler->getTVSec() * 1000LL) + ((quint64) m_SDRdaemonUDPHandler->getTVuSec() / 1000LL); - QDateTime dt = QDateTime::fromMSecsSinceEpoch(startingTimeStampMsec); + QDateTime dt = QDateTime::fromMSecsSinceEpoch(m_SDRdaemonUDPHandler->getTVmSec()); response.getSdrDaemonSourceReport()->setDaemonTimestamp(new QString(dt.toString("yyyy-MM-dd HH:mm:ss.zzz"))); response.getSdrDaemonSourceReport()->setMinNbBlocks(m_SDRdaemonUDPHandler->getMinNbBlocks()); diff --git a/plugins/samplesource/sdrdaemonsource/sdrdaemonsourceinput.h b/plugins/samplesource/sdrdaemonsource/sdrdaemonsourceinput.h index 077a2b1ac..3f5c09a29 100644 --- a/plugins/samplesource/sdrdaemonsource/sdrdaemonsourceinput.h +++ b/plugins/samplesource/sdrdaemonsource/sdrdaemonsourceinput.h @@ -99,26 +99,23 @@ public: public: int getSampleRate() const { return m_sampleRate; } quint64 getCenterFrequency() const { return m_centerFrequency; } - uint32_t get_tv_sec() const { return m_tv_sec; } - uint32_t get_tv_usec() const { return m_tv_usec; } + uint32_t get_tv_msec() const { return m_tv_msec; } - static MsgReportSDRdaemonSourceStreamData* create(int sampleRate, quint64 centerFrequency, uint32_t tv_sec, uint32_t tv_usec) + static MsgReportSDRdaemonSourceStreamData* create(int sampleRate, quint64 centerFrequency, uint64_t tv_msec) { - return new MsgReportSDRdaemonSourceStreamData(sampleRate, centerFrequency, tv_sec, tv_usec); + return new MsgReportSDRdaemonSourceStreamData(sampleRate, centerFrequency, tv_msec); } protected: int m_sampleRate; quint64 m_centerFrequency; - uint32_t m_tv_sec; - uint32_t m_tv_usec; + uint64_t m_tv_msec; - MsgReportSDRdaemonSourceStreamData(int sampleRate, quint64 centerFrequency, uint32_t tv_sec, uint32_t tv_usec) : + MsgReportSDRdaemonSourceStreamData(int sampleRate, quint64 centerFrequency, uint64_t tv_msec) : Message(), m_sampleRate(sampleRate), m_centerFrequency(centerFrequency), - m_tv_sec(tv_sec), - m_tv_usec(tv_usec) + m_tv_msec(tv_msec) { } }; @@ -126,8 +123,7 @@ public: MESSAGE_CLASS_DECLARATION public: - uint32_t get_tv_sec() const { return m_tv_sec; } - uint32_t get_tv_usec() const { return m_tv_usec; } + uint64_t get_tv_msec() const { return m_tv_msec; } int getFramesDecodingStatus() const { return m_framesDecodingStatus; } bool allBlocksReceived() const { return m_allBlocksReceived; } float getBufferLengthInSecs() const { return m_bufferLenSec; } @@ -143,8 +139,7 @@ public: int getSampleBits() const { return m_sampleBits; } int getSampleBytes() const { return m_sampleBytes; } - static MsgReportSDRdaemonSourceStreamTiming* create(uint32_t tv_sec, - uint32_t tv_usec, + static MsgReportSDRdaemonSourceStreamTiming* create(uint64_t tv_msec, float bufferLenSec, int32_t bufferGauge, int framesDecodingStatus, @@ -160,8 +155,7 @@ public: int sampleBits, int sampleBytes) { - return new MsgReportSDRdaemonSourceStreamTiming(tv_sec, - tv_usec, + return new MsgReportSDRdaemonSourceStreamTiming(tv_msec, bufferLenSec, bufferGauge, framesDecodingStatus, @@ -179,8 +173,7 @@ public: } protected: - uint32_t m_tv_sec; - uint32_t m_tv_usec; + uint64_t m_tv_msec; int m_framesDecodingStatus; bool m_allBlocksReceived; float m_bufferLenSec; @@ -196,8 +189,7 @@ public: int m_sampleBits; int m_sampleBytes; - MsgReportSDRdaemonSourceStreamTiming(uint32_t tv_sec, - uint32_t tv_usec, + MsgReportSDRdaemonSourceStreamTiming(uint64_t tv_msec, float bufferLenSec, int32_t bufferGauge, int framesDecodingStatus, @@ -213,8 +205,7 @@ public: int sampleBits, int sampleBytes) : Message(), - m_tv_sec(tv_sec), - m_tv_usec(tv_usec), + m_tv_msec(tv_msec), m_framesDecodingStatus(framesDecodingStatus), m_allBlocksReceived(allBlocksReceived), m_bufferLenSec(bufferLenSec), diff --git a/plugins/samplesource/sdrdaemonsource/sdrdaemonsourceudphandler.cpp b/plugins/samplesource/sdrdaemonsource/sdrdaemonsourceudphandler.cpp index 399ca525e..9dfa8e7af 100644 --- a/plugins/samplesource/sdrdaemonsource/sdrdaemonsourceudphandler.cpp +++ b/plugins/samplesource/sdrdaemonsource/sdrdaemonsourceudphandler.cpp @@ -17,7 +17,6 @@ #include #include #include -#include #include "dsp/dspcommands.h" #include "dsp/dspengine.h" @@ -42,8 +41,7 @@ SDRdaemonSourceUDPHandler::SDRdaemonSourceUDPHandler(SampleSinkFifo *sampleFifo, m_sampleFifo(sampleFifo), m_samplerate(0), m_centerFrequency(0), - m_tv_sec(0), - m_tv_usec(0), + m_tv_msec(0), m_outputMessageQueueToGUI(0), m_tickCount(0), m_samplesCount(0), @@ -180,8 +178,7 @@ void SDRdaemonSourceUDPHandler::processData() const SDRDaemonMetaDataFEC& metaData = m_sdrDaemonBuffer.getCurrentMeta(); bool change = false; - m_tv_sec = m_sdrDaemonBuffer.getTVOutSec(); - m_tv_usec = m_sdrDaemonBuffer.getTVOutUsec(); + m_tv_msec = m_sdrDaemonBuffer.getTVOutMSec(); if (m_centerFrequency != metaData.m_centerFrequency) { @@ -207,8 +204,7 @@ void SDRdaemonSourceUDPHandler::processData() SDRdaemonSourceInput::MsgReportSDRdaemonSourceStreamData *report = SDRdaemonSourceInput::MsgReportSDRdaemonSourceStreamData::create( m_samplerate, m_centerFrequency * 1000, // Frequency in Hz for the GUI - m_tv_sec, - m_tv_usec); + m_tv_msec); m_outputMessageQueueToGUI->push(report); } @@ -266,13 +262,7 @@ void SDRdaemonSourceUDPHandler::tick() const SDRDaemonMetaDataFEC& metaData = m_sdrDaemonBuffer.getCurrentMeta(); m_readLength = m_readLengthSamples * (metaData.m_sampleBytes & 0xF) * 2; - if (SDR_RX_SAMP_SZ == metaData.m_sampleBits) // same sample size - { - // read samples directly feeding the SampleFifo (no callback) - m_sampleFifo->write(reinterpret_cast(m_sdrDaemonBuffer.readData(m_readLength)), m_readLength); - m_samplesCount += m_readLengthSamples; - } - else if (metaData.m_sampleBits == 16) // 16 -> 24 bits + if ((metaData.m_sampleBits == 16) && (SDR_RX_SAMP_SZ == 24)) // 16 -> 24 bits { if (m_readLengthSamples > m_converterBufferNbSamples) { @@ -292,7 +282,7 @@ void SDRdaemonSourceUDPHandler::tick() m_sampleFifo->write(reinterpret_cast(m_converterBuffer), m_readLengthSamples*sizeof(Sample)); } - else if (metaData.m_sampleBits == 24) // 24 -> 16 bits + else if ((metaData.m_sampleBits == 24) && (SDR_RX_SAMP_SZ == 16)) // 24 -> 16 bits { if (m_readLengthSamples > m_converterBufferNbSamples) { @@ -311,7 +301,13 @@ void SDRdaemonSourceUDPHandler::tick() m_sampleFifo->write(reinterpret_cast(m_converterBuffer), m_readLengthSamples*sizeof(Sample)); } - else + else if ((metaData.m_sampleBits == 16) || (metaData.m_sampleBits == 24)) // same sample size and valid size + { + // read samples directly feeding the SampleFifo (no callback) + m_sampleFifo->write(reinterpret_cast(m_sdrDaemonBuffer.readData(m_readLength)), m_readLength); + m_samplesCount += m_readLengthSamples; + } + else // invalid size { qWarning("SDRdaemonSourceUDPHandler::tick: unexpected sample size in stream: %d bits", (int) metaData.m_sampleBits); } @@ -344,8 +340,7 @@ void SDRdaemonSourceUDPHandler::tick() } SDRdaemonSourceInput::MsgReportSDRdaemonSourceStreamTiming *report = SDRdaemonSourceInput::MsgReportSDRdaemonSourceStreamTiming::create( - m_tv_sec, - m_tv_usec, + m_tv_msec, m_sdrDaemonBuffer.getBufferLengthInSecs(), m_sdrDaemonBuffer.getBufferGauge(), framesDecodingStatus, diff --git a/plugins/samplesource/sdrdaemonsource/sdrdaemonsourceudphandler.h b/plugins/samplesource/sdrdaemonsource/sdrdaemonsourceudphandler.h index 6abc6b03f..23b335f24 100644 --- a/plugins/samplesource/sdrdaemonsource/sdrdaemonsourceudphandler.h +++ b/plugins/samplesource/sdrdaemonsource/sdrdaemonsourceudphandler.h @@ -48,8 +48,7 @@ public: int getSampleRate() const { return m_samplerate; } int getCenterFrequency() const { return m_centerFrequency * 1000; } int getBufferGauge() const { return m_sdrDaemonBuffer.getBufferGauge(); } - uint32_t getTVSec() const { return m_tv_sec; } - uint32_t getTVuSec() const { return m_tv_usec; } + uint64_t getTVmSec() const { return m_tv_msec; } int getMinNbBlocks() { return m_sdrDaemonBuffer.getMinNbBlocks(); } int getMaxNbRecovery() { return m_sdrDaemonBuffer.getMaxNbRecovery(); } public slots: @@ -72,8 +71,7 @@ private: SampleSinkFifo *m_sampleFifo; uint32_t m_samplerate; uint32_t m_centerFrequency; - uint32_t m_tv_sec; - uint32_t m_tv_usec; + uint64_t m_tv_msec; MessageQueue *m_outputMessageQueueToGUI; uint32_t m_tickCount; std::size_t m_samplesCount; diff --git a/plugins/samplesource/sdrplay/sdrplayinput.cpp b/plugins/samplesource/sdrplay/sdrplayinput.cpp index cc970b956..80ff8815a 100644 --- a/plugins/samplesource/sdrplay/sdrplayinput.cpp +++ b/plugins/samplesource/sdrplay/sdrplayinput.cpp @@ -625,8 +625,9 @@ bool SDRPlayInput::setDeviceCenterFrequency(quint64 freq_hz) int SDRPlayInput::webapiRunGet( SWGSDRangel::SWGDeviceState& response, - QString& errorMessage __attribute__((unused))) + QString& errorMessage) { + (void) errorMessage; m_deviceAPI->getDeviceEngineStateStr(*response.getState()); return 200; } @@ -634,8 +635,9 @@ int SDRPlayInput::webapiRunGet( int SDRPlayInput::webapiRun( bool run, SWGSDRangel::SWGDeviceState& response, - QString& errorMessage __attribute__((unused))) + QString& errorMessage) { + (void) errorMessage; m_deviceAPI->getDeviceEngineStateStr(*response.getState()); MsgStartStop *message = MsgStartStop::create(run); m_inputMessageQueue.push(message); @@ -651,8 +653,9 @@ int SDRPlayInput::webapiRun( int SDRPlayInput::webapiSettingsGet( SWGSDRangel::SWGDeviceSettings& response, - QString& errorMessage __attribute__((unused))) + QString& errorMessage) { + (void) errorMessage; response.setSdrPlaySettings(new SWGSDRangel::SWGSDRPlaySettings()); response.getSdrPlaySettings()->init(); webapiFormatDeviceSettings(response, m_settings); @@ -663,8 +666,9 @@ int SDRPlayInput::webapiSettingsPutPatch( bool force, const QStringList& deviceSettingsKeys, SWGSDRangel::SWGDeviceSettings& response, // query + response - QString& errorMessage __attribute__((unused))) + QString& errorMessage) { + (void) errorMessage; SDRPlaySettings settings = m_settings; if (deviceSettingsKeys.contains("centerFrequency")) { @@ -759,8 +763,9 @@ void SDRPlayInput::webapiFormatDeviceSettings(SWGSDRangel::SWGDeviceSettings& re int SDRPlayInput::webapiReportGet( SWGSDRangel::SWGDeviceReport& response, - QString& errorMessage __attribute__((unused))) + QString& errorMessage) { + (void) errorMessage; response.setSdrPlayReport(new SWGSDRangel::SWGSDRPlayReport()); response.getSdrPlayReport()->init(); webapiFormatDeviceReport(response); diff --git a/plugins/samplesource/soapysdrinput/CMakeLists.txt b/plugins/samplesource/soapysdrinput/CMakeLists.txt index b87a6567f..4bc9a72cf 100644 --- a/plugins/samplesource/soapysdrinput/CMakeLists.txt +++ b/plugins/samplesource/soapysdrinput/CMakeLists.txt @@ -28,8 +28,8 @@ include_directories( ${CMAKE_CURRENT_BINARY_DIR} ${CMAKE_SOURCE_DIR}/swagger/sdrangel/code/qt5/client ${CMAKE_SOURCE_DIR}/devices - ${SOAPYSDRSRC}/include - ${SOAPYSDRSRC}/src + ${SOAPYSDR_SOURCE_DIR}/include + ${SOAPYSDR_SOURCE_DIR}/src ) else (BUILD_DEBIAN) include_directories( @@ -56,7 +56,7 @@ add_library(inputsoapysdr SHARED if (BUILD_DEBIAN) target_link_libraries(inputsoapysdr ${QT_LIBRARIES} - bladerf + SoapySDR sdrbase sdrgui swagger diff --git a/plugins/samplesource/soapysdrinput/readme.md b/plugins/samplesource/soapysdrinput/readme.md new file mode 100644 index 000000000..e84fd2678 --- /dev/null +++ b/plugins/samplesource/soapysdrinput/readme.md @@ -0,0 +1,224 @@ +

SoapySDR input plugin

+ +

Introduction

+ +This input sample source plugin gets its samples from a device interfaced with [SoapySDR](https://github.com/pothosware/SoapySDR/wiki). + +SoapySDR is a [C/C++ API](https://github.com/pothosware/SoapySDR/blob/master/include/SoapySDR/Device.hpp) that interfaces SDR hardware on one side and application software on the other. Due to its very generic nature it was fairly difficult to implement and specific UI widgets were developped to handle specific types of parameters. The level of control depends on how the device API was implemented by the vendors. On application side some parts of the API have not been implemented and can be left as possible enhancements (see next). In any case it is recommended to use the native plugins if they are available. + +SoapySDR devices appear in the list of available devices in the order they are listed in the API call to SoapySDR. If more than one device controlled by SoapySDR is listed then its sequence number is incremented like: + + - SoapySDR[0:0] Generic RTL... + - SoapySDR[1:0] Generic RTL... + +If the same device exposes several channels they appear as distinct devices with the channel number incremented like: + + - SoapySDR[1:0] LimeSDR... + - SoapySDR[1:1] LimeSDR... + +This works similarly to LimeSDR USB or BladeRF 2.0 micro + +

Binary distributions

+ +The binary distributions provide only the SoapySDR base library. It is your responsibility to install SoapySDR in your system with the SoapySDR plugins suitable for your hardware. + +

SoapySDR API implementation

+ +Not all parts are implemented. Currently the following have been left out: + + - Frequency API tuning arguments. The tuning elements are of course supported. + - Clocking API + - Time API + - Sensor API + - Register API + - GPIO API + - I2C API + - SPI API + - UART API + +

Particular considerations concerning hardware

+ +In general as previously stated you should choose the native plugins if they are available. These are: + + - Airspy + - AirspyHF + - BladeRF + - HackRF + - LimeSDR + - PlutoSDR + - RTLSDR + - SDRplay RSP1 + +The following paragraphs list the known issues or oddities. + +

BladeRF

+ +It is very important NOT to use SoapySDR. The default parameters are set to flash the FPGA but as this does not suceeds it results in a FPGA image wipe out and the device returns in "Cypress" mode. It is not too difficult to recover but there is no point risking the hassle. + +

SDRplay RSP2

+ +Do not use sample rates lower than 2 MS/s + +

Red Pitaya

+ +When installed the Red Pitaya SoapySDR plugin lists a Red Pitaya device even if there is no Red Pitaya attached. Trying to select and start it when there is no Red Pitaya will result in program crash. + +

Interface

+ +![SoapySDR input plugin GUI](../../../doc/img/SoapySDRInput_plugin1.png) + +The top part described by number tags is common for all devices. The bottom part under the "A" tag depends on the SoapySDR device implementation. The corresponding widgets are stacked vertically inside a scrollable area as there may be many controls depending on how the device interface is implemented in SoapySDR. Move the slider on the right to see all parameters available. + +

1: Common stream parameters

+ +![SDR Daemon source input stream GUI](../../../doc/img/SDRdaemonSource_plugin_01.png) + +

1.1: Frequency

+ +This is the center frequency of reception in kHz. The center frequency is usually the same for all Rx channels. The GUI of the sibling channel if present is adjusted automatically if necessary. This control corresponds to the first SoapySDR tuning element usually labeled as "RF" and would generally control the main local oscillator (LO). + +Use the wheels to adjust the value. Left click on a digit sets the cursor position at this digit. Right click on a digit sets all digits on the right to zero. This effectively floors value at the digit position. Wheels are moved with the mousewheel while pointing at the wheel or by selecting the wheel with the left mouse click and using the keyboard arrows. Pressing shift simultaneously moves digit by 5 and pressing control moves it by 2. + +

1.2: Start/Stop

+ +Device start / stop button. + + - Blue triangle icon: device is ready and can be started + - Green square icon: device is running and can be stopped + - Magenta (or pink) square icon: an error occurred. In the case the device was accidentally disconnected you may click on the icon, plug back in and start again. Check the console log for possible errors. + +

1.3: Record

+ +Record baseband I/Q stream toggle button + +

1.4: Stream sample rate

+ +Baseband I/Q sample rate in kS/s. This is the device sample rate (the "SR" SoapySDR control) divided by the decimation factor (4). + +

2: Software auto correction options

+ +These buttons control the SDRangel internal DSP auto correction options: + + - **DC**: auto remove DC component + - **IQ**: auto make I/Q balance. The DC correction must be enabled for this to be effective. + +

3: Baseband center frequency position relative the LO center frequency

+ +Possible values are: + + - **Cen**: the decimation operation takes place around the LO frequency Fs + - **Inf**: the decimation operation takes place around Fs - Fc. + - **Sup**: the decimation operation takes place around Fs + Fc. + +With SR as the sample rate before decimation Fc is calculated as: + + - if decimation n is 4 or lower: Fc = SR/2^(log2(n)-1). The device center frequency is on the side of the baseband. You need a RF filter bandwidth at least twice the baseband. + - if decimation n is 8 or higher: Fc = SR/n. The device center frequency is half the baseband away from the side of the baseband. You need a RF filter bandwidth at least 3 times the baseband. + +

4: Decimation factor

+ +The I/Q stream from the SoapySDR I/Q stream is downsampled by a power of two before being sent to the passband. Possible values are increasing powers of two: 1 (no decimation), 2, 4, 8, 16, 32, 64. + +

5: Transverter mode open dialog

+ +This button opens a dialog to set the transverter mode frequency translation options: + +![Input stream transverter dialog](../../../doc/img/RTLSDR_plugin_xvrt.png) + +Note that if you mouse over the button a tooltip appears that displays the translating frequency and if translation is enabled or disabled. When the frequency translation is enabled the button is lit. + +

5.1: Translating frequency

+ +You can set the translating frequency in Hz with this dial. The manipulation of the dial is described in (1.1: Frequency). + +The frequency set in the device is the frequency on the main dial (1) minus this frequency. Thus it is positive for down converters and negative for up converters. + +For example a mixer at 120 MHz for HF operation you would set the value to -120,000,000 Hz so that if the main dial frequency is set at 7,130 kHz the PlutoSDR will be set to 127.130 MHz. + +If you use a down converter to receive the 6 cm band narrowband center frequency of 5670 MHz at 432 MHz you would set the translating frequency to 5760 - 432 = 5328 MHz thus dial +5,328,000,000 Hz. + +For bands even higher in the frequency spectrum the GHz digits are not really significant so you can have them set at 1 GHz. Thus to receive the 10368 MHz frequency at 432 MHz you would set the translating frequency to 1368 - 432 = 936 MHz. Note that in this case the frequency of the LO used in the mixer of the transverter is set at 9936 MHz. + +The Hz precision allows a fine tuning of the transverter LO offset + +

5.2: Translating frequency enable/disable

+ +Use this toggle button to activate or deactivate the frequency translation + +

5.3: Confirmation buttons

+ +Use these buttons to confirm ("OK") or dismiss ("Cancel") your changes. + +

6: Software LO ppm correction

+ +Use this slider to adjust SDRangel internal LO correction in ppm. It can be varied from -100.0 to 100.0 in 0.1 steps and is applied in software when calculating the frequency at which the LO should be set. + +

A: SoapySDR variable interface

+ +The form of widgets is closely related to the type of setting defined in the [SoapySDR interface](https://github.com/pothosware/SoapySDR/blob/master/include/SoapySDR/Types.hpp). These are: + + - Ranges + - Continuous range when maximum and minimum are different + - Discrete value when maximum and minimum are equal. Usually this appears in a range list to define a set of values + - List of ranges: more than one range applies to the same setting + - Arguments defined by + - type: boolean, integer, floating point, string + - nature: continuous or discrete + - String list + +

A.1: Continuous range

+ +If the range is all in the positive domain the unsigned variation is used: + +![SoapySDR input plugin GUI](../../../doc/img/SoapySDR_range_pos.png) + +Note that the same widget is used for single ranges and ranges list. In this case the range selection combo on the right is disabled. The manipulation of the dial is described in (1.1: Frequency) + +If the range is in both the positive and negative domains the signed variation is used: + +![SoapySDR input plugin GUI](../../../doc/img/SoapySDR_range_neg.png) + +If the range applies to a gain a slider is used: + +![SoapySDR input plugin GUI](../../../doc/img/SoapySDR_range_gain.png) + +

A.2: Discrete range

+ +Appears with a combo box to select a discrete value: + +![SoapySDR input plugin GUI](../../../doc/img/SoapySDR_range_discrete.png) + +

A.3: List of ranges

+ +In this case the range selection combo on the right is enabled: + +![SoapySDR input plugin GUI](../../../doc/img/SoapySDR_range_list1.png) + +

A.4: Boolean argument

+ +A checkbox is used to control boolean values: + +![SoapySDR input plugin GUI](../../../doc/img/SoapySDR_arg_bool2.png) + +For AGC, Auto DC and Auto IQ corrections the checkbox has its text label on the right: + +![SoapySDR input plugin GUI](../../../doc/img/SoapySDR_arg_bool1.png) + +When set (true) a checkbox is lit in orange: + +![SoapySDR input plugin GUI](../../../doc/img/SoapySDR_arg_bool3.png) + +

A.5: Int, Float and String arguments

+ +For all these types of values a line editor is used. Numerical values are parsed from string: + +![SoapySDR input plugin GUI](../../../doc/img/SoapySDR_arg_str.png) + +

A.6 String lists

+ +Some parameters like the antenna ports are expressed as a list of possible string values. These are presented in a combo box: + +![SoapySDR input plugin GUI](../../../doc/img/SoapySDR_arg_strlist.png) + + + diff --git a/plugins/samplesource/soapysdrinput/soapysdrinput.cpp b/plugins/samplesource/soapysdrinput/soapysdrinput.cpp index 198c9d822..b516f9eb6 100644 --- a/plugins/samplesource/soapysdrinput/soapysdrinput.cpp +++ b/plugins/samplesource/soapysdrinput/soapysdrinput.cpp @@ -18,6 +18,12 @@ #include "util/simpleserializer.h" +#include "SWGDeviceSettings.h" +#include "SWGSoapySDRInputSettings.h" +#include "SWGDeviceState.h" +#include "SWGDeviceReport.h" +#include "SWGSoapySDRReport.h" + #include "device/devicesourceapi.h" #include "device/devicesinkapi.h" #include "dsp/dspcommands.h" @@ -42,6 +48,9 @@ SoapySDRInput::SoapySDRInput(DeviceSourceAPI *deviceAPI) : { openDevice(); initGainSettings(m_settings); + initTunableElementsSettings(m_settings); + initStreamArgSettings(m_settings); + initDeviceArgSettings(m_settings); m_fileSink = new FileRecord(QString("test_%1.sdriq").arg(m_deviceAPI->getDeviceUID())); m_deviceAPI->addSink(m_fileSink); @@ -269,6 +278,17 @@ const std::vector& SoapySDRInput::getIndividu return channelSettings->m_gainSettings; } +const SoapySDR::ArgInfoList& SoapySDRInput::getStreamArgInfoList() +{ + const DeviceSoapySDRParams::ChannelSettings* channelSettings = m_deviceShared.m_deviceParams->getRxChannelSettings(m_deviceShared.m_channel); + return channelSettings->m_streamSettingsArgs; +} + +const SoapySDR::ArgInfoList& SoapySDRInput::getDeviceArgInfoList() +{ + return m_deviceShared.m_deviceParams->getDeviceArgs(); +} + void SoapySDRInput::initGainSettings(SoapySDRInputSettings& settings) { const DeviceSoapySDRParams::ChannelSettings* channelSettings = m_deviceShared.m_deviceParams->getRxChannelSettings(m_deviceShared.m_channel); @@ -282,6 +302,63 @@ void SoapySDRInput::initGainSettings(SoapySDRInputSettings& settings) updateGains(m_deviceShared.m_device, m_deviceShared.m_channel, settings); } +void SoapySDRInput::initTunableElementsSettings(SoapySDRInputSettings& settings) +{ + const DeviceSoapySDRParams::ChannelSettings* channelSettings = m_deviceShared.m_deviceParams->getRxChannelSettings(m_deviceShared.m_channel); + settings.m_tunableElements.clear(); + bool first = true; + + for (const auto &it : channelSettings->m_frequencySettings) + { + if (first) + { + first = false; + continue; + } + + settings.m_tunableElements[QString(it.m_name.c_str())] = 0.0; + } + + updateTunableElements(m_deviceShared.m_device, m_deviceShared.m_channel, settings); +} + +void SoapySDRInput::initStreamArgSettings(SoapySDRInputSettings& settings) +{ + const DeviceSoapySDRParams::ChannelSettings* channelSettings = m_deviceShared.m_deviceParams->getRxChannelSettings(m_deviceShared.m_channel); + settings.m_streamArgSettings.clear(); + + for (const auto &it : channelSettings->m_streamSettingsArgs) + { + if (it.type == SoapySDR::ArgInfo::BOOL) { + settings.m_streamArgSettings[QString(it.key.c_str())] = QVariant(it.value == "true"); + } else if (it.type == SoapySDR::ArgInfo::INT) { + settings.m_streamArgSettings[QString(it.key.c_str())] = QVariant(atoi(it.value.c_str())); + } else if (it.type == SoapySDR::ArgInfo::FLOAT) { + settings.m_streamArgSettings[QString(it.key.c_str())] = QVariant(atof(it.value.c_str())); + } else if (it.type == SoapySDR::ArgInfo::STRING) { + settings.m_streamArgSettings[QString(it.key.c_str())] = QVariant(it.value.c_str()); + } + } +} + +void SoapySDRInput::initDeviceArgSettings(SoapySDRInputSettings& settings) +{ + settings.m_deviceArgSettings.clear(); + + for (const auto &it : m_deviceShared.m_deviceParams->getDeviceArgs()) + { + if (it.type == SoapySDR::ArgInfo::BOOL) { + settings.m_deviceArgSettings[QString(it.key.c_str())] = QVariant(it.value == "true"); + } else if (it.type == SoapySDR::ArgInfo::INT) { + settings.m_deviceArgSettings[QString(it.key.c_str())] = QVariant(atoi(it.value.c_str())); + } else if (it.type == SoapySDR::ArgInfo::FLOAT) { + settings.m_deviceArgSettings[QString(it.key.c_str())] = QVariant(atof(it.value.c_str())); + } else if (it.type == SoapySDR::ArgInfo::STRING) { + settings.m_deviceArgSettings[QString(it.key.c_str())] = QVariant(it.value.c_str()); + } + } +} + bool SoapySDRInput::hasDCAutoCorrection() { const DeviceSoapySDRParams::ChannelSettings* channelSettings = m_deviceShared.m_deviceParams->getRxChannelSettings(m_deviceShared.m_channel); @@ -592,8 +669,9 @@ QByteArray SoapySDRInput::serialize() const return s.final(); } -bool SoapySDRInput::deserialize(const QByteArray& data __attribute__((unused))) +bool SoapySDRInput::deserialize(const QByteArray& data) { + (void) data; return false; } @@ -613,7 +691,7 @@ quint64 SoapySDRInput::getCenterFrequency() const return m_settings.m_centerFrequency; } -void SoapySDRInput::setCenterFrequency(qint64 centerFrequency __attribute__((unused))) +void SoapySDRInput::setCenterFrequency(qint64 centerFrequency) { SoapySDRInputSettings settings = m_settings; settings.m_centerFrequency = centerFrequency; @@ -662,7 +740,18 @@ void SoapySDRInput::updateGains(SoapySDR::Device *dev, int requestedChannel, Soa } } -bool SoapySDRInput::handleMessage(const Message& message __attribute__((unused))) +void SoapySDRInput::updateTunableElements(SoapySDR::Device *dev, int requestedChannel, SoapySDRInputSettings& settings) +{ + if (dev == 0) { + return; + } + + for (const auto &name : settings.m_tunableElements.keys()) { + settings.m_tunableElements[name] = dev->getFrequency(SOAPY_SDR_RX, requestedChannel, name.toStdString()); + } +} + +bool SoapySDRInput::handleMessage(const Message& message) { if (MsgConfigureSoapySDRInput::match(message)) { @@ -751,6 +840,33 @@ bool SoapySDRInput::handleMessage(const Message& message __attribute__((unused)) return true; } + else if (DeviceSoapySDRShared::MsgReportDeviceArgsChange::match(message)) + { + DeviceSoapySDRShared::MsgReportDeviceArgsChange& report = (DeviceSoapySDRShared::MsgReportDeviceArgsChange&) message; + QMap deviceArgSettings = report.getDeviceArgSettings(); + + for (const auto &oname : m_settings.m_deviceArgSettings.keys()) + { + auto nvalue = deviceArgSettings.find(oname); + + if (nvalue != deviceArgSettings.end() && (m_settings.m_deviceArgSettings[oname] != *nvalue)) + { + m_settings.m_deviceArgSettings[oname] = *nvalue; + qDebug("SoapySDRInput::handleMessage: MsgReportDeviceArgsChange: device argument %s set to %s", + oname.toStdString().c_str(), nvalue->toString().toStdString().c_str()); + } + } + + // propagate settings to GUI if any + if (getMessageQueueToGUI()) + { + DeviceSoapySDRShared::MsgReportDeviceArgsChange *reportToGUI = DeviceSoapySDRShared::MsgReportDeviceArgsChange::create( + m_settings.m_deviceArgSettings); + getMessageQueueToGUI()->push(reportToGUI); + } + + return true; + } else { return false; @@ -763,6 +879,7 @@ bool SoapySDRInput::applySettings(const SoapySDRInputSettings& settings, bool fo bool forwardChangeToBuddies = false; bool globalGainChanged = false; bool individualGainsChanged = false; + bool deviceArgsChanged = false; SoapySDR::Device *dev = m_deviceShared.m_device; SoapySDRInputThread *inputThread = findThread(); @@ -892,7 +1009,7 @@ bool SoapySDRInput::applySettings(const SoapySDRInputSettings& settings, bool fo { auto nvalue = settings.m_tunableElements.find(oname); - if (nvalue != settings.m_tunableElements.end() && (m_settings.m_tunableElements[oname] != *nvalue)) + if (nvalue != settings.m_tunableElements.end() && ((m_settings.m_tunableElements[oname] != *nvalue) ||force)) { if (dev != 0) { @@ -1021,6 +1138,57 @@ bool SoapySDRInput::applySettings(const SoapySDRInputSettings& settings, bool fo } } + for (const auto &oname : m_settings.m_streamArgSettings.keys()) + { + auto nvalue = settings.m_streamArgSettings.find(oname); + + if (nvalue != settings.m_streamArgSettings.end() && ((m_settings.m_streamArgSettings[oname] != *nvalue) || force)) + { + if (dev != 0) + { + try + { + dev->writeSetting(SOAPY_SDR_RX, requestedChannel, oname.toStdString(), nvalue->toString().toStdString()); + qDebug("SoapySDRInput::applySettings: stream argument %s set to %s", + oname.toStdString().c_str(), nvalue->toString().toStdString().c_str()); + } + catch (const std::exception &ex) + { + qCritical("SoapySDRInput::applySettings: cannot set stream argument %s to %s: %s", + oname.toStdString().c_str(), nvalue->toString().toStdString().c_str(), ex.what()); + } + } + + m_settings.m_streamArgSettings[oname] = *nvalue; + } + } + + for (const auto &oname : m_settings.m_deviceArgSettings.keys()) + { + auto nvalue = settings.m_deviceArgSettings.find(oname); + + if (nvalue != settings.m_deviceArgSettings.end() && ((m_settings.m_deviceArgSettings[oname] != *nvalue) || force)) + { + if (dev != 0) + { + try + { + dev->writeSetting(oname.toStdString(), nvalue->toString().toStdString()); + qDebug("SoapySDRInput::applySettings: device argument %s set to %s", + oname.toStdString().c_str(), nvalue->toString().toStdString().c_str()); + } + catch (const std::exception &ex) + { + qCritical("SoapySDRInput::applySettings: cannot set device argument %s to %s: %s", + oname.toStdString().c_str(), nvalue->toString().toStdString().c_str(), ex.what()); + } + } + + m_settings.m_deviceArgSettings[oname] = *nvalue; + deviceArgsChanged = true; + } + } + if (forwardChangeOwnDSP) { int sampleRate = settings.m_devSampleRate/(1<& sourceBuddies = m_deviceAPI->getSourceBuddies(); const std::vector& sinkBuddies = m_deviceAPI->getSinkBuddies(); @@ -1058,6 +1226,27 @@ bool SoapySDRInput::applySettings(const SoapySDRInputSettings& settings, bool fo } } + if (deviceArgsChanged) + { + // send to buddies + const std::vector& sourceBuddies = m_deviceAPI->getSourceBuddies(); + const std::vector& sinkBuddies = m_deviceAPI->getSinkBuddies(); + + for (const auto &itSource : sourceBuddies) + { + DeviceSoapySDRShared::MsgReportDeviceArgsChange *report = DeviceSoapySDRShared::MsgReportDeviceArgsChange::create( + settings.m_deviceArgSettings); + itSource->getSampleSourceInputMessageQueue()->push(report); + } + + for (const auto &itSink : sinkBuddies) + { + DeviceSoapySDRShared::MsgReportDeviceArgsChange *report = DeviceSoapySDRShared::MsgReportDeviceArgsChange::create( + settings.m_deviceArgSettings); + itSink->getSampleSinkInputMessageQueue()->push(report); + } + } + m_settings = settings; if (globalGainChanged || individualGainsChanged) @@ -1085,7 +1274,520 @@ bool SoapySDRInput::applySettings(const SoapySDRInputSettings& settings, bool fo << " m_softIQCorrection: " << m_settings.m_softIQCorrection << " m_antenna: " << m_settings.m_antenna << " m_bandwidth: " << m_settings.m_bandwidth - << " m_globalGain: " << m_settings.m_globalGain; + << " m_globalGain: " << m_settings.m_globalGain + << " force: " << force; + + QMap::const_iterator doubleIt = m_settings.m_individualGains.begin(); + + for(; doubleIt != m_settings.m_individualGains.end(); ++doubleIt) { + qDebug("SoapySDRInput::applySettings: m_individualGains[%s]: %lf", doubleIt.key().toStdString().c_str(), doubleIt.value()); + } + + doubleIt = m_settings.m_tunableElements.begin(); + + for(; doubleIt != m_settings.m_tunableElements.end(); ++doubleIt) { + qDebug("SoapySDRInput::applySettings: m_tunableElements[%s]: %lf", doubleIt.key().toStdString().c_str(), doubleIt.value()); + } + + QMap::const_iterator varIt = m_settings.m_deviceArgSettings.begin(); + + for(; varIt != m_settings.m_deviceArgSettings.end(); ++varIt) + { + qDebug("SoapySDRInput::applySettings: m_deviceArgSettings[%s] (type %d): %s", + varIt.key().toStdString().c_str(), + (int) varIt.value().type(), // bool: 1, int: 2, double: 6, string: 10 (http://doc.qt.io/archives/qt-4.8/qvariant.html) + varIt.value().toString().toStdString().c_str()); + } + + varIt = m_settings.m_streamArgSettings.begin(); + + for(; varIt != m_settings.m_streamArgSettings.end(); ++varIt) + { + qDebug("SoapySDRInput::applySettings: m_streamArgSettings[%s] (type %d): %s", + varIt.key().toStdString().c_str(), + (int) varIt.value().type(), + varIt.value().toString().toStdString().c_str()); + } return true; } + +int SoapySDRInput::webapiSettingsGet( + SWGSDRangel::SWGDeviceSettings& response, + QString& errorMessage) +{ + (void) errorMessage; + response.setSoapySdrInputSettings(new SWGSDRangel::SWGSoapySDRInputSettings()); + response.getSoapySdrInputSettings()->init(); + webapiFormatDeviceSettings(response, m_settings); + return 200; +} + +int SoapySDRInput::webapiSettingsPutPatch( + bool force, + const QStringList& deviceSettingsKeys, + SWGSDRangel::SWGDeviceSettings& response, // query + response + QString& errorMessage) +{ + (void) errorMessage; + SoapySDRInputSettings settings = m_settings; + + if (deviceSettingsKeys.contains("centerFrequency")) { + settings.m_centerFrequency = response.getSoapySdrInputSettings()->getCenterFrequency(); + } + if (deviceSettingsKeys.contains("LOppmTenths")) { + settings.m_LOppmTenths = response.getSoapySdrInputSettings()->getLOppmTenths(); + } + if (deviceSettingsKeys.contains("devSampleRate")) { + settings.m_devSampleRate = response.getSoapySdrInputSettings()->getDevSampleRate(); + } + if (deviceSettingsKeys.contains("bandwidth")) { + settings.m_bandwidth = response.getSoapySdrInputSettings()->getBandwidth(); + } + if (deviceSettingsKeys.contains("log2Decim")) { + settings.m_log2Decim = response.getSoapySdrInputSettings()->getLog2Decim(); + } + if (deviceSettingsKeys.contains("fcPos")) { + settings.m_fcPos = static_cast(response.getSoapySdrInputSettings()->getFcPos()); + } + if (deviceSettingsKeys.contains("softDCCorrection")) { + settings.m_softDCCorrection = response.getSoapySdrInputSettings()->getSoftDcCorrection() != 0; + } + if (deviceSettingsKeys.contains("softIQCorrection")) { + settings.m_softIQCorrection = response.getSoapySdrInputSettings()->getSoftIqCorrection() != 0; + } + if (deviceSettingsKeys.contains("transverterDeltaFrequency")) { + settings.m_transverterDeltaFrequency = response.getSoapySdrInputSettings()->getTransverterDeltaFrequency(); + } + if (deviceSettingsKeys.contains("transverterMode")) { + settings.m_transverterMode = response.getSoapySdrInputSettings()->getTransverterMode() != 0; + } + if (deviceSettingsKeys.contains("fileRecordName")) { + settings.m_fileRecordName = *response.getSoapySdrInputSettings()->getFileRecordName(); + } + if (deviceSettingsKeys.contains("antenna")) { + settings.m_antenna = *response.getSoapySdrInputSettings()->getAntenna(); + } + + if (deviceSettingsKeys.contains("tunableElements")) + { + QList *tunableElements = response.getSoapySdrInputSettings()->getTunableElements(); + + for (const auto &itArg : *tunableElements) + { + QMap::iterator itSettings = settings.m_tunableElements.find(*(itArg->getKey())); + + if (itSettings != settings.m_tunableElements.end()) + { + QVariant v = webapiVariantFromArgValue(itArg); + itSettings.value() = v.toDouble(); + } + } + } + + if (deviceSettingsKeys.contains("globalGain")) { + settings.m_globalGain = response.getSoapySdrInputSettings()->getGlobalGain(); + } + + if (deviceSettingsKeys.contains("individualGains")) + { + QList *individualGains = response.getSoapySdrInputSettings()->getIndividualGains(); + + for (const auto &itArg : *individualGains) + { + QMap::iterator itSettings = settings.m_individualGains.find(*(itArg->getKey())); + + if (itSettings != settings.m_individualGains.end()) + { + QVariant v = webapiVariantFromArgValue(itArg); + itSettings.value() = v.toDouble(); + } + } + } + + if (deviceSettingsKeys.contains("autoGain")) { + settings.m_autoGain = response.getSoapySdrInputSettings()->getAutoGain() != 0; + } + if (deviceSettingsKeys.contains("autoDCCorrection")) { + settings.m_autoDCCorrection = response.getSoapySdrInputSettings()->getAutoDcCorrection() != 0; + } + if (deviceSettingsKeys.contains("autoIQCorrection")) { + settings.m_autoIQCorrection = response.getSoapySdrInputSettings()->getAutoIqCorrection() != 0; + } + if (deviceSettingsKeys.contains("dcCorrection")) + { + settings.m_dcCorrection.real(response.getSoapySdrInputSettings()->getDcCorrection()->getReal()); + settings.m_dcCorrection.imag(response.getSoapySdrInputSettings()->getDcCorrection()->getImag()); + } + if (deviceSettingsKeys.contains("iqCorrection")) + { + settings.m_iqCorrection.real(response.getSoapySdrInputSettings()->getIqCorrection()->getReal()); + settings.m_iqCorrection.imag(response.getSoapySdrInputSettings()->getIqCorrection()->getImag()); + } + + if (deviceSettingsKeys.contains("streamArgSettings")) + { + QList *streamArgSettings = response.getSoapySdrInputSettings()->getStreamArgSettings(); + + for (const auto itArg : *streamArgSettings) + { + QMap::iterator itSettings = settings.m_streamArgSettings.find(*itArg->getKey()); + + if (itSettings != settings.m_streamArgSettings.end()) { + itSettings.value() = webapiVariantFromArgValue(itArg); + } + } + } + + if (deviceSettingsKeys.contains("deviceArgSettings")) + { + QList *deviceArgSettings = response.getSoapySdrInputSettings()->getDeviceArgSettings(); + + for (const auto itArg : *deviceArgSettings) + { + QMap::iterator itSettings = settings.m_deviceArgSettings.find(*itArg->getKey()); + + if (itSettings != settings.m_deviceArgSettings.end()) { + itSettings.value() = webapiVariantFromArgValue(itArg); + } + } + } + + MsgConfigureSoapySDRInput *msg = MsgConfigureSoapySDRInput::create(settings, force); + m_inputMessageQueue.push(msg); + + if (m_guiMessageQueue) // forward to GUI if any + { + MsgConfigureSoapySDRInput *msgToGUI = MsgConfigureSoapySDRInput::create(settings, force); + m_guiMessageQueue->push(msgToGUI); + } + + webapiFormatDeviceSettings(response, settings); + return 200; +} + +int SoapySDRInput::webapiReportGet(SWGSDRangel::SWGDeviceReport& response, QString& errorMessage) +{ + (void) errorMessage; + response.setSoapySdrInputReport(new SWGSDRangel::SWGSoapySDRReport()); + response.getSoapySdrInputReport()->init(); + webapiFormatDeviceReport(response); + return 200; +} + +int SoapySDRInput::webapiRunGet( + SWGSDRangel::SWGDeviceState& response, + QString& errorMessage) +{ + (void) errorMessage; + m_deviceAPI->getDeviceEngineStateStr(*response.getState()); + return 200; +} + +int SoapySDRInput::webapiRun( + bool run, + SWGSDRangel::SWGDeviceState& response, + QString& errorMessage) +{ + (void) errorMessage; + m_deviceAPI->getDeviceEngineStateStr(*response.getState()); + MsgStartStop *message = MsgStartStop::create(run); + m_inputMessageQueue.push(message); + + if (m_guiMessageQueue) // forward to GUI if any + { + MsgStartStop *msgToGUI = MsgStartStop::create(run); + m_guiMessageQueue->push(msgToGUI); + } + + return 200; +} + +void SoapySDRInput::webapiFormatDeviceSettings(SWGSDRangel::SWGDeviceSettings& response, const SoapySDRInputSettings& settings) +{ + response.getSoapySdrInputSettings()->setCenterFrequency(settings.m_centerFrequency); + response.getSoapySdrInputSettings()->setLOppmTenths(settings.m_LOppmTenths); + response.getSoapySdrInputSettings()->setDevSampleRate(settings.m_devSampleRate); + response.getSoapySdrInputSettings()->setLog2Decim(settings.m_log2Decim); + response.getSoapySdrInputSettings()->setFcPos((int) settings.m_fcPos); + response.getSoapySdrInputSettings()->setSoftDcCorrection(settings.m_softDCCorrection ? 1 : 0); + response.getSoapySdrInputSettings()->setSoftIqCorrection(settings.m_softIQCorrection ? 1 : 0); + response.getSoapySdrInputSettings()->setTransverterDeltaFrequency(settings.m_transverterDeltaFrequency); + response.getSoapySdrInputSettings()->setTransverterMode(settings.m_transverterMode ? 1 : 0); + + if (response.getSoapySdrInputSettings()->getFileRecordName()) { + *response.getSoapySdrInputSettings()->getFileRecordName() = settings.m_fileRecordName; + } else { + response.getSoapySdrInputSettings()->setFileRecordName(new QString(settings.m_fileRecordName)); + } + + if (response.getSoapySdrInputSettings()->getAntenna()) { + *response.getSoapySdrInputSettings()->getAntenna() = settings.m_antenna; + } else { + response.getSoapySdrInputSettings()->setAntenna(new QString(settings.m_antenna)); + } + + if (response.getSoapySdrInputSettings()->getTunableElements()) { + response.getSoapySdrInputSettings()->getTunableElements()->clear(); + } else { + response.getSoapySdrInputSettings()->setTunableElements(new QList); + } + + for (const auto itName : settings.m_tunableElements.keys()) + { + response.getSoapySdrInputSettings()->getTunableElements()->append(new SWGSDRangel::SWGArgValue); + response.getSoapySdrInputSettings()->getTunableElements()->back()->setKey(new QString(itName)); + double value = settings.m_tunableElements.value(itName); + response.getSoapySdrInputSettings()->getTunableElements()->back()->setValueString(new QString(tr("%1").arg(value))); + response.getSoapySdrInputSettings()->getTunableElements()->back()->setValueType(new QString("float")); + } + + response.getSoapySdrInputSettings()->setBandwidth(settings.m_bandwidth); + response.getSoapySdrInputSettings()->setGlobalGain(settings.m_globalGain); + + if (response.getSoapySdrInputSettings()->getIndividualGains()) { + response.getSoapySdrInputSettings()->getIndividualGains()->clear(); + } else { + response.getSoapySdrInputSettings()->setIndividualGains(new QList); + } + + for (const auto itName : settings.m_individualGains.keys()) + { + response.getSoapySdrInputSettings()->getIndividualGains()->append(new SWGSDRangel::SWGArgValue); + response.getSoapySdrInputSettings()->getIndividualGains()->back()->setKey(new QString(itName)); + double value = settings.m_individualGains.value(itName); + response.getSoapySdrInputSettings()->getIndividualGains()->back()->setValueString(new QString(tr("%1").arg(value))); + response.getSoapySdrInputSettings()->getIndividualGains()->back()->setValueType(new QString("float")); + } + + response.getSoapySdrInputSettings()->setAutoGain(settings.m_autoGain ? 1 : 0); + response.getSoapySdrInputSettings()->setAutoDcCorrection(settings.m_autoDCCorrection ? 1 : 0); + response.getSoapySdrInputSettings()->setAutoIqCorrection(settings.m_autoIQCorrection ? 1 : 0); + + if (!response.getSoapySdrInputSettings()->getDcCorrection()) { + response.getSoapySdrInputSettings()->setDcCorrection(new SWGSDRangel::SWGComplex()); + } + + response.getSoapySdrInputSettings()->getDcCorrection()->setReal(settings.m_dcCorrection.real()); + response.getSoapySdrInputSettings()->getDcCorrection()->setImag(settings.m_dcCorrection.imag()); + + if (!response.getSoapySdrInputSettings()->getIqCorrection()) { + response.getSoapySdrInputSettings()->setIqCorrection(new SWGSDRangel::SWGComplex()); + } + + response.getSoapySdrInputSettings()->getIqCorrection()->setReal(settings.m_iqCorrection.real()); + response.getSoapySdrInputSettings()->getIqCorrection()->setImag(settings.m_iqCorrection.imag()); + + if (response.getSoapySdrInputSettings()->getStreamArgSettings()) { + response.getSoapySdrInputSettings()->getStreamArgSettings()->clear(); + } else { + response.getSoapySdrInputSettings()->setStreamArgSettings(new QList); + } + + for (const auto itName : settings.m_streamArgSettings.keys()) + { + response.getSoapySdrInputSettings()->getStreamArgSettings()->append(new SWGSDRangel::SWGArgValue); + response.getSoapySdrInputSettings()->getStreamArgSettings()->back()->setKey(new QString(itName)); + const QVariant& v = settings.m_streamArgSettings.value(itName); + webapiFormatArgValue(v, response.getSoapySdrInputSettings()->getStreamArgSettings()->back()); + } + + if (response.getSoapySdrInputSettings()->getDeviceArgSettings()) { + response.getSoapySdrInputSettings()->getDeviceArgSettings()->clear(); + } else { + response.getSoapySdrInputSettings()->setDeviceArgSettings(new QList); + } + + for (const auto itName : settings.m_deviceArgSettings.keys()) + { + response.getSoapySdrInputSettings()->getDeviceArgSettings()->append(new SWGSDRangel::SWGArgValue); + response.getSoapySdrInputSettings()->getDeviceArgSettings()->back()->setKey(new QString(itName)); + const QVariant& v = settings.m_deviceArgSettings.value(itName); + webapiFormatArgValue(v, response.getSoapySdrInputSettings()->getDeviceArgSettings()->back()); + } +} + +void SoapySDRInput::webapiFormatDeviceReport(SWGSDRangel::SWGDeviceReport& response) +{ + const DeviceSoapySDRParams::ChannelSettings* channelSettings = m_deviceShared.m_deviceParams->getRxChannelSettings(m_deviceShared.m_channel); + + response.getSoapySdrInputReport()->setDeviceSettingsArgs(new QList); + + for (const auto itArg : m_deviceShared.m_deviceParams->getDeviceArgs()) + { + response.getSoapySdrInputReport()->getDeviceSettingsArgs()->append(new SWGSDRangel::SWGArgInfo()); + webapiFormatArgInfo(itArg, response.getSoapySdrInputReport()->getDeviceSettingsArgs()->back()); + } + + response.getSoapySdrInputReport()->setStreamSettingsArgs(new QList); + + for (const auto itArg : channelSettings->m_streamSettingsArgs) + { + response.getSoapySdrInputReport()->getStreamSettingsArgs()->append(new SWGSDRangel::SWGArgInfo()); + webapiFormatArgInfo(itArg, response.getSoapySdrInputReport()->getStreamSettingsArgs()->back()); + } + + response.getSoapySdrInputReport()->setFrequencySettingsArgs(new QList); + + for (const auto itArg : channelSettings->m_frequencySettingsArgs) + { + response.getSoapySdrInputReport()->getFrequencySettingsArgs()->append(new SWGSDRangel::SWGArgInfo()); + webapiFormatArgInfo(itArg, response.getSoapySdrInputReport()->getFrequencySettingsArgs()->back()); + } + + response.getSoapySdrInputReport()->setHasAgc(channelSettings->m_hasAGC ? 1 : 0); + response.getSoapySdrInputReport()->setHasDcAutoCorrection(channelSettings->m_hasDCAutoCorrection ? 1 : 0); + response.getSoapySdrInputReport()->setHasDcOffsetValue(channelSettings->m_hasDCOffsetValue ? 1 : 0); + response.getSoapySdrInputReport()->setHasFrequencyCorrectionValue(channelSettings->m_hasFrequencyCorrectionValue ? 1 : 0); + response.getSoapySdrInputReport()->setHasIqBalanceValue(channelSettings->m_hasIQBalanceValue ? 1 : 0); + + if (channelSettings->m_antennas.size() != 0) + { + response.getSoapySdrInputReport()->setAntennas(new QList); + + for (const auto itAntenna : channelSettings->m_antennas) { + response.getSoapySdrInputReport()->getAntennas()->append(new QString(itAntenna.c_str())); + } + } + + if ((channelSettings->m_gainRange.maximum() != 0.0) || (channelSettings->m_gainRange.minimum() != 0.0)) + { + response.getSoapySdrInputReport()->setGainRange(new SWGSDRangel::SWGRangeFloat()); + response.getSoapySdrInputReport()->getGainRange()->setMin(channelSettings->m_gainRange.minimum()); + response.getSoapySdrInputReport()->getGainRange()->setMax(channelSettings->m_gainRange.maximum()); + } + + if (channelSettings->m_gainSettings.size() != 0) + { + response.getSoapySdrInputReport()->setGainSettings(new QList); + + for (const auto itGain : channelSettings->m_gainSettings) + { + response.getSoapySdrInputReport()->getGainSettings()->append(new SWGSDRangel::SWGSoapySDRGainSetting()); + response.getSoapySdrInputReport()->getGainSettings()->back()->setRange(new SWGSDRangel::SWGRangeFloat()); + response.getSoapySdrInputReport()->getGainSettings()->back()->getRange()->setMin(itGain.m_range.minimum()); + response.getSoapySdrInputReport()->getGainSettings()->back()->getRange()->setMax(itGain.m_range.maximum()); + response.getSoapySdrInputReport()->getGainSettings()->back()->setName(new QString(itGain.m_name.c_str())); + } + } + + if (channelSettings->m_frequencySettings.size() != 0) + { + response.getSoapySdrInputReport()->setFrequencySettings(new QList); + + for (const auto itFreq : channelSettings->m_frequencySettings) + { + response.getSoapySdrInputReport()->getFrequencySettings()->append(new SWGSDRangel::SWGSoapySDRFrequencySetting()); + response.getSoapySdrInputReport()->getFrequencySettings()->back()->setRanges(new QList); + + for (const auto itRange : itFreq.m_ranges) + { + response.getSoapySdrInputReport()->getFrequencySettings()->back()->getRanges()->append(new SWGSDRangel::SWGRangeFloat()); + response.getSoapySdrInputReport()->getFrequencySettings()->back()->getRanges()->back()->setMin(itRange.minimum()); + response.getSoapySdrInputReport()->getFrequencySettings()->back()->getRanges()->back()->setMax(itRange.maximum()); + } + + response.getSoapySdrInputReport()->getFrequencySettings()->back()->setName(new QString(itFreq.m_name.c_str())); + } + } + + if (channelSettings->m_ratesRanges.size() != 0) + { + response.getSoapySdrInputReport()->setRatesRanges(new QList); + + for (const auto itRange : channelSettings->m_ratesRanges) + { + response.getSoapySdrInputReport()->getRatesRanges()->append(new SWGSDRangel::SWGRangeFloat()); + response.getSoapySdrInputReport()->getRatesRanges()->back()->setMin(itRange.minimum()); + response.getSoapySdrInputReport()->getRatesRanges()->back()->setMax(itRange.maximum()); + } + } + + if (channelSettings->m_bandwidthsRanges.size() != 0) + { + response.getSoapySdrInputReport()->setBandwidthsRanges(new QList); + + for (const auto itBandwidth : channelSettings->m_bandwidthsRanges) + { + response.getSoapySdrInputReport()->getBandwidthsRanges()->append(new SWGSDRangel::SWGRangeFloat()); + response.getSoapySdrInputReport()->getBandwidthsRanges()->back()->setMin(itBandwidth.minimum()); + response.getSoapySdrInputReport()->getBandwidthsRanges()->back()->setMax(itBandwidth.maximum()); + } + } +} + +QVariant SoapySDRInput::webapiVariantFromArgValue(SWGSDRangel::SWGArgValue *argValue) +{ + if (*argValue->getValueType() == "bool") { + return QVariant((bool) (*argValue->getValueString() == "1")); + } else if (*argValue->getValueType() == "int") { + return QVariant((int) (atoi(argValue->getValueString()->toStdString().c_str()))); + } else if (*argValue->getValueType() == "float") { + return QVariant((double) (atof(argValue->getValueString()->toStdString().c_str()))); + } else { + return QVariant(QString(*argValue->getValueString())); + } +} + +void SoapySDRInput::webapiFormatArgValue(const QVariant& v, SWGSDRangel::SWGArgValue *argValue) +{ + if (v.type() == QVariant::Bool) + { + argValue->setValueType(new QString("bool")); + argValue->setValueString(new QString(v.toBool() ? "1" : "0")); + } + else if (v.type() == QVariant::Int) + { + argValue->setValueType(new QString("int")); + argValue->setValueString(new QString(tr("%1").arg(v.toInt()))); + } + else if (v.type() == QVariant::Double) + { + argValue->setValueType(new QString("float")); + argValue->setValueString(new QString(tr("%1").arg(v.toDouble()))); + } + else + { + argValue->setValueType(new QString("string")); + argValue->setValueString(new QString(v.toString())); + } +} + +void SoapySDRInput::webapiFormatArgInfo(const SoapySDR::ArgInfo& arg, SWGSDRangel::SWGArgInfo *argInfo) +{ + argInfo->setKey(new QString(arg.key.c_str())); + + if (arg.type == SoapySDR::ArgInfo::BOOL) { + argInfo->setValueType(new QString("bool")); + } else if (arg.type == SoapySDR::ArgInfo::INT) { + argInfo->setValueType(new QString("int")); + } else if (arg.type == SoapySDR::ArgInfo::FLOAT) { + argInfo->setValueType(new QString("float")); + } else { + argInfo->setValueType(new QString("string")); + } + + argInfo->setValueString(new QString(arg.value.c_str())); + argInfo->setName(new QString(arg.name.c_str())); + argInfo->setDescription(new QString(arg.description.c_str())); + argInfo->setUnits(new QString(arg.units.c_str())); + + if ((arg.range.minimum() != 0.0) || (arg.range.maximum() != 0.0)) + { + argInfo->setRange(new SWGSDRangel::SWGRangeFloat()); + argInfo->getRange()->setMin(arg.range.minimum()); + argInfo->getRange()->setMax(arg.range.maximum()); + } + + argInfo->setValueOptions(new QList); + + for (const auto itOpt : arg.options) { + argInfo->getValueOptions()->append(new QString(itOpt.c_str())); + } + + argInfo->setOptionNames(new QList); + + for (const auto itOpt : arg.optionNames) { + argInfo->getOptionNames()->append(new QString(itOpt.c_str())); + } +} diff --git a/plugins/samplesource/soapysdrinput/soapysdrinput.h b/plugins/samplesource/soapysdrinput/soapysdrinput.h index d18c5194e..d0cfb2739 100644 --- a/plugins/samplesource/soapysdrinput/soapysdrinput.h +++ b/plugins/samplesource/soapysdrinput/soapysdrinput.h @@ -33,6 +33,13 @@ class FileRecord; namespace SoapySDR { class Device; + class ArgInfo; +} + +namespace SWGSDRangel +{ + class SWGArgValue; + class SWGArgInfo; } class SoapySDRInput : public DeviceSampleSource @@ -155,12 +162,40 @@ public: int getAntennaIndex(const std::string& antenna); const std::vector& getTunableElements(); const std::vector& getIndividualGainsRanges(); + const SoapySDR::ArgInfoList& getStreamArgInfoList(); + const SoapySDR::ArgInfoList& getDeviceArgInfoList(); void initGainSettings(SoapySDRInputSettings& settings); + void initTunableElementsSettings(SoapySDRInputSettings& settings); + void initStreamArgSettings(SoapySDRInputSettings& settings); + void initDeviceArgSettings(SoapySDRInputSettings& settings); bool hasDCAutoCorrection(); bool hasDCCorrectionValue(); bool hasIQAutoCorrection() { return false; } // not in SoapySDR interface bool hasIQCorrectionValue(); + virtual int webapiSettingsGet( + SWGSDRangel::SWGDeviceSettings& response, + QString& errorMessage); + + virtual int webapiSettingsPutPatch( + bool force, + const QStringList& deviceSettingsKeys, + SWGSDRangel::SWGDeviceSettings& response, // query + response + QString& errorMessage); + + virtual int webapiReportGet( + SWGSDRangel::SWGDeviceReport& response, + QString& errorMessage); + + virtual int webapiRunGet( + SWGSDRangel::SWGDeviceState& response, + QString& errorMessage); + + virtual int webapiRun( + bool run, + SWGSDRangel::SWGDeviceState& response, + QString& errorMessage); + private: DeviceSourceAPI *m_deviceAPI; QMutex m_mutex; @@ -178,6 +213,12 @@ private: bool applySettings(const SoapySDRInputSettings& settings, bool force = false); bool setDeviceCenterFrequency(SoapySDR::Device *dev, int requestedChannel, quint64 freq_hz, int loPpmTenths); void updateGains(SoapySDR::Device *dev, int requestedChannel, SoapySDRInputSettings& settings); + void updateTunableElements(SoapySDR::Device *dev, int requestedChannel, SoapySDRInputSettings& settings); + void webapiFormatDeviceSettings(SWGSDRangel::SWGDeviceSettings& response, const SoapySDRInputSettings& settings); + void webapiFormatDeviceReport(SWGSDRangel::SWGDeviceReport& response); + QVariant webapiVariantFromArgValue(SWGSDRangel::SWGArgValue *argValue); + void webapiFormatArgValue(const QVariant& v, SWGSDRangel::SWGArgValue *argValue); + void webapiFormatArgInfo(const SoapySDR::ArgInfo& arg, SWGSDRangel::SWGArgInfo *argInfo); }; diff --git a/plugins/samplesource/soapysdrinput/soapysdrinput.pro b/plugins/samplesource/soapysdrinput/soapysdrinput.pro new file mode 100644 index 000000000..f16575928 --- /dev/null +++ b/plugins/samplesource/soapysdrinput/soapysdrinput.pro @@ -0,0 +1,43 @@ +#------------------------------------------------- +# +# Pro file for Windows MSVC builds with Qt Creator +# +#------------------------------------------------- + +TEMPLATE = lib +CONFIG += plugin + +QT += core gui multimedia opengl + +TARGET = inputsoapysdr + +INCLUDEPATH += $$PWD +INCLUDEPATH += ../../../exports +INCLUDEPATH += ../../../sdrbase +INCLUDEPATH += ../../../sdrgui +INCLUDEPATH += ../../../devices +INCLUDEPATH += ../../../swagger/sdrangel/code/qt5/client +INCLUDEPATH += "C:\Program Files\PothosSDR\include" + +CONFIG(Release):build_subdir = release +CONFIG(Debug):build_subdir = debug + +SOURCES += soapysdrinput.cpp\ + soapysdrinputgui.cpp\ + soapysdrinputplugin.cpp\ + soapysdrinputsettings.cpp\ + soapysdrinputthread.cpp + +HEADERS += soapysdrinput.h\ + soapysdrinputgui.h\ + soapysdrinputplugin.h\ + soapysdrinputsettings.h\ + soapysdrinputthread.h + +FORMS += soapysdrinputgui.ui + +LIBS += -L../../../sdrbase/$${build_subdir} -lsdrbase +LIBS += -L../../../sdrgui/$${build_subdir} -lsdrgui +LIBS += -L../../../swagger/$${build_subdir} -lswagger +LIBS += -L../../../devices/$${build_subdir} -ldevices +LIBS += -L"C:\Program Files\PothosSDR\bin" -L"C:\Program Files\PothosSDR\lib" -lSoapySDR diff --git a/plugins/samplesource/soapysdrinput/soapysdrinputgui.cpp b/plugins/samplesource/soapysdrinput/soapysdrinputgui.cpp index b8c387d76..baac02b5a 100644 --- a/plugins/samplesource/soapysdrinput/soapysdrinputgui.cpp +++ b/plugins/samplesource/soapysdrinput/soapysdrinputgui.cpp @@ -29,6 +29,8 @@ #include "soapygui/dynamicitemsettinggui.h" #include "soapygui/intervalslidergui.h" #include "soapygui/complexfactorgui.h" +#include "soapygui/arginfogui.h" +#include "soapygui/dynamicargsettinggui.h" #include "ui_soapysdrinputgui.h" #include "soapysdrinputgui.h" @@ -68,7 +70,12 @@ SoapySDRInputGui::SoapySDRInputGui(DeviceUISet *deviceUISet, QWidget* parent) : createTunableElementsControl(m_sampleSource->getTunableElements()); createGlobalGainControl(); createIndividualGainsControl(m_sampleSource->getIndividualGainsRanges()); + createArgumentsControl(m_sampleSource->getDeviceArgInfoList(), true); + createArgumentsControl(m_sampleSource->getStreamArgInfoList(), false); m_sampleSource->initGainSettings(m_settings); + m_sampleSource->initTunableElementsSettings(m_settings); + m_sampleSource->initStreamArgSettings(m_settings); + m_sampleSource->initDeviceArgSettings(m_settings); if (m_sampleRateGUI) { connect(m_sampleRateGUI, SIGNAL(valueChanged(double)), this, SLOT(sampleRateChanged(double))); @@ -219,6 +226,7 @@ void SoapySDRInputGui::createGlobalGainControl() { m_autoGain = new QCheckBox(this); m_autoGain->setText(QString("AGC")); + m_autoGain->setStyleSheet("QCheckBox::indicator::unchecked {background: rgb(79,79,79);} QCheckBox::indicator::checked {background: rgb(255, 157, 38);}"); layout->addWidget(m_autoGain); connect(m_autoGain, SIGNAL(toggled(bool)), this, SLOT(autoGainChanged(bool))); @@ -275,6 +283,7 @@ void SoapySDRInputGui::createCorrectionsControl() m_autoDCCorrection = new QCheckBox(this); m_autoDCCorrection->setText(QString("Auto DC corr")); m_autoDCCorrection->setToolTip(QString("Automatic hardware DC offset correction")); + m_autoDCCorrection->setStyleSheet("QCheckBox::indicator::unchecked {background: rgb(79,79,79);} QCheckBox::indicator::checked {background: rgb(255, 157, 38);}"); layout->addWidget(m_autoDCCorrection); connect(m_autoDCCorrection, SIGNAL(toggled(bool)), this, SLOT(autoDCCorrectionChanged(bool))); @@ -300,12 +309,106 @@ void SoapySDRInputGui::createCorrectionsControl() m_autoIQCorrection = new QCheckBox(this); m_autoIQCorrection->setText(QString("Auto IQ corr")); m_autoIQCorrection->setToolTip(QString("Automatic hardware IQ imbalance correction")); + m_autoIQCorrection->setStyleSheet("QCheckBox::indicator::unchecked {background: rgb(79,79,79);} QCheckBox::indicator::checked {background: rgb(255, 157, 38);}"); layout->addWidget(m_autoIQCorrection); connect(m_autoIQCorrection, SIGNAL(toggled(bool)), this, SLOT(autoIQCorrectionChanged(bool))); } } +void SoapySDRInputGui::createArgumentsControl(const SoapySDR::ArgInfoList& argInfoList, bool deviceArguments) +{ + if (argInfoList.size() == 0) { // return early if list is empty + return; + } + + QVBoxLayout *layout = (QVBoxLayout *) ui->scrollAreaWidgetContents->layout(); + + QFrame *line = new QFrame(this); + line->setFrameShape(QFrame::HLine); + line->setFrameShadow(QFrame::Sunken); + layout->addWidget(line); + + std::vector::const_iterator it = argInfoList.begin(); + + for (; it != argInfoList.end(); ++it) + { + ArgInfoGUI::ArgInfoValueType valueType; + ArgInfoGUI *argGUI; + + if (it->type == SoapySDR::ArgInfo::BOOL) { + valueType = ArgInfoGUI::ArgInfoValueBool; + } else if (it->type == SoapySDR::ArgInfo::INT) { + valueType = ArgInfoGUI::ArgInfoValueInt; + } else if (it->type == SoapySDR::ArgInfo::FLOAT) { + valueType = ArgInfoGUI::ArgInfoValueFloat; + } else if (it->type == SoapySDR::ArgInfo::STRING) { + valueType = ArgInfoGUI::ArgInfoValueString; + } else { + continue; + } + + if (valueType == ArgInfoGUI::ArgInfoValueBool) + { + argGUI = new ArgInfoGUI(ArgInfoGUI::ArgInfoBinary, ArgInfoGUI::ArgInfoValueBool, this); + } + else if (it->options.size() == 0) + { + argGUI = new ArgInfoGUI(ArgInfoGUI::ArgInfoContinuous, valueType, this); + } + else + { + argGUI = new ArgInfoGUI(ArgInfoGUI::ArgInfoDiscrete, valueType, this); + std::vector::const_iterator optionIt = it->options.begin(); + std::vector::const_iterator optionNameIt = it->optionNames.begin(); + + for (int i = 0; optionIt != it->options.end(); ++optionIt, i++) + { + QString name(optionNameIt == it->optionNames.end() ? optionIt->c_str() : optionNameIt->c_str()); + + if (optionNameIt != it->optionNames.end()) { + ++optionNameIt; + } + + if (valueType == ArgInfoGUI::ArgInfoValueInt) { + argGUI->addIntValue(name, atoi(optionIt->c_str())); + } else if (valueType == ArgInfoGUI::ArgInfoValueFloat) { + argGUI->addFloatValue(name, atof(optionIt->c_str())); + } else if (valueType == ArgInfoGUI::ArgInfoValueString) { + argGUI->addStringValue(name, QString(optionIt->c_str())); + } + } + } + + if ((it->range.minimum() != 0) || (it->range.maximum() != 0)) { + argGUI->setRange(it->range.minimum(), it->range.maximum()); + } + + argGUI->setLabel(QString(it->name.size() == 0 ? it->key.c_str() : it->name.c_str())); + argGUI->setUnits(QString(it->units.c_str())); + + if (it->description.size() != 0) { + argGUI->setToolTip(QString(it->description.c_str())); + } + + layout->addWidget(argGUI); + + DynamicArgSettingGUI *gui = new DynamicArgSettingGUI(argGUI, QString(it->key.c_str())); + + // This could be made more elegant but let's make it more simple + if (deviceArguments) + { + m_deviceArgsGUIs.push_back(gui); + connect(gui, SIGNAL(valueChanged(QString, QVariant)), this, SLOT(deviceArgChanged(QString, QVariant))); + } + else + { + m_streamArgsGUIs.push_back(gui); + connect(gui, SIGNAL(valueChanged(QString, QVariant)), this, SLOT(streamArgChanged(QString, QVariant))); + } + } +} + void SoapySDRInputGui::setName(const QString& name) { setObjectName(name); @@ -342,12 +445,15 @@ QByteArray SoapySDRInputGui::serialize() const bool SoapySDRInputGui::deserialize(const QByteArray& data) { - if(m_settings.deserialize(data)) { + if (m_settings.deserialize(data)) + { displaySettings(); m_forceSettings = true; sendSettings(); return true; - } else { + } + else + { resetToDefaults(); return false; } @@ -383,6 +489,14 @@ bool SoapySDRInputGui::handleMessage(const Message& message) return true; } + else if (DeviceSoapySDRShared::MsgReportDeviceArgsChange::match(message)) + { + DeviceSoapySDRShared::MsgReportDeviceArgsChange& notif = (DeviceSoapySDRShared::MsgReportDeviceArgsChange&) message; + m_settings.m_deviceArgSettings = notif.getDeviceArgSettings(); + displayDeviceArgsSettings(); + + return true; + } else if (SoapySDRInput::MsgStartStop::match(message)) { SoapySDRInput::MsgStartStop& notif = (SoapySDRInput::MsgStartStop&) message; @@ -436,13 +550,13 @@ void SoapySDRInputGui::antennasChanged() void SoapySDRInputGui::sampleRateChanged(double sampleRate) { - m_settings.m_devSampleRate = sampleRate; + m_settings.m_devSampleRate = round(sampleRate); sendSettings(); } void SoapySDRInputGui::bandwidthChanged(double bandwidth) { - m_settings.m_bandwidth = bandwidth; + m_settings.m_bandwidth = round(bandwidth); sendSettings(); } @@ -484,7 +598,7 @@ void SoapySDRInputGui::autoIQCorrectionChanged(bool set) void SoapySDRInputGui::dcCorrectionModuleChanged(double value) { - std::complex dcCorrection = std::polar(value, arg(m_settings.m_dcCorrection)); + std::complex dcCorrection = std::polar(value, arg(m_settings.m_dcCorrection)); m_settings.m_dcCorrection = dcCorrection; sendSettings(); } @@ -492,14 +606,14 @@ void SoapySDRInputGui::dcCorrectionModuleChanged(double value) void SoapySDRInputGui::dcCorrectionArgumentChanged(double value) { double angleInRadians = (value / 180.0) * M_PI; - std::complex dcCorrection = std::polar(abs(m_settings.m_dcCorrection), angleInRadians); + std::complex dcCorrection = std::polar(abs(m_settings.m_dcCorrection), angleInRadians); m_settings.m_dcCorrection = dcCorrection; sendSettings(); } void SoapySDRInputGui::iqCorrectionModuleChanged(double value) { - std::complex iqCorrection = std::polar(value, arg(m_settings.m_iqCorrection)); + std::complex iqCorrection = std::polar(value, arg(m_settings.m_iqCorrection)); m_settings.m_iqCorrection = iqCorrection; sendSettings(); } @@ -507,11 +621,23 @@ void SoapySDRInputGui::iqCorrectionModuleChanged(double value) void SoapySDRInputGui::iqCorrectionArgumentChanged(double value) { double angleInRadians = (value / 180.0) * M_PI; - std::complex iqCorrection = std::polar(abs(m_settings.m_iqCorrection), angleInRadians); + std::complex iqCorrection = std::polar(abs(m_settings.m_iqCorrection), angleInRadians); m_settings.m_iqCorrection = iqCorrection; sendSettings(); } +void SoapySDRInputGui::streamArgChanged(QString itemName, QVariant value) +{ + m_settings.m_streamArgSettings[itemName] = value; + sendSettings(); +} + +void SoapySDRInputGui::deviceArgChanged(QString itemName, QVariant value) +{ + m_settings.m_deviceArgSettings[itemName] = value; + sendSettings(); +} + void SoapySDRInputGui::on_centerFrequency_changed(quint64 value) { m_settings.m_centerFrequency = value * 1000; @@ -597,17 +723,22 @@ void SoapySDRInputGui::displaySettings() ui->centerFrequency->setValue(m_settings.m_centerFrequency / 1000); if (m_antennas) { - qDebug("SoapySDRInputGui::displaySettings: m_antenna: %s", m_settings.m_antenna.toStdString().c_str()); m_antennas->setValue(m_settings.m_antenna.toStdString()); } - if (m_sampleRateGUI) { + if (m_sampleRateGUI) + { m_sampleRateGUI->setValue(m_settings.m_devSampleRate); + m_settings.m_devSampleRate = m_sampleRateGUI->getCurrentValue(); } - if (m_bandwidthGUI) { + if (m_bandwidthGUI) + { m_bandwidthGUI->setValue(m_settings.m_bandwidth); + m_settings.m_bandwidth = m_bandwidthGUI->getCurrentValue(); } - if (m_gainSliderGUI) { + if (m_gainSliderGUI) + { m_gainSliderGUI->setValue(m_settings.m_globalGain); + m_settings.m_globalGain = m_gainSliderGUI->getCurrentValue(); } if (m_autoGain) { m_autoGain->setChecked(m_settings.m_autoGain); @@ -625,6 +756,8 @@ void SoapySDRInputGui::displaySettings() displayTunableElementsControlSettings(); displayIndividualGainsControlSettings(); displayCorrectionsSettings(); + displayStreamArgsSettings(); + displayDeviceArgsSettings(); blockApplySettings(false); } @@ -645,10 +778,12 @@ void SoapySDRInputGui::displayIndividualGainsControlSettings() { for (const auto &it : m_individualGainsGUIs) { - QMap::const_iterator elIt = m_settings.m_individualGains.find(it->getName()); + QMap::iterator elIt = m_settings.m_individualGains.find(it->getName()); - if (elIt != m_settings.m_individualGains.end()) { + if (elIt != m_settings.m_individualGains.end()) + { it->setValue(*elIt); + *elIt = it->getValue(); } } } @@ -678,6 +813,34 @@ void SoapySDRInputGui::displayCorrectionsSettings() } } +void SoapySDRInputGui::displayStreamArgsSettings() +{ + for (const auto &it : m_streamArgsGUIs) + { + QMap::iterator elIt = m_settings.m_streamArgSettings.find(it->getName()); + + if (elIt != m_settings.m_streamArgSettings.end()) + { + it->setValue(elIt.value()); + *elIt = it->getValue(); + } + } +} + +void SoapySDRInputGui::displayDeviceArgsSettings() +{ + for (const auto &it : m_deviceArgsGUIs) + { + QMap::iterator elIt = m_settings.m_deviceArgSettings.find(it->getName()); + + if (elIt != m_settings.m_deviceArgSettings.end()) + { + it->setValue(elIt.value()); + *elIt = it->getValue(); + } + } +} + void SoapySDRInputGui::sendSettings() { if (!m_updateTimer.isActive()) { diff --git a/plugins/samplesource/soapysdrinput/soapysdrinputgui.h b/plugins/samplesource/soapysdrinput/soapysdrinputgui.h index 7f65de91a..e71340818 100644 --- a/plugins/samplesource/soapysdrinput/soapysdrinputgui.h +++ b/plugins/samplesource/soapysdrinput/soapysdrinputgui.h @@ -29,6 +29,7 @@ class DeviceUISet; class ItemSettingGUI; class StringRangeGUI; class DynamicItemSettingGUI; +class DynamicArgSettingGUI; class IntervalSliderGUI; class QCheckBox; class ComplexFactorGUI; @@ -67,6 +68,7 @@ private: void createGlobalGainControl(); void createIndividualGainsControl(const std::vector& individualGainsList); void createCorrectionsControl(); + void createArgumentsControl(const SoapySDR::ArgInfoList& argInfoList, bool deviceArguments); Ui::SoapySDRInputGui* ui; @@ -93,11 +95,15 @@ private: ComplexFactorGUI *m_iqCorrectionGUI; QCheckBox *m_autoDCCorrection; QCheckBox *m_autoIQCorrection; + std::vector m_streamArgsGUIs; + std::vector m_deviceArgsGUIs; void displaySettings(); void displayTunableElementsControlSettings(); void displayIndividualGainsControlSettings(); void displayCorrectionsSettings(); + void displayStreamArgsSettings(); + void displayDeviceArgsSettings(); void sendSettings(); void updateSampleRateAndFrequency(); void updateFrequencyLimits(); @@ -119,6 +125,8 @@ private slots: void dcCorrectionArgumentChanged(double value); void iqCorrectionModuleChanged(double value); void iqCorrectionArgumentChanged(double value); + void streamArgChanged(QString itemName, QVariant value); + void deviceArgChanged(QString itemName, QVariant value); void on_centerFrequency_changed(quint64 value); void on_LOppm_valueChanged(int value); diff --git a/plugins/samplesource/soapysdrinput/soapysdrinputplugin.cpp b/plugins/samplesource/soapysdrinput/soapysdrinputplugin.cpp index f0e6ed867..d103760d2 100644 --- a/plugins/samplesource/soapysdrinput/soapysdrinputplugin.cpp +++ b/plugins/samplesource/soapysdrinput/soapysdrinputplugin.cpp @@ -30,7 +30,7 @@ const PluginDescriptor SoapySDRInputPlugin::m_pluginDescriptor = { QString("SoapySDR Input"), - QString("4.3.0"), + QString("4.3.1"), QString("(c) Edouard Griffiths, F4EXB"), QString("https://github.com/f4exb/sdrangel"), true, diff --git a/plugins/samplesource/soapysdrinput/soapysdrinputsettings.cpp b/plugins/samplesource/soapysdrinput/soapysdrinputsettings.cpp index 7cceae2c4..72500dfec 100644 --- a/plugins/samplesource/soapysdrinput/soapysdrinputsettings.cpp +++ b/plugins/samplesource/soapysdrinput/soapysdrinputsettings.cpp @@ -71,6 +71,8 @@ QByteArray SoapySDRInputSettings::serialize() const s.writeDouble(18, m_dcCorrection.imag()); s.writeDouble(19, m_iqCorrection.real()); s.writeDouble(20, m_iqCorrection.imag()); + s.writeBlob(21, serializeArgumentMap(m_streamArgSettings)); + s.writeBlob(22, serializeArgumentMap(m_deviceArgSettings)); return s.final(); } @@ -116,6 +118,10 @@ bool SoapySDRInputSettings::deserialize(const QByteArray& data) d.readDouble(19, &realval, 0); d.readDouble(20, &imagval, 0); m_iqCorrection = std::complex{realval, imagval}; + d.readBlob(21, &blob); + deserializeArgumentMap(blob, m_streamArgSettings); + d.readBlob(22, &blob); + deserializeArgumentMap(blob, m_deviceArgSettings); return true; } @@ -142,3 +148,21 @@ void SoapySDRInputSettings::deserializeNamedElementMap(const QByteArray& data, Q (*stream) >> map; delete stream; } + +QByteArray SoapySDRInputSettings::serializeArgumentMap(const QMap& map) const +{ + QByteArray data; + QDataStream *stream = new QDataStream(&data, QIODevice::WriteOnly); + (*stream) << map; + delete stream; + + return data; +} + +void SoapySDRInputSettings::deserializeArgumentMap(const QByteArray& data, QMap& map) +{ + QDataStream *stream = new QDataStream(data); + (*stream) >> map; + delete stream; +} + diff --git a/plugins/samplesource/soapysdrinput/soapysdrinputsettings.h b/plugins/samplesource/soapysdrinput/soapysdrinputsettings.h index 4bbb2db47..82bf66f25 100644 --- a/plugins/samplesource/soapysdrinput/soapysdrinputsettings.h +++ b/plugins/samplesource/soapysdrinput/soapysdrinputsettings.h @@ -19,6 +19,7 @@ #include #include +#include #include struct SoapySDRInputSettings { @@ -48,6 +49,8 @@ struct SoapySDRInputSettings { bool m_autoIQCorrection; std::complex m_dcCorrection; std::complex m_iqCorrection; + QMap m_streamArgSettings; + QMap m_deviceArgSettings; SoapySDRInputSettings(); void resetToDefaults(); @@ -57,6 +60,8 @@ struct SoapySDRInputSettings { private: QByteArray serializeNamedElementMap(const QMap& map) const; void deserializeNamedElementMap(const QByteArray& data, QMap& map); + QByteArray serializeArgumentMap(const QMap& map) const; + void deserializeArgumentMap(const QByteArray& data, QMap& map); }; #endif /* PLUGINS_SAMPLESOURCE_SOAPYSDRINPUT_SOAPYSDRINPUTSETTINGS_H_ */ diff --git a/plugins/samplesource/soapysdrinput/soapysdrinputthread.cpp b/plugins/samplesource/soapysdrinput/soapysdrinputthread.cpp index dd969a8f6..e01164aaf 100644 --- a/plugins/samplesource/soapysdrinput/soapysdrinputthread.cpp +++ b/plugins/samplesource/soapysdrinput/soapysdrinputthread.cpp @@ -129,9 +129,11 @@ void SoapySDRInputThread::run() int flags(0); long long timeNs(0); float blockTime = ((float) numElems) / (m_sampleRate <= 0 ? 1024000 : m_sampleRate); - long timeoutUs = 2000000 * blockTime; // 10 times the block time + long initialTtimeoutUs = 10000000 * blockTime; // 10 times the block time + long timeoutUs = initialTtimeoutUs < 250000 ? 250000 : initialTtimeoutUs; // 250ms minimum - qDebug("SoapySDRInputThread::run: numElems: %u elemSize: %u timeoutUs: %ld", numElems, elemSize, timeoutUs); + qDebug("SoapySDRInputThread::run: numElems: %u elemSize: %u initialTtimeoutUs: %ld timeoutUs: %ld", + numElems, elemSize, initialTtimeoutUs, timeoutUs); qDebug("SoapySDRInputThread::run: start running loop"); while (m_running) @@ -142,6 +144,10 @@ void SoapySDRInputThread::run() { qWarning("SoapySDRInputThread::run: timeout: flags: %d timeNs: %lld timeoutUs: %ld", flags, timeNs, timeoutUs); } + else if (ret == SOAPY_SDR_OVERFLOW) + { + qWarning("SoapySDRInputThread::run: overflow: flags: %d timeNs: %lld timeoutUs: %ld", flags, timeNs, timeoutUs); + } else if (ret < 0) { qCritical("SoapySDRInputThread::run: Unexpected read stream error: %s", SoapySDR::errToStr(ret)); diff --git a/plugins/samplesource/testsource/testsourcegui.cpp b/plugins/samplesource/testsource/testsourcegui.cpp index e91b49dec..ccffc6a25 100644 --- a/plugins/samplesource/testsource/testsourcegui.cpp +++ b/plugins/samplesource/testsource/testsourcegui.cpp @@ -198,16 +198,18 @@ void TestSourceGui::on_sampleSize_currentIndexChanged(int index) sendSettings(); } -void TestSourceGui::on_amplitudeCoarse_valueChanged(int value __attribute__((unused))) +void TestSourceGui::on_amplitudeCoarse_valueChanged(int value) { + (void) value; updateAmpFineLimit(); displayAmplitude(); m_settings.m_amplitudeBits = ui->amplitudeCoarse->value() * 100 + ui->amplitudeFine->value(); sendSettings(); } -void TestSourceGui::on_amplitudeFine_valueChanged(int value __attribute__((unused))) +void TestSourceGui::on_amplitudeFine_valueChanged(int value) { + (void) value; displayAmplitude(); m_settings.m_amplitudeBits = ui->amplitudeCoarse->value() * 100 + ui->amplitudeFine->value(); sendSettings(); diff --git a/plugins/samplesource/testsource/testsourceinput.cpp b/plugins/samplesource/testsource/testsourceinput.cpp index 3d230b2d6..776a1c540 100644 --- a/plugins/samplesource/testsource/testsourceinput.cpp +++ b/plugins/samplesource/testsource/testsourceinput.cpp @@ -388,8 +388,9 @@ bool TestSourceInput::applySettings(const TestSourceSettings& settings, bool for int TestSourceInput::webapiRunGet( SWGSDRangel::SWGDeviceState& response, - QString& errorMessage __attribute__((unused))) + QString& errorMessage) { + (void) errorMessage; m_deviceAPI->getDeviceEngineStateStr(*response.getState()); return 200; } @@ -397,8 +398,9 @@ int TestSourceInput::webapiRunGet( int TestSourceInput::webapiRun( bool run, SWGSDRangel::SWGDeviceState& response, - QString& errorMessage __attribute__((unused))) + QString& errorMessage) { + (void) errorMessage; m_deviceAPI->getDeviceEngineStateStr(*response.getState()); MsgStartStop *message = MsgStartStop::create(run); m_inputMessageQueue.push(message); @@ -414,8 +416,9 @@ int TestSourceInput::webapiRun( int TestSourceInput::webapiSettingsGet( SWGSDRangel::SWGDeviceSettings& response, - QString& errorMessage __attribute__((unused))) + QString& errorMessage) { + (void) errorMessage; response.setTestSourceSettings(new SWGSDRangel::SWGTestSourceSettings()); response.getTestSourceSettings()->init(); webapiFormatDeviceSettings(response, m_settings); @@ -426,8 +429,9 @@ int TestSourceInput::webapiSettingsPutPatch( bool force, const QStringList& deviceSettingsKeys, SWGSDRangel::SWGDeviceSettings& response, // query + response - QString& errorMessage __attribute__((unused))) + QString& errorMessage) { + (void) errorMessage; TestSourceSettings settings = m_settings; if (deviceSettingsKeys.contains("centerFrequency")) { diff --git a/plugins/samplesource/testsource/testsourcethread.cpp b/plugins/samplesource/testsource/testsourcethread.cpp index 0e972b776..7aa56531c 100644 --- a/plugins/samplesource/testsource/testsourcethread.cpp +++ b/plugins/samplesource/testsource/testsourcethread.cpp @@ -14,6 +14,8 @@ // along with this program. If not, see . // /////////////////////////////////////////////////////////////////////////////////// +#define _USE_MATH_DEFINES +#include #include #include #include "testsourcethread.h" diff --git a/pluginssrv/samplesink/CMakeLists.txt b/pluginssrv/samplesink/CMakeLists.txt index ec27eee6c..3fa769ebc 100644 --- a/pluginssrv/samplesink/CMakeLists.txt +++ b/pluginssrv/samplesink/CMakeLists.txt @@ -28,6 +28,11 @@ if(CM256CC_FOUND) add_subdirectory(sdrdaemonsink) endif(CM256CC_FOUND) +find_package(SoapySDR) +if(LIBUSB_FOUND AND SOAPYSDR_FOUND) + add_subdirectory(soapysdroutput) +endif() + if (BUILD_DEBIAN) add_subdirectory(bladerf1output) add_subdirectory(bladerf2output) diff --git a/pluginssrv/samplesink/soapysdroutput/CMakeLists.txt b/pluginssrv/samplesink/soapysdroutput/CMakeLists.txt new file mode 100644 index 000000000..b84de7a4a --- /dev/null +++ b/pluginssrv/samplesink/soapysdroutput/CMakeLists.txt @@ -0,0 +1,68 @@ +project(soapysdroutput) + +set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++11") +set(PLUGIN_PREFIX "../../../plugins/samplesink/soapysdroutput") + +set(soapysdroutput_SOURCES + ${PLUGIN_PREFIX}/soapysdroutput.cpp + ${PLUGIN_PREFIX}/soapysdroutputplugin.cpp + ${PLUGIN_PREFIX}/soapysdroutputsettings.cpp + ${PLUGIN_PREFIX}/soapysdroutputthread.cpp +) + +set(soapysdroutput_HEADERS + ${PLUGIN_PREFIX}/soapysdroutput.h + ${PLUGIN_PREFIX}/soapysdroutputplugin.h + ${PLUGIN_PREFIX}/soapysdroutputsettings.h + ${PLUGIN_PREFIX}/soapysdroutputthread.h +) + +if (BUILD_DEBIAN) +include_directories( + . + ${CMAKE_CURRENT_BINARY_DIR} + ${CMAKE_SOURCE_DIR}/swagger/sdrangel/code/qt5/client + ${CMAKE_SOURCE_DIR}/devices + ${SOAPYSDR_SOURCE_DIR}/include + ${SOAPYSDR_SOURCE_DIR}/src +) +else (BUILD_DEBIAN) +include_directories( + . + ${CMAKE_CURRENT_BINARY_DIR} + ${CMAKE_SOURCE_DIR}/swagger/sdrangel/code/qt5/client + ${CMAKE_SOURCE_DIR}/devices + ${SOAPYSDR_INCLUDE_DIR} +) +endif (BUILD_DEBIAN) + +add_definitions(${QT_DEFINITIONS}) +add_definitions(-DQT_PLUGIN) +add_definitions(-DQT_SHARED) + +add_library(outputsoapysdrsrv SHARED + ${soapysdroutput_SOURCES} + ${soapysdroutput_HEADERS_MOC} +) + +if (BUILD_DEBIAN) +target_link_libraries(outputsoapysdrsrv + ${QT_LIBRARIES} + soapysdr + sdrbase + swagger + soapysdrdevice +) +else (BUILD_DEBIAN) +target_link_libraries(outputsoapysdrsrv + ${QT_LIBRARIES} + ${SOAPYSDR_LIBRARY} + sdrbase + swagger + soapysdrdevice +) +endif (BUILD_DEBIAN) + +target_link_libraries(outputsoapysdrsrv Qt5::Core) + +install(TARGETS outputsoapysdrsrv DESTINATION lib/plugins/samplesink) diff --git a/pluginssrv/samplesource/CMakeLists.txt b/pluginssrv/samplesource/CMakeLists.txt index 8e23ea759..5bcb15917 100644 --- a/pluginssrv/samplesource/CMakeLists.txt +++ b/pluginssrv/samplesource/CMakeLists.txt @@ -77,6 +77,14 @@ else(LIBUSB_FOUND AND LIBMIRISDR_FOUND) message(STATUS "LibMiriSDR NOT found") endif(LIBUSB_FOUND AND LIBMIRISDR_FOUND) +find_package(SoapySDR) +if(LIBUSB_FOUND AND SOAPYSDR_FOUND) + add_subdirectory(soapysdrinput) + message(STATUS "SoapySDR found") +else() + message(STATUS "SoapySDR not found") +endif() + if (BUILD_DEBIAN) add_subdirectory(airspy) add_subdirectory(airspyhf) diff --git a/pluginssrv/samplesource/soapysdrinput/CMakeLists.txt b/pluginssrv/samplesource/soapysdrinput/CMakeLists.txt new file mode 100644 index 000000000..ceccc4ff2 --- /dev/null +++ b/pluginssrv/samplesource/soapysdrinput/CMakeLists.txt @@ -0,0 +1,68 @@ +project(soapysdrinput) + +set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++11") +set(PLUGIN_PREFIX "../../../plugins/samplesource/soapysdrinput") + +set(soapysdrinput_SOURCES + ${PLUGIN_PREFIX}/soapysdrinput.cpp + ${PLUGIN_PREFIX}/soapysdrinputplugin.cpp + ${PLUGIN_PREFIX}/soapysdrinputsettings.cpp + ${PLUGIN_PREFIX}/soapysdrinputthread.cpp +) + +set(soapysdrinput_HEADERS + ${PLUGIN_PREFIX}/soapysdrinput.h + ${PLUGIN_PREFIX}/soapysdrinputplugin.h + ${PLUGIN_PREFIX}/soapysdrinputsettings.h + ${PLUGIN_PREFIX}/soapysdrinputthread.h +) + +if (BUILD_DEBIAN) +include_directories( + . + ${CMAKE_CURRENT_BINARY_DIR} + ${CMAKE_SOURCE_DIR}/swagger/sdrangel/code/qt5/client + ${CMAKE_SOURCE_DIR}/devices + ${SOAPYSDR_SOURCE_DIR}/include + ${SOAPYSDR_SOURCE_DIR}/src +) +else (BUILD_DEBIAN) +include_directories( + . + ${CMAKE_CURRENT_BINARY_DIR} + ${CMAKE_SOURCE_DIR}/swagger/sdrangel/code/qt5/client + ${CMAKE_SOURCE_DIR}/devices + ${SOAPYSDR_INCLUDE_DIR} +) +endif (BUILD_DEBIAN) + +add_definitions(${QT_DEFINITIONS}) +add_definitions(-DQT_PLUGIN) +add_definitions(-DQT_SHARED) + +add_library(inputsoapysdrsrv SHARED + ${soapysdrinput_SOURCES} + ${soapysdrinput_HEADERS_MOC} +) + +if (BUILD_DEBIAN) +target_link_libraries(inputsoapysdrsrv + ${QT_LIBRARIES} + soapysdr + sdrbase + swagger + soapysdrdevice +) +else (BUILD_DEBIAN) +target_link_libraries(inputsoapysdrsrv + ${QT_LIBRARIES} + ${SOAPYSDR_LIBRARY} + sdrbase + swagger + soapysdrdevice +) +endif (BUILD_DEBIAN) + +target_link_libraries(inputsoapysdrsrv Qt5::Core) + +install(TARGETS inputsoapysdrsrv DESTINATION lib/plugins/samplesource) diff --git a/qrtplib/CMakeLists.txt b/qrtplib/CMakeLists.txt index 784e7f504..ef57c69c2 100644 --- a/qrtplib/CMakeLists.txt +++ b/qrtplib/CMakeLists.txt @@ -1,5 +1,7 @@ project(qrtplib) +set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++11") + set (qrtplib_HEADERS rtcpapppacket.h rtcpbyepacket.h diff --git a/qrtplib/rtcpcompoundpacketbuilder.h b/qrtplib/rtcpcompoundpacketbuilder.h index 7daff9dc1..f105f9959 100644 --- a/qrtplib/rtcpcompoundpacketbuilder.h +++ b/qrtplib/rtcpcompoundpacketbuilder.h @@ -38,13 +38,15 @@ #define RTCPCOMPOUNDPACKETBUILDER_H +#include +#include + #include "rtpconfig.h" #include "rtcpcompoundpacket.h" #include "rtptimeutilities.h" #include "rtcpsdespacket.h" #include "rtperrors.h" #include "rtpendian.h" -#include #include "export.h" @@ -151,6 +153,7 @@ private: Report() { headerdata = (uint8_t *) headerdata32; + std::fill(&headerdata32[0], &headerdata32[0] + ((sizeof(uint32_t) + sizeof(RTCPSenderReport)) / sizeof(uint32_t)), 0U); isSR = false; headerlength = 0; } diff --git a/qrtplib/rtpconfig.h b/qrtplib/rtpconfig.h index faf4e6e2f..c69114266 100644 --- a/qrtplib/rtpconfig.h +++ b/qrtplib/rtpconfig.h @@ -84,7 +84,11 @@ // No SRTP support +#ifdef _MSC_VER +#define RTP_HAVE_QUERYPERFORMANCECOUNTER +#else #define RTP_HAVE_CLOCK_GETTIME +#endif #define RTP_HAVE_POLL diff --git a/qrtplib/rtperrors.h b/qrtplib/rtperrors.h index ec12c7955..fba59d681 100644 --- a/qrtplib/rtperrors.h +++ b/qrtplib/rtperrors.h @@ -38,6 +38,7 @@ #define RTPERRORS_H +#include "export.h" #include "rtpconfig.h" #include @@ -45,7 +46,7 @@ namespace qrtplib { /** Returns a string describing the error code \c errcode. */ -std::string RTPGetErrorString(int errcode); +QRTPLIB_API std::string RTPGetErrorString(int errcode); } // end namespace diff --git a/qrtplib/rtprandom.cpp b/qrtplib/rtprandom.cpp index 5fbb5562f..e5764714c 100644 --- a/qrtplib/rtprandom.cpp +++ b/qrtplib/rtprandom.cpp @@ -40,7 +40,11 @@ #include "rtprandomrand48.h" #include +#ifdef _MSC_VER +#include "Windows.h" +#else #include +#endif #include @@ -50,7 +54,11 @@ namespace qrtplib uint32_t RTPRandom::PickSeed() { uint32_t x; +#ifdef _MSC_VER + x = GetCurrentProcessId(); +#else x = (uint32_t) getpid(); +#endif QDateTime currentDateTime = QDateTime::currentDateTime(); x += currentDateTime.toTime_t(); #if defined(WIN32) diff --git a/qrtplib/rtpsession.cpp b/qrtplib/rtpsession.cpp index a9d42a8d2..1740409d0 100644 --- a/qrtplib/rtpsession.cpp +++ b/qrtplib/rtpsession.cpp @@ -49,7 +49,6 @@ #endif // RTP_SUPPORT_SENDAPP #include "rtpinternalutils.h" -#include #include #include @@ -1143,8 +1142,9 @@ int RTPSession::ProcessPolledData() return 0; } -int RTPSession::CreateCNAME(uint8_t *buffer, std::size_t *bufferlength, bool resolve __attribute__((unused))) +int RTPSession::CreateCNAME(uint8_t *buffer, std::size_t *bufferlength, bool resolve) { + (void) resolve; buffer[*bufferlength - 1] = 0; std::size_t offset = strlen((const char *) buffer); diff --git a/qrtplib/rtpsessionparams.cpp b/qrtplib/rtpsessionparams.cpp index 40b611899..916c49852 100644 --- a/qrtplib/rtpsessionparams.cpp +++ b/qrtplib/rtpsessionparams.cpp @@ -67,13 +67,15 @@ RTPSessionParams::RTPSessionParams() : predefinedssrc = 0; } -int RTPSessionParams::SetUsePollThread(bool usethread __attribute__((unused))) +int RTPSessionParams::SetUsePollThread(bool usethread) { + (void) usethread; return ERR_RTP_NOTHREADSUPPORT; } -int RTPSessionParams::SetNeedThreadSafety(bool __attribute__((unused))) +int RTPSessionParams::SetNeedThreadSafety(bool x) { + (void) x; return ERR_RTP_NOTHREADSUPPORT; } diff --git a/qrtplib/rtptimeutilities.h b/qrtplib/rtptimeutilities.h index d474ff2fc..526141777 100644 --- a/qrtplib/rtptimeutilities.h +++ b/qrtplib/rtptimeutilities.h @@ -44,6 +44,8 @@ #include #include #include +#else +#include "Windows.h" #endif // RTP_HAVE_QUERYPERFORMANCECOUNTER #include "export.h" @@ -143,7 +145,7 @@ public: bool IsZero() const { - return m_t == 0; + return m_t == 0.0; } private: #ifdef RTP_HAVE_QUERYPERFORMANCECOUNTER diff --git a/sdrangel.windows.pro b/sdrangel.windows.pro index a27c13f78..a85891506 100644 --- a/sdrangel.windows.pro +++ b/sdrangel.windows.pro @@ -15,8 +15,8 @@ SUBDIRS += qrtplib SUBDIRS += swagger SUBDIRS += sdrbase SUBDIRS += sdrgui -SUBDIRS += fcdhid -SUBDIRS += fcdlib +CONFIG(!MSVC):SUBDIRS += fcdhid +CONFIG(!MSVC):SUBDIRS += fcdlib SUBDIRS += libairspy SUBDIRS += libairspyhf #SUBDIRS += libbladerf @@ -28,31 +28,34 @@ SUBDIRS += librtlsdr SUBDIRS += devices SUBDIRS += mbelib SUBDIRS += dsdcc -#SUBDIRS += cm256cc +CONFIG(MSVC):SUBDIRS += cm256cc SUBDIRS += plugins/samplesource/airspy SUBDIRS += plugins/samplesource/airspyhf -SUBDIRS += plugins/samplesource/bladerf1input -SUBDIRS += plugins/samplesource/bladerf2input +CONFIG(!MSVC):SUBDIRS += plugins/samplesource/bladerf1input +CONFIG(!MSVC):SUBDIRS += plugins/samplesource/bladerf2input SUBDIRS += plugins/samplesource/filesource SUBDIRS += plugins/samplesource/hackrfinput SUBDIRS += plugins/samplesource/limesdrinput CONFIG(!MSVC):SUBDIRS += plugins/samplesource/plutosdrinput -#SUBDIRS += plugins/samplesource/sdrdaemonsource +CONFIG(MSVC):SUBDIRS += plugins/samplesource/sdrdaemonsource SUBDIRS += plugins/samplesource/rtlsdr +CONFIG(MSVC):SUBDIRS += plugins/samplesource/soapysdrinput SUBDIRS += plugins/samplesource/testsource SUBDIRS += plugins/samplesink/filesink -SUBDIRS += plugins/samplesink/bladerf1output -SUBDIRS += plugins/samplesink/bladerf2output +CONFIG(!MSVC):SUBDIRS += plugins/samplesink/bladerf1output +CONFIG(!MSVC):SUBDIRS += plugins/samplesink/bladerf2output SUBDIRS += plugins/samplesink/hackrfoutput SUBDIRS += plugins/samplesink/limesdroutput CONFIG(!MSVC):SUBDIRS += plugins/samplesink/plutosdroutput -#SUBDIRS += plugins/samplesink/sdrdaemonsink +CONFIG(MSVC):SUBDIRS += plugins/samplesink/sdrdaemonsink +CONFIG(MSVC):SUBDIRS += plugins/samplesink/soapysdroutput SUBDIRS += plugins/channelrx/chanalyzer SUBDIRS += plugins/channelrx/demodam SUBDIRS += plugins/channelrx/demodatv SUBDIRS += plugins/channelrx/demodbfm +CONFIG(MSVC):SUBDIRS += plugins/channelrx/demoddatv SUBDIRS += plugins/channelrx/demoddsd -SUBDIRS += plugins/channelrx/demodlora +CONFIG(!MSVC):SUBDIRS += plugins/channelrx/demodlora SUBDIRS += plugins/channelrx/demodnfm SUBDIRS += plugins/channelrx/demodssb SUBDIRS += plugins/channelrx/demodwfm diff --git a/sdrbase/CMakeLists.txt b/sdrbase/CMakeLists.txt index 9613b434a..13ddb98f6 100644 --- a/sdrbase/CMakeLists.txt +++ b/sdrbase/CMakeLists.txt @@ -1,5 +1,6 @@ project (sdrbase) +set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++11") #set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fsanitize=undefined") set(sdrbase_SOURCES @@ -81,6 +82,7 @@ set(sdrbase_SOURCES util/simpleserializer.cpp #util/spinlock.cpp util/uid.cpp + util/timeutil.cpp plugin/plugininterface.cpp plugin/pluginapi.cpp @@ -204,6 +206,7 @@ set(sdrbase_HEADERS util/simpleserializer.h #util/spinlock.h util/uid.h + util/timeutil.h webapi/webapiadapterinterface.h webapi/webapirequestmapper.h diff --git a/sdrbase/audio/audioinput.cpp b/sdrbase/audio/audioinput.cpp index 316100dbb..28f4acb65 100644 --- a/sdrbase/audio/audioinput.cpp +++ b/sdrbase/audio/audioinput.cpp @@ -64,12 +64,12 @@ bool AudioInput::start(int device, int rate) if (device < devicesInfo.size()) { devInfo = devicesInfo[device]; - qWarning("AudioInput::start: using audio device #%d: %s", device, qPrintable(devInfo.defaultInputDevice().deviceName())); + qWarning("AudioInput::start: using audio device #%d: %s", device, qPrintable(devInfo.deviceName())); } else { devInfo = QAudioDeviceInfo::defaultInputDevice(); - qWarning("AudioInput::start: audio device #%d does not exist. Using default device %s", device, qPrintable(devInfo.defaultInputDevice().deviceName())); + qWarning("AudioInput::start: audio device #%d does not exist. Using default device %s", device, qPrintable(devInfo.deviceName())); } } @@ -80,12 +80,13 @@ bool AudioInput::start(int device, int rate) m_audioFormat.setSampleSize(16); m_audioFormat.setCodec("audio/pcm"); m_audioFormat.setByteOrder(QAudioFormat::LittleEndian); - m_audioFormat.setSampleType(QAudioFormat::SignedInt); + m_audioFormat.setSampleType(QAudioFormat::SignedInt); // Unknown, SignedInt, UnSignedInt, Float if (!devInfo.isFormatSupported(m_audioFormat)) { m_audioFormat = devInfo.nearestFormat(m_audioFormat); - qWarning("AudioInput::start: %d Hz S16_LE audio format not supported. New rate: %d", rate, m_audioFormat.sampleRate()); + qWarning("AudioInput::start: %d Hz S16_LE audio format not supported. Nearest is sampleRate: %d channelCount: %d sampleSize: %d sampleType: %d", + rate, m_audioFormat.sampleRate(), m_audioFormat.channelCount(), m_audioFormat.sampleSize(), (int) m_audioFormat.sampleType()); } else { diff --git a/sdrbase/audio/audionetsink.cpp b/sdrbase/audio/audionetsink.cpp index 70c7dac0f..4da761a5e 100644 --- a/sdrbase/audio/audionetsink.cpp +++ b/sdrbase/audio/audionetsink.cpp @@ -18,7 +18,6 @@ #include "audionetsink.h" #include "util/rtpsink.h" -#include #include const int AudioNetSink::m_udpBlockSize = 512; diff --git a/sdrbase/channel/channelsinkapi.h b/sdrbase/channel/channelsinkapi.h index ecfa13bf3..ebebe1adf 100644 --- a/sdrbase/channel/channelsinkapi.h +++ b/sdrbase/channel/channelsinkapi.h @@ -46,41 +46,33 @@ public: virtual QByteArray serialize() const = 0; virtual bool deserialize(const QByteArray& data) = 0; -#ifdef _MSC_VER virtual int webapiSettingsGet( SWGSDRangel::SWGChannelSettings& response, QString& errorMessage) - { errorMessage = "Not implemented"; return 501; } + { + (void) response; + errorMessage = "Not implemented"; return 501; + } virtual int webapiSettingsPutPatch( bool force, const QStringList& channelSettingsKeys, SWGSDRangel::SWGChannelSettings& response, QString& errorMessage) - { errorMessage = "Not implemented"; return 501; } + { + (void) force; + (void) channelSettingsKeys; + (void) response; + errorMessage = "Not implemented"; return 501; + } virtual int webapiReportGet( SWGSDRangel::SWGChannelReport& response, QString& errorMessage) - { errorMessage = "Not implemented"; return 501; } -#else - virtual int webapiSettingsGet( - SWGSDRangel::SWGChannelSettings& response __attribute__((unused)), - QString& errorMessage) - { errorMessage = "Not implemented"; return 501; } - - virtual int webapiSettingsPutPatch( - bool force __attribute__((unused)), - const QStringList& channelSettingsKeys __attribute__((unused)), - SWGSDRangel::SWGChannelSettings& response __attribute__((unused)), - QString& errorMessage) - { errorMessage = "Not implemented"; return 501; } - - virtual int webapiReportGet( - SWGSDRangel::SWGChannelReport& response __attribute__((unused)), - QString& errorMessage) - { errorMessage = "Not implemented"; return 501; } -#endif + { + (void) response; + errorMessage = "Not implemented"; return 501; + } int getIndexInDeviceSet() const { return m_indexInDeviceSet; } void setIndexInDeviceSet(int indexInDeviceSet) { m_indexInDeviceSet = indexInDeviceSet; } diff --git a/sdrbase/channel/channelsourceapi.h b/sdrbase/channel/channelsourceapi.h index 44466bd33..48d02c108 100644 --- a/sdrbase/channel/channelsourceapi.h +++ b/sdrbase/channel/channelsourceapi.h @@ -38,29 +38,40 @@ public: virtual void getIdentifier(QString& id) = 0; virtual void getTitle(QString& title) = 0; - virtual void setName(const QString& name) { m_name = name; }; - virtual QString getName() const { return m_name; }; + virtual void setName(const QString& name) { m_name = name; } + virtual QString getName() const { return m_name; } virtual qint64 getCenterFrequency() const = 0; virtual QByteArray serialize() const = 0; virtual bool deserialize(const QByteArray& data) = 0; virtual int webapiSettingsGet( - SWGSDRangel::SWGChannelSettings& response __attribute__((unused)), + SWGSDRangel::SWGChannelSettings& response, QString& errorMessage) - { errorMessage = "Not implemented"; return 501; } + { + (void) response; + errorMessage = "Not implemented"; return 501; + } virtual int webapiSettingsPutPatch( - bool force __attribute__((unused)), - const QStringList& channelSettingsKeys __attribute__((unused)), - SWGSDRangel::SWGChannelSettings& response __attribute__((unused)), + bool force, + const QStringList& channelSettingsKeys, + SWGSDRangel::SWGChannelSettings& response, QString& errorMessage) - { errorMessage = "Not implemented"; return 501; } + { + (void) force; + (void) channelSettingsKeys; + (void) response; + errorMessage = "Not implemented"; return 501; + } virtual int webapiReportGet( - SWGSDRangel::SWGChannelReport& response __attribute__((unused)), + SWGSDRangel::SWGChannelReport& response, QString& errorMessage) - { errorMessage = "Not implemented"; return 501; } + { + (void) response; + errorMessage = "Not implemented"; return 501; + } int getIndexInDeviceSet() const { return m_indexInDeviceSet; } void setIndexInDeviceSet(int indexInDeviceSet) { m_indexInDeviceSet = indexInDeviceSet; } diff --git a/sdrbase/channel/sdrdaemondatablock.h b/sdrbase/channel/sdrdaemondatablock.h index 1b877f8f1..ed0b2241e 100644 --- a/sdrbase/channel/sdrdaemondatablock.h +++ b/sdrbase/channel/sdrdaemondatablock.h @@ -42,13 +42,20 @@ struct SDRDaemonMetaDataFEC uint8_t m_sampleBits; //!< 10 number of effective bits per sample (deprecated) uint8_t m_nbOriginalBlocks; //!< 11 number of blocks with original (protected) data uint8_t m_nbFECBlocks; //!< 12 number of blocks carrying FEC + uint32_t m_tv_sec; //!< 16 seconds of timestamp at start time of super-frame processing uint32_t m_tv_usec; //!< 20 microseconds of timestamp at start time of super-frame processing uint32_t m_crc32; //!< 24 CRC32 of the above bool operator==(const SDRDaemonMetaDataFEC& rhs) { - return (memcmp((const void *) this, (const void *) &rhs, 12) == 0); // Only the 12 first bytes are relevant + // Only the first 6 fields are relevant + return (m_centerFrequency == rhs.m_centerFrequency) + && (m_sampleRate == rhs.m_sampleRate) + && (m_sampleBytes == rhs.m_sampleBytes) + && (m_sampleBits == rhs.m_sampleBits) + && (m_nbOriginalBlocks == rhs.m_nbOriginalBlocks) + && (m_nbFECBlocks == rhs.m_nbFECBlocks); } void init() diff --git a/sdrbase/channel/sdrdaemondatareadqueue.cpp b/sdrbase/channel/sdrdaemondatareadqueue.cpp index 601a5f12a..a1fd28f48 100644 --- a/sdrbase/channel/sdrdaemondatareadqueue.cpp +++ b/sdrbase/channel/sdrdaemondatareadqueue.cpp @@ -130,14 +130,11 @@ void SDRDaemonDataReadQueue::readSample(Sample& s, bool scaleForTx) } else { - if (m_dataBlock) - { - delete m_dataBlock; - m_dataBlock = 0; + delete m_dataBlock; + m_dataBlock = 0; - if (length() == 0) { - qWarning("SDRDaemonDataReadQueue::readSample: try to pop new block but queue is empty"); - } + if (length() == 0) { + qWarning("SDRDaemonDataReadQueue::readSample: try to pop new block but queue is empty"); } if (length() > 0) diff --git a/sdrbase/channel/sdrdaemondatareadqueue.h b/sdrbase/channel/sdrdaemondatareadqueue.h index ce120f8d2..46645c33b 100644 --- a/sdrbase/channel/sdrdaemondatareadqueue.h +++ b/sdrbase/channel/sdrdaemondatareadqueue.h @@ -59,11 +59,7 @@ private: int samplebits = m_dataBlock->m_superBlocks[blockIndex].m_header.m_sampleBits; // I or Q sample size in bits int32_t iconv, qconv; - if (sizeof(Sample) == sampleSize) // generally 16->16 or 24->24 bits - { - s = *((Sample*) &(m_dataBlock->m_superBlocks[blockIndex].m_protectedBlock.buf[sampleIndex*sampleSize])); - } - else if ((sizeof(Sample) == 4) && (sampleSize == 8)) // generally 24->16 bits + if ((sizeof(Sample) == 4) && (sampleSize == 8)) // generally 24->16 bits { iconv = ((int32_t*) &(m_dataBlock->m_superBlocks[blockIndex].m_protectedBlock.buf[sampleIndex*sampleSize]))[0]; qconv = ((int32_t*) &(m_dataBlock->m_superBlocks[blockIndex].m_protectedBlock.buf[sampleIndex*sampleSize+4]))[0]; @@ -81,7 +77,11 @@ private: s.setReal(iconv); s.setImag(qconv); } - else + else if ((sampleSize == 4) || (sampleSize == 8)) // generally 16->16 or 24->24 bits + { + s = *((Sample*) &(m_dataBlock->m_superBlocks[blockIndex].m_protectedBlock.buf[sampleIndex*sampleSize])); + } + else // invalid size { s = Sample{0, 0}; } diff --git a/sdrbase/commands/command.cpp b/sdrbase/commands/command.cpp index 4e82037b0..e9199b4b9 100644 --- a/sdrbase/commands/command.cpp +++ b/sdrbase/commands/command.cpp @@ -14,14 +14,17 @@ // along with this program. If not, see . // /////////////////////////////////////////////////////////////////////////////////// -#include "command.h" -#include "util/simpleserializer.h" +#include #include #include +#include "command.h" +#include "util/simpleserializer.h" +#include "util/timeutil.h" + Command::Command() : - m_currentProcess(0), + m_currentProcess(nullptr), m_currentProcessState(QProcess::NotRunning), m_isInError(false), m_currentProcessError(QProcess::UnknownError), @@ -30,10 +33,8 @@ Command::Command() : m_currentProcessExitStatus(QProcess::NormalExit), m_currentProcessPid(0) { - m_currentProcessStartTimeStamp.tv_sec = 0; - m_currentProcessStartTimeStamp.tv_usec = 0; - m_currentProcessFinishTimeStamp.tv_sec = 0; - m_currentProcessFinishTimeStamp.tv_usec = 0; + m_currentProcessStartTimeStampms = 0; + m_currentProcessFinishTimeStampms = 0; resetToDefaults(); } @@ -48,7 +49,7 @@ Command::Command(const Command& command) : m_keyModifiers(command.m_keyModifiers), m_associateKey(command.m_associateKey), m_release(command.m_release), - m_currentProcess(0), + m_currentProcess(nullptr), m_currentProcessState(QProcess::NotRunning), m_isInError(false), m_currentProcessError(QProcess::UnknownError), @@ -57,10 +58,8 @@ Command::Command(const Command& command) : m_currentProcessExitStatus(QProcess::NormalExit), m_currentProcessPid(0) { - m_currentProcessStartTimeStamp.tv_sec = 0; - m_currentProcessStartTimeStamp.tv_usec = 0; - m_currentProcessFinishTimeStamp.tv_sec = 0; - m_currentProcessFinishTimeStamp.tv_usec = 0; + m_currentProcessStartTimeStampms = 0; + m_currentProcessFinishTimeStampms = 0; } Command::~Command() @@ -85,7 +84,7 @@ void Command::resetToDefaults() m_command = ""; m_argString = ""; m_key = static_cast(0); - m_keyModifiers = Qt::NoModifier, + m_keyModifiers = Qt::NoModifier; m_associateKey = false; m_release = false; } @@ -202,7 +201,7 @@ void Command::run(const QString& apiAddress, int apiPort, int deviceSetIndex) connect(m_currentProcess, SIGNAL(stateChanged(QProcess::ProcessState)), this, SLOT(processStateChanged(QProcess::ProcessState))); m_currentProcess->setProcessChannelMode(QProcess::MergedChannels); - gettimeofday(&m_currentProcessStartTimeStamp, 0); + m_currentProcessStartTimeStampms = TimeUtil::nowms(); m_currentProcess->start(m_currentProcessCommandLine); } @@ -258,7 +257,7 @@ void Command::processStateChanged(QProcess::ProcessState newState) void Command::processError(QProcess::ProcessError error) { //qDebug("Command::processError: %d state: %d", error, m_currentProcessState); - gettimeofday(&m_currentProcessFinishTimeStamp, 0); + m_currentProcessFinishTimeStampms = TimeUtil::nowms(); m_currentProcessError = error; m_isInError = true; @@ -275,14 +274,14 @@ void Command::processError(QProcess::ProcessError error) disconnect(m_currentProcess, SIGNAL(stateChanged(QProcess::ProcessState)), this, SLOT(processStateChanged(QProcess::ProcessState))); m_currentProcess->deleteLater(); // make sure other threads can still access it until all events have been processed - m_currentProcess = 0; // for this thread it can assume it was deleted + m_currentProcess = nullptr; // for this thread it can assume it was deleted } } void Command::processFinished(int exitCode, QProcess::ExitStatus exitStatus) { //qDebug("Command::processFinished: (%d) %d", exitCode, exitStatus); - gettimeofday(&m_currentProcessFinishTimeStamp, 0); + m_currentProcessFinishTimeStampms = TimeUtil::nowms(); m_currentProcessExitCode = exitCode; m_currentProcessExitStatus = exitStatus; m_hasExited = true; @@ -297,5 +296,5 @@ void Command::processFinished(int exitCode, QProcess::ExitStatus exitStatus) disconnect(m_currentProcess, SIGNAL(stateChanged(QProcess::ProcessState)), this, SLOT(processStateChanged(QProcess::ProcessState))); m_currentProcess->deleteLater(); // make sure other threads can still access it until all events have been processed - m_currentProcess = 0; // for this thread it can assume it was deleted + m_currentProcess = nullptr; // for this thread it can assume it was deleted } diff --git a/sdrbase/commands/command.h b/sdrbase/commands/command.h index 8103b1791..baae07f71 100644 --- a/sdrbase/commands/command.h +++ b/sdrbase/commands/command.h @@ -23,7 +23,7 @@ #include #include #include -#include +#include #include "export.h" @@ -63,8 +63,8 @@ public: bool getLastProcessError(QProcess::ProcessError& error) const; bool getLastProcessExit(int& exitCode, QProcess::ExitStatus& exitStatus) const; const QString& getLastProcessLog() const; - struct timeval getLastProcessStartTimestamp() const { return m_currentProcessStartTimeStamp; } - struct timeval getLastProcessFinishTimestamp() const { return m_currentProcessFinishTimeStamp; } + uint64_t getLastProcessStartTimestampms() const { return m_currentProcessStartTimeStampms; } + uint64_t getLastProcessFinishTimestampms() const { return m_currentProcessFinishTimeStampms; } const QString& getLastProcessCommandLine() const { return m_currentProcessCommandLine; } qint64 getLastProcessPid() const { return m_currentProcessPid; } @@ -107,8 +107,8 @@ private: int m_currentProcessExitCode; QProcess::ExitStatus m_currentProcessExitStatus; QString m_log; - struct timeval m_currentProcessStartTimeStamp; - struct timeval m_currentProcessFinishTimeStamp; + uint64_t m_currentProcessStartTimeStampms; + uint64_t m_currentProcessFinishTimeStampms; QString m_currentProcessCommandLine; qint64 m_currentProcessPid; diff --git a/sdrbase/dsp/basebandsamplesink.h b/sdrbase/dsp/basebandsamplesink.h index 21e122434..e6a85a0d4 100644 --- a/sdrbase/dsp/basebandsamplesink.h +++ b/sdrbase/dsp/basebandsamplesink.h @@ -30,7 +30,7 @@ class SDRBASE_API BasebandSampleSink : public QObject { Q_OBJECT public: /** Used to notify on which thread the sample sink is now running (with ThreadedSampleSink) */ - class MsgThreadedSink : public Message { + class SDRBASE_API MsgThreadedSink : public Message { MESSAGE_CLASS_DECLARATION public: diff --git a/sdrbase/dsp/basebandsamplesource.h b/sdrbase/dsp/basebandsamplesource.h index f9f2a66a9..e323fd230 100644 --- a/sdrbase/dsp/basebandsamplesource.h +++ b/sdrbase/dsp/basebandsamplesource.h @@ -35,7 +35,7 @@ public: virtual void start() = 0; virtual void stop() = 0; virtual void pull(Sample& sample) = 0; - virtual void pullAudio(int nbSamples __attribute__((unused))) {} + virtual void pullAudio(int nbSamples) { (void) nbSamples; } /** direct feeding of sample source FIFO */ void feed(SampleSourceFifo* sampleFifo, int nbSamples) diff --git a/sdrbase/dsp/cwkeyer.h b/sdrbase/dsp/cwkeyer.h index a1c977a0c..3b2718d6f 100644 --- a/sdrbase/dsp/cwkeyer.h +++ b/sdrbase/dsp/cwkeyer.h @@ -50,7 +50,7 @@ class SDRBASE_API CWKeyer : public QObject { Q_OBJECT public: - class MsgConfigureCWKeyer : public Message { + class SDRBASE_API MsgConfigureCWKeyer : public Message { MESSAGE_CLASS_DECLARATION public: diff --git a/sdrbase/dsp/decimators.h b/sdrbase/dsp/decimators.h index ee54b56e9..3979d92f8 100644 --- a/sdrbase/dsp/decimators.h +++ b/sdrbase/dsp/decimators.h @@ -184,6 +184,42 @@ struct decimation_shifts<24, 8> static const uint post64 = 0; }; +#ifdef _MSC_VER +#pragma pack(push,1) +template +struct TripleByteLE +{ + uint8_t b0; + uint8_t b1; + uint8_t b2; + + typedef union { +#pragma pack(push,1) + struct { + int32_t i; + }; +#pragma pack(pop) +#pragma pack(push, 1) + struct { + uint8_t i0; + uint8_t i1; + uint8_t i2; + uint8_t i3; + }; +#pragma pack(pop) + } isample; + + operator T() const { + isample s; + s.i0 = 0; + s.i1 = b0; + s.i2 = b1; + s.i3 = b2; + return s.i; + } +}; +#pragma pack(pop) +#else template struct TripleByteLE { @@ -212,7 +248,44 @@ struct TripleByteLE return s.i; } } __attribute__((__packed__)); +#endif +#ifdef _MSC_VER +#pragma pack(push, 1) +template<> +struct TripleByteLE +{ + uint8_t b0; + uint8_t b1; + uint8_t b2; + + typedef union { +#pragma pack(push, 1) + struct { + qint32 i; + }; +#pragma pack(pop) +#pragma pack(push, 1) + struct { + uint8_t i0; + uint8_t i1; + uint8_t i2; + uint8_t i3; + }; +#pragma pack(pop) + } isample; + + operator qint32() const { + isample s; + s.i0 = 0; + s.i1 = b0; + s.i2 = b1; + s.i3 = b2; + return s.i >> 8; + } +}; +#pragma pack(pop) +#else template<> struct TripleByteLE { @@ -241,7 +314,46 @@ struct TripleByteLE return s.i >> 8; } } __attribute__((__packed__)); +#endif +#ifdef _MSC_VER +#pragma pack(push, 1) +template<> +struct TripleByteLE +{ + uint8_t b0; + uint8_t b1; + uint8_t b2; + + typedef union { +#pragma pack(push, 1) + struct { + qint64 i; + }; +#pragma pack(pop) +#pragma pack(push, 1) + struct { + uint32_t ia; + uint8_t i0; + uint8_t i1; + uint8_t i2; + uint8_t i3; + }; +#pragma pack(pop) + } isample; + + operator qint64() const { + isample s; + s.ia = 0; + s.i0 = 0; + s.i1 = b0; + s.i2 = b1; + s.i3 = b2; + return s.i >> 40; + } +}; +#pragma pack(pop) +#else template<> struct TripleByteLE { @@ -272,7 +384,7 @@ struct TripleByteLE return s.i >> 40; } } __attribute__((__packed__)); - +#endif /** Decimators with integer input and integer output */ template diff --git a/sdrbase/dsp/decimatorsu.h b/sdrbase/dsp/decimatorsu.h index 36f897634..26489c1d5 100644 --- a/sdrbase/dsp/decimatorsu.h +++ b/sdrbase/dsp/decimatorsu.h @@ -387,7 +387,7 @@ void DecimatorsU::decimate4_sup(Sampl } template -void DecimatorsU::decimate8_inf(SampleVector::iterator* it, const T* buf __attribute__((unused)), qint32 len) +void DecimatorsU::decimate8_inf(SampleVector::iterator* it, const T* buf, qint32 len) { StorageType buf2[16], buf4[8], buf8[4]; @@ -463,7 +463,7 @@ void DecimatorsU::decimate8_inf(Sampl } template -void DecimatorsU::decimate8_sup(SampleVector::iterator* it, const T* buf __attribute__((unused)), qint32 len) +void DecimatorsU::decimate8_sup(SampleVector::iterator* it, const T* buf, qint32 len) { StorageType buf2[16], buf4[8], buf8[4]; diff --git a/sdrbase/dsp/devicesamplesink.h b/sdrbase/dsp/devicesamplesink.h index 5666f5e8c..8ecb74d20 100644 --- a/sdrbase/dsp/devicesamplesink.h +++ b/sdrbase/dsp/devicesamplesink.h @@ -54,31 +54,54 @@ public: virtual bool handleMessage(const Message& message) = 0; virtual int webapiSettingsGet( - SWGSDRangel::SWGDeviceSettings& response __attribute__((unused)), + SWGSDRangel::SWGDeviceSettings& response, QString& errorMessage) - { errorMessage = "Not implemented"; return 501; } + { + (void) response; + errorMessage = "Not implemented"; + return 501; + } virtual int webapiSettingsPutPatch( - bool force __attribute__((unused)), //!< true to force settings = put - const QStringList& deviceSettingsKeys __attribute__((unused)), - SWGSDRangel::SWGDeviceSettings& response __attribute__((unused)), + bool force, //!< true to force settings = put + const QStringList& deviceSettingsKeys, + SWGSDRangel::SWGDeviceSettings& response, QString& errorMessage) - { errorMessage = "Not implemented"; return 501; } + { + (void) force; + (void) deviceSettingsKeys; + (void) response; + errorMessage = "Not implemented"; + return 501; + } virtual int webapiRunGet( - SWGSDRangel::SWGDeviceState& response __attribute__((unused)), + SWGSDRangel::SWGDeviceState& response, QString& errorMessage) - { errorMessage = "Not implemented"; return 501; } + { + (void) response; + errorMessage = "Not implemented"; + return 501; + } - virtual int webapiRun(bool run __attribute__((unused)), - SWGSDRangel::SWGDeviceState& response __attribute__((unused)), + virtual int webapiRun(bool run, + SWGSDRangel::SWGDeviceState& response, QString& errorMessage) - { errorMessage = "Not implemented"; return 501; } + { + (void) run; + (void) response; + errorMessage = "Not implemented"; + return 501; + } virtual int webapiReportGet( - SWGSDRangel::SWGDeviceReport& response __attribute__((unused)), + SWGSDRangel::SWGDeviceReport& response, QString& errorMessage) - { errorMessage = "Not implemented"; return 501; } + { + (void) response; + errorMessage = "Not implemented"; + return 501; + } MessageQueue *getInputMessageQueue() { return &m_inputMessageQueue; } virtual void setMessageQueueToGUI(MessageQueue *queue) = 0; // pure virtual so that child classes must have to deal with this diff --git a/sdrbase/dsp/devicesamplesource.h b/sdrbase/dsp/devicesamplesource.h index 60c541d8a..c07d2426b 100644 --- a/sdrbase/dsp/devicesamplesource.h +++ b/sdrbase/dsp/devicesamplesource.h @@ -61,31 +61,54 @@ public: virtual bool handleMessage(const Message& message) = 0; virtual int webapiSettingsGet( - SWGSDRangel::SWGDeviceSettings& response __attribute__((unused)), + SWGSDRangel::SWGDeviceSettings& response, QString& errorMessage) - { errorMessage = "Not implemented"; return 501; } + { + (void) response; + errorMessage = "Not implemented"; + return 501; + } virtual int webapiSettingsPutPatch( - bool force __attribute__((unused)), //!< true to force settings = put - const QStringList& deviceSettingsKeys __attribute__((unused)), - SWGSDRangel::SWGDeviceSettings& response __attribute__((unused)), + bool force, //!< true to force settings = put + const QStringList& deviceSettingsKeys, + SWGSDRangel::SWGDeviceSettings& response, QString& errorMessage) - { errorMessage = "Not implemented"; return 501; } + { + (void) force; + (void) deviceSettingsKeys; + (void) response; + errorMessage = "Not implemented"; + return 501; + } virtual int webapiRunGet( - SWGSDRangel::SWGDeviceState& response __attribute__((unused)), + SWGSDRangel::SWGDeviceState& response, QString& errorMessage) - { errorMessage = "Not implemented"; return 501; } + { + (void) response; + errorMessage = "Not implemented"; + return 501; + } - virtual int webapiRun(bool run __attribute__((unused)), - SWGSDRangel::SWGDeviceState& response __attribute__((unused)), + virtual int webapiRun(bool run, + SWGSDRangel::SWGDeviceState& response, QString& errorMessage) - { errorMessage = "Not implemented"; return 501; } + { + (void) run; + (void) response; + errorMessage = "Not implemented"; + return 501; + } virtual int webapiReportGet( - SWGSDRangel::SWGDeviceReport& response __attribute__((unused)), + SWGSDRangel::SWGDeviceReport& response, QString& errorMessage) - { errorMessage = "Not implemented"; return 501; } + { + (void) response; + errorMessage = "Not implemented"; + return 501; + } MessageQueue *getInputMessageQueue() { return &m_inputMessageQueue; } virtual void setMessageQueueToGUI(MessageQueue *queue) = 0; // pure virtual so that child classes must have to deal with this diff --git a/sdrbase/dsp/downchannelizer.cpp b/sdrbase/dsp/downchannelizer.cpp index b8fe5f3f3..4d53b3b45 100644 --- a/sdrbase/dsp/downchannelizer.cpp +++ b/sdrbase/dsp/downchannelizer.cpp @@ -295,7 +295,7 @@ void DownChannelizer::freeFilterChain() void DownChannelizer::debugFilterChain() { - qDebug("DownChannelizer::debugFilterChain: %lu stages", m_filterStages.size()); + qDebug("DownChannelizer::debugFilterChain: %u stages", m_filterStages.size()); for(FilterStages::iterator it = m_filterStages.begin(); it != m_filterStages.end(); ++it) { diff --git a/sdrbase/dsp/downchannelizer.h b/sdrbase/dsp/downchannelizer.h index 3e5059154..d67f3b4de 100644 --- a/sdrbase/dsp/downchannelizer.h +++ b/sdrbase/dsp/downchannelizer.h @@ -32,7 +32,7 @@ class MessageQueue; class SDRBASE_API DownChannelizer : public BasebandSampleSink { Q_OBJECT public: - class MsgChannelizerNotification : public Message { + class SDRBASE_API MsgChannelizerNotification : public Message { MESSAGE_CLASS_DECLARATION public: diff --git a/sdrbase/dsp/dspcommands.cpp b/sdrbase/dsp/dspcommands.cpp index 71ab79ca2..a6cc3765a 100644 --- a/sdrbase/dsp/dspcommands.cpp +++ b/sdrbase/dsp/dspcommands.cpp @@ -40,7 +40,6 @@ MESSAGE_CLASS_DEFINITION(DSPRemoveThreadedBasebandSampleSink, Message) MESSAGE_CLASS_DEFINITION(DSPRemoveThreadedBasebandSampleSource, Message) MESSAGE_CLASS_DEFINITION(DSPAddAudioSink, Message) MESSAGE_CLASS_DEFINITION(DSPRemoveAudioSink, Message) -//MESSAGE_CLASS_DEFINITION(DSPConfigureSpectrumVis, Message) MESSAGE_CLASS_DEFINITION(DSPConfigureCorrection, Message) MESSAGE_CLASS_DEFINITION(DSPEngineReport, Message) MESSAGE_CLASS_DEFINITION(DSPConfigureScopeVis, Message) diff --git a/sdrbase/dsp/dspcommands.h b/sdrbase/dsp/dspcommands.h index ca1a5343b..3d66541e3 100644 --- a/sdrbase/dsp/dspcommands.h +++ b/sdrbase/dsp/dspcommands.h @@ -256,27 +256,6 @@ private: AudioFifo* m_audioFifo; }; -class SDRBASE_API DSPConfigureSpectrumVis : public Message { - MESSAGE_CLASS_DECLARATION - -public: - DSPConfigureSpectrumVis(int fftSize, int overlapPercent, FFTWindow::Function window) : - Message(), - m_fftSize(fftSize), - m_overlapPercent(overlapPercent), - m_window(window) - { } - - int getFFTSize() const { return m_fftSize; } - int getOverlapPercent() const { return m_overlapPercent; } - FFTWindow::Function getWindow() const { return m_window; } - -private: - int m_fftSize; - int m_overlapPercent; - FFTWindow::Function m_window; -}; - class SDRBASE_API DSPConfigureCorrection : public Message { MESSAGE_CLASS_DECLARATION diff --git a/sdrbase/dsp/dspengine.cpp b/sdrbase/dsp/dspengine.cpp index afa9c4453..623d93f39 100644 --- a/sdrbase/dsp/dspengine.cpp +++ b/sdrbase/dsp/dspengine.cpp @@ -134,8 +134,8 @@ void DSPEngine::setDVSerialSupport(bool support) } } #else -void DSPEngine::setDVSerialSupport(bool support __attribute__((unused))) -{} +void DSPEngine::setDVSerialSupport(bool support) +{ (void) support; } #endif bool DSPEngine::hasDVSerialSupport() @@ -153,8 +153,8 @@ void DSPEngine::getDVSerialNames(std::vector& deviceNames) m_dvSerialEngine.getDevicesNames(deviceNames); } #else -void DSPEngine::getDVSerialNames(std::vector& deviceNames __attribute((unused))) -{} +void DSPEngine::getDVSerialNames(std::vector& deviceNames) +{ (void) deviceNames; } #endif #ifdef DSD_USE_SERIALDV @@ -171,12 +171,20 @@ void DSPEngine::pushMbeFrame( } #else void DSPEngine::pushMbeFrame( - const unsigned char *mbeFrame __attribute((unused)), - int mbeRateIndex __attribute((unused)), - int mbeVolumeIndex __attribute((unused)), - unsigned char channels __attribute((unused)), - bool useHP __attribute((unused)), - int upsampling __attribute((unused)), - AudioFifo *audioFifo __attribute((unused))) -{} + const unsigned char *mbeFrame, + int mbeRateIndex, + int mbeVolumeIndex, + unsigned char channels, + bool useHP, + int upsampling, + AudioFifo *audioFifo) +{ + (void) mbeFrame; + (void) mbeRateIndex; + (void) mbeVolumeIndex; + (void) channels; + (void) useHP; + (void) upsampling; + (void) audioFifo; +} #endif diff --git a/sdrbase/dsp/dvserialengine.cpp b/sdrbase/dsp/dvserialengine.cpp index ddb4370b9..5aba10314 100644 --- a/sdrbase/dsp/dvserialengine.cpp +++ b/sdrbase/dsp/dvserialengine.cpp @@ -16,14 +16,16 @@ /////////////////////////////////////////////////////////////////////////////////// #include -#include #include #include #include -#include #include #include +#ifndef _MSC_VER +#include +#include #include +#endif #ifndef __WINDOWS__ #include diff --git a/sdrbase/dsp/dvserialworker.cpp b/sdrbase/dsp/dvserialworker.cpp index e72f0f5db..cc5f04b56 100644 --- a/sdrbase/dsp/dvserialworker.cpp +++ b/sdrbase/dsp/dvserialworker.cpp @@ -15,7 +15,8 @@ // along with this program. If not, see . // /////////////////////////////////////////////////////////////////////////////////// -#include +#include +#include #include "dsp/dvserialworker.h" #include "audio/audiofifo.h" @@ -60,7 +61,7 @@ void DVSerialWorker::process() while (m_running) { - sleep(1); + std::this_thread::sleep_for(std::chrono::seconds(1)); } qDebug("DVSerialWorker::process: stopped"); diff --git a/sdrbase/dsp/fftfilt.cpp b/sdrbase/dsp/fftfilt.cpp index 8b7a6698f..e05029b3c 100644 --- a/sdrbase/dsp/fftfilt.cpp +++ b/sdrbase/dsp/fftfilt.cpp @@ -37,7 +37,6 @@ #include #include -#include #include #include diff --git a/sdrbase/dsp/filerecord.cpp b/sdrbase/dsp/filerecord.cpp index 5a483e7d9..5e7e3a6bd 100644 --- a/sdrbase/dsp/filerecord.cpp +++ b/sdrbase/dsp/filerecord.cpp @@ -68,8 +68,9 @@ void FileRecord::genUniqueFileName(uint deviceUID) setFileName(QString("rec%1_%2.sdriq").arg(deviceUID).arg(QDateTime::currentDateTimeUtc().toString("yyyy-MM-ddTHH_mm_ss_zzz"))); } -void FileRecord::feed(const SampleVector::const_iterator& begin, const SampleVector::const_iterator& end, bool positiveOnly __attribute__((unused))) +void FileRecord::feed(const SampleVector::const_iterator& begin, const SampleVector::const_iterator& end, bool positiveOnly) { + (void) positiveOnly; // if no recording is active, send the samples to /dev/null if(!m_recordOn) return; @@ -173,4 +174,4 @@ void FileRecord::writeHeader(std::ofstream& sampleFile, Header& header) crc32.process_bytes(&header, 28); header.crc32 = crc32.checksum(); sampleFile.write((const char *) &header, sizeof(Header)); -} \ No newline at end of file +} diff --git a/sdrbase/dsp/filtermbe.h b/sdrbase/dsp/filtermbe.h index 2b4cc3dc1..1406fa32f 100644 --- a/sdrbase/dsp/filtermbe.h +++ b/sdrbase/dsp/filtermbe.h @@ -76,8 +76,12 @@ private: IIRFilter m_filterLP; IIRFilter m_filterHP; bool m_useHP; - static const float m_lpa[3], m_lpb[3]; // low pass coefficients - static const float m_hpa[3], m_hpb[3]; // band pass coefficients + // low pass coefficients + static const float m_lpa[3]; + static const float m_lpb[3]; + // band pass coefficients + static const float m_hpa[3]; + static const float m_hpb[3]; }; diff --git a/sdrbase/dsp/freqlockcomplex.cpp b/sdrbase/dsp/freqlockcomplex.cpp index 2e8b9676f..8a7e787d0 100644 --- a/sdrbase/dsp/freqlockcomplex.cpp +++ b/sdrbase/dsp/freqlockcomplex.cpp @@ -21,6 +21,7 @@ /////////////////////////////////////////////////////////////////////////////////// #include "freqlockcomplex.h" +#define _USE_MATH_DEFINES #include FreqLockComplex::FreqLockComplex() : diff --git a/sdrbase/dsp/hbfiltertraits.h b/sdrbase/dsp/hbfiltertraits.h index 9232c9a73..066d34b93 100644 --- a/sdrbase/dsp/hbfiltertraits.h +++ b/sdrbase/dsp/hbfiltertraits.h @@ -38,7 +38,11 @@ struct SDRBASE_API HBFIRFilterTraits<16> static const int32_t hbOrder = 16; static const int32_t hbShift = 12; static const int16_t hbMod[16+6]; +#ifdef _MSC_VER + __declspec(align(16)) static const int32_t hbCoeffs[4]; +#else static const int32_t hbCoeffs[4] __attribute__ ((aligned (16))); +#endif static const double hbCoeffsF[4]; }; @@ -48,7 +52,11 @@ struct SDRBASE_API HBFIRFilterTraits<32> static const int32_t hbOrder = 32; static const int32_t hbShift = 12; static const int16_t hbMod[32+6]; +#ifdef _MSC_VER + __declspec(align(32)) static const int32_t hbCoeffs[8]; +#else static const int32_t hbCoeffs[8] __attribute__ ((aligned (32))); +#endif static const double hbCoeffsF[8]; }; @@ -58,7 +66,11 @@ struct SDRBASE_API HBFIRFilterTraits<48> static const int32_t hbOrder = 48; static const int32_t hbShift = 12; static const int16_t hbMod[48+6]; +#ifdef _MSC_VER + __declspec(align(16)) static const int32_t hbCoeffs[12]; +#else static const int32_t hbCoeffs[12] __attribute__ ((aligned (16))); +#endif static const double hbCoeffsF[12]; }; @@ -68,7 +80,11 @@ struct SDRBASE_API HBFIRFilterTraits<64> static const int32_t hbOrder = 64; static const int32_t hbShift = 12; static const int16_t hbMod[64+6]; +#ifdef _MSC_VER + __declspec(align(32)) static const int32_t hbCoeffs[16]; +#else static const int32_t hbCoeffs[16] __attribute__ ((aligned (32))); +#endif static const float hbCoeffsF[16]; }; @@ -78,7 +94,11 @@ struct SDRBASE_API HBFIRFilterTraits<80> static const int32_t hbOrder = 80; static const int32_t hbShift = 14; static const int16_t hbMod[80+6]; +#ifdef _MSC_VER + __declspec(align(16)) static const int32_t hbCoeffs[20]; +#else static const int32_t hbCoeffs[20] __attribute__ ((aligned (16))); +#endif static const double hbCoeffsF[20]; }; @@ -88,7 +108,11 @@ struct SDRBASE_API HBFIRFilterTraits<96> static const int32_t hbOrder = 96; static const int32_t hbShift = 16; static const int16_t hbMod[96+6]; +#ifdef _MSC_VER + __declspec(align(32)) static const int32_t hbCoeffs[24]; +#else static const int32_t hbCoeffs[24] __attribute__ ((aligned (32))); +#endif static const double hbCoeffsF[24]; }; @@ -98,7 +122,11 @@ struct SDRBASE_API HBFIRFilterTraits<112> static const int32_t hbOrder = 112; static const int32_t hbShift = 18; static const int16_t hbMod[112+6]; +#ifdef _MSC_VER + __declspec(align(16)) static const int32_t hbCoeffs[28]; +#else static const int32_t hbCoeffs[28] __attribute__ ((aligned (16))); +#endif static const double hbCoeffsF[28]; }; @@ -108,7 +136,11 @@ struct SDRBASE_API HBFIRFilterTraits<128> static const int32_t hbOrder = 128; static const int32_t hbShift = 20; static const int16_t hbMod[128+6]; +#ifdef _MSC_VER + __declspec(align(16)) static const int32_t hbCoeffs[32]; +#else static const int32_t hbCoeffs[32] __attribute__ ((aligned (16))); +#endif static const double hbCoeffsF[32]; }; diff --git a/sdrbase/dsp/interpolator.h b/sdrbase/dsp/interpolator.h index 607b3fe97..07d5171d0 100644 --- a/sdrbase/dsp/interpolator.h +++ b/sdrbase/dsp/interpolator.h @@ -7,9 +7,6 @@ #include "dsp/dsptypes.h" #include "export.h" #include -#ifndef __WINDOWS__ -#include -#endif class SDRBASE_API Interpolator { public: diff --git a/sdrbase/dsp/inthalfbandfilterdb.h b/sdrbase/dsp/inthalfbandfilterdb.h index a4b00bd8f..702e1281e 100644 --- a/sdrbase/dsp/inthalfbandfilterdb.h +++ b/sdrbase/dsp/inthalfbandfilterdb.h @@ -24,12 +24,23 @@ #include #include "dsp/dsptypes.h" #include "dsp/hbfiltertraits.h" -#include "export.h" template -class SDRBASE_API IntHalfbandFilterDB { +class IntHalfbandFilterDB { public: - IntHalfbandFilterDB(); + IntHalfbandFilterDB() + { + m_size = HBFIRFilterTraits::hbOrder - 1; + + for (int i = 0; i < m_size; i++) + { + m_samplesDB[i][0] = 0; + m_samplesDB[i][1] = 0; + } + + m_ptr = 0; + m_state = 0; + } // downsample by 2, return center part of original spectrum bool workDecimateCenter(Sample* sample) @@ -754,19 +765,4 @@ protected: } }; -template -IntHalfbandFilterDB::IntHalfbandFilterDB() -{ - m_size = HBFIRFilterTraits::hbOrder - 1; - - for (int i = 0; i < m_size; i++) - { - m_samplesDB[i][0] = 0; - m_samplesDB[i][1] = 0; - } - - m_ptr = 0; - m_state = 0; -} - #endif // INCLUDE_INTHALFBANDFILTER_DB_H diff --git a/sdrbase/dsp/inthalfbandfiltereo.h b/sdrbase/dsp/inthalfbandfiltereo.h index a5cff5344..fb598521e 100644 --- a/sdrbase/dsp/inthalfbandfiltereo.h +++ b/sdrbase/dsp/inthalfbandfiltereo.h @@ -26,12 +26,27 @@ #include #include "dsp/dsptypes.h" #include "dsp/hbfiltertraits.h" -#include "export.h" template -class SDRBASE_API IntHalfbandFilterEO { +class IntHalfbandFilterEO { public: - IntHalfbandFilterEO(); + IntHalfbandFilterEO() + { + m_size = HBFIRFilterTraits::hbOrder/2; + + for (int i = 0; i < 2*m_size; i++) + { + m_even[0][i] = 0; + m_even[1][i] = 0; + m_odd[0][i] = 0; + m_odd[1][i] = 0; + m_samples[i][0] = 0; + m_samples[i][1] = 0; + } + + m_ptr = 0; + m_state = 0; + } // downsample by 2, return center part of original spectrum bool workDecimateCenter(Sample* sample) @@ -912,23 +927,23 @@ protected: } }; -template -IntHalfbandFilterEO::IntHalfbandFilterEO() -{ - m_size = HBFIRFilterTraits::hbOrder/2; +//template +//IntHalfbandFilterEO::IntHalfbandFilterEO() +//{ +// m_size = HBFIRFilterTraits::hbOrder/2; - for (int i = 0; i < 2*m_size; i++) - { - m_even[0][i] = 0; - m_even[1][i] = 0; - m_odd[0][i] = 0; - m_odd[1][i] = 0; - m_samples[i][0] = 0; - m_samples[i][1] = 0; - } +// for (int i = 0; i < 2*m_size; i++) +// { +// m_even[0][i] = 0; +// m_even[1][i] = 0; +// m_odd[0][i] = 0; +// m_odd[1][i] = 0; +// m_samples[i][0] = 0; +// m_samples[i][1] = 0; +// } - m_ptr = 0; - m_state = 0; -} +// m_ptr = 0; +// m_state = 0; +//} #endif /* SDRBASE_DSP_INTHALFBANDFILTEREO_H_ */ diff --git a/sdrbase/dsp/inthalfbandfiltereo1.h b/sdrbase/dsp/inthalfbandfiltereo1.h index 21bc112de..5062984cf 100644 --- a/sdrbase/dsp/inthalfbandfiltereo1.h +++ b/sdrbase/dsp/inthalfbandfiltereo1.h @@ -27,10 +27,9 @@ #include "dsp/dsptypes.h" #include "dsp/hbfiltertraits.h" //#include "dsp/inthalfbandfiltereo1i.h" -#include "export.h" template -class SDRBASE_API IntHalfbandFilterEO1 { +class IntHalfbandFilterEO1 { public: IntHalfbandFilterEO1(); diff --git a/sdrbase/dsp/inthalfbandfiltereof.h b/sdrbase/dsp/inthalfbandfiltereof.h index 09f188e0a..f6cf12f75 100644 --- a/sdrbase/dsp/inthalfbandfiltereof.h +++ b/sdrbase/dsp/inthalfbandfiltereof.h @@ -29,7 +29,7 @@ #include "export.h" template -class SDRBASE_API IntHalfbandFilterEOF { +class IntHalfbandFilterEOF { public: IntHalfbandFilterEOF(); diff --git a/sdrbase/dsp/nullsink.cpp b/sdrbase/dsp/nullsink.cpp index 592735116..1c372a6b1 100644 --- a/sdrbase/dsp/nullsink.cpp +++ b/sdrbase/dsp/nullsink.cpp @@ -11,13 +11,17 @@ NullSink::~NullSink() { } -bool NullSink::init(const Message& message __attribute__((unused))) +bool NullSink::init(const Message& message) { + (void) message; return false; } -void NullSink::feed(const SampleVector::const_iterator& begin __attribute__((unused)), const SampleVector::const_iterator& end __attribute__((unused)), bool positiveOnly __attribute__((unused))) +void NullSink::feed(const SampleVector::const_iterator& begin, const SampleVector::const_iterator& end, bool positiveOnly) { + (void) begin; + (void) end; + (void) positiveOnly; } void NullSink::start() @@ -28,7 +32,8 @@ void NullSink::stop() { } -bool NullSink::handleMessage(const Message& message __attribute__((unused))) +bool NullSink::handleMessage(const Message& message) { + (void) message; return false; } diff --git a/sdrbase/dsp/phaselock.h b/sdrbase/dsp/phaselock.h index ab1b2af03..b6984b67f 100644 --- a/sdrbase/dsp/phaselock.h +++ b/sdrbase/dsp/phaselock.h @@ -95,7 +95,7 @@ protected: * Callback method to produce multiple outputs from the current phase value in m_phase * and/or the sin and cos values in m_psin and m_pcos */ - virtual void processPhase(Real *samples_out __attribute__((unused))) const {}; + virtual void processPhase(Real *samples_out) const { (void) samples_out; } private: Real m_minfreq, m_maxfreq; diff --git a/sdrbase/dsp/phaselockcomplex.cpp b/sdrbase/dsp/phaselockcomplex.cpp index 0c8d604f3..5aa35c534 100644 --- a/sdrbase/dsp/phaselockcomplex.cpp +++ b/sdrbase/dsp/phaselockcomplex.cpp @@ -21,6 +21,7 @@ /////////////////////////////////////////////////////////////////////////////////// #include +#define _USE_MATH_DEFINES #include #include "phaselockcomplex.h" diff --git a/sdrbase/dsp/projector.cpp b/sdrbase/dsp/projector.cpp index 887be37c0..e557e410d 100644 --- a/sdrbase/dsp/projector.cpp +++ b/sdrbase/dsp/projector.cpp @@ -15,6 +15,7 @@ // along with this program. If not, see . // /////////////////////////////////////////////////////////////////////////////////// +#define _USE_MATH_DEFINES #include #include "projector.h" diff --git a/sdrbase/dsp/projector.h b/sdrbase/dsp/projector.h index 3e2f65602..093b878fb 100644 --- a/sdrbase/dsp/projector.h +++ b/sdrbase/dsp/projector.h @@ -15,9 +15,10 @@ // along with this program. If not, see . // /////////////////////////////////////////////////////////////////////////////////// +#include "export.h" #include "dsptypes.h" -class Projector +class SDRBASE_API Projector { public: enum ProjectionType diff --git a/sdrbase/dsp/threadedbasebandsamplesink.cpp b/sdrbase/dsp/threadedbasebandsamplesink.cpp index e646cd7cc..cce47ec6a 100644 --- a/sdrbase/dsp/threadedbasebandsamplesink.cpp +++ b/sdrbase/dsp/threadedbasebandsamplesink.cpp @@ -111,8 +111,9 @@ void ThreadedBasebandSampleSink::stop() m_thread->wait(); } -void ThreadedBasebandSampleSink::feed(SampleVector::const_iterator begin, SampleVector::const_iterator end, bool positiveOnly __attribute__((unused))) +void ThreadedBasebandSampleSink::feed(SampleVector::const_iterator begin, SampleVector::const_iterator end, bool positiveOnly) { + (void) positiveOnly; //m_sampleSink->feed(begin, end, positiveOnly); //m_sampleFifo.write(begin, end); m_threadedBasebandSampleSinkFifo->writeToFifo(begin, end); diff --git a/sdrbase/dsp/upchannelizer.h b/sdrbase/dsp/upchannelizer.h index 63698f334..3a99183a0 100644 --- a/sdrbase/dsp/upchannelizer.h +++ b/sdrbase/dsp/upchannelizer.h @@ -36,7 +36,7 @@ class MessageQueue; class SDRBASE_API UpChannelizer : public BasebandSampleSource { Q_OBJECT public: - class MsgChannelizerNotification : public Message { + class SDRBASE_API MsgChannelizerNotification : public Message { MESSAGE_CLASS_DECLARATION public: diff --git a/sdrbase/plugin/plugininterface.h b/sdrbase/plugin/plugininterface.h index 64d73793d..fca56083b 100644 --- a/sdrbase/plugin/plugininterface.h +++ b/sdrbase/plugin/plugininterface.h @@ -73,7 +73,7 @@ public: }; typedef QList SamplingDevices; - virtual ~PluginInterface() { }; + virtual ~PluginInterface() { } virtual const PluginDescriptor& getPluginDescriptor() const = 0; virtual void initPlugin(PluginAPI* pluginAPI) = 0; @@ -81,44 +81,76 @@ public: // channel Rx plugins virtual PluginInstanceGUI* createRxChannelGUI( - DeviceUISet *deviceUISet __attribute__((unused)), - BasebandSampleSink *rxChannel __attribute__((unused))) - { return 0; } + DeviceUISet *deviceUISet, + BasebandSampleSink *rxChannel) + { + (void) deviceUISet; + (void) rxChannel; + return nullptr; + } virtual BasebandSampleSink* createRxChannelBS( - DeviceSourceAPI *deviceAPI __attribute__((unused)) ) - { return 0; } + DeviceSourceAPI *deviceAPI) + { + (void) deviceAPI; + return nullptr; + } virtual ChannelSinkAPI* createRxChannelCS( - DeviceSourceAPI *deviceAPI __attribute__((unused)) ) - { return 0; } + DeviceSourceAPI *deviceAPI) + { + (void) deviceAPI; + return nullptr; + } // channel Tx plugins virtual PluginInstanceGUI* createTxChannelGUI( - DeviceUISet *deviceUISet __attribute__((unused)), - BasebandSampleSource *txChannel __attribute__((unused))) - { return 0; } + DeviceUISet *deviceUISet, + BasebandSampleSource *txChannel) + { + (void) deviceUISet; + (void) txChannel; + return nullptr; + } virtual BasebandSampleSource* createTxChannelBS( - DeviceSinkAPI *deviceAPI __attribute__((unused)) ) - { return 0; } + DeviceSinkAPI *deviceAPI) + { + (void) deviceAPI; + return nullptr; + } virtual ChannelSourceAPI* createTxChannelCS( - DeviceSinkAPI *deviceAPI __attribute__((unused)) ) - { return 0; } + DeviceSinkAPI *deviceAPI) + { + (void) deviceAPI; + return nullptr; + } // device source plugins only virtual SamplingDevices enumSampleSources() { return SamplingDevices(); } virtual PluginInstanceGUI* createSampleSourcePluginInstanceGUI( - const QString& sourceId __attribute__((unused)), - QWidget **widget __attribute__((unused)), - DeviceUISet *deviceUISet __attribute__((unused))) - { return 0; } + const QString& sourceId, + QWidget **widget, + DeviceUISet *deviceUISet) + { + (void) sourceId; + (void) widget; + (void) deviceUISet; + return nullptr; + } - virtual DeviceSampleSource* createSampleSourcePluginInstanceInput(const QString& sourceId __attribute__((unused)), DeviceSourceAPI *deviceAPI __attribute__((unused))) { return 0; } // creates the input "core" + virtual DeviceSampleSource* createSampleSourcePluginInstanceInput( // creates the input "core" + const QString& sourceId, + DeviceSourceAPI *deviceAPI) + { + (void) sourceId; + (void) deviceAPI; + return nullptr; + } virtual void deleteSampleSourcePluginInstanceGUI(PluginInstanceGUI *ui); virtual void deleteSampleSourcePluginInstanceInput(DeviceSampleSource *source); @@ -127,12 +159,25 @@ public: virtual SamplingDevices enumSampleSinks() { return SamplingDevices(); } virtual PluginInstanceGUI* createSampleSinkPluginInstanceGUI( - const QString& sinkId __attribute__((unused)), - QWidget **widget __attribute__((unused)), - DeviceUISet *deviceUISet __attribute__((unused))) - { return 0; } + const QString& sinkId, + QWidget **widget, + DeviceUISet *deviceUISet) + { + (void) sinkId; + (void) widget; + (void) deviceUISet; + return nullptr; + } + + virtual DeviceSampleSink* createSampleSinkPluginInstanceOutput( // creates the output "core" + const QString& sinkId, + DeviceSinkAPI *deviceAPI) + { + (void) sinkId; + (void) deviceAPI; + return nullptr; + } - virtual DeviceSampleSink* createSampleSinkPluginInstanceOutput(const QString& sinkId __attribute__((unused)), DeviceSinkAPI *deviceAPI __attribute__((unused))) { return 0; } // creates the output "core" virtual void deleteSampleSinkPluginInstanceGUI(PluginInstanceGUI *ui); virtual void deleteSampleSinkPluginInstanceOutput(DeviceSampleSink *sink); }; diff --git a/sdrbase/resources/res.qrc b/sdrbase/resources/res.qrc index 36e34505d..be9edc854 100644 --- a/sdrbase/resources/res.qrc +++ b/sdrbase/resources/res.qrc @@ -27,6 +27,7 @@ webapi/doc/swagger/include/SDRDaemonSource.yaml webapi/doc/swagger/include/SDRDaemonSink.yaml webapi/doc/swagger/include/SDRPlay.yaml + webapi/doc/swagger/include/SoapySDR.yaml webapi/doc/swagger/include/SSBDemod.yaml webapi/doc/swagger/include/SSBMod.yaml webapi/doc/swagger/include/Structs.yaml diff --git a/sdrbase/resources/webapi/doc/html2/index.html b/sdrbase/resources/webapi/doc/html2/index.html index 61c526a87..54b9dc825 100644 --- a/sdrbase/resources/webapi/doc/html2/index.html +++ b/sdrbase/resources/webapi/doc/html2/index.html @@ -1031,6 +1031,58 @@ margin-bottom: 20px; } }, "description" : "Airspy" +}; + defs.ArgInfo = { + "properties" : { + "key" : { + "type" : "string" + }, + "valueType" : { + "type" : "string", + "enum" : [ "bool", "int", "float", "string" ] + }, + "valueString" : { + "type" : "string" + }, + "name" : { + "type" : "string" + }, + "description" : { + "type" : "string" + }, + "units" : { + "type" : "string" + }, + "range" : { + "$ref" : "#/definitions/RangeFloat" + }, + "valueOptions" : { + "type" : "array", + "items" : { + "type" : "string" + } + }, + "optionNames" : { + "type" : "array", + "items" : { + "type" : "string" + } + } + } +}; + defs.ArgValue = { + "properties" : { + "key" : { + "type" : "string" + }, + "valueType" : { + "type" : "string", + "enum" : [ "bool", "int", "float", "string" ] + }, + "valueString" : { + "type" : "string" + } + } }; defs.AudioDevices = { "required" : [ "nbInputDevices", "nbOutputDevices" ], @@ -1636,6 +1688,19 @@ margin-bottom: 20px; } }, "description" : "All channels detailed information" +}; + defs.Complex = { + "properties" : { + "real" : { + "type" : "number", + "format" : "float" + }, + "imag" : { + "type" : "number", + "format" : "float" + } + }, + "description" : "A complex number" }; defs.DSDDemodReport = { "properties" : { @@ -1996,6 +2061,12 @@ margin-bottom: 20px; }, "sdrPlayReport" : { "$ref" : "#/definitions/SDRPlayReport" + }, + "soapySDRInputReport" : { + "$ref" : "#/definitions/SoapySDRReport" + }, + "soapySDROutputReport" : { + "$ref" : "#/definitions/SoapySDRReport" } }, "description" : "Base device report. Only the device report corresponding to the device specified in the deviceHwType is or should be present." @@ -2112,6 +2183,12 @@ margin-bottom: 20px; "sdrPlaySettings" : { "$ref" : "#/definitions/SDRPlaySettings" }, + "soapySDRInputSettings" : { + "$ref" : "#/definitions/SoapySDRInputSettings" + }, + "soapySDROutputSettings" : { + "$ref" : "#/definitions/SoapySDROutputSettings" + }, "testSourceSettings" : { "$ref" : "#/definitions/TestSourceSettings" } @@ -2549,6 +2626,14 @@ margin-bottom: 20px; "temperature" : { "type" : "number", "format" : "float" + }, + "gpioDir" : { + "type" : "integer", + "format" : "int8" + }, + "gpioPins" : { + "type" : "integer", + "format" : "int8" } }, "description" : "LimeSDR" @@ -2622,6 +2707,14 @@ margin-bottom: 20px; }, "fileRecordName" : { "type" : "string" + }, + "gpioDir" : { + "type" : "integer", + "format" : "int8" + }, + "gpioPins" : { + "type" : "integer", + "format" : "int8" } }, "description" : "LimeSDR" @@ -2663,6 +2756,14 @@ margin-bottom: 20px; "temperature" : { "type" : "number", "format" : "float" + }, + "gpioDir" : { + "type" : "integer", + "format" : "int8" + }, + "gpioPins" : { + "type" : "integer", + "format" : "int8" } }, "description" : "LimeSDR" @@ -2715,6 +2816,14 @@ margin-bottom: 20px; "transverterDeltaFrequency" : { "type" : "integer", "format" : "int64" + }, + "gpioDir" : { + "type" : "integer", + "format" : "int8" + }, + "gpioPins" : { + "type" : "integer", + "format" : "int8" } }, "description" : "LimeSDR" @@ -3331,7 +3440,24 @@ margin-bottom: 20px; "type" : "integer" } }, - "description" : "An arbitrary range of values" + "description" : "An arbitrary range of integer values" +}; + defs.RangeFloat = { + "properties" : { + "min" : { + "type" : "number", + "format" : "float" + }, + "max" : { + "type" : "number", + "format" : "float" + }, + "step" : { + "type" : "number", + "format" : "float" + } + }, + "description" : "An arbitrary range of floating point values" }; defs.RtlSdrReport = { "properties" : { @@ -3380,6 +3506,9 @@ margin-bottom: 20px; "noModMode" : { "type" : "integer" }, + "offsetTuning" : { + "type" : "integer" + }, "transverterMode" : { "type" : "integer" }, @@ -3828,6 +3957,275 @@ margin-bottom: 20px; } }, "description" : "Information about a logical device available from an attached hardware device that can be used as a sampling device" +}; + defs.SoapySDRFrequencySetting = { + "properties" : { + "name" : { + "type" : "string" + }, + "ranges" : { + "type" : "array", + "items" : { + "$ref" : "#/definitions/RangeFloat" + } + } + }, + "description" : "A named frequency setting specified by a range list" +}; + defs.SoapySDRGainSetting = { + "properties" : { + "name" : { + "type" : "string" + }, + "range" : { + "$ref" : "#/definitions/RangeFloat" + } + }, + "description" : "A named gain setting specified by its range" +}; + defs.SoapySDRInputSettings = { + "properties" : { + "centerFrequency" : { + "type" : "integer", + "format" : "int64" + }, + "LOppmTenths" : { + "type" : "integer" + }, + "devSampleRate" : { + "type" : "integer" + }, + "log2Decim" : { + "type" : "integer" + }, + "fcPos" : { + "type" : "integer" + }, + "softDCCorrection" : { + "type" : "integer", + "description" : "boolean not zero for true" + }, + "softIQCorrection" : { + "type" : "integer", + "description" : "boolean not zero for true" + }, + "transverterMode" : { + "type" : "integer", + "description" : "boolean not zero for true" + }, + "transverterDeltaFrequency" : { + "type" : "integer", + "format" : "int64" + }, + "fileRecordName" : { + "type" : "string" + }, + "antenna" : { + "type" : "string" + }, + "bandwidth" : { + "type" : "integer" + }, + "tunableElements" : { + "type" : "array", + "items" : { + "$ref" : "#/definitions/ArgValue" + } + }, + "globalGain" : { + "type" : "integer" + }, + "individualGains" : { + "type" : "array", + "items" : { + "$ref" : "#/definitions/ArgValue" + } + }, + "autoGain" : { + "type" : "integer", + "description" : "boolean not zero for true" + }, + "autoDCCorrection" : { + "type" : "integer", + "description" : "boolean not zero for true" + }, + "autoIQCorrection" : { + "type" : "integer", + "description" : "boolean not zero for true" + }, + "dcCorrection" : { + "$ref" : "#/definitions/Complex" + }, + "iqCorrection" : { + "$ref" : "#/definitions/Complex" + }, + "streamArgSettings" : { + "type" : "array", + "items" : { + "$ref" : "#/definitions/ArgValue" + } + }, + "deviceArgSettings" : { + "type" : "array", + "items" : { + "$ref" : "#/definitions/ArgValue" + } + } + }, + "description" : "SoapySDR" +}; + defs.SoapySDROutputSettings = { + "properties" : { + "centerFrequency" : { + "type" : "integer", + "format" : "int64" + }, + "LOppmTenths" : { + "type" : "integer" + }, + "devSampleRate" : { + "type" : "integer" + }, + "log2Interp" : { + "type" : "integer" + }, + "transverterMode" : { + "type" : "integer", + "description" : "boolean not zero for true" + }, + "transverterDeltaFrequency" : { + "type" : "integer", + "format" : "int64" + }, + "antenna" : { + "type" : "string" + }, + "bandwidth" : { + "type" : "integer" + }, + "tunableElements" : { + "type" : "array", + "items" : { + "$ref" : "#/definitions/ArgValue" + } + }, + "globalGain" : { + "type" : "integer" + }, + "individualGains" : { + "type" : "array", + "items" : { + "$ref" : "#/definitions/ArgValue" + } + }, + "autoGain" : { + "type" : "integer", + "description" : "boolean not zero for true" + }, + "autoDCCorrection" : { + "type" : "integer", + "description" : "boolean not zero for true" + }, + "autoIQCorrection" : { + "type" : "integer", + "description" : "boolean not zero for true" + }, + "dcCorrection" : { + "$ref" : "#/definitions/Complex" + }, + "iqCorrection" : { + "$ref" : "#/definitions/Complex" + }, + "streamArgSettings" : { + "type" : "array", + "items" : { + "$ref" : "#/definitions/ArgValue" + } + }, + "deviceArgSettings" : { + "type" : "array", + "items" : { + "$ref" : "#/definitions/ArgValue" + } + } + }, + "description" : "SoapySDR" +}; + defs.SoapySDRReport = { + "properties" : { + "deviceSettingsArgs" : { + "type" : "array", + "items" : { + "$ref" : "#/definitions/ArgInfo" + } + }, + "streamSettingsArgs" : { + "type" : "array", + "items" : { + "$ref" : "#/definitions/ArgInfo" + } + }, + "hasDCAutoCorrection" : { + "type" : "integer", + "description" : "boolean not zero for true" + }, + "hasDCOffsetValue" : { + "type" : "integer", + "description" : "boolean not zero for true" + }, + "hasIQBalanceValue" : { + "type" : "integer", + "description" : "boolean not zero for true" + }, + "hasFrequencyCorrectionValue" : { + "type" : "integer", + "description" : "boolean not zero for true" + }, + "antennas" : { + "type" : "array", + "items" : { + "type" : "string" + } + }, + "hasAGC" : { + "type" : "integer", + "description" : "boolean not zero for true" + }, + "gainRange" : { + "$ref" : "#/definitions/RangeFloat" + }, + "gainSettings" : { + "type" : "array", + "items" : { + "$ref" : "#/definitions/SoapySDRGainSetting" + } + }, + "frequencySettings" : { + "type" : "array", + "items" : { + "$ref" : "#/definitions/SoapySDRFrequencySetting" + } + }, + "frequencySettingsArgs" : { + "type" : "array", + "items" : { + "$ref" : "#/definitions/ArgInfo" + } + }, + "ratesRanges" : { + "type" : "array", + "items" : { + "$ref" : "#/definitions/RangeFloat" + } + }, + "bandwidthsRanges" : { + "type" : "array", + "items" : { + "$ref" : "#/definitions/RangeFloat" + } + } + }, + "description" : "SoapySDR" }; defs.SuccessResponse = { "required" : [ "message" ], @@ -4383,7 +4781,7 @@ margin-bottom: 20px;