Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Make the streaming implementation more robust #1

Merged
merged 4 commits into from
Feb 23, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
16 changes: 5 additions & 11 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
4 changes: 1 addition & 3 deletions Settings.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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)
*/

Expand Down Expand Up @@ -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;
}
Expand All @@ -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();
Expand Down
3 changes: 2 additions & 1 deletion SoapySDRPlay.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,7 @@
class SoapySDRPlay: public SoapySDR::Device
{
public:
SoapySDRPlay(const SoapySDR::Kwargs &args);
explicit SoapySDRPlay(const SoapySDR::Kwargs &args);

~SoapySDRPlay(void);

Expand Down Expand Up @@ -296,6 +296,7 @@ class SoapySDRPlay: public SoapySDR::Device
std::vector<std::vector<short> > buffs;
size_t head;
size_t tail;
/// number of in-flight buffers
size_t count;
short *currentBuff;
bool overflowEvent;
Expand Down
27 changes: 18 additions & 9 deletions Streaming.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,8 @@
*/

#include "SoapySDRPlay.hpp"
#include <thread>
#include <chrono>

// globals declared in Registration.cpp
extern SoapySDR::Stream *activeStream;
Expand Down Expand Up @@ -105,6 +107,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
Expand Down Expand Up @@ -194,7 +199,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()
Expand Down Expand Up @@ -279,7 +283,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;
}

Expand Down Expand Up @@ -316,7 +320,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;
}

Expand Down Expand Up @@ -369,16 +372,22 @@ 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)
{
return 0;
using us = std::chrono::microseconds;
std::this_thread::sleep_for(us(timeoutUs));
if(!streamActive){
return SOAPY_SDR_TIMEOUT;
}
}

SoapySDRPlayStream *sdrplay_stream = reinterpret_cast<SoapySDRPlayStream *>(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.
Expand All @@ -388,8 +397,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;
Expand All @@ -405,7 +414,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
Expand Down