From 3173bc0b07ba99b612f9f82b6daa70cbb2711242 Mon Sep 17 00:00:00 2001 From: f4exb Date: Mon, 31 Oct 2016 23:40:46 +0100 Subject: [PATCH] Tx ph.2: Interpolator polyphase filter: add possibility to specify the number of taps per phase --- sdrbase/dsp/interpolator.cpp | 46 ++++++++++++++++++++++++------------ sdrbase/dsp/interpolator.h | 19 ++++++++++++++- 2 files changed, 49 insertions(+), 16 deletions(-) diff --git a/sdrbase/dsp/interpolator.cpp b/sdrbase/dsp/interpolator.cpp index 1e03c422a..c2dade6aa 100644 --- a/sdrbase/dsp/interpolator.cpp +++ b/sdrbase/dsp/interpolator.cpp @@ -3,20 +3,36 @@ #include #include "dsp/interpolator.h" -static std::vector createPolyphaseLowPass( - int phaseSteps, - double gain, - double sampleRateHz, - double cutoffFreqHz, - double transitionWidthHz, - double oobAttenuationdB) + +void Interpolator::createPolyphaseLowPass( + std::vector& taps, + int phaseSteps, + double gain, + double sampleRateHz, + double cutoffFreqHz, + double transitionWidthHz, + double oobAttenuationdB) { - int ntaps = (int)(oobAttenuationdB * sampleRateHz / (22.0 * transitionWidthHz)); + double nbTapsPerPhase = (oobAttenuationdB * sampleRateHz) / (22.0 * transitionWidthHz * phaseSteps); + return createPolyphaseLowPass(taps, phaseSteps, gain, sampleRateHz, cutoffFreqHz, nbTapsPerPhase); +} + + +void Interpolator::createPolyphaseLowPass( + std::vector& taps, + int phaseSteps, + double gain, + double sampleRateHz, + double cutoffFreqHz, + double nbTapsPerPhase) +{ + int ntaps = (int)(nbTapsPerPhase * phaseSteps); + qDebug("Interpolator::createPolyphaseLowPass: ntaps: %d", ntaps); if((ntaps % 2) != 0) ntaps++; ntaps *= phaseSteps; - std::vector taps(ntaps); + taps.resize(ntaps); std::vector window(ntaps); for(int n = 0; n < ntaps; n++) @@ -37,8 +53,6 @@ static std::vector createPolyphaseLowPass( for(int i = 0; i < ntaps; i++) taps[i] *= gain; - - return taps; } Interpolator::Interpolator() : @@ -52,17 +66,19 @@ Interpolator::~Interpolator() free(); } -void Interpolator::create(int phaseSteps, double sampleRate, double cutoff) +void Interpolator::create(int phaseSteps, double sampleRate, double cutoff, double nbTapsPerPhase) { free(); - std::vector taps = createPolyphaseLowPass( + std::vector taps; + + createPolyphaseLowPass( + taps, phaseSteps, // number of polyphases 1.0, // gain phaseSteps * sampleRate, // sampling frequency cutoff, // hz beginning of transition band - sampleRate / 5.0, // hz width of transition band - 20.0); // out of band attenuation + nbTapsPerPhase); // init state m_ptr = 0; diff --git a/sdrbase/dsp/interpolator.h b/sdrbase/dsp/interpolator.h index 24f7e1b36..9e3e8c602 100644 --- a/sdrbase/dsp/interpolator.h +++ b/sdrbase/dsp/interpolator.h @@ -16,7 +16,7 @@ public: Interpolator(); ~Interpolator(); - void create(int phaseSteps, double sampleRate, double cutoff); + void create(int phaseSteps, double sampleRate, double cutoff, double nbTapsPerPhase = 4.5); void free(); // Original code allowed for upsampling, but was never used that way @@ -85,6 +85,23 @@ private: int m_phaseSteps; int m_nTaps; + static void createPolyphaseLowPass( + std::vector& taps, + int phaseSteps, + double gain, + double sampleRateHz, + double cutoffFreqHz, + double transitionWidthHz, + double oobAttenuationdB); + + static void createPolyphaseLowPass( + std::vector& taps, + int phaseSteps, + double gain, + double sampleRateHz, + double cutoffFreqHz, + double nbTapsPerPhase); + void createTaps(int nTaps, double sampleRate, double cutoff, std::vector* taps); void advanceFilter(const Complex& next)