diff --git a/sdrbase/CMakeLists.txt b/sdrbase/CMakeLists.txt index 5a5f0642c..08450ef8a 100644 --- a/sdrbase/CMakeLists.txt +++ b/sdrbase/CMakeLists.txt @@ -86,6 +86,7 @@ set(sdrbase_SOURCES dsp/decimatorsif.cpp dsp/decimatorsff.cpp dsp/decimatorsfi.cpp + dsp/decimatorc.cpp dsp/dspcommands.cpp dsp/dspengine.cpp dsp/dspdevicesourceengine.cpp @@ -211,6 +212,7 @@ set(sdrbase_HEADERS dsp/decimatorsff.h dsp/decimatorsfi.h dsp/decimatorsu.h + dsp/decimatorc.h dsp/interpolators.h dsp/interpolatorsif.h dsp/dspcommands.h diff --git a/sdrbase/dsp/decimatorc.cpp b/sdrbase/dsp/decimatorc.cpp new file mode 100644 index 000000000..ad93c062a --- /dev/null +++ b/sdrbase/dsp/decimatorc.cpp @@ -0,0 +1,221 @@ +/////////////////////////////////////////////////////////////////////////////////// +// Copyright (C) 2020 Edouard Griffiths, F4EXB // +// // +// This program is free software; you can redistribute it and/or modify // +// it under the terms of the GNU General Public License as published by // +// the Free Software Foundation as version 3 of the License, or // +// (at your option) any later version. // +// // +// This program is distributed in the hope that it will be useful, // +// but WITHOUT ANY WARRANTY; without even the implied warranty of // +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // +// GNU General Public License V3 for more details. // +// // +// You should have received a copy of the GNU General Public License // +// along with this program. If not, see . // +/////////////////////////////////////////////////////////////////////////////////// + +#include "decimatorc.h" + +DecimatorC::DecimatorC() : + m_log2Decim(0), + m_decim(1) +{} + +void DecimatorC::setLog2Decim(unsigned int log2Decim) +{ + m_log2Decim = log2Decim; + m_decim = 1 << log2Decim; +} + +bool DecimatorC::decimate(Complex c, Complex& cd) +{ + if (m_log2Decim == 0) { // no decimation hence no translation possible + return true; + } + + if (m_log2Decim == 1) { + return decimate2(c, cd); + } else if (m_log2Decim == 2) { + return decimate4(c, cd); + } else if (m_log2Decim == 3) { + return decimate8(c, cd); + } else if (m_log2Decim == 4) { + return decimate16(c, cd); + } else if (m_log2Decim == 5) { + return decimate32(c, cd); + } else if (m_log2Decim == 6) { + return decimate64(c, cd); + } +} + +bool DecimatorC::decimate2(Complex c, Complex& cd) +{ + float x = c.real(); + float y = c.imag(); + bool done2 = m_decimator2.workDecimateCenter(&x, &y); + + if (done2) + { + cd.real(x); + cd.imag(y); + } + + return done2; +} + +bool DecimatorC::decimate4(Complex c, Complex& cd) +{ + float x = c.real(); + float y = c.imag(); + bool done2 = m_decimator2.workDecimateCenter(&x, &y); + + if (done2) + { + bool done4 = m_decimator4.workDecimateCenter(&x, &y); + + if (done4) + { + cd.real(x); + cd.imag(y); + return true; + } + } + + return false; +} + +bool DecimatorC::decimate8(Complex c, Complex& cd) +{ + float x = c.real(); + float y = c.imag(); + bool done2 = m_decimator2.workDecimateCenter(&x, &y); + + if (done2) + { + bool done4 = m_decimator4.workDecimateCenter(&x, &y); + + if (done4) + { + bool done8 = m_decimator8.workDecimateCenter(&x, &y); + + if (done8) + { + cd.real(x); + cd.imag(y); + return true; + } + } + } + + return false; +} + +bool DecimatorC::decimate16(Complex c, Complex& cd) +{ + float x = c.real(); + float y = c.imag(); + bool done2 = m_decimator2.workDecimateCenter(&x, &y); + + if (done2) + { + bool done4 = m_decimator4.workDecimateCenter(&x, &y); + + if (done4) + { + bool done8 = m_decimator8.workDecimateCenter(&x, &y); + + if (done8) + { + bool done16 = m_decimator16.workDecimateCenter(&x, &y); + + if (done16) + { + cd.real(x); + cd.imag(y); + return true; + } + } + } + } + + return false; +} + + +bool DecimatorC::decimate32(Complex c, Complex& cd) +{ + float x = c.real(); + float y = c.imag(); + bool done2 = m_decimator2.workDecimateCenter(&x, &y); + + if (done2) + { + bool done4 = m_decimator4.workDecimateCenter(&x, &y); + + if (done4) + { + bool done8 = m_decimator8.workDecimateCenter(&x, &y); + + if (done8) + { + bool done16 = m_decimator16.workDecimateCenter(&x, &y); + + if (done16) + { + bool done32 = m_decimator32.workDecimateCenter(&x, &y); + + if (done32) + { + cd.real(x); + cd.imag(y); + return true; + } + } + } + } + } + + return false; +} + +bool DecimatorC::decimate64(Complex c, Complex& cd) +{ + float x = c.real(); + float y = c.imag(); + bool done2 = m_decimator2.workDecimateCenter(&x, &y); + + if (done2) + { + bool done4 = m_decimator4.workDecimateCenter(&x, &y); + + if (done4) + { + bool done8 = m_decimator8.workDecimateCenter(&x, &y); + + if (done8) + { + bool done16 = m_decimator16.workDecimateCenter(&x, &y); + + if (done16) + { + bool done32 = m_decimator32.workDecimateCenter(&x, &y); + + if (done32) + { + bool done64 = m_decimator32.workDecimateCenter(&x, &y); + + if (done64) + { + cd.real(x); + cd.imag(y); + return true; + } + } + } + } + } + } + + return false; +} diff --git a/sdrbase/dsp/decimatorc.h b/sdrbase/dsp/decimatorc.h new file mode 100644 index 000000000..1c722e899 --- /dev/null +++ b/sdrbase/dsp/decimatorc.h @@ -0,0 +1,55 @@ +/////////////////////////////////////////////////////////////////////////////////// +// Copyright (C) 2020 Edouard Griffiths, F4EXB // +// // +// This program is free software; you can redistribute it and/or modify // +// it under the terms of the GNU General Public License as published by // +// the Free Software Foundation as version 3 of the License, or // +// (at your option) any later version. // +// // +// This program is distributed in the hope that it will be useful, // +// but WITHOUT ANY WARRANTY; without even the implied warranty of // +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // +// GNU General Public License V3 for more details. // +// // +// You should have received a copy of the GNU General Public License // +// along with this program. If not, see . // +/////////////////////////////////////////////////////////////////////////////////// + +// Half-band centered decimators with Complex (i.e. omplex) input/output +// Decimates by a power of two using centered half-band filters + +#ifndef INCLUDE_DSP_DECIMATORC_H_ +#define INCLUDE_DSP_DECIMATORC_H_ + +#include "dsp/dsptypes.h" +#include "dsp/inthalfbandfiltereof.h" + +#define DECIMATORSXS_HB_FILTER_ORDER 64 + +class DecimatorC +{ +public: + DecimatorC(); + void setLog2Decim(unsigned int log2Decim); + bool decimate(Complex c, Complex& cd); + unsigned int getDecim() const { return m_decim; } + +private: + IntHalfbandFilterEOF m_decimator2; // 1st stages + IntHalfbandFilterEOF m_decimator4; // 2nd stages + IntHalfbandFilterEOF m_decimator8; // 3rd stages + IntHalfbandFilterEOF m_decimator16; // 4th stages + IntHalfbandFilterEOF m_decimator32; // 5th stages + IntHalfbandFilterEOF m_decimator64; // 6th stages + unsigned int m_log2Decim; + unsigned int m_decim; + + bool decimate2(Complex c, Complex& cd); + bool decimate4(Complex c, Complex& cd); + bool decimate8(Complex c, Complex& cd); + bool decimate16(Complex c, Complex& cd); + bool decimate32(Complex c, Complex& cd); + bool decimate64(Complex c, Complex& cd); +}; + +#endif // INCLUDE_DSP_DECIMATORC_H_ \ No newline at end of file