diff --git a/plugins/channelrx/wdsprx/CMakeLists.txt b/plugins/channelrx/wdsprx/CMakeLists.txt index d24c9587f..bb3b9f1d5 100644 --- a/plugins/channelrx/wdsprx/CMakeLists.txt +++ b/plugins/channelrx/wdsprx/CMakeLists.txt @@ -19,7 +19,8 @@ set(wdsprx_HEADERS ) include_directories( - ${CMAKE_SOURCE_DIR}/swagger/sdrangel/code/qt5/client + ${CMAKE_SOURCE_DIR}/swagger/sdrangel/code/qt5/client + ${CMAKE_SOURCE_DIR}/wdsp ) if(NOT SERVER_MODE) diff --git a/plugins/channelrx/wdsprx/wdsprxsink.cpp b/plugins/channelrx/wdsprx/wdsprxsink.cpp index 299a5192f..027b465da 100644 --- a/plugins/channelrx/wdsprx/wdsprxsink.cpp +++ b/plugins/channelrx/wdsprx/wdsprxsink.cpp @@ -25,11 +25,14 @@ #include "util/db.h" #include "util/messagequeue.h" #include "maincore.h" +#include "RXA.hpp" #include "wdsprxsink.h" const int WDSPRxSink::m_ssbFftLen = 2048; const int WDSPRxSink::m_agcTarget = 3276; // 32768/10 -10 dB amplitude => -20 dB power: center of normal signal +const int WDSPRxSink::m_wdspSampleRate = 48000; +const int WDSPRxSink::m_wdspBufSize = 512; WDSPRxSink::WDSPRxSink() : m_audioBinaual(false), @@ -69,6 +72,12 @@ WDSPRxSink::WDSPRxSink() : m_magsqPeak = 0.0; m_magsqCount = 0; + m_rxa = WDSP::RXA::create_rxa( + m_wdspSampleRate, // input samplerate + m_wdspSampleRate, // output samplerate + m_wdspSampleRate, // sample rate for mainstream dsp processing (dsp) + m_wdspBufSize // number complex samples processed per buffer in mainstream dsp processing + ); SSBFilter = new fftfilt(m_LowCutoff / m_audioSampleRate, m_Bandwidth / m_audioSampleRate, m_ssbFftLen); DSBFilter = new fftfilt((2.0f * m_Bandwidth) / m_audioSampleRate, 2 * m_ssbFftLen); @@ -81,6 +90,7 @@ WDSPRxSink::WDSPRxSink() : WDSPRxSink::~WDSPRxSink() { + WDSP::RXA::destroy_rxa(m_rxa); delete SSBFilter; delete DSBFilter; } @@ -289,7 +299,7 @@ void WDSPRxSink::applyChannelSettings(int channelSampleRate, int channelFrequenc Real interpolatorBandwidth = (m_Bandwidth * 1.5f) > channelSampleRate ? channelSampleRate : (m_Bandwidth * 1.5f); m_interpolator.create(16, channelSampleRate, interpolatorBandwidth, 2.0f); m_interpolatorDistanceRemain = 0; - m_interpolatorDistance = (Real) channelSampleRate / (Real) m_audioSampleRate; + m_interpolatorDistance = (Real) channelSampleRate / (Real) m_wdspSampleRate; } m_channelSampleRate = channelSampleRate; @@ -303,7 +313,9 @@ void WDSPRxSink::applyAudioSampleRate(int sampleRate) Real interpolatorBandwidth = (m_Bandwidth * 1.5f) > m_channelSampleRate ? m_channelSampleRate : (m_Bandwidth * 1.5f); m_interpolator.create(16, m_channelSampleRate, interpolatorBandwidth, 2.0f); m_interpolatorDistanceRemain = 0; - m_interpolatorDistance = (Real) m_channelSampleRate / (Real) sampleRate; + m_interpolatorDistance = (Real) m_channelSampleRate / (Real) m_wdspSampleRate; + + WDSP::RXA::setOutputSamplerate(m_rxa, sampleRate); SSBFilter->create_filter(m_LowCutoff / (float) sampleRate, m_Bandwidth / (float) sampleRate, m_settings.m_filterBank[m_settings.m_filterIndex].m_fftWindow); DSBFilter->create_dsb_filter(m_Bandwidth / (float) sampleRate, m_settings.m_filterBank[m_settings.m_filterIndex].m_fftWindow); diff --git a/plugins/channelrx/wdsprx/wdsprxsink.h b/plugins/channelrx/wdsprx/wdsprxsink.h index f2e9ccdac..d16b8c6ca 100644 --- a/plugins/channelrx/wdsprx/wdsprxsink.h +++ b/plugins/channelrx/wdsprx/wdsprxsink.h @@ -34,6 +34,10 @@ class SpectrumVis; class ChannelAPI; +namespace WDSP { + class RXA; +} + class WDSPRxSink : public ChannelSampleSink { public: WDSPRxSink(); @@ -132,9 +136,12 @@ private: QVector m_demodBuffer; int m_demodBufferFill; + WDSP::RXA *m_rxa; static const int m_ssbFftLen; static const int m_agcTarget; + static const int m_wdspSampleRate; + static const int m_wdspBufSize; void processOneSample(Complex &ci); }; diff --git a/wdsp/RXA.cpp b/wdsp/RXA.cpp index 0d3ab966e..4d4629079 100644 --- a/wdsp/RXA.cpp +++ b/wdsp/RXA.cpp @@ -58,24 +58,26 @@ namespace WDSP { RXA* RXA::create_rxa ( int in_rate, // input samplerate int out_rate, // output samplerate - int in_size, // input buffsize (complex samples) in a fexchange() operation int dsp_rate, // sample rate for mainstream dsp processing - int dsp_size, // number complex samples processed per buffer in mainstream dsp processing - int dsp_insize, // size (complex samples) of the output of the r1 (input) buffer - int dsp_outsize, // size (complex samples) of the input of the r2 (output) buffer - int out_size // output buffsize (complex samples) in a fexchange() operation + int dsp_size // number complex samples processed per buffer in mainstream dsp processing ) { RXA* rxa = new RXA; rxa->in_rate = in_rate; rxa->out_rate = out_rate; - rxa->in_size = in_size; rxa->dsp_rate = dsp_rate; rxa->dsp_size = dsp_size; - rxa->dsp_insize = dsp_insize; - rxa->dsp_outsize = dsp_outsize; - rxa->out_size = out_size; + + if (in_rate >= dsp_rate) + rxa->dsp_insize = dsp_size * (in_rate / dsp_rate); + else + rxa->dsp_insize = dsp_size / (dsp_rate / in_rate); + + if (out_rate >= dsp_rate) + rxa->dsp_outsize = dsp_size * (out_rate / dsp_rate); + else + rxa->dsp_outsize = dsp_size / (dsp_rate / out_rate); rxa->mode = RXA_LSB; rxa->inbuff = new double[1 * rxa->dsp_insize * 2]; // (double *) malloc0 (1 * ch.dsp_insize * sizeof (complex)); @@ -645,10 +647,13 @@ void RXA::xrxa (RXA *rxa) RESAMPLE::xresample (rxa->rsmpout.p); } -void RXA::setInputSamplerate (RXA *rxa, int dsp_insize, int in_rate) +void RXA::setInputSamplerate (RXA *rxa, int in_rate) { rxa->csDSP.lock(); - rxa->dsp_insize = dsp_insize; + if (in_rate >= rxa->dsp_rate) + rxa->dsp_insize = rxa->dsp_size * (in_rate / rxa->dsp_rate); + else + rxa->dsp_insize = rxa->dsp_size / (rxa->dsp_rate / in_rate); rxa->in_rate = in_rate; // buffers delete[] (rxa->inbuff); @@ -665,10 +670,13 @@ void RXA::setInputSamplerate (RXA *rxa, int dsp_insize, int in_rate) rxa->csDSP.unlock(); } -void RXA::setOutputSamplerate (RXA *rxa, int dsp_outsize, int out_rate) +void RXA::setOutputSamplerate (RXA *rxa, int out_rate) { rxa->csDSP.lock(); - rxa->dsp_outsize = dsp_outsize; + if (out_rate >= rxa->dsp_rate) + rxa->dsp_outsize = rxa->dsp_size * (out_rate / rxa->dsp_rate); + else + rxa->dsp_outsize = rxa->dsp_size / (rxa->dsp_rate / out_rate); rxa->out_rate = out_rate; // buffers delete[] (rxa->outbuff); @@ -680,11 +688,17 @@ void RXA::setOutputSamplerate (RXA *rxa, int dsp_outsize, int out_rate) rxa->csDSP.unlock(); } -void RXA::setDSPSamplerate (RXA *rxa, int dsp_insize, int dsp_outsize, int dsp_rate) +void RXA::setDSPSamplerate (RXA *rxa, int dsp_rate) { rxa->csDSP.lock(); - rxa->dsp_insize = dsp_insize; - rxa->dsp_outsize = dsp_outsize; + if (rxa->in_rate >= dsp_rate) + rxa->dsp_insize = rxa->dsp_size * (rxa->in_rate / dsp_rate); + else + rxa->dsp_insize = rxa->dsp_size / (dsp_rate / rxa->in_rate); + if (rxa->out_rate >= dsp_rate) + rxa->dsp_outsize = rxa->dsp_size * (rxa->out_rate / dsp_rate); + else + rxa->dsp_outsize = rxa->dsp_size / (dsp_rate / rxa->out_rate); rxa->dsp_rate = dsp_rate; // buffers delete[] (rxa->inbuff); @@ -731,12 +745,18 @@ void RXA::setDSPSamplerate (RXA *rxa, int dsp_insize, int dsp_outsize, int dsp_r rxa->csDSP.unlock(); } -void RXA::setDSPBuffsize (RXA *rxa, int dsp_insize, int dsp_size, int dsp_outsize) +void RXA::setDSPBuffsize (RXA *rxa, int dsp_size) { rxa->csDSP.lock(); - rxa->dsp_insize = dsp_insize; + if (rxa->in_rate >= rxa->dsp_rate) + rxa->dsp_insize = dsp_size * (rxa->in_rate / rxa->dsp_rate); + else + rxa->dsp_insize = dsp_size / (rxa->dsp_rate / rxa->in_rate); + if (rxa->out_rate >= rxa->dsp_rate) + rxa->dsp_outsize = dsp_size * (rxa->out_rate / rxa->dsp_rate); + else + rxa->dsp_outsize = dsp_size / (rxa->dsp_rate / rxa->out_rate); rxa->dsp_size = dsp_size; - rxa->dsp_outsize = dsp_outsize; // buffers delete[](rxa->inbuff); rxa->inbuff = new double[1 * rxa->dsp_insize * 2]; // (double *)malloc0(1 * rxa->dsp_insize * sizeof(complex)); diff --git a/wdsp/RXA.hpp b/wdsp/RXA.hpp index 333cff458..02e797044 100644 --- a/wdsp/RXA.hpp +++ b/wdsp/RXA.hpp @@ -95,9 +95,6 @@ public: RXA_METERTYPE_LAST }; - double* inbuff; - double* outbuff; - double* midbuff; int mode; double meter[RXA_METERTYPE_LAST]; QRecursiveMutex* pmtupdate[RXA_METERTYPE_LAST]; @@ -209,20 +206,20 @@ public: static RXA* create_rxa ( int in_rate, // input samplerate int out_rate, // output samplerate - int in_size, // input buffsize (complex samples) in a fexchange() operation int dsp_rate, // sample rate for mainstream dsp processing - int dsp_size, // number complex samples processed per buffer in mainstream dsp processing - int dsp_insize, // size (complex samples) of the output of the r1 (input) buffer - int dsp_outsize, // size (complex samples) of the input of the r2 (output) buffer - int out_size // output buffsize (complex samples) in a fexchange() operation + int dsp_size // number complex samples processed per buffer in mainstream dsp processing ); static void destroy_rxa (RXA *rxa); static void flush_rxa (RXA *rxa); static void xrxa (RXA *rxa); - static void setInputSamplerate (RXA *rxa, int dsp_insize, int in_rate); - static void setOutputSamplerate (RXA *rxa, int dsp_outsize, int out_rate); - static void setDSPSamplerate (RXA *rxa, int dsp_insize, int dsp_outsize, int dsp_rate); - static void setDSPBuffsize (RXA *rxa, int dsp_insize, int dsp_size, int dsp_outsize); + int get_insize() const { return dsp_insize; } + int get_outsize() const { return dsp_outsize; } + double *get_inbuff() { return inbuff; } + double *get_outbuff() { return outbuff; } + static void setInputSamplerate (RXA *rxa, int in_rate); + static void setOutputSamplerate (RXA *rxa, int out_rate); + static void setDSPSamplerate (RXA *rxa, int dsp_rate); + static void setDSPBuffsize (RXA *rxa, int dsp_size); // RXA Properties static void SetMode (RXA& rxa, int mode); @@ -236,6 +233,11 @@ public: static void SetPassband (RXA& rxa, double f_low, double f_high); static void SetNC (RXA& rxa, int nc); static void SetMP (RXA& rxa, int mp); + +private: + double* inbuff; + double* midbuff; + double* outbuff; }; } // namespace WDSP diff --git a/wdsp/TXA.cpp b/wdsp/TXA.cpp index af67eb069..6a414db4b 100644 --- a/wdsp/TXA.cpp +++ b/wdsp/TXA.cpp @@ -54,24 +54,26 @@ namespace WDSP { TXA* TXA::create_txa ( int in_rate, // input samplerate int out_rate, // output samplerate - int in_size, // input buffsize (complex samples) in a fexchange() operation int dsp_rate, // sample rate for mainstream dsp processing - int dsp_size, // number complex samples processed per buffer in mainstream dsp processing - int dsp_insize, // size (complex samples) of the output of the r1 (input) buffer - int dsp_outsize, // size (complex samples) of the input of the r2 (output) buffer - int out_size // output buffsize (complex samples) in a fexchange() operation + int dsp_size // number complex samples processed per buffer in mainstream dsp processing ) { TXA *txa = new TXA; txa->in_rate = in_rate; txa->out_rate = out_rate; - txa->in_size = in_size; txa->dsp_rate = dsp_rate; txa->dsp_size = dsp_size; - txa->dsp_insize = dsp_insize; - txa->dsp_outsize = dsp_outsize; - txa->out_size = out_size; + + if (in_rate >= dsp_rate) + txa->dsp_insize = dsp_size * (in_rate / dsp_rate); + else + txa->dsp_insize = dsp_size / (dsp_rate / in_rate); + + if (out_rate >= dsp_rate) + txa->dsp_outsize = dsp_size * (out_rate / dsp_rate); + else + txa->dsp_outsize = dsp_size / (dsp_rate / out_rate); txa->mode = TXA_LSB; txa->f_low = -5000.0; @@ -561,7 +563,7 @@ void TXA::destroy_txa (TXA *txa) delete txa; } -void flush_txa (TXA* txa) +void TXA::flush_txa (TXA* txa) { memset (txa->inbuff, 0, 1 * txa->dsp_insize * sizeof (dcomplex)); memset (txa->outbuff, 0, 1 * txa->dsp_outsize * sizeof (dcomplex)); @@ -635,10 +637,15 @@ void xtxa (TXA* txa) // print_peak_env ("env_exception.txt", txa->dsp_outsize, txa->outbuff, 0.7); } -void TXA::setInputSamplerate (TXA *txa, int dsp_insize, int in_rate) +void TXA::setInputSamplerate (TXA *txa, int in_rate) { txa->csDSP.lock(); - txa->dsp_insize = dsp_insize; + + if (in_rate >= txa->dsp_rate) + txa->dsp_insize = txa->dsp_size * (in_rate / txa->dsp_rate); + else + txa->dsp_insize = txa->dsp_size / (txa->dsp_rate / in_rate); + txa->in_rate = in_rate; // buffers delete[] (txa->inbuff); @@ -651,10 +658,15 @@ void TXA::setInputSamplerate (TXA *txa, int dsp_insize, int in_rate) txa->csDSP.unlock(); } -void TXA::setOutputSamplerate (TXA* txa, int dsp_outsize, int out_rate) +void TXA::setOutputSamplerate (TXA* txa, int out_rate) { txa->csDSP.lock(); - txa->dsp_outsize = dsp_outsize; + + if (out_rate >= txa->dsp_rate) + txa->dsp_outsize = txa->dsp_size * (out_rate / txa->dsp_rate); + else + txa->dsp_outsize = txa->dsp_size / (txa->dsp_rate / out_rate); + txa->out_rate = out_rate; // buffers delete[] (txa->outbuff); @@ -672,11 +684,20 @@ void TXA::setOutputSamplerate (TXA* txa, int dsp_outsize, int out_rate) txa->csDSP.unlock(); } -void TXA::setDSPSamplerate (TXA *txa, int dsp_insize, int dsp_outsize, int dsp_rate) +void TXA::setDSPSamplerate (TXA *txa, int dsp_rate) { txa->csDSP.lock(); - txa->dsp_insize = dsp_insize; - txa->dsp_outsize = dsp_outsize; + + if (txa->in_rate >= dsp_rate) + txa->dsp_insize = txa->dsp_size * (txa->in_rate / dsp_rate); + else + txa->dsp_insize = txa->dsp_size / (dsp_rate / txa->in_rate); + + if (txa->out_rate >= dsp_rate) + txa->dsp_outsize = txa->dsp_size * (txa->out_rate / dsp_rate); + else + txa->dsp_outsize = txa->dsp_size / (dsp_rate / txa->out_rate); + txa->dsp_rate = dsp_rate; // buffers delete[] (txa->inbuff); @@ -725,12 +746,21 @@ void TXA::setDSPSamplerate (TXA *txa, int dsp_insize, int dsp_outsize, int dsp_r txa->csDSP.unlock(); } -void TXA::setDSPBuffsize (TXA *txa, int dsp_insize, int dsp_size, int dsp_outsize) +void TXA::setDSPBuffsize (TXA *txa, int dsp_size) { txa->csDSP.lock(); - txa->dsp_insize = dsp_insize; + + if (txa->in_rate >= txa->dsp_rate) + txa->dsp_insize = dsp_size * (txa->in_rate / txa->dsp_rate); + else + txa->dsp_insize = dsp_size / (txa->dsp_rate / txa->in_rate); + + if (txa->out_rate >= txa->dsp_rate) + txa->dsp_outsize = dsp_size * (txa->out_rate / txa->dsp_rate); + else + txa->dsp_outsize = dsp_size / (txa->dsp_rate / txa->out_rate); + txa->dsp_size = dsp_size; - txa->dsp_outsize = dsp_outsize; // buffers delete[] (txa->inbuff); txa->inbuff = new double[1 * txa->dsp_insize * 2]; // (double *)malloc0(1 * txa->dsp_insize * sizeof(complex)); diff --git a/wdsp/TXA.hpp b/wdsp/TXA.hpp index e6ab30ae8..58b3d578d 100644 --- a/wdsp/TXA.hpp +++ b/wdsp/TXA.hpp @@ -124,9 +124,6 @@ public: TXA_METERTYPE_LAST }; - double* inbuff; - double* outbuff; - double* midbuff; int mode; double f_low; double f_high; @@ -223,20 +220,20 @@ public: static TXA* create_txa ( int in_rate, // input samplerate int out_rate, // output samplerate - int in_size, // input buffsize (complex samples) in a fexchange() operation int dsp_rate, // sample rate for mainstream dsp processing - int dsp_size, // number complex samples processed per buffer in mainstream dsp processing - int dsp_insize, // size (complex samples) of the output of the r1 (input) buffer - int dsp_outsize, // size (complex samples) of the input of the r2 (output) buffer - int out_size // output buffsize (complex samples) in a fexchange() operation + int dsp_size // number complex samples processed per buffer in mainstream dsp processing ); static void destroy_txa (TXA *txa); static void flush_txa (TXA *txa); static void xtxa (TXA *txa); - static void setInputSamplerate (TXA *txa, int dsp_insize, int in_rate); - static void setOutputSamplerate (TXA *txa, int dsp_outsize, int out_rate); - static void setDSPSamplerate (TXA *txa, int dsp_insize, int dsp_outsize, int dsp_rate); - static void setDSPBuffsize (TXA *txa, int dsp_insize, int dsp_size, int dsp_outsize); + int get_insize() const { return dsp_insize; } + int get_outsize() const { return dsp_outsize; } + double *get_inbuff() { return inbuff; } + double *get_outbuff() { return outbuff; } + static void setInputSamplerate (TXA *txa, int in_rate); + static void setOutputSamplerate (TXA *txa, int out_rate); + static void setDSPSamplerate (TXA *txa, int dsp_rate); + static void setDSPBuffsize (TXA *txa, int dsp_size); // TXA Properties static void SetMode (TXA& txa, int mode); @@ -251,6 +248,9 @@ public: private: static void ResCheck (TXA& txa); + double* inbuff; + double* midbuff; + double* outbuff; }; } // namespace WDSP diff --git a/wdsp/unit.hpp b/wdsp/unit.hpp index ee1fafcc2..35d917533 100644 --- a/wdsp/unit.hpp +++ b/wdsp/unit.hpp @@ -39,12 +39,10 @@ class WDSP_API Unit public: int in_rate; // input samplerate int out_rate; // output samplerate - int in_size; // input buffsize (complex samples) in a fexchange() operation int dsp_rate; // sample rate for mainstream dsp processing int dsp_size; // number complex samples processed per buffer in mainstream dsp processing - int dsp_insize; // size (complex samples) of the output of the r1 (input) buffer - int dsp_outsize; // size (complex samples) of the input of the r2 (output) buffer - int out_size; // output buffsize (complex samples) in a fexchange() operation + int dsp_insize; // size (complex samples) of the input buffer + int dsp_outsize; // size (complex samples) of the output buffer QRecursiveMutex csDSP; // used to block dsp while parameters are updated or buffers flushed QRecursiveMutex csEXCH; // used to block fexchange() while parameters are updated or buffers flushed int state; // 0 for unit OFF; 1 for unit ON