From dcc9f1917c1cde23aa075701a8ffe529ed7aeafe Mon Sep 17 00:00:00 2001 From: John Greb Date: Mon, 17 Nov 2014 19:51:36 +0000 Subject: [PATCH] Downsample filtering. --- include-gpl/dsp/inthalfbandfilter.h | 53 +++++++++++++------- plugins/samplesource/rtlsdr/rtlsdrthread.cpp | 34 +++++++------ plugins/samplesource/rtlsdr/rtlsdrthread.h | 4 ++ 3 files changed, 56 insertions(+), 35 deletions(-) diff --git a/include-gpl/dsp/inthalfbandfilter.h b/include-gpl/dsp/inthalfbandfilter.h index ccc1bfa45..faa690cc2 100644 --- a/include-gpl/dsp/inthalfbandfilter.h +++ b/include-gpl/dsp/inthalfbandfilter.h @@ -223,9 +223,23 @@ public: } } + void myDecimate(Sample* sample1, Sample* sample2) + { + static const qint16 mod33[38] = { 31,32,0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19, + 20,21,22,23,24,25,26,27,28,29,30,31,32,0,1,2} ; + m_samples[m_ptr][0] = sample1->real(); + m_samples[m_ptr][1] = sample1->imag(); + m_ptr = mod33[m_ptr + 2 - 1]; + + m_samples[m_ptr][0] = sample2->real(); + m_samples[m_ptr][1] = sample2->imag(); + doFIR(sample2); + m_ptr = mod33[m_ptr + 2 - 1]; + } + protected: qint16 m_samples[HB_FILTERORDER + 1][2]; - int m_ptr; + qint16 m_ptr; int m_state; void doFIR(Sample* sample) @@ -267,15 +281,17 @@ protected: 0.317491986549921390015072120149852707982 * (1 << HB_SHIFT) }; #elif HB_FILTERORDER == 32 + static const qint16 mod33[38] = { 31,32,0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19, + 20,21,22,23,24,25,26,27,28,29,30,31,32,0,1,2} ; static const qint32 COEFF[8] = { - -0.015956912844043127236437484839370881673 * (1 << HB_SHIFT), - 0.013023031678944928940522274274371739011 * (1 << HB_SHIFT), - -0.01866942273717486777684371190844103694 * (1 << HB_SHIFT), - 0.026550887571157304190005987720724078827 * (1 << HB_SHIFT), - -0.038350314277854319344740474662103224546 * (1 << HB_SHIFT), - 0.058429248652825838128421764849917963147 * (1 << HB_SHIFT), - -0.102889802028955756885153505209018476307 * (1 << HB_SHIFT), - 0.317237706405931241260276465254719369113 * (1 << HB_SHIFT) + (qint32)(-0.015956912844043127236437484839370881673 * (1 << HB_SHIFT)), + (qint32)( 0.013023031678944928940522274274371739011 * (1 << HB_SHIFT)), + (qint32)(-0.01866942273717486777684371190844103694 * (1 << HB_SHIFT)), + (qint32)( 0.026550887571157304190005987720724078827 * (1 << HB_SHIFT)), + (qint32)(-0.038350314277854319344740474662103224546 * (1 << HB_SHIFT)), + (qint32)( 0.058429248652825838128421764849917963147 * (1 << HB_SHIFT)), + (qint32)(-0.102889802028955756885153505209018476307 * (1 << HB_SHIFT)), + (qint32)( 0.317237706405931241260276465254719369113 * (1 << HB_SHIFT)) }; #else #error unsupported filter order @@ -283,8 +299,8 @@ protected: // init read-pointer - int a = (m_ptr + 1) % (HB_FILTERORDER + 1); - int b = (m_ptr + (HB_FILTERORDER - 1)) % (HB_FILTERORDER + 1); + int a = mod33[m_ptr + 2 + 1]; // 0 + 1 + int b = mod33[m_ptr + 2 - 2]; //-1 - 1 // go through samples in buffer qint32 iAcc = 0; @@ -297,17 +313,16 @@ protected: qAcc += qTmp * COEFF[i]; // update read-pointer - a = (a + 2) % (HB_FILTERORDER + 1); - b = (b + (HB_FILTERORDER - 1)) % (HB_FILTERORDER + 1); + a = mod33[a + 2 + 2]; + b = mod33[b + 2 - 2]; } - a = (a + HB_FILTERORDER) % (HB_FILTERORDER + 1); - iAcc += m_samples[a][0] * (qint32)(0.5 * (1 << HB_SHIFT)); - qAcc += m_samples[a][1] * (qint32)(0.5 * (1 << HB_SHIFT)); + a = mod33[a + 2 - 1]; + iAcc += ((qint32)m_samples[a][0] + 1) << (HB_SHIFT - 1); + qAcc += ((qint32)m_samples[a][1] + 1) << (HB_SHIFT - 1); - // done, save result - sample->setReal((iAcc + (qint32)(0.5 * (1 << HB_SHIFT))) >> HB_SHIFT); - sample->setImag((qAcc + (qint32)(0.5 * (1 << HB_SHIFT))) >> HB_SHIFT); + sample->setReal(iAcc >> HB_SHIFT); + sample->setImag(qAcc >> HB_SHIFT); } }; diff --git a/plugins/samplesource/rtlsdr/rtlsdrthread.cpp b/plugins/samplesource/rtlsdr/rtlsdrthread.cpp index 8346668c7..fe9c4f981 100644 --- a/plugins/samplesource/rtlsdr/rtlsdrthread.cpp +++ b/plugins/samplesource/rtlsdr/rtlsdrthread.cpp @@ -96,7 +96,7 @@ void RTLSDRThread::decimate4(SampleVector::iterator* it, const quint8* buf, qint for (int pos = 0; pos < len - 7; pos += 8) { xreal = buf[pos+0] - buf[pos+3] + buf[pos+7] - buf[pos+4]; yimag = buf[pos+1] - buf[pos+5] + buf[pos+2] - buf[pos+6]; - Sample s( xreal << 4, yimag << 4 ); + Sample s( xreal << 3, yimag << 3 ); **it = s; (*it)++; } @@ -122,25 +122,29 @@ void RTLSDRThread::decimate16(SampleVector::iterator* it, const quint8* buf, qin { // Offset tuning: 4x downsample and rotate, then // downsample 4x more. [ rotate: 0, 1, -3, 2, -4, -5, 7, -6] - qint16 xreal, yimag; - for (int step = 0; step < len - 31; step +=32) { - xreal = yimag = 0; - for (int pos = step; pos < step + 32; pos += 8) { - xreal += buf[pos+0] - buf[pos+3] + buf[pos+7] - buf[pos+4]; - yimag += buf[pos+1] - buf[pos+5] + buf[pos+2] - buf[pos+6]; + qint16 xreal[4], yimag[4]; + bool b; + for (int pos = 0; pos < len - 31; ) { + for (int i = 0; i < 4; i++) { + xreal[i] = (buf[pos+0] - buf[pos+3] + buf[pos+7] - buf[pos+4]) << 4; + yimag[i] = (buf[pos+1] - buf[pos+5] + buf[pos+2] - buf[pos+6]) << 4; + pos += 8; } - Sample s( xreal << 3, yimag << 3 ); - **it = s; + Sample s1( xreal[0], yimag[0] ); + Sample s2( xreal[1], yimag[1] ); + Sample s3( xreal[2], yimag[2] ); + Sample s4( xreal[3], yimag[3] ); + m_decimator2.myDecimate(&s1, &s2); + m_decimator2.myDecimate(&s3, &s4); + m_decimator4.myDecimate(&s2, &s4); + **it = s4; (*it)++; } } -/* - Decimate everything by 16x, except 288kHz - TODO : no offset tuning for direct sampling -*/ +// Decimate everything by 16x, except 288kHz void RTLSDRThread::callback(const quint8* buf, qint32 len) { qint16 xreal, yimag, phase; @@ -149,14 +153,12 @@ void RTLSDRThread::callback(const quint8* buf, qint32 len) int mode = 0; if (m_samplerate < 800000) mode = 2; - // if (directsampling) mode++; switch(mode) { case 0: decimate16(&it, buf, len); break; case 1: - // no_rotate16(&it, buf, len); break; case 2: @@ -164,7 +166,6 @@ void RTLSDRThread::callback(const quint8* buf, qint32 len) break; case 3: - // norotate4(&it, buf, len); break; default: @@ -183,3 +184,4 @@ void RTLSDRThread::callbackHelper(unsigned char* buf, uint32_t len, void* ctx) RTLSDRThread* thread = (RTLSDRThread*)ctx; thread->callback(buf, len); } + diff --git a/plugins/samplesource/rtlsdr/rtlsdrthread.h b/plugins/samplesource/rtlsdr/rtlsdrthread.h index 13983b003..48e5aeabd 100644 --- a/plugins/samplesource/rtlsdr/rtlsdrthread.h +++ b/plugins/samplesource/rtlsdr/rtlsdrthread.h @@ -23,6 +23,7 @@ #include #include #include "dsp/samplefifo.h" +#include "dsp/inthalfbandfilter.h" class RTLSDRThread : public QThread { Q_OBJECT @@ -46,6 +47,9 @@ private: int m_samplerate; + IntHalfbandFilter m_decimator2; + IntHalfbandFilter m_decimator4; + void run(); void decimate2(SampleVector::iterator* it, const quint8* buf, qint32 len); void decimate4(SampleVector::iterator* it, const quint8* buf, qint32 len);