From 70ce8f1044cfc4e88cc3f34b6b2f82c7cb1c75e6 Mon Sep 17 00:00:00 2001 From: f4exb Date: Wed, 7 Feb 2018 23:44:20 +0100 Subject: [PATCH] Perseus support (6) --- plugins/samplesource/perseus/CMakeLists.txt | 12 +-- .../samplesource/perseus/perseusthread.cpp | 66 +++++++++++++- plugins/samplesource/perseus/perseusthread.h | 12 ++- sdrbase/dsp/decimators.h | 90 +++++++++++++++++++ 4 files changed, 168 insertions(+), 12 deletions(-) diff --git a/plugins/samplesource/perseus/CMakeLists.txt b/plugins/samplesource/perseus/CMakeLists.txt index 57673ba22..0d1e3f918 100644 --- a/plugins/samplesource/perseus/CMakeLists.txt +++ b/plugins/samplesource/perseus/CMakeLists.txt @@ -7,7 +7,7 @@ set(perseus_SOURCES # perseusinput.cpp # perseusplugin.cpp perseussettings.cpp -# perseusthread.cpp + perseusthread.cpp ) set(perseus_HEADERS @@ -15,7 +15,7 @@ set(perseus_HEADERS # perseusinput.h # perseusplugin.h perseussettings.h -# perseusthread.h + perseusthread.h ) set(perseus_FORMS @@ -27,15 +27,15 @@ include_directories( . ${CMAKE_CURRENT_BINARY_DIR} ${CMAKE_SOURCE_DIR}/swagger/sdrangel/code/qt5/client - ${LIBAIRSPYHFSRC} - ${LIBAIRSPYHFSRC}/libperseus/src + ${LIBPERSEUSSRC} + ${LIBPERSEUSSRC}/libperseus/src ) else (BUILD_DEBIAN) include_directories( . ${CMAKE_CURRENT_BINARY_DIR} ${CMAKE_SOURCE_DIR}/swagger/sdrangel/code/qt5/client - ${LIBAIRSPYHF_INCLUDE_DIR} + ${LIBPERSEUS_INCLUDE_DIR} ) endif (BUILD_DEBIAN) @@ -65,7 +65,7 @@ target_link_libraries(inputperseus else (BUILD_DEBIAN) target_link_libraries(inputperseus ${QT_LIBRARIES} - ${LIBAIRSPYHF_LIBRARIES} + ${LIBPERSEUS_LIBRARIES} sdrbase sdrgui swagger diff --git a/plugins/samplesource/perseus/perseusthread.cpp b/plugins/samplesource/perseus/perseusthread.cpp index eff34912c..5dee339a0 100644 --- a/plugins/samplesource/perseus/perseusthread.cpp +++ b/plugins/samplesource/perseus/perseusthread.cpp @@ -17,12 +17,56 @@ #include #include "perseusthread.h" +PerseusThread::PerseusThread(perseus_descr* dev, SampleSinkFifo* sampleFifo, QObject* parent) : + QThread(parent), + m_running(false), + m_dev(dev), + m_convertBuffer(PERSEUS_NBSAMPLES), + m_sampleFifo(sampleFifo), + m_samplerate(10), + m_log2Decim(0) +{ + m_this = this; +} + +PerseusThread::~PerseusThread() +{ + stopWork(); + m_this = 0; +} + +void PerseusThread::startWork() +{ + m_startWaitMutex.lock(); + start(); + while(!m_running) + m_startWaiter.wait(&m_startWaitMutex, 100); + m_startWaitMutex.unlock(); +} + +void PerseusThread::stopWork() +{ + qDebug("AirspyThread::stopWork"); + m_running = false; + wait(); +} + +void PerseusThread::setSamplerate(uint32_t samplerate) +{ + m_samplerate = samplerate; +} + +void PerseusThread::setLog2Decimation(unsigned int log2_decim) +{ + m_log2Decim = log2_decim; +} + void PerseusThread::run() { m_running = true; m_startWaiter.wakeAll(); - int rc = perseus_start_async_input(m_dev, 6*1024, rx_callback, 0); + int rc = perseus_start_async_input(m_dev, PERSEUS_BLOCKSIZE, rx_callback, 0); if (rc < 0) { qCritical("PerseusThread::run: failed to start Perseus Rx: %s", perseus_errorstr()); @@ -47,12 +91,30 @@ void PerseusThread::run() void PerseusThread::callback(const uint8_t* buf, qint32 len) { + SampleVector::iterator it = m_convertBuffer.begin(); + switch (m_log2Decim) + { + case 0: + m_decimators32.decimate1(&it, (TripleByteLE*) buf, len); + break; + case 1: + m_decimators64.decimate2_cen(&it, (TripleByteLE*) buf, len); + break; + case 2: + m_decimators64.decimate4_cen(&it, (TripleByteLE*) buf, len); + break; + default: + break; + } + + m_sampleFifo->write(m_convertBuffer.begin(), it); } -int PerseusThread::rx_callback(void *buf, int buf_size, void *extra) +int PerseusThread::rx_callback(void *buf, int buf_size, void *extra __attribute__((unused))) { 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/perseus/perseusthread.h b/plugins/samplesource/perseus/perseusthread.h index 2929dd4dd..a4ab5540e 100644 --- a/plugins/samplesource/perseus/perseusthread.h +++ b/plugins/samplesource/perseus/perseusthread.h @@ -22,8 +22,11 @@ #include #include "perseus-sdr.h" -//#define PERSEUS_NBSAMPLES = 1024 // Number of I/Q samples in each callback from Perseus -//#define PERSEUS_BLOCKSIZE = 6*PERSEUS_NBSAMPLES // Perseus sends 2*3 bytes samples +#include "dsp/samplesinkfifo.h" +#include "dsp/decimators.h" + +#define PERSEUS_NBSAMPLES 1024 // Number of I/Q samples in each callback from Perseus +#define PERSEUS_BLOCKSIZE 6*PERSEUS_NBSAMPLES // Perseus sends 2*3 bytes samples class PerseusThread : public QThread { Q_OBJECT @@ -43,7 +46,7 @@ private: bool m_running; perseus_descr* m_dev; - qint32 m_buf[2*1024]; + qint32 m_buf[2*PERSEUS_NBSAMPLES]; SampleVector m_convertBuffer; SampleSinkFifo* m_sampleFifo; @@ -51,7 +54,8 @@ private: unsigned int m_log2Decim; static PerseusThread *m_this; - Decimators m_decimators; + Decimators, SDR_RX_SAMP_SZ, 16> m_decimators32; + Decimators, SDR_RX_SAMP_SZ, 16> m_decimators64; void run(); void callback(const uint8_t* buf, qint32 len); // inner call back diff --git a/sdrbase/dsp/decimators.h b/sdrbase/dsp/decimators.h index 9abd7350c..a854edc75 100644 --- a/sdrbase/dsp/decimators.h +++ b/sdrbase/dsp/decimators.h @@ -192,6 +192,96 @@ struct decimation_shifts<24, 8> static const uint post64 = 0; }; +template +struct TripleByteLE +{ + uint8_t b0; + uint8_t b1; + uint8_t b2; + + typedef union { + struct { + int32_t i; + } __attribute__((__packed__)); + struct { + uint8_t i0; + uint8_t i1; + uint8_t i2; + uint8_t i3; + } __attribute__((__packed__)); + } isample; + + operator T() const { + isample s; + s.i0 = 0; + s.i1 = b0; + s.i2 = b1; + s.i3 = b2; + return s.i; + } +} __attribute__((__packed__)); + +template<> +struct TripleByteLE +{ + uint8_t b0; + uint8_t b1; + uint8_t b2; + + typedef union { + struct { + qint32 i; + } __attribute__((__packed__)); + struct { + uint8_t i0; + uint8_t i1; + uint8_t i2; + uint8_t i3; + } __attribute__((__packed__)); + } isample; + + operator qint32() const { + isample s; + s.i0 = 0; + s.i1 = b0; + s.i2 = b1; + s.i3 = b2; + return s.i >> 8; + } +} __attribute__((__packed__)); + +template<> +struct TripleByteLE +{ + uint8_t b0; + uint8_t b1; + uint8_t b2; + + typedef union { + struct { + qint64 i; + } __attribute__((__packed__)); + struct { + uint32_t ia; + uint8_t i0; + uint8_t i1; + uint8_t i2; + uint8_t i3; + } __attribute__((__packed__)); + } 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; + } +} __attribute__((__packed__)); + + template class Decimators {