diff --git a/CMakeLists.txt b/CMakeLists.txt index 6a0a9ff51..045a10b06 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -397,7 +397,7 @@ if (BUILD_DEBIAN) endif (BUILD_DEBIAN) set_target_properties(sdrbase PROPERTIES DEFINE_SYMBOL "sdrangel_EXPORTS") -target_compile_features(sdrbase PUBLIC cxx_generalized_initializers) # cmake >= 3.1.0 +target_compile_features(sdrbase PRIVATE cxx_generalized_initializers) # cmake >= 3.1.0 qt5_use_modules(sdrbase Core Widgets OpenGL Multimedia) diff --git a/plugins/samplesource/bladerf/bladerfthread.h b/plugins/samplesource/bladerf/bladerfthread.h index 85f94213d..6abf3ee60 100644 --- a/plugins/samplesource/bladerf/bladerfthread.h +++ b/plugins/samplesource/bladerf/bladerfthread.h @@ -54,36 +54,9 @@ private: unsigned int m_log2Decim; int m_fcPos; - /* - IntHalfbandFilter m_decimator2; // 1st stages - IntHalfbandFilter m_decimator4; // 2nd stages - IntHalfbandFilter m_decimator8; // 3rd stages - IntHalfbandFilter m_decimator16; // 4th stages - IntHalfbandFilter m_decimator32; // 5th stages - */ - Decimators m_decimators; void run(); - /* - void decimate1(SampleVector::iterator* it, const qint16* buf, qint32 len); - void decimate2_u(SampleVector::iterator* it, const quint16* buf, qint32 len); - void decimate2(SampleVector::iterator* it, const qint16* buf, qint32 len); - void decimate2_sup(SampleVector::iterator* it, const qint16* buf, qint32 len); - void decimate2_cen(SampleVector::iterator* it, const qint16* buf, qint32 len); - void decimate4(SampleVector::iterator* it, const qint16* buf, qint32 len); - void decimate4_sup(SampleVector::iterator* it, const qint16* buf, qint32 len); - void decimate4_cen(SampleVector::iterator* it, const qint16* buf, qint32 len); - void decimate8(SampleVector::iterator* it, const qint16* buf, qint32 len); - void decimate8_sup(SampleVector::iterator* it, const qint16* buf, qint32 len); - void decimate8_cen(SampleVector::iterator* it, const qint16* buf, qint32 len); - void decimate16(SampleVector::iterator* it, const qint16* buf, qint32 len); - void decimate16_sup(SampleVector::iterator* it, const qint16* buf, qint32 len); - void decimate16_cen(SampleVector::iterator* it, const qint16* buf, qint32 len); - void decimate32(SampleVector::iterator* it, const qint16* buf, qint32 len); - void decimate32_sup(SampleVector::iterator* it, const qint16* buf, qint32 len); - void decimate32_cen(SampleVector::iterator* it, const qint16* buf, qint32 len); - */ void callback(const qint16* buf, qint32 len); }; diff --git a/plugins/samplesource/rtlsdr/rtlsdrthread.h b/plugins/samplesource/rtlsdr/rtlsdrthread.h index 8aad5b0ee..b5b35e080 100644 --- a/plugins/samplesource/rtlsdr/rtlsdrthread.h +++ b/plugins/samplesource/rtlsdr/rtlsdrthread.h @@ -23,7 +23,7 @@ #include #include -#include "../../../sdrbase/dsp/samplesinkfifo.h" +#include "dsp/samplesinkfifo.h" #include "dsp/decimators.h" class RTLSDRThread : public QThread { diff --git a/sdrbase/dsp/decimators.h b/sdrbase/dsp/decimators.h index 403e908fc..7b25be45c 100644 --- a/sdrbase/dsp/decimators.h +++ b/sdrbase/dsp/decimators.h @@ -20,20 +20,22 @@ #include "dsp/dsptypes.h" #include "dsp/inthalfbandfilter.h" -template +#define DECIMATORS_HB_FILTER_ORDER 48 + +template struct decimation_shifts { - static const uint pre1 = 0; - static const uint pre2 = 0; - static const uint post2 = 0; - static const uint pre4 = 0; - static const uint post4 = 0; - static const uint pre8 = 0; - static const uint post8 = 0; - static const uint pre16 = 0; - static const uint post16 = 0; - static const uint pre32 = 0; - static const uint post32 = 0; + static const uint pre1 = 0; + static const uint pre2 = 0; + static const uint post2 = 0; + static const uint pre4 = 0; + static const uint post4 = 0; + static const uint pre8 = 0; + static const uint post8 = 0; + static const uint pre16 = 0; + static const uint post16 = 0; + static const uint pre32 = 0; + static const uint post32 = 0; static const uint pre64 = 0; static const uint post64 = 0; }; @@ -59,17 +61,17 @@ struct decimation_shifts<16, 16> template<> struct decimation_shifts<16, 12> { - static const uint pre1 = 4; - static const uint pre2 = 3; - static const uint post2 = 0; - static const uint pre4 = 2; - static const uint post4 = 0; - static const uint pre8 = 1; - static const uint post8 = 0; - static const uint pre16 = 0; - static const uint post16 = 0; - static const uint pre32 = 0; - static const uint post32 = 1; + static const uint pre1 = 4; + static const uint pre2 = 3; + static const uint post2 = 0; + static const uint pre4 = 2; + static const uint post4 = 0; + static const uint pre8 = 1; + static const uint post8 = 0; + static const uint pre16 = 0; + static const uint post16 = 0; + static const uint pre32 = 0; + static const uint post32 = 1; static const uint pre64 = 0; static const uint post64 = 2; }; @@ -79,15 +81,15 @@ struct decimation_shifts<16, 8> { static const uint pre1 = 6; static const uint pre2 = 5; - static const uint post2 = 0; + static const uint post2 = 0; static const uint pre4 = 4; - static const uint post4 = 0; + static const uint post4 = 0; static const uint pre8 = 3; - static const uint post8 = 0; + static const uint post8 = 0; static const uint pre16 = 2; - static const uint post16 = 0; + static const uint post16 = 0; static const uint pre32 = 1; - static const uint post32 = 0; + static const uint post32 = 0; static const uint pre64 = 0; static const uint post64 = 0; }; @@ -118,12 +120,12 @@ public: void decimate64_cen(SampleVector::iterator* it, const T* buf, qint32 len); private: - IntHalfbandFilter m_decimator2; // 1st stages - IntHalfbandFilter m_decimator4; // 2nd stages - IntHalfbandFilter m_decimator8; // 3rd stages - IntHalfbandFilter m_decimator16; // 4th stages - IntHalfbandFilter m_decimator32; // 5th stages - IntHalfbandFilter m_decimator64; // 6th stages + IntHalfbandFilter m_decimator2; // 1st stages + IntHalfbandFilter m_decimator4; // 2nd stages + IntHalfbandFilter m_decimator8; // 3rd stages + IntHalfbandFilter m_decimator16; // 4th stages + IntHalfbandFilter m_decimator32; // 5th stages + IntHalfbandFilter m_decimator64; // 6th stages }; template @@ -308,7 +310,7 @@ void Decimators::decimate16_inf(SampleVector::iterator* i m_decimator2.myDecimate(xreal[0], yimag[0], &xreal[1], &yimag[1]); m_decimator2.myDecimate(xreal[2], yimag[2], &xreal[3], &yimag[3]); - + m_decimator4.myDecimate(xreal[1], yimag[1], &xreal[3], &yimag[3]); (**it).setReal(xreal[3] >> decimation_shifts::post16); diff --git a/sdrbase/dsp/downchannelizer.cpp b/sdrbase/dsp/downchannelizer.cpp index d2452c98f..7ebcd92d1 100644 --- a/sdrbase/dsp/downchannelizer.cpp +++ b/sdrbase/dsp/downchannelizer.cpp @@ -187,20 +187,20 @@ void DownChannelizer::applyConfiguration() } DownChannelizer::FilterStage::FilterStage(Mode mode) : - m_filter(new IntHalfbandFilter), + m_filter(new IntHalfbandFilter), m_workFunction(0) { switch(mode) { case ModeCenter: - m_workFunction = &IntHalfbandFilter::workDecimateCenter; + m_workFunction = &IntHalfbandFilter::workDecimateCenter; break; case ModeLowerHalf: - m_workFunction = &IntHalfbandFilter::workDecimateLowerHalf; + m_workFunction = &IntHalfbandFilter::workDecimateLowerHalf; break; case ModeUpperHalf: - m_workFunction = &IntHalfbandFilter::workDecimateUpperHalf; + m_workFunction = &IntHalfbandFilter::workDecimateUpperHalf; break; } } diff --git a/sdrbase/dsp/downchannelizer.h b/sdrbase/dsp/downchannelizer.h index 3979a14b7..96b36f211 100644 --- a/sdrbase/dsp/downchannelizer.h +++ b/sdrbase/dsp/downchannelizer.h @@ -23,9 +23,11 @@ #include #include "util/export.h" #include "util/message.h" +#include "dsp/inthalfbandfilter.h" + +#define DOWNCHANNELIZER_HB_FILTER_ORDER 48 class MessageQueue; -class IntHalfbandFilter; class SDRANGEL_API DownChannelizer : public BasebandSampleSink { Q_OBJECT @@ -67,8 +69,8 @@ protected: ModeUpperHalf }; - typedef bool (IntHalfbandFilter::*WorkFunction)(Sample* s); - IntHalfbandFilter* m_filter; + typedef bool (IntHalfbandFilter::*WorkFunction)(Sample* s); + IntHalfbandFilter* m_filter; WorkFunction m_workFunction; FilterStage(Mode mode); diff --git a/sdrbase/dsp/inthalfbandfilter.cpp b/sdrbase/dsp/inthalfbandfilter.cpp index db41dc996..7b876ba71 100644 --- a/sdrbase/dsp/inthalfbandfilter.cpp +++ b/sdrbase/dsp/inthalfbandfilter.cpp @@ -1,11 +1,102 @@ #include "dsp/inthalfbandfilter.h" -IntHalfbandFilter::IntHalfbandFilter() -{ - for(int i = 0; i < HB_FILTERORDER + 1; i++) { - m_samples[i][0] = 0; - m_samples[i][1] = 0; - } - m_ptr = 0; - m_state = 0; -} +const qint16 HBFIRFilterTraits<32>::hbMod[32+6] = { + 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 +}; + + +const qint32 HBFIRFilterTraits<32>::hbCoeffs[8] = { + //* Firwin as in https://www.dsprelated.com/showcode/270.php */ + (qint32)(-0.0018878783958199373254477348993418672762 * (1 << hbShift)), + (qint32)( 0.0038624783041994003966734805288751886110 * (1 << hbShift)), + (qint32)(-0.0082424665965482504098593707908548822161 * (1 << hbShift)), + (qint32)( 0.0159471139705940345709933581019868142903 * (1 << hbShift)), + (qint32)(-0.0286765592339759019246958615667608682998 * (1 << hbShift)), + (qint32)( 0.0507185615622293764492845014046906726435 * (1 << hbShift)), + (qint32)(-0.0980159074728618323613105189906491432339 * (1 << hbShift)), + (qint32)( 0.3159417644358786247948955860920250415802 * (1 << hbShift)), +}; + +const qint16 HBFIRFilterTraits<48>::hbMod[48+6] = { + 47,48,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,33,34,35,36,37,38,39,40,41,42,43,44,45,46, + 47,48,0,1,2 +}; + + +const qint32 HBFIRFilterTraits<48>::hbCoeffs[12] = { + //* Firwin as in https://www.dsprelated.com/showcode/270.php */ + (qint32)(-0.0011627994808655962074434020436797254661 * (1 << hbShift)), + (qint32)( 0.0017451165792459334517860991553561689216 * (1 << hbShift)), + (qint32)(-0.0029357205890606303047563052643909031758 * (1 << hbShift)), + (qint32)( 0.0048726090910227891003780875678330630763 * (1 << hbShift)), + (qint32)(-0.0077313759655872928144848543752232217230 * (1 << hbShift)), + (qint32)( 0.0117637971494846688830238079503942572046 * (1 << hbShift)), + (qint32)(-0.0173810771817523163074170611253066454083 * (1 << hbShift)), + (qint32)( 0.0253500636065296450216699497559602605179 * (1 << hbShift)), + (qint32)(-0.0373266939135983855102551842719549313188 * (1 << hbShift)), + (qint32)( 0.0576685041500848358242414803953579394147 * (1 << hbShift)), + (qint32)(-0.1024912545928038654086122960507054813206 * (1 << hbShift)), + (qint32)( 0.3173768238826674692454332671331940218806 * (1 << hbShift)), +}; + +const qint16 HBFIRFilterTraits<64>::hbMod[64+6] = { + 63,64,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,33,34,35,36,37,38,39,40,41,42,43,44,45,46, + 47,48,49,50,51,52,53,54,55,56,57,58,59,60,61,62,63,64,0,1,2 +}; + + +const qint32 HBFIRFilterTraits<64>::hbCoeffs[16] = { + //* Remez as in https://www.dsprelated.com/showcode/270.php */ + (qint32)(-0.0004653050334792540416659067936677729449 * (1 << hbShift)), + (qint32)( 0.0007120490624526883919470643391491648799 * (1 << hbShift)), + (qint32)(-0.0012303473710125558716887983479182366864 * (1 << hbShift)), + (qint32)( 0.0019716520179919017584369012041634050547 * (1 << hbShift)), + (qint32)(-0.0029947484165425580261710170049127555103 * (1 << hbShift)), + (qint32)( 0.0043703902150498061263128590780979720876 * (1 << hbShift)), + (qint32)(-0.0061858352927315653213558022116558277048 * (1 << hbShift)), + (qint32)( 0.0085554408639278121950777489246320328675 * (1 << hbShift)), + (qint32)(-0.0116397924445187355563247066925214312505 * (1 << hbShift)), + (qint32)( 0.0156852221106748394852115069397768820636 * (1 << hbShift)), + (qint32)(-0.0211070832238078286147153761476147337817 * (1 << hbShift)), + (qint32)( 0.0286850846890029896607554604770484729670 * (1 << hbShift)), + (qint32)(-0.0400956173930921908055147184768429724500 * (1 << hbShift)), + (qint32)( 0.0597215923200692666572564348825835622847 * (1 << hbShift)), + (qint32)(-0.1036982054813635201195864965484361164272 * (1 << hbShift)), + (qint32)( 0.3175014394028848885298543791577685624361 * (1 << hbShift)), +}; + +const qint16 HBFIRFilterTraits<80>::hbMod[80+6] = { + 79,80,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,33,34,35,36,37,38,39,40,41,42,43,44,45,46, + 47,48,49,50,51,52,53,54,55,56,57,58,59,60,61,62,63,64,65,66,67,68,69, + 70,71,72,73,74,75,76,77,78,79,80,0,1,2 +}; + + +const qint32 HBFIRFilterTraits<80>::hbCoeffs[20] = { + //* Remez as in https://www.dsprelated.com/showcode/270.php */ + (qint32)(-0.0001054430663706784843331246137587697831 * (1 << hbShift)), + (qint32)( 0.0001895717826405601933066613629108587702 * (1 << hbShift)), + (qint32)(-0.0003519516996893227891822497621632237497 * (1 << hbShift)), + (qint32)( 0.0005975111594421821190753485453228677216 * (1 << hbShift)), + (qint32)(-0.0009524124279789792160699768430731637636 * (1 << hbShift)), + (qint32)( 0.0014474605824692796454677967687985074008 * (1 << hbShift)), + (qint32)(-0.0021186428821101787461911314380813564640 * (1 << hbShift)), + (qint32)( 0.0030082068742630901220236339099756150972 * (1 << hbShift)), + (qint32)(-0.0041664004891296358909502650647027621744 * (1 << hbShift)), + (qint32)( 0.0056547140936428538088298623165428580251 * (1 << hbShift)), + (qint32)(-0.0075518323360079901707120342280177283101 * (1 << hbShift)), + (qint32)( 0.0099644038858163180155669280679830990266 * (1 << hbShift)), + (qint32)(-0.0130470841719700410971105597468522319105 * (1 << hbShift)), + (qint32)( 0.0170422818715445859028001507340377429500 * (1 << hbShift)), + (qint32)(-0.0223637819225956900603957677731159492396 * (1 << hbShift)), + (qint32)( 0.0297925991327811050257690084208661573939 * (1 << hbShift)), + (qint32)(-0.0410092859102263174175817539435229264200 * (1 << hbShift)), + (qint32)( 0.0604034694948822267757115866970707429573 * (1 << hbShift)), + (qint32)(-0.1041194584045879306666293473426776472479 * (1 << hbShift)), + (qint32)( 0.3176437752925042046214798574510496109724 * (1 << hbShift)), +}; + diff --git a/sdrbase/dsp/inthalfbandfilter.h b/sdrbase/dsp/inthalfbandfilter.h index 97ce9e857..9209ed72d 100644 --- a/sdrbase/dsp/inthalfbandfilter.h +++ b/sdrbase/dsp/inthalfbandfilter.h @@ -1,7 +1,7 @@ #ifndef INCLUDE_INTHALFBANDFILTER_H #define INCLUDE_INTHALFBANDFILTER_H -#include +#include #include "dsp/dsptypes.h" #include "util/export.h" @@ -9,33 +9,11 @@ /* * supported filter orders: 64, 48, 32 + * any usage of another value will be prevented by compilation errors */ -#define HB_FILTERORDER 64 -#define HB_SHIFT 14 - template struct HBFIRFilterTraits { - static const qint32 hbOrder = 32; - static const qint32 hbShift = 14; - static constexpr qint16 hbMod[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}; - /* Coefficents. This is a sinc function: - * Half of the half of coefficients are stored because: - * - half of the coefficients are 0 - * - there is a symmertry around the central 1.0 coefficient (not stored either) - * There are actually order+1 coefficients - */ - static constexpr qint32 hbCoeffs[8] = { - (qint32)(-0.015956912844043127236437484839370881673 * (1 << hbShift)), - (qint32)( 0.013023031678944928940522274274371739011 * (1 << hbShift)), - (qint32)(-0.01866942273717486777684371190844103694 * (1 << hbShift)), - (qint32)( 0.026550887571157304190005987720724078827 * (1 << hbShift)), - (qint32)(-0.038350314277854319344740474662103224546 * (1 << hbShift)), - (qint32)( 0.058429248652825838128421764849917963147 * (1 << hbShift)), - (qint32)(-0.102889802028955756885153505209018476307 * (1 << hbShift)), - (qint32)( 0.317237706405931241260276465254719369113 * (1 << hbShift)) - }; }; template<> @@ -43,18 +21,8 @@ struct HBFIRFilterTraits<32> { static const qint32 hbOrder = 32; static const qint32 hbShift = 14; - static constexpr qint16 hbMod[32+6] = { 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 constexpr qint32 hbCoeffs[8] = { - (qint32)(-0.015956912844043127236437484839370881673 * (1 << hbShift)), - (qint32)( 0.013023031678944928940522274274371739011 * (1 << hbShift)), - (qint32)(-0.01866942273717486777684371190844103694 * (1 << hbShift)), - (qint32)( 0.026550887571157304190005987720724078827 * (1 << hbShift)), - (qint32)(-0.038350314277854319344740474662103224546 * (1 << hbShift)), - (qint32)( 0.058429248652825838128421764849917963147 * (1 << hbShift)), - (qint32)(-0.102889802028955756885153505209018476307 * (1 << hbShift)), - (qint32)( 0.317237706405931241260276465254719369113 * (1 << hbShift)) - }; + static const qint16 hbMod[32+6]; + static const qint32 hbCoeffs[8]; }; template<> @@ -62,23 +30,8 @@ struct HBFIRFilterTraits<48> { static const qint32 hbOrder = 48; static const qint32 hbShift = 14; - static constexpr qint16 hbMod[48+6] = { 47,48,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,33,34,35,36,37,38,39,40,41, - 42,43,44,45,46,47,48,0,1,2} ; - static constexpr qint32 hbCoeffs[12] = { - (qint32)(-0.004102576237611492253332112767338912818 * (1 << hbShift)), - (qint32)( 0.003950551047979387886410762575906119309 * (1 << hbShift)), - (qint32)(-0.005807875789391703583164350277456833282 * (1 << hbShift)), - (qint32)( 0.00823497890520805998770814682075069868 * (1 << hbShift)), - (qint32)(-0.011372226513199541059195851744334504474 * (1 << hbShift)), - (qint32)( 0.015471557140973646315984524335362948477 * (1 << hbShift)), - (qint32)(-0.020944996398689276484450516591095947661 * (1 << hbShift)), - (qint32)( 0.028568078132034283034279553703527199104 * (1 << hbShift)), - (qint32)(-0.040015143905614086738964374490024056286 * (1 << hbShift)), - (qint32)( 0.059669519431831075095828964549582451582 * (1 << hbShift)), - (qint32)(-0.103669138691865420076609893840213771909 * (1 << hbShift)), - (qint32)( 0.317491986549921390015072120149852707982 * (1 << hbShift)) - }; + static const qint16 hbMod[48+6]; + static const qint32 hbCoeffs[12]; }; template<> @@ -86,29 +39,20 @@ struct HBFIRFilterTraits<64> { static const qint32 hbOrder = 64; static const qint32 hbShift = 14; - static constexpr qint16 hbMod[64+6] = { 63,64,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,33,34,35,36,37,38,39,40,41,42,43,44, - 45,46,47,48,49,50,51,52,53,54,55,56,57,58,59,60,61,62,63,64,0,1,2} ; - static constexpr qint32 hbCoeffs[16] = { - (qint32)(-0.001114417441601693505720538368564120901 * (1 << hbShift)), - (qint32)( 0.001268007827185253051302527005361753254 * (1 << hbShift)), - (qint32)(-0.001959831378850490895410230152151598304 * (1 << hbShift)), - (qint32)( 0.002878308307661380308073439948657323839 * (1 << hbShift)), - (qint32)(-0.004071361818258721100571850826099762344 * (1 << hbShift)), - (qint32)( 0.005597288494657440618973431867289036745 * (1 << hbShift)), - (qint32)(-0.007532345003308904551886371336877346039 * (1 << hbShift)), - (qint32)( 0.009980346844667375288961963519795972388 * (1 << hbShift)), - (qint32)(-0.013092614174300500062830820979797863401 * (1 << hbShift)), - (qint32)( 0.01710934914871829748417297878404497169 * (1 << hbShift)), - (qint32)(-0.022443558692997273018576720460259821266 * (1 << hbShift)), - (qint32)( 0.029875811511593811098386197500076377764 * (1 << hbShift)), - (qint32)(-0.041086352085710403647667021687084343284 * (1 << hbShift)), - (qint32)( 0.060465467462665789533104998554335907102 * (1 << hbShift)), - (qint32)(-0.104159517495977321788203084906854201108 * (1 << hbShift)), - (qint32)( 0.317657589850154464805598308885237202048 * (1 << hbShift)), - }; + static const qint16 hbMod[64+6]; + static const qint32 hbCoeffs[16]; }; +template<> +struct HBFIRFilterTraits<80> +{ + static const qint32 hbOrder = 80; + static const qint32 hbShift = 14; + static const qint16 hbMod[80+6]; + static const qint32 hbCoeffs[20]; +}; + +template class SDRANGEL_API IntHalfbandFilter { public: IntHalfbandFilter(); @@ -124,7 +68,7 @@ public: { case 0: // advance write-pointer - m_ptr = (m_ptr + HB_FILTERORDER) % (HB_FILTERORDER + 1); + m_ptr = (m_ptr + HBFIRFilterTraits::hbOrder) % (HBFIRFilterTraits::hbOrder + 1); // next state m_state = 1; @@ -137,7 +81,7 @@ public: doFIR(sample); // advance write-pointer - m_ptr = (m_ptr + HB_FILTERORDER) % (HB_FILTERORDER + 1); + m_ptr = (m_ptr + HBFIRFilterTraits::hbOrder) % (HBFIRFilterTraits::hbOrder + 1); // next state m_state = 0; @@ -161,7 +105,7 @@ public: doFIR(SampleOut); // advance write-pointer - m_ptr = (m_ptr + HB_FILTERORDER) % (HB_FILTERORDER + 1); + m_ptr = (m_ptr + HBFIRFilterTraits::hbOrder) % (HBFIRFilterTraits::hbOrder + 1); // next state m_state = 1; @@ -178,7 +122,7 @@ public: doFIR(SampleOut); // advance write-pointer - m_ptr = (m_ptr + HB_FILTERORDER) % (HB_FILTERORDER + 1); + m_ptr = (m_ptr + HBFIRFilterTraits::hbOrder) % (HBFIRFilterTraits::hbOrder + 1); // next state m_state = 0; @@ -198,7 +142,7 @@ public: { case 0: // advance write-pointer - m_ptr = (m_ptr + HB_FILTERORDER) % (HB_FILTERORDER + 1); + m_ptr = (m_ptr + HBFIRFilterTraits::hbOrder) % (HBFIRFilterTraits::hbOrder + 1); // next state m_state = 1; @@ -211,7 +155,7 @@ public: doFIR(x, y); // advance write-pointer - m_ptr = (m_ptr + HB_FILTERORDER) % (HB_FILTERORDER + 1); + m_ptr = (m_ptr + HBFIRFilterTraits::hbOrder) % (HBFIRFilterTraits::hbOrder + 1); // next state m_state = 0; @@ -270,7 +214,7 @@ public: m_samples[m_ptr][1] = sample->real(); // advance write-pointer - m_ptr = (m_ptr + HB_FILTERORDER) % (HB_FILTERORDER + 1); + m_ptr = (m_ptr + HBFIRFilterTraits::hbOrder) % (HBFIRFilterTraits::hbOrder + 1); // next state m_state = 1; @@ -287,7 +231,7 @@ public: doFIR(sample); // advance write-pointer - m_ptr = (m_ptr + HB_FILTERORDER) % (HB_FILTERORDER + 1); + m_ptr = (m_ptr + HBFIRFilterTraits::hbOrder) % (HBFIRFilterTraits::hbOrder + 1); // next state m_state = 2; @@ -301,7 +245,7 @@ public: m_samples[m_ptr][1] = -sample->real(); // advance write-pointer - m_ptr = (m_ptr + HB_FILTERORDER) % (HB_FILTERORDER + 1); + m_ptr = (m_ptr + HBFIRFilterTraits::hbOrder) % (HBFIRFilterTraits::hbOrder + 1); // next state m_state = 3; @@ -318,7 +262,7 @@ public: doFIR(sample); // advance write-pointer - m_ptr = (m_ptr + HB_FILTERORDER) % (HB_FILTERORDER + 1); + m_ptr = (m_ptr + HBFIRFilterTraits::hbOrder) % (HBFIRFilterTraits::hbOrder + 1); // next state m_state = 0; @@ -346,7 +290,7 @@ public: sampleOut->setImag(-s.real()); // advance write-pointer - m_ptr = (m_ptr + HB_FILTERORDER) % (HB_FILTERORDER + 1); + m_ptr = (m_ptr + HBFIRFilterTraits::hbOrder) % (HBFIRFilterTraits::hbOrder + 1); // next state m_state = 1; @@ -365,7 +309,7 @@ public: sampleOut->setImag(-s.imag()); // advance write-pointer - m_ptr = (m_ptr + HB_FILTERORDER) % (HB_FILTERORDER + 1); + m_ptr = (m_ptr + HBFIRFilterTraits::hbOrder) % (HBFIRFilterTraits::hbOrder + 1); // next state m_state = 2; @@ -384,7 +328,7 @@ public: sampleOut->setImag(s.real()); // advance write-pointer - m_ptr = (m_ptr + HB_FILTERORDER) % (HB_FILTERORDER + 1); + m_ptr = (m_ptr + HBFIRFilterTraits::hbOrder) % (HBFIRFilterTraits::hbOrder + 1); // next state m_state = 3; @@ -403,7 +347,7 @@ public: sampleOut->setImag(s.imag()); // advance write-pointer - m_ptr = (m_ptr + HB_FILTERORDER) % (HB_FILTERORDER + 1); + m_ptr = (m_ptr + HBFIRFilterTraits::hbOrder) % (HBFIRFilterTraits::hbOrder + 1); // next state m_state = 0; @@ -424,7 +368,7 @@ public: m_samples[m_ptr][1] = -sample->real(); // advance write-pointer - m_ptr = (m_ptr + HB_FILTERORDER) % (HB_FILTERORDER + 1); + m_ptr = (m_ptr + HBFIRFilterTraits::hbOrder) % (HBFIRFilterTraits::hbOrder + 1); // next state m_state = 1; @@ -441,7 +385,7 @@ public: doFIR(sample); // advance write-pointer - m_ptr = (m_ptr + HB_FILTERORDER) % (HB_FILTERORDER + 1); + m_ptr = (m_ptr + HBFIRFilterTraits::hbOrder) % (HBFIRFilterTraits::hbOrder + 1); // next state m_state = 2; @@ -455,7 +399,7 @@ public: m_samples[m_ptr][1] = sample->real(); // advance write-pointer - m_ptr = (m_ptr + HB_FILTERORDER) % (HB_FILTERORDER + 1); + m_ptr = (m_ptr + HBFIRFilterTraits::hbOrder) % (HBFIRFilterTraits::hbOrder + 1); // next state m_state = 3; @@ -472,7 +416,7 @@ public: doFIR(sample); // advance write-pointer - m_ptr = (m_ptr + HB_FILTERORDER) % (HB_FILTERORDER + 1); + m_ptr = (m_ptr + HBFIRFilterTraits::hbOrder) % (HBFIRFilterTraits::hbOrder + 1); // next state m_state = 0; @@ -500,7 +444,7 @@ public: sampleOut->setImag(s.real()); // advance write-pointer - m_ptr = (m_ptr + HB_FILTERORDER) % (HB_FILTERORDER + 1); + m_ptr = (m_ptr + HBFIRFilterTraits::hbOrder) % (HBFIRFilterTraits::hbOrder + 1); // next state m_state = 1; @@ -519,7 +463,7 @@ public: sampleOut->setImag(-s.imag()); // advance write-pointer - m_ptr = (m_ptr + HB_FILTERORDER) % (HB_FILTERORDER + 1); + m_ptr = (m_ptr + HBFIRFilterTraits::hbOrder) % (HBFIRFilterTraits::hbOrder + 1); // next state m_state = 2; @@ -538,7 +482,7 @@ public: sampleOut->setImag(-s.real()); // advance write-pointer - m_ptr = (m_ptr + HB_FILTERORDER) % (HB_FILTERORDER + 1); + m_ptr = (m_ptr + HBFIRFilterTraits::hbOrder) % (HBFIRFilterTraits::hbOrder + 1); // next state m_state = 3; @@ -557,7 +501,7 @@ public: sampleOut->setImag(s.imag()); // advance write-pointer - m_ptr = (m_ptr + HB_FILTERORDER) % (HB_FILTERORDER + 1); + m_ptr = (m_ptr + HBFIRFilterTraits::hbOrder) % (HBFIRFilterTraits::hbOrder + 1); // next state m_state = 0; @@ -569,161 +513,67 @@ public: void myDecimate(const Sample* sample1, Sample* sample2) { - #if HB_FILTERORDER == 64 - static const qint16 HB_MOD[64+6] = { 63,64,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,33,34,35,36,37,38,39,40,41,42,43,44, - 45,46,47,48,49,50,51,52,53,54,55,56,57,58,59,60,61,62,63,64,0,1,2} ; - #elif HB_FILTERORDER == 48 - static const qint16 HB_MOD[48+6] = { 47,48,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,33,34,35,36,37,38,39,40,41, - 42,43,44,45,46,47,48,0,1,2} ; - #elif HB_FILTERORDER == 32 - static const qint16 HB_MOD[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}; - #else - #error unsupported filter order - #endif - m_samples[m_ptr][0] = sample1->real(); m_samples[m_ptr][1] = sample1->imag(); - m_ptr = HB_MOD[m_ptr + 2 - 1]; + m_ptr = HBFIRFilterTraits::hbMod[m_ptr + 2 - 1]; m_samples[m_ptr][0] = sample2->real(); m_samples[m_ptr][1] = sample2->imag(); doFIR(sample2); - m_ptr = HB_MOD[m_ptr + 2 - 1]; + m_ptr = HBFIRFilterTraits::hbMod[m_ptr + 2 - 1]; } void myDecimate(qint32 x1, qint32 y1, qint32 *x2, qint32 *y2) { - #if HB_FILTERORDER == 64 - static const qint16 HB_MOD[64+6] = { 63,64,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,33,34,35,36,37,38,39,40,41,42,43,44, - 45,46,47,48,49,50,51,52,53,54,55,56,57,58,59,60,61,62,63,64,0,1,2} ; - #elif HB_FILTERORDER == 48 - static const qint16 HB_MOD[48+6] = { 47,48,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,33,34,35,36,37,38,39,40,41, - 42,43,44,45,46,47,48,0,1,2} ; - #elif HB_FILTERORDER == 32 - static const qint16 HB_MOD[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}; - #else - #error unsupported filter order - #endif - m_samples[m_ptr][0] = x1; m_samples[m_ptr][1] = y1; - m_ptr = HB_MOD[m_ptr + 2 - 1]; + m_ptr = HBFIRFilterTraits::hbMod[m_ptr + 2 - 1]; m_samples[m_ptr][0] = *x2; m_samples[m_ptr][1] = *y2; doFIR(x2, y2); - m_ptr = HB_MOD[m_ptr + 2 - 1]; + m_ptr = HBFIRFilterTraits::hbMod[m_ptr + 2 - 1]; } protected: - qint32 m_samples[HB_FILTERORDER + 1][2]; // Valgrind optim (from qint16) + qint32 m_samples[HBFIRFilterTraits::hbOrder + 1][2]; // Valgrind optim (from qint16) qint16 m_ptr; int m_state; void doFIR(Sample* sample) { - // Coefficents. This is a sinc function: - // Half of the half of coefficients are stored because: - // - half of the coefficients are 0 - // - there is a symmertry around the central 1.0 coefficient (not stored either) - // There are actually order+1 coefficients - -#if HB_FILTERORDER == 64 - static const qint16 HB_MOD[64+6] = { 63,64,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,33,34,35,36,37,38,39,40,41,42,43,44, - 45,46,47,48,49,50,51,52,53,54,55,56,57,58,59,60,61,62,63,64,0,1,2} ; - static const qint32 COEFF[16] = { - (qint32)(-0.001114417441601693505720538368564120901 * (1 << HB_SHIFT)), - (qint32)( 0.001268007827185253051302527005361753254 * (1 << HB_SHIFT)), - (qint32)(-0.001959831378850490895410230152151598304 * (1 << HB_SHIFT)), - (qint32)( 0.002878308307661380308073439948657323839 * (1 << HB_SHIFT)), - (qint32)(-0.004071361818258721100571850826099762344 * (1 << HB_SHIFT)), - (qint32)( 0.005597288494657440618973431867289036745 * (1 << HB_SHIFT)), - (qint32)(-0.007532345003308904551886371336877346039 * (1 << HB_SHIFT)), - (qint32)( 0.009980346844667375288961963519795972388 * (1 << HB_SHIFT)), - (qint32)(-0.013092614174300500062830820979797863401 * (1 << HB_SHIFT)), - (qint32)( 0.01710934914871829748417297878404497169 * (1 << HB_SHIFT)), - (qint32)(-0.022443558692997273018576720460259821266 * (1 << HB_SHIFT)), - (qint32)( 0.029875811511593811098386197500076377764 * (1 << HB_SHIFT)), - (qint32)(-0.041086352085710403647667021687084343284 * (1 << HB_SHIFT)), - (qint32)( 0.060465467462665789533104998554335907102 * (1 << HB_SHIFT)), - (qint32)(-0.104159517495977321788203084906854201108 * (1 << HB_SHIFT)), - (qint32)( 0.317657589850154464805598308885237202048 * (1 << HB_SHIFT)), - }; -#elif HB_FILTERORDER == 48 - static const qint16 HB_MOD[48+6] = { 47,48,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,33,34,35,36,37,38,39,40,41, - 42,43,44,45,46,47,48,0,1,2} ; - static const qint32 COEFF[12] = { - (qint32)(-0.004102576237611492253332112767338912818 * (1 << HB_SHIFT)), - (qint32)( 0.003950551047979387886410762575906119309 * (1 << HB_SHIFT)), - (qint32)(-0.005807875789391703583164350277456833282 * (1 << HB_SHIFT)), - (qint32)( 0.00823497890520805998770814682075069868 * (1 << HB_SHIFT)), - (qint32)(-0.011372226513199541059195851744334504474 * (1 << HB_SHIFT)), - (qint32)( 0.015471557140973646315984524335362948477 * (1 << HB_SHIFT)), - (qint32)(-0.020944996398689276484450516591095947661 * (1 << HB_SHIFT)), - (qint32)( 0.028568078132034283034279553703527199104 * (1 << HB_SHIFT)), - (qint32)(-0.040015143905614086738964374490024056286 * (1 << HB_SHIFT)), - (qint32)( 0.059669519431831075095828964549582451582 * (1 << HB_SHIFT)), - (qint32)(-0.103669138691865420076609893840213771909 * (1 << HB_SHIFT)), - (qint32)( 0.317491986549921390015072120149852707982 * (1 << HB_SHIFT)) - }; -#elif HB_FILTERORDER == 32 - static const qint16 HB_MOD[32+6] = { 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] = { - (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 -#endif - - // init read-pointer - int a = HB_MOD[m_ptr + 2 + 1]; // 0 + 1 - int b = HB_MOD[m_ptr + 2 - 2]; //-1 - 1 + int a = HBFIRFilterTraits::hbMod[m_ptr + 2 + 1]; // 0 + 1 + int b = HBFIRFilterTraits::hbMod[m_ptr + 2 - 2]; //-1 - 1 // go through samples in buffer qint32 iAcc = 0; qint32 qAcc = 0; - for (int i = 0; i < HB_FILTERORDER / 4; i++) + for (int i = 0; i < HBFIRFilterTraits::hbOrder / 4; i++) { // do multiply-accumulate //qint32 iTmp = m_samples[a][0] + m_samples[b][0]; // Valgrind optim //qint32 qTmp = m_samples[a][1] + m_samples[b][1]; // Valgrind optim - iAcc += (m_samples[a][0] + m_samples[b][0]) * COEFF[i]; - qAcc += (m_samples[a][1] + m_samples[b][1]) * COEFF[i]; + iAcc += (m_samples[a][0] + m_samples[b][0]) * HBFIRFilterTraits::hbCoeffs[i]; + qAcc += (m_samples[a][1] + m_samples[b][1]) * HBFIRFilterTraits::hbCoeffs[i]; // update read-pointer - a = HB_MOD[a + 2 + 2]; - b = HB_MOD[b + 2 - 2]; + a = HBFIRFilterTraits::hbMod[a + 2 + 2]; + b = HBFIRFilterTraits::hbMod[b + 2 - 2]; } - a = HB_MOD[a + 2 - 1]; + a = HBFIRFilterTraits::hbMod[a + 2 - 1]; - iAcc += ((qint32)m_samples[a][0] + 1) << (HB_SHIFT - 1); - qAcc += ((qint32)m_samples[a][1] + 1) << (HB_SHIFT - 1); + iAcc += ((qint32)m_samples[a][0] + 1) << (HBFIRFilterTraits::hbShift - 1); + qAcc += ((qint32)m_samples[a][1] + 1) << (HBFIRFilterTraits::hbShift - 1); - sample->setReal(iAcc >> HB_SHIFT); - sample->setImag(qAcc >> HB_SHIFT); + sample->setReal(iAcc >> HBFIRFilterTraits::hbShift); + sample->setImag(qAcc >> HBFIRFilterTraits::hbShift); } void doFIR(qint32 *x, qint32 *y) @@ -731,97 +581,50 @@ protected: // Coefficents. This is a sinc function: // Half of the half of coefficients are stored because: // - half of the coefficients are 0 - // - there is a symmertry around the central 1.0 coefficient (not stored either) + // - there is a symmertry around the central 0.5 coefficient (not stored either) // There are actually order+1 coefficients - #if HB_FILTERORDER == 64 - static const qint16 HB_MOD[64+6] = { 63,64,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,33,34,35,36,37,38,39,40,41,42,43,44, - 45,46,47,48,49,50,51,52,53,54,55,56,57,58,59,60,61,62,63,64,0,1,2} ; - static const qint32 COEFF[16] = { - (qint32)(-0.001114417441601693505720538368564120901 * (1 << HB_SHIFT)), - (qint32)( 0.001268007827185253051302527005361753254 * (1 << HB_SHIFT)), - (qint32)(-0.001959831378850490895410230152151598304 * (1 << HB_SHIFT)), - (qint32)( 0.002878308307661380308073439948657323839 * (1 << HB_SHIFT)), - (qint32)(-0.004071361818258721100571850826099762344 * (1 << HB_SHIFT)), - (qint32)( 0.005597288494657440618973431867289036745 * (1 << HB_SHIFT)), - (qint32)(-0.007532345003308904551886371336877346039 * (1 << HB_SHIFT)), - (qint32)( 0.009980346844667375288961963519795972388 * (1 << HB_SHIFT)), - (qint32)(-0.013092614174300500062830820979797863401 * (1 << HB_SHIFT)), - (qint32)( 0.01710934914871829748417297878404497169 * (1 << HB_SHIFT)), - (qint32)(-0.022443558692997273018576720460259821266 * (1 << HB_SHIFT)), - (qint32)( 0.029875811511593811098386197500076377764 * (1 << HB_SHIFT)), - (qint32)(-0.041086352085710403647667021687084343284 * (1 << HB_SHIFT)), - (qint32)( 0.060465467462665789533104998554335907102 * (1 << HB_SHIFT)), - (qint32)(-0.104159517495977321788203084906854201108 * (1 << HB_SHIFT)), - (qint32)( 0.317657589850154464805598308885237202048 * (1 << HB_SHIFT)), - }; - #elif HB_FILTERORDER == 48 - static const qint16 HB_MOD[48+6] = { 47,48,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,33,34,35,36,37,38,39,40,41, - 42,43,44,45,46,47,48,0,1,2} ; - static const qint32 COEFF[12] = { - (qint32)(-0.004102576237611492253332112767338912818 * (1 << HB_SHIFT)), - (qint32)( 0.003950551047979387886410762575906119309 * (1 << HB_SHIFT)), - (qint32)(-0.005807875789391703583164350277456833282 * (1 << HB_SHIFT)), - (qint32)( 0.00823497890520805998770814682075069868 * (1 << HB_SHIFT)), - (qint32)(-0.011372226513199541059195851744334504474 * (1 << HB_SHIFT)), - (qint32)( 0.015471557140973646315984524335362948477 * (1 << HB_SHIFT)), - (qint32)(-0.020944996398689276484450516591095947661 * (1 << HB_SHIFT)), - (qint32)( 0.028568078132034283034279553703527199104 * (1 << HB_SHIFT)), - (qint32)(-0.040015143905614086738964374490024056286 * (1 << HB_SHIFT)), - (qint32)( 0.059669519431831075095828964549582451582 * (1 << HB_SHIFT)), - (qint32)(-0.103669138691865420076609893840213771909 * (1 << HB_SHIFT)), - (qint32)( 0.317491986549921390015072120149852707982 * (1 << HB_SHIFT)) - }; - #elif HB_FILTERORDER == 32 - static const int HB_MOD[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] = { - (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 - #endif - - // init read-pointer - int a = HB_MOD[m_ptr + 2 + 1]; // 0 + 1 - int b = HB_MOD[m_ptr + 2 - 2]; //-1 - 1 + int a = HBFIRFilterTraits::hbMod[m_ptr + 2 + 1]; // 0 + 1 + int b = HBFIRFilterTraits::hbMod[m_ptr + 2 - 2]; //-1 - 1 // go through samples in buffer qint32 iAcc = 0; qint32 qAcc = 0; - for (int i = 0; i < HB_FILTERORDER / 4; i++) + for (int i = 0; i < HBFIRFilterTraits::hbOrder / 4; i++) { // do multiply-accumulate //qint32 iTmp = m_samples[a][0] + m_samples[b][0]; // Valgrind optim //qint32 qTmp = m_samples[a][1] + m_samples[b][1]; // Valgrind optim - iAcc += (m_samples[a][0] + m_samples[b][0]) * COEFF[i]; - qAcc += (m_samples[a][1] + m_samples[b][1]) * COEFF[i]; + iAcc += (m_samples[a][0] + m_samples[b][0]) * HBFIRFilterTraits::hbCoeffs[i]; + qAcc += (m_samples[a][1] + m_samples[b][1]) * HBFIRFilterTraits::hbCoeffs[i]; // update read-pointer - a = HB_MOD[a + 2 + 2]; - b = HB_MOD[b + 2 - 2]; + a = HBFIRFilterTraits::hbMod[a + 2 + 2]; + b = HBFIRFilterTraits::hbMod[b + 2 - 2]; } - a = HB_MOD[a + 2 - 1]; + a = HBFIRFilterTraits::hbMod[a + 2 - 1]; - iAcc += ((qint32)m_samples[a][0] + 1) << (HB_SHIFT - 1); - qAcc += ((qint32)m_samples[a][1] + 1) << (HB_SHIFT - 1); + iAcc += ((qint32)m_samples[a][0] + 1) << (HBFIRFilterTraits::hbShift - 1); + qAcc += ((qint32)m_samples[a][1] + 1) << (HBFIRFilterTraits::hbShift - 1); - *x = iAcc >> (HB_SHIFT -1); // HB_SHIFT incorrect do not loose the gained bit - *y = qAcc >> (HB_SHIFT -1); + *x = iAcc >> (HBFIRFilterTraits::hbShift -1); // HB_SHIFT incorrect do not loose the gained bit + *y = qAcc >> (HBFIRFilterTraits::hbShift -1); } }; +template +IntHalfbandFilter::IntHalfbandFilter() +{ + for(int i = 0; i < HBFIRFilterTraits::hbOrder + 1; i++) { + m_samples[i][0] = 0; + m_samples[i][1] = 0; + } + m_ptr = 0; + m_state = 0; +} + #endif // INCLUDE_INTHALFBANDFILTER_H diff --git a/sdrbase/dsp/samplesinkfifodecimator.h b/sdrbase/dsp/samplesinkfifodecimator.h index c67f7faf7..1340b1f47 100644 --- a/sdrbase/dsp/samplesinkfifodecimator.h +++ b/sdrbase/dsp/samplesinkfifodecimator.h @@ -120,12 +120,12 @@ public: void decimate64_cen(SampleSinkFifoDoubleBuffered& fifo, const T* buf, qint32 len); private: - IntHalfbandFilter m_decimator2; // 1st stages - IntHalfbandFilter m_decimator4; // 2nd stages - IntHalfbandFilter m_decimator8; // 3rd stages - IntHalfbandFilter m_decimator16; // 4th stages - IntHalfbandFilter m_decimator32; // 5th stages - IntHalfbandFilter m_decimator64; // 6th stages + IntHalfbandFilter<32> m_decimator2; // 1st stages + IntHalfbandFilter<32> m_decimator4; // 2nd stages + IntHalfbandFilter<32> m_decimator8; // 3rd stages + IntHalfbandFilter<32> m_decimator16; // 4th stages + IntHalfbandFilter<32> m_decimator32; // 5th stages + IntHalfbandFilter<32> m_decimator64; // 6th stages }; template @@ -337,7 +337,7 @@ void SampleSinkFifoDecimator::decimate16_inf(SampleSinkFi m_decimator2.myDecimate(xreal[0], yimag[0], &xreal[1], &yimag[1]); m_decimator2.myDecimate(xreal[2], yimag[2], &xreal[3], &yimag[3]); - + m_decimator4.myDecimate(xreal[1], yimag[1], &xreal[3], &yimag[3]); (*it).setReal(xreal[3] >> decimation_shifts::post16); diff --git a/sdrbase/dsp/upchannelizer.cpp b/sdrbase/dsp/upchannelizer.cpp index 88ac0af7b..6605f9c4e 100644 --- a/sdrbase/dsp/upchannelizer.cpp +++ b/sdrbase/dsp/upchannelizer.cpp @@ -185,20 +185,20 @@ void UpChannelizer::applyConfiguration() } UpChannelizer::FilterStage::FilterStage(Mode mode) : - m_filter(new IntHalfbandFilter), + m_filter(new IntHalfbandFilter), m_workFunction(0) { switch(mode) { case ModeCenter: - m_workFunction = &IntHalfbandFilter::workInterpolateCenter; + m_workFunction = &IntHalfbandFilter::workInterpolateCenter; break; case ModeLowerHalf: - m_workFunction = &IntHalfbandFilter::workInterpolateLowerHalf; + m_workFunction = &IntHalfbandFilter::workInterpolateLowerHalf; break; case ModeUpperHalf: - m_workFunction = &IntHalfbandFilter::workInterpolateUpperHalf; + m_workFunction = &IntHalfbandFilter::workInterpolateUpperHalf; break; } } diff --git a/sdrbase/dsp/upchannelizer.h b/sdrbase/dsp/upchannelizer.h index 140f944fc..111308f65 100644 --- a/sdrbase/dsp/upchannelizer.h +++ b/sdrbase/dsp/upchannelizer.h @@ -23,9 +23,11 @@ #include #include "util/export.h" #include "util/message.h" +#include "dsp/inthalfbandfilter.h" + +#define UPCHANNELIZER_HB_FILTER_ORDER 80 class MessageQueue; -class IntHalfbandFilter; class SDRANGEL_API UpChannelizer : public BasebandSampleSource { Q_OBJECT @@ -67,8 +69,8 @@ protected: ModeUpperHalf }; - typedef bool (IntHalfbandFilter::*WorkFunction)(Sample* sIn, Sample *sOut); - IntHalfbandFilter* m_filter; + typedef bool (IntHalfbandFilter::*WorkFunction)(Sample* sIn, Sample *sOut); + IntHalfbandFilter* m_filter; WorkFunction m_workFunction; FilterStage(Mode mode);