From 70bfad431ce54173600a57933bac14964ba156ba Mon Sep 17 00:00:00 2001 From: Felix Moessbauer Date: Sun, 23 Feb 2020 11:52:19 +0100 Subject: [PATCH 1/4] fix: do not use exceptions in streaming API --- Settings.cpp | 2 +- Streaming.cpp | 13 ++++++------- 2 files changed, 7 insertions(+), 8 deletions(-) diff --git a/Settings.cpp b/Settings.cpp index 7dc9846..b7d17dd 100644 --- a/Settings.cpp +++ b/Settings.cpp @@ -756,7 +756,7 @@ SoapySDR::ArgInfoList SoapySDRPlay::getFrequencyArgsInfo(const int direction, co ******************************************************************/ /* input_sample_rate: sample rate used by the SDR - * output_sample_rate: sample rate the as seen by the client app + * output_sample_rate: sample rate as seen by the client app * (<= input_sample_rate because of decimation) */ diff --git a/Streaming.cpp b/Streaming.cpp index 9d66f78..deb262c 100644 --- a/Streaming.cpp +++ b/Streaming.cpp @@ -279,7 +279,7 @@ int SoapySDRPlay::activateStream(SoapySDR::Stream *stream, { if (flags != 0) { - throw std::runtime_error("error in activateStream() - flags != 0"); + SoapySDR_log(SOAPY_SDR_ERROR, "error in activateStream() - flags != 0"); return SOAPY_SDR_NOT_SUPPORTED; } @@ -316,7 +316,6 @@ int SoapySDRPlay::activateStream(SoapySDR::Stream *stream, if (err != sdrplay_api_Success) { SoapySDR_logf(SOAPY_SDR_ERROR, "error in activateStream() - Init() failed: %s", sdrplay_api_GetErrorString(err)); - throw std::runtime_error("error in activateStream() - Init() failed"); return SOAPY_SDR_NOT_SUPPORTED; } @@ -377,8 +376,8 @@ int SoapySDRPlay::readStream(SoapySDR::Stream *stream, SoapySDRPlayStream *sdrplay_stream = reinterpret_cast(stream); if (_streams[sdrplay_stream->channel] == 0) { - throw std::runtime_error("readStream stream not activated"); - return 0; + //throw std::runtime_error("readStream stream not activated"); + return SOAPY_SDR_STREAM_ERROR; } // are elements left in the buffer? if not, do a new read. @@ -388,8 +387,8 @@ int SoapySDRPlay::readStream(SoapySDR::Stream *stream, if (ret < 0) { - SoapySDR_logf(SOAPY_SDR_ERROR, "readStream() failed: %s", SoapySDR_errToStr(ret)); - throw std::runtime_error("readStream() failed"); + // Do not generate logs here, as interleaving with stream indicators + //SoapySDR_logf(SOAPY_SDR_WARNING, "readStream() failed: %s", SoapySDR_errToStr(ret)); return ret; } sdrplay_stream->nElems = ret; @@ -405,7 +404,7 @@ int SoapySDRPlay::readStream(SoapySDR::Stream *stream, } else { - std::memcpy(buffs[0], (float *)sdrplay_stream->currentBuff, returnedElems * 2 * sizeof(float)); + std::memcpy(buffs[0], (float*)((void*)sdrplay_stream->currentBuff), returnedElems * 2 * sizeof(float)); } // bump variables for next call into readStream From 85d92b0afdd1f23e516ad0b7b0a6342441709124 Mon Sep 17 00:00:00 2001 From: Felix Moessbauer Date: Sun, 23 Feb 2020 12:01:05 +0100 Subject: [PATCH 2/4] fix: addressed cppcheck warnings --- Settings.cpp | 2 -- SoapySDRPlay.hpp | 2 +- Streaming.cpp | 2 +- 3 files changed, 2 insertions(+), 4 deletions(-) diff --git a/Settings.cpp b/Settings.cpp index b7d17dd..e2e6b47 100644 --- a/Settings.cpp +++ b/Settings.cpp @@ -1643,7 +1643,6 @@ void SoapySDRPlay::releaseDevice() sdrplay_api_UnlockDeviceApi(); SoapySDR_logf(SOAPY_SDR_ERROR, "ReleaseDevice Error: %s", sdrplay_api_GetErrorString(err)); throw std::runtime_error("ReleaseDevice() failed"); - return; } deviceSelected = nullptr; } @@ -1660,7 +1659,6 @@ void SoapySDRPlay::selectDevice() sdrplay_api_UnlockDeviceApi(); SoapySDR_logf(SOAPY_SDR_ERROR, "SelectDevice Error: %s", sdrplay_api_GetErrorString(err)); throw std::runtime_error("SelectDevice() failed"); - return; } sdrplay_api_UnlockDeviceApi(); diff --git a/SoapySDRPlay.hpp b/SoapySDRPlay.hpp index 1ec995b..8220031 100644 --- a/SoapySDRPlay.hpp +++ b/SoapySDRPlay.hpp @@ -46,7 +46,7 @@ class SoapySDRPlay: public SoapySDR::Device { public: - SoapySDRPlay(const SoapySDR::Kwargs &args); + explicit SoapySDRPlay(const SoapySDR::Kwargs &args); ~SoapySDRPlay(void); diff --git a/Streaming.cpp b/Streaming.cpp index deb262c..7cfe94d 100644 --- a/Streaming.cpp +++ b/Streaming.cpp @@ -404,7 +404,7 @@ int SoapySDRPlay::readStream(SoapySDR::Stream *stream, } else { - std::memcpy(buffs[0], (float*)((void*)sdrplay_stream->currentBuff), returnedElems * 2 * sizeof(float)); + std::memcpy(buffs[0], (float *)(void*)sdrplay_stream->currentBuff, returnedElems * 2 * sizeof(float)); } // bump variables for next call into readStream From 20c5d8a0a9e8958e09f265b99ac2135389f80976 Mon Sep 17 00:00:00 2001 From: Felix Moessbauer Date: Sun, 23 Feb 2020 14:14:27 +0100 Subject: [PATCH 3/4] fix: properly handle reads on inactive streams --- SoapySDRPlay.hpp | 1 + Streaming.cpp | 7 +++++-- 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/SoapySDRPlay.hpp b/SoapySDRPlay.hpp index 8220031..bbf81d5 100644 --- a/SoapySDRPlay.hpp +++ b/SoapySDRPlay.hpp @@ -296,6 +296,7 @@ class SoapySDRPlay: public SoapySDR::Device std::vector > buffs; size_t head; size_t tail; + /// number of in-flight buffers size_t count; short *currentBuff; bool overflowEvent; diff --git a/Streaming.cpp b/Streaming.cpp index 7cfe94d..92e47df 100644 --- a/Streaming.cpp +++ b/Streaming.cpp @@ -105,6 +105,9 @@ void SoapySDRPlay::rx_callback(short *xi, short *xq, unsigned int numSamples, // get current fill buffer auto &buff = stream->buffs[stream->tail]; + + // we do not reallocate here, as we only resize within + // the buffers capacity buff.resize(buff.size() + spaceReqd); // copy into the buffer queue @@ -194,7 +197,6 @@ SoapySDRPlay::SoapySDRPlayStream::SoapySDRPlayStream(size_t channel, // allocate buffers buffs.resize(numBuffers); for (auto &buff : buffs) buff.reserve(bufferLength); - for (auto &buff : buffs) buff.clear(); } SoapySDRPlay::SoapySDRPlayStream::~SoapySDRPlayStream() @@ -370,7 +372,8 @@ int SoapySDRPlay::readStream(SoapySDR::Stream *stream, { if (!streamActive) { - return 0; + // TODO: wait timeoutUS and try again + return SOAPY_SDR_TIMEOUT; } SoapySDRPlayStream *sdrplay_stream = reinterpret_cast(stream); From 9e41cdde47d0d8b72d6f12a6ebb35e4a1377dfab Mon Sep 17 00:00:00 2001 From: Felix Moessbauer Date: Sun, 23 Feb 2020 14:46:36 +0100 Subject: [PATCH 4/4] fix: wait for timeout in readStream on disabled stream --- CMakeLists.txt | 16 +++++----------- Streaming.cpp | 11 +++++++++-- 2 files changed, 14 insertions(+), 13 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index acd1c1b..57fcc56 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -21,21 +21,15 @@ message(STATUS "LIBSDRPLAY_LIBRARIES - ${LIBSDRPLAY_LIBRARIES}") include_directories(${CMAKE_CURRENT_SOURCE_DIR}) include_directories(${LIBSDRPLAY_INCLUDE_DIRS}) +# As SoapySDR requires this, we can safely +# do the same +set(CMAKE_CXX_STANDARD 11) +set(CMAKE_CXX_STANDARD_REQUIRED ON) + #enable c++11 features if(CMAKE_COMPILER_IS_GNUCXX) - - #C++11 is a required language feature for this project - include(CheckCXXCompilerFlag) - CHECK_CXX_COMPILER_FLAG("-std=c++11" HAS_STD_CXX11) - if(HAS_STD_CXX11) - set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++11") - else(HAS_STD_CXX11) - set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++0x") - endif() - #disable warnings for unused parameters add_definitions(-Wno-unused-parameter) - endif(CMAKE_COMPILER_IS_GNUCXX) # Configurable feature set diff --git a/Streaming.cpp b/Streaming.cpp index 92e47df..6c8f712 100644 --- a/Streaming.cpp +++ b/Streaming.cpp @@ -25,6 +25,8 @@ */ #include "SoapySDRPlay.hpp" +#include +#include // globals declared in Registration.cpp extern SoapySDR::Stream *activeStream; @@ -370,10 +372,15 @@ int SoapySDRPlay::readStream(SoapySDR::Stream *stream, long long &timeNs, const long timeoutUs) { + // the API requests us to wait until either the + // timeout is reached or the stream is activated if (!streamActive) { - // TODO: wait timeoutUS and try again - return SOAPY_SDR_TIMEOUT; + using us = std::chrono::microseconds; + std::this_thread::sleep_for(us(timeoutUs)); + if(!streamActive){ + return SOAPY_SDR_TIMEOUT; + } } SoapySDRPlayStream *sdrplay_stream = reinterpret_cast(stream);