From a229c583ee06dcfe1f6ec148d5eeb440ee218ca4 Mon Sep 17 00:00:00 2001 From: f4exb Date: Wed, 3 Jul 2024 00:52:16 +0200 Subject: [PATCH] WDSP: separate SNBA and BPSNBA --- plugins/channelrx/wdsprx/wdsprxsink.cpp | 16 +- wdsp/CMakeLists.txt | 6 +- wdsp/RXA.cpp | 3 +- wdsp/amd.cpp | 2 +- wdsp/anf.cpp | 2 +- wdsp/anr.cpp | 2 +- wdsp/bpsnba.cpp | 221 +++++++++++++++++ wdsp/bpsnba.hpp | 105 ++++++++ wdsp/emnr.cpp | 12 +- wdsp/nbp.cpp | 2 +- wdsp/{snb.cpp => snba.cpp} | 316 +++++++----------------- wdsp/{snb.hpp => snba.hpp} | 112 ++------- 12 files changed, 458 insertions(+), 341 deletions(-) create mode 100644 wdsp/bpsnba.cpp create mode 100644 wdsp/bpsnba.hpp rename wdsp/{snb.cpp => snba.cpp} (69%) rename wdsp/{snb.hpp => snba.hpp} (58%) diff --git a/plugins/channelrx/wdsprx/wdsprxsink.cpp b/plugins/channelrx/wdsprx/wdsprxsink.cpp index 2f9c3f217..1fcf9f6fb 100644 --- a/plugins/channelrx/wdsprx/wdsprxsink.cpp +++ b/plugins/channelrx/wdsprx/wdsprxsink.cpp @@ -32,7 +32,7 @@ #include "wcpAGC.hpp" #include "anr.hpp" #include "emnr.hpp" -#include "snb.hpp" +#include "snba.hpp" #include "anf.hpp" #include "anb.hpp" #include "nob.hpp" @@ -547,10 +547,10 @@ void WDSPRxSink::applySettings(const WDSPRxSettings& settings, bool force) WDSP::ANF::SetANFRun(*m_rxa, settings.m_anf ? 1 : 0); } - // Causes corruption - // if ((m_settings.m_snb != settings.m_snb) || force) { - // WDSP::SNBA::SetSNBARun(*m_rxa, settings.m_snb ? 1 : 0); - // } + // Caution: Causes corruption + if ((m_settings.m_snb != settings.m_snb) || force) { + WDSP::SNBA::SetSNBARun(*m_rxa, settings.m_snb ? 1 : 0); + } // CW Peaking @@ -636,12 +636,6 @@ void WDSPRxSink::applySettings(const WDSPRxSettings& settings, bool force) WDSP::PANEL::SetPanelGain1(*m_rxa, settings.m_volume); } - // if ((m_settings.m_volume != settings.m_volume) || force) - // { - // m_volume = settings.m_volume; - // m_volume /= 4.0; // for 3276.8 - // } - if ((m_settings.m_audioBinaural != settings.m_audioBinaural) || force) { WDSP::PANEL::SetPanelBinaural(*m_rxa, settings.m_audioBinaural ? 1 : 0); } diff --git a/wdsp/CMakeLists.txt b/wdsp/CMakeLists.txt index 18feb71dd..060b11a86 100644 --- a/wdsp/CMakeLists.txt +++ b/wdsp/CMakeLists.txt @@ -11,6 +11,7 @@ set(wdsp_SOURCES bandpass.cpp bldr.cpp bps.cpp + bpsnba.cpp calculus.cpp cblock.cpp cfcomp.cpp @@ -45,7 +46,7 @@ set(wdsp_SOURCES shift.cpp siphon.cpp slew.cpp - snb.cpp + snba.cpp ssql.cpp TXA.cpp varsamp.cpp @@ -62,6 +63,7 @@ set(wdsp_HEADERS bandpass.hpp bldr.hpp bps.hpp + bpsnba.hpp bufferprobe.hpp calculus.hpp cblock.hpp @@ -98,7 +100,7 @@ set(wdsp_HEADERS shift.hpp siphon.hpp slew.hpp - snb.hpp + snba.hpp ssql.hpp TXA.hpp varsamp.hpp diff --git a/wdsp/RXA.cpp b/wdsp/RXA.cpp index 32dc81ae1..4952b9e43 100644 --- a/wdsp/RXA.cpp +++ b/wdsp/RXA.cpp @@ -36,7 +36,8 @@ warren@wpratt.com #include "bandpass.hpp" #include "bps.hpp" #include "nbp.hpp" -#include "snb.hpp" +#include "snba.hpp" +#include "bpsnba.hpp" #include "sender.hpp" #include "amsq.hpp" #include "fmd.hpp" diff --git a/wdsp/amd.cpp b/wdsp/amd.cpp index a81a40494..f1e26b494 100644 --- a/wdsp/amd.cpp +++ b/wdsp/amd.cpp @@ -32,7 +32,7 @@ warren@wpratt.com #include "anf.hpp" #include "emnr.hpp" #include "anr.hpp" -#include "snb.hpp" +#include "snba.hpp" #include "RXA.hpp" namespace WDSP { diff --git a/wdsp/anf.cpp b/wdsp/anf.cpp index 4ad4154ec..5b48c75c3 100644 --- a/wdsp/anf.cpp +++ b/wdsp/anf.cpp @@ -27,7 +27,7 @@ warren@wpratt.com #include "comm.hpp" #include "amd.hpp" -#include "snb.hpp" +#include "snba.hpp" #include "emnr.hpp" #include "anr.hpp" #include "anf.hpp" diff --git a/wdsp/anr.cpp b/wdsp/anr.cpp index d0761486a..5c44da011 100644 --- a/wdsp/anr.cpp +++ b/wdsp/anr.cpp @@ -30,7 +30,7 @@ warren@wpratt.com #include "comm.hpp" #include "anr.hpp" #include "amd.hpp" -#include "snb.hpp" +#include "snba.hpp" #include "emnr.hpp" #include "anf.hpp" #include "bandpass.hpp" diff --git a/wdsp/bpsnba.cpp b/wdsp/bpsnba.cpp new file mode 100644 index 000000000..540609ba4 --- /dev/null +++ b/wdsp/bpsnba.cpp @@ -0,0 +1,221 @@ +/* snb.c + +This file is part of a program that implements a Software-Defined Radio. + +Copyright (C) 2015, 2016 Warren Pratt, NR0V +Copyright (C) 2024 Edouard Griffiths, F4EXB Adapted to SDRangel + +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; either version 2 +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 for more details. + +You should have received a copy of the GNU General Public License +along with this program; if not, write to the Free Software +Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + +The author can be reached by email at + +warren@wpratt.com + +*/ + +#include "comm.hpp" +#include "resample.hpp" +#include "lmath.hpp" +#include "firmin.hpp" +#include "nbp.hpp" +#include "amd.hpp" +#include "anf.hpp" +#include "anr.hpp" +#include "emnr.hpp" +#include "bpsnba.hpp" +#include "RXA.hpp" + +#define MAXIMP 256 + +namespace WDSP { + +/******************************************************************************************************** +* * +* BPSNBA Bandpass Filter * +* * +********************************************************************************************************/ + +// This is a thin wrapper for a notched-bandpass filter (nbp). The basic difference is that it provides +// for its input and output to happen at different points in the processing pipeline. This means it must +// include a buffer, 'buff'. Its input and output are done via functions xbpshbain() and xbpshbaout(). + +void BPSNBA::calc_bpsnba (BPSNBA *a) +{ + a->buff = new float[a->size * 2]; // (double *) malloc0 (a->size * sizeof (complex)); + a->bpsnba = NBP::create_nbp ( + 1, // run, always runs (use bpsnba 'run') + a->run_notches, // run the notches + 0, // position variable for nbp (not for bpsnba), always 0 + a->size, // buffer size + a->nc, // number of filter coefficients + a->mp, // minimum phase flag + a->buff, // pointer to input buffer + a->out, // pointer to output buffer + a->f_low, // lower filter frequency + a->f_high, // upper filter frequency + a->rate, // sample rate + a->wintype, // wintype + a->gain, // gain + a->autoincr, // auto-increase notch width if below min + a->maxpb, // max number of passbands + a->ptraddr); // addr of database pointer +} + +BPSNBA* BPSNBA::create_bpsnba ( + int run, + int run_notches, + int position, + int size, + int nc, + int mp, + float* in, + float* out, + int rate, + double abs_low_freq, + double abs_high_freq, + double f_low, + double f_high, + int wintype, + double gain, + int autoincr, + int maxpb, + NOTCHDB* ptraddr +) +{ + BPSNBA *a = new BPSNBA; + a->run = run; + a->run_notches = run_notches; + a->position = position; + a->size = size; + a->nc = nc; + a->mp = mp; + a->in = in; + a->out = out; + a->rate = rate; + a->abs_low_freq = abs_low_freq; + a->abs_high_freq = abs_high_freq; + a->f_low = f_low; + a->f_high = f_high; + a->wintype = wintype; + a->gain = gain; + a->autoincr = autoincr; + a->maxpb = maxpb; + a->ptraddr = ptraddr; + calc_bpsnba (a); + return a; +} + +void BPSNBA::decalc_bpsnba (BPSNBA *a) +{ + NBP::destroy_nbp (a->bpsnba); + delete[] (a->buff); +} + +void BPSNBA::destroy_bpsnba (BPSNBA *a) +{ + decalc_bpsnba (a); + delete[] (a); +} + +void BPSNBA::flush_bpsnba (BPSNBA *a) +{ + memset (a->buff, 0, a->size * sizeof (wcomplex)); + NBP::flush_nbp (a->bpsnba); +} + +void BPSNBA::setBuffers_bpsnba (BPSNBA *a, float* in, float* out) +{ + decalc_bpsnba (a); + a->in = in; + a->out = out; + calc_bpsnba (a); +} + +void BPSNBA::setSamplerate_bpsnba (BPSNBA *a, int rate) +{ + decalc_bpsnba (a); + a->rate = rate; + calc_bpsnba (a); +} + +void BPSNBA::setSize_bpsnba (BPSNBA *a, int size) +{ + decalc_bpsnba (a); + a->size = size; + calc_bpsnba (a); +} + +void BPSNBA::xbpsnbain (BPSNBA *a, int position) +{ + if (a->run && a->position == position) + memcpy (a->buff, a->in, a->size * sizeof (wcomplex)); +} + +void BPSNBA::xbpsnbaout (BPSNBA *a, int position) +{ + if (a->run && a->position == position) + NBP::xnbp (a->bpsnba, 0); +} + +void BPSNBA::recalc_bpsnba_filter (BPSNBA *a, int update) +{ + // Call anytime one of the parameters listed below has been changed in + // the BPSNBA struct. + NBP *b = a->bpsnba; + b->fnfrun = a->run_notches; + b->flow = a->f_low; + b->fhigh = a->f_high; + b->wintype = a->wintype; + b->gain = a->gain; + b->autoincr = a->autoincr; + NBP::calc_nbp_impulse (b); + FIRCORE::setImpulse_fircore (b->p, b->impulse, update); + delete[] (b->impulse); +} + +/******************************************************************************************************** +* * +* RXA Properties * +* * +********************************************************************************************************/ + +void BPSNBA::BPSNBASetNC (RXA& rxa, int nc) +{ + BPSNBA *a = rxa.bpsnba.p; + rxa.csDSP.lock(); + + if (a->nc != nc) + { + a->nc = nc; + a->bpsnba->nc = a->nc; + NBP::setNc_nbp (a->bpsnba); + } + + rxa.csDSP.unlock(); +} + +void BPSNBA::BPSNBASetMP (RXA& rxa, int mp) +{ + BPSNBA *a = rxa.bpsnba.p; + + if (a->mp != mp) + { + a->mp = mp; + a->bpsnba->mp = a->mp; + NBP::setMp_nbp (a->bpsnba); + } +} + +} // namespace diff --git a/wdsp/bpsnba.hpp b/wdsp/bpsnba.hpp new file mode 100644 index 000000000..179e5c8d3 --- /dev/null +++ b/wdsp/bpsnba.hpp @@ -0,0 +1,105 @@ +/* snb.h + +This file is part of a program that implements a Software-Defined Radio. + +Copyright (C) 2015, 2016 Warren Pratt, NR0V +Copyright (C) 2024 Edouard Griffiths, F4EXB Adapted to SDRangel + +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; either version 2 +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 for more details. + +You should have received a copy of the GNU General Public License +along with this program; if not, write to the Free Software +Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + +The author can be reached by email at + +warren@wpratt.com + +*/ + +#ifndef wdsp_bpsnba_h +#define wdsp_bpsnba_h + +namespace WDSP{ + +class RXA; + +class NOTCHDB; +class NBP; + +class BPSNBA +{ +public: + int run; // run the filter + int run_notches; // use the notches, vs straight bandpass + int position; // position in the processing pipeline + int size; // buffer size + int nc; // number of filter coefficients + int mp; // minimum phase flag + float* in; // input buffer + float* out; // output buffer + int rate; // sample rate + float* buff; // internal buffer + NBP *bpsnba; // pointer to the notched bandpass filter, nbp + double f_low; // low cutoff frequency + double f_high; // high cutoff frequency + double abs_low_freq; // lowest positive freq supported by SNB + double abs_high_freq; // highest positive freq supported by SNG + int wintype; // filter window type + double gain; // filter gain + int autoincr; // use auto increment for notch width + int maxpb; // maximum passband segments supported + NOTCHDB* ptraddr; // pointer to address of NOTCH DATABASE + + static BPSNBA* create_bpsnba ( + int run, + int run_notches, + int position, + int size, + int nc, + int mp, + float* in, + float* out, + int rate, + double abs_low_freq, + double abs_high_freq, + double f_low, + double f_high, + int wintype, + double gain, + int autoincr, + int maxpb, + NOTCHDB* ptraddr + ); + static void destroy_bpsnba (BPSNBA *a); + static void flush_bpsnba (BPSNBA *a); + static void setBuffers_bpsnba (BPSNBA *a, float* in, float* out); + static void setSamplerate_bpsnba (BPSNBA *a, int rate); + static void setSize_bpsnba (BPSNBA *a, int size); + static void xbpsnbain (BPSNBA *a, int position); + static void xbpsnbaout (BPSNBA *a, int position); + static void recalc_bpsnba_filter (BPSNBA *a, int update); + // RXA Propertoes + static void BPSNBASetNC (RXA& rxa, int nc); + static void BPSNBASetMP (RXA& rxa, int mp); + +private: + static void calc_bpsnba (BPSNBA *a); + static void decalc_bpsnba (BPSNBA *a); +}; + + + + + +#endif + +} // namespace diff --git a/wdsp/emnr.cpp b/wdsp/emnr.cpp index 933677fff..2472787c7 100644 --- a/wdsp/emnr.cpp +++ b/wdsp/emnr.cpp @@ -30,7 +30,7 @@ warren@wpratt.com #include "amd.hpp" #include "anr.hpp" #include "anf.hpp" -#include "snb.hpp" +#include "snba.hpp" #include "bandpass.hpp" #include "RXA.hpp" @@ -908,8 +908,14 @@ void EMNR::SetEMNRRun (RXA& rxa, int run) EMNR *a = rxa.emnr.p; if (a->run != run) { - RXA::bp1Check (rxa, rxa.amd.p->run, rxa.snba.p->run, - run, rxa.anf.p->run, rxa.anr.p->run); + RXA::bp1Check ( + rxa, + rxa.amd.p->run, + rxa.snba.p->run, + run, + rxa.anf.p->run, + rxa.anr.p->run + ); rxa.csDSP.lock(); a->run = run; RXA::bp1Set (rxa); diff --git a/wdsp/nbp.cpp b/wdsp/nbp.cpp index ceb080fe8..edb55c17c 100644 --- a/wdsp/nbp.cpp +++ b/wdsp/nbp.cpp @@ -28,7 +28,7 @@ warren@wpratt.com #include "comm.hpp" #include "fir.hpp" #include "firmin.hpp" -#include "snb.hpp" +#include "bpsnba.hpp" #include "nbp.hpp" #include "RXA.hpp" diff --git a/wdsp/snb.cpp b/wdsp/snba.cpp similarity index 69% rename from wdsp/snb.cpp rename to wdsp/snba.cpp index 02a79c3f4..97aba8add 100644 --- a/wdsp/snb.cpp +++ b/wdsp/snba.cpp @@ -34,10 +34,9 @@ warren@wpratt.com #include "anf.hpp" #include "anr.hpp" #include "emnr.hpp" -#include "snb.hpp" +#include "snba.hpp" #include "RXA.hpp" - #define MAXIMP 256 namespace WDSP { @@ -48,25 +47,31 @@ void SNBA::calc_snba (SNBA *d) d->isize = d->bsize / (d->inrate / d->internalrate); else d->isize = d->bsize * (d->internalrate / d->inrate); - d->inbuff = new float[d->isize * 2]; // (float *) malloc0 (d->isize * sizeof (complex)); - d->outbuff = new float[d->isize * 2]; // (float *) malloc0 (d->isize * sizeof (complex)); + + d->inbuff = new float[d->isize * 2]; // (double *) malloc0 (d->isize * sizeof (complex)); + d->outbuff = new float[d->isize * 2]; // (double *) malloc0 (d->isize * sizeof (complex)); + if (d->inrate != d->internalrate) d->resamprun = 1; else d->resamprun = 0; + d->inresamp = RESAMPLE::create_resample (d->resamprun, d->bsize, d->in, d->inbuff, d->inrate, d->internalrate, 0.0, 0, 2.0); RESAMPLE::setFCLow_resample (d->inresamp, 250.0); d->outresamp = RESAMPLE::create_resample (d->resamprun, d->isize, d->outbuff, d->out, d->internalrate, d->inrate, 0.0, 0, 2.0); RESAMPLE::setFCLow_resample (d->outresamp, 200.0); d->incr = d->xsize / d->ovrlp; + if (d->incr > d->isize) d->iasize = d->incr; else d->iasize = d->isize; + d->iainidx = 0; d->iaoutidx = 0; - d->inaccum = new float[d->isize]; // (float *) malloc0 (d->iasize * sizeof (float)); + d->inaccum = new float[d->iasize * 2]; // (double *) malloc0 (d->iasize * sizeof (double)); d->nsamps = 0; + if (d->incr > d->isize) { d->oasize = d->incr; @@ -79,8 +84,9 @@ void SNBA::calc_snba (SNBA *d) d->oainidx = 0; d->oaoutidx = 0; } + d->init_oaoutidx = d->oaoutidx; - d->outaccum = new float[d->oasize]; // (float *) malloc0 (d->oasize * sizeof (float)); + d->outaccum = new float[d->oasize * 2]; // (double *) malloc0 (d->oasize * sizeof (double)); } SNBA* SNBA::create_snba ( @@ -94,14 +100,14 @@ SNBA* SNBA::create_snba ( int xsize, int asize, int npasses, - float k1, - float k2, + double k1, + double k2, int b, int pre, int post, - float pmultmin, - float out_low_cut, - float out_high_cut + double pmultmin, + double out_low_cut, + double out_high_cut ) { SNBA *d = new SNBA; @@ -126,30 +132,30 @@ SNBA* SNBA::create_snba ( calc_snba (d); - d->xbase = new float[2 * d->xsize]; // (float *) malloc0 (2 * d->xsize * sizeof (float)); - d->xaux = d->xbase + d->xsize; - d->exec.a = new float[d->xsize]; // (float *) malloc0 (d->xsize * sizeof (float)); - d->exec.v = new float[d->xsize]; // (float *) malloc0 (d->xsize * sizeof (float)); - d->exec.detout = new int[d->xsize]; // (int *) malloc0 (d->xsize * sizeof (int)); - d->exec.savex = new float[d->xsize]; // (float *) malloc0 (d->xsize * sizeof (float)); - d->exec.xHout = new float[d->xsize]; // (float *) malloc0 (d->xsize * sizeof (float)); - d->exec.unfixed = new int32_t[d->xsize]; // (int *) malloc0 (d->xsize * sizeof (int)); - d->sdet.vp = new float[d->xsize]; // (float *) malloc0 (d->xsize * sizeof (float)); - d->sdet.vpwr = new float[d->xsize]; // (float *) malloc0 (d->xsize * sizeof (float)); + d->xbase = new float[2 * d->xsize]; // (double *) malloc0 (2 * d->xsize * sizeof (double)); + d->xaux = d->xbase + d->xsize; + d->exec.a = new float[d->xsize]; //(double *) malloc0 (d->xsize * sizeof (double)); + d->exec.v = new float[d->xsize]; //(double *) malloc0 (d->xsize * sizeof (double)); + d->exec.detout = new int[d->xsize]; //(int *) malloc0 (d->xsize * sizeof (int)); + d->exec.savex = new float[d->xsize]; //(double *) malloc0 (d->xsize * sizeof (double)); + d->exec.xHout = new float[d->xsize]; //(double *) malloc0 (d->xsize * sizeof (double)); + d->exec.unfixed = new int[d->xsize]; //(int *) malloc0 (d->xsize * sizeof (int)); + d->sdet.vp = new float[d->xsize]; //(double *) malloc0 (d->xsize * sizeof (double)); + d->sdet.vpwr = new float[d->xsize]; //(double *) malloc0 (d->xsize * sizeof (double)); d->wrk.xHat_a1rows_max = d->xsize + d->exec.asize; d->wrk.xHat_a2cols_max = d->xsize + 2 * d->exec.asize; - d->wrk.xHat_r = new float[d->xsize]; // (float *) malloc0 (d->xsize * sizeof(float)); - d->wrk.xHat_ATAI = new float[d->xsize * d->xsize]; // (float *) malloc0 (d->xsize * d->xsize * sizeof(float)); - d->wrk.xHat_A1 = new float[d->wrk.xHat_a1rows_max * d->xsize]; // (float *) malloc0 (d->wrk.xHat_a1rows_max * d->xsize * sizeof(float)); - d->wrk.xHat_A2 = new float[d->wrk.xHat_a1rows_max * d->wrk.xHat_a2cols_max]; // (float *) malloc0 (d->wrk.xHat_a1rows_max * d->wrk.xHat_a2cols_max * sizeof(float)); - d->wrk.xHat_P1 = new float[d->xsize * d->wrk.xHat_a2cols_max]; // (float *) malloc0 (d->xsize * d->wrk.xHat_a2cols_max * sizeof(float)); - d->wrk.xHat_P2 = new float[d->xsize]; // (float *) malloc0 (d->xsize * sizeof(float)); - d->wrk.trI_y = new float[d->xsize - 1]; // (float *) malloc0 ((d->xsize - 1) * sizeof(float)); - d->wrk.trI_v = new float[d->xsize - 1]; // (float *) malloc0 ((d->xsize - 1) * sizeof(float)); - d->wrk.dR_z = new float[d->xsize - 2]; // (float *) malloc0 ((d->xsize - 2) * sizeof(float)); - d->wrk.asolve_r = new float[d->exec.asize + 1]; // (float *) malloc0 ((d->exec.asize + 1) * sizeof(float)); - d->wrk.asolve_z = new float[d->exec.asize + 1]; // (float *) malloc0 ((d->exec.asize + 1) * sizeof(float)); + d->wrk.xHat_r = new float[d->xsize]; // (double *) malloc0 (d->xsize * sizeof(double)); + d->wrk.xHat_ATAI = new float[d->xsize * d->xsize]; // (double *) malloc0 (d->xsize * d->xsize * sizeof(double)); + d->wrk.xHat_A1 = new float[d->wrk.xHat_a1rows_max * d->xsize]; // (double *) malloc0 (d->wrk.xHat_a1rows_max * d->xsize * sizeof(double)); + d->wrk.xHat_A2 = new float[d->wrk.xHat_a1rows_max * d->wrk.xHat_a2cols_max]; // (double *) malloc0 (d->wrk.xHat_a1rows_max * d->wrk.xHat_a2cols_max * sizeof(double)); + d->wrk.xHat_P1 = new float[d->xsize * d->wrk.xHat_a2cols_max]; // (double *) malloc0 (d->xsize * d->wrk.xHat_a2cols_max * sizeof(double)); + d->wrk.xHat_P2 = new float[d->xsize]; // (double *) malloc0 (d->xsize * sizeof(double)); + d->wrk.trI_y = new float[d->xsize - 1]; // (double *) malloc0 ((d->xsize - 1) * sizeof(double)); + d->wrk.trI_v = new float[d->xsize - 1]; // (double *) malloc0 ((d->xsize - 1) * sizeof(double)); + d->wrk.dR_z = new float[d->xsize - 2]; // (double *) malloc0 ((d->xsize - 2) * sizeof(double)); + d->wrk.asolve_r = new float[d->exec.asize + 1]; // (double *) malloc0 ((d->exec.asize + 1) * sizeof(double)); + d->wrk.asolve_z = new float[d->exec.asize + 1]; // (double *) malloc0 ((d->exec.asize + 1) * sizeof(double)); return d; } @@ -191,7 +197,7 @@ void SNBA::destroy_snba (SNBA *d) decalc_snba (d); - delete (d); + delete[] (d); } void SNBA::flush_snba (SNBA *d) @@ -216,6 +222,7 @@ void SNBA::flush_snba (SNBA *d) memset (d->inbuff, 0, d->isize * sizeof (wcomplex)); memset (d->outbuff, 0, d->isize * sizeof (wcomplex)); + RESAMPLE::flush_resample (d->inresamp); RESAMPLE::flush_resample (d->outresamp); } @@ -256,6 +263,7 @@ void SNBA::multA1TA2(float* a1, float* a2, int m, int n, int q, float* c) int i, j, k; int p = q - m; memset (c, 0, m * n * sizeof (float)); + for (i = 0; i < m; i++) { for (j = 0; j < n; j++) @@ -278,6 +286,7 @@ void SNBA::multXKE(float* a, float* xk, int m, int q, int p, float* vout) { int i, k; memset (vout, 0, m * sizeof (float)); + for (i = 0; i < m; i++) { for (k = i; k < p; k++) @@ -291,6 +300,7 @@ void SNBA::multAv(float* a, float* v, int m, int q, float* vout) { int i, k; memset (vout, 0, m * sizeof (float)); + for (i = 0; i < m; i++) { for (k = 0; k < q; k++) @@ -356,6 +366,7 @@ void SNBA::invf(int xsize, int asize, float* a, float* x, float* v) { int i, j; memset (v, 0, xsize * sizeof (float)); + for (i = asize; i < xsize - asize; i++) { for (j = 0; j < asize; j++) @@ -373,16 +384,20 @@ void SNBA::invf(int xsize, int asize, float* a, float* x, float* v) void SNBA::det(SNBA *d, int asize, float* v, int* detout) { int i, j; - float medpwr, t1, t2; + float medpwr; + double t1, t2; int bstate, bcount, bsamp; + for (i = asize, j = 0; i < d->xsize; i++, j++) { d->sdet.vpwr[i] = v[i] * v[i]; d->sdet.vp[j] = d->sdet.vpwr[i]; } + LMath::median(d->xsize - asize, d->sdet.vp, &medpwr); t1 = d->sdet.k1 * medpwr; t2 = 0.0; + for (i = asize; i < d->xsize; i++) { if (d->sdet.vpwr[i] <= t1) @@ -390,7 +405,8 @@ void SNBA::det(SNBA *d, int asize, float* v, int* detout) else if (d->sdet.vpwr[i] <= 2.0 * t1) t2 += 2.0 * t1 - d->sdet.vpwr[i]; } - t2 *= d->sdet.k2 / (float)(d->xsize - asize); + t2 *= d->sdet.k2 / (double)(d->xsize - asize); + for (i = asize; i < d->xsize; i++) { if (d->sdet.vpwr[i] > t2) @@ -398,9 +414,11 @@ void SNBA::det(SNBA *d, int asize, float* v, int* detout) else detout[i] = 0; } + bstate = 0; bcount = 0; bsamp = 0; + for (i = asize; i < d->xsize; i++) { switch (bstate) @@ -453,7 +471,7 @@ void SNBA::det(SNBA *d, int asize, float* v, int* detout) int SNBA::scanFrame( int xsize, int pval, - float pmultmin, + double pmultmin, int* det, int* bimp, int* limp, @@ -466,9 +484,9 @@ int SNBA::scanFrame( int inflag = 0; int i = 0, j = 0, k = 0; int nimp = 0; - float td; + double td; int ti; - float merit[MAXIMP] = { 0 }; + double merit[MAXIMP] = { 0 }; int nextlist[MAXIMP]; memset (befimp, 0, MAXIMP * sizeof (int)); memset (aftimp, 0, MAXIMP * sizeof (int)); @@ -508,7 +526,7 @@ int SNBA::scanFrame( for (i = 0; i < nimp; i++) { - merit[i] = (float)p_opt[i] / (float)limp[i]; + merit[i] = (double)p_opt[i] / (double)limp[i]; nextlist[i] = i; } for (j = 0; j < nimp - 1; j++) @@ -564,15 +582,19 @@ void SNBA::execFrame(SNBA *d, float* x) LMath::asolve(d->xsize, d->exec.asize, x, d->exec.a, d->wrk.asolve_r, d->wrk.asolve_z); invf(d->xsize, d->exec.asize, d->exec.a, x, d->exec.v); det(d, d->exec.asize, d->exec.v, d->exec.detout); + for (i = 0; i < d->xsize; i++) { if (d->exec.detout[i] != 0) x[i] = 0.0; } + nimp = scanFrame(d->xsize, d->exec.asize, d->scan.pmultmin, d->exec.detout, bimp, limp, befimp, aftimp, p_opt, &next); + for (pass = 0; pass < d->exec.npasses; pass++) { memcpy (d->exec.unfixed, d->exec.detout, d->xsize * sizeof (int)); + for (k = 0; k < nimp; k++) { if (k > 0) @@ -601,12 +623,15 @@ void SNBA::xsnba (SNBA *d) { int i; RESAMPLE::xresample (d->inresamp); + for (i = 0; i < 2 * d->isize; i += 2) { d->inaccum[d->iainidx] = d->inbuff[i]; d->iainidx = (d->iainidx + 1) % d->iasize; } + d->nsamps += d->isize; + while (d->nsamps >= d->incr) { memcpy (&d->xaux[d->xsize - d->incr], &d->inaccum[d->iaoutidx], d->incr * sizeof (float)); @@ -617,12 +642,14 @@ void SNBA::xsnba (SNBA *d) d->oainidx = (d->oainidx + d->incr) % d->oasize; memmove (d->xbase, &d->xbase[d->incr], (2 * d->xsize - d->incr) * sizeof (float)); } + for (i = 0; i < d->isize; i++) { d->outbuff[2 * i + 0] = d->outaccum[d->oaoutidx]; d->outbuff[2 * i + 1] = 0.0; d->oaoutidx = (d->oaoutidx + 1) % d->oasize; } + RESAMPLE::xresample (d->outresamp); } else if (d->out != d->in) @@ -641,8 +668,14 @@ void SNBA::SetSNBARun (RXA& rxa, int run) if (a->run != run) { RXA::bpsnbaCheck (rxa, rxa.mode, rxa.ndb.p->master_run); - RXA::bp1Check (rxa, rxa.amd.p->run, run, rxa.emnr.p->run, - rxa.anf.p->run, rxa.anr.p->run); + RXA::bp1Check ( + rxa, + rxa.amd.p->run, + run, + rxa.emnr.p->run, + rxa.anf.p->run, + rxa.anr.p->run + ); rxa.csDSP.lock(); a->run = run; RXA::bp1Set (rxa); @@ -660,7 +693,7 @@ void SNBA::SetSNBAovrlp (RXA& rxa, int ovrlp) rxa.csDSP.unlock(); } -void SetSNBAasize (RXA& rxa, int size) +void SNBA::SetSNBAasize (RXA& rxa, int size) { rxa.csDSP.lock(); rxa.snba.p->exec.asize = size; @@ -674,14 +707,14 @@ void SNBA::SetSNBAnpasses (RXA& rxa, int npasses) rxa.csDSP.unlock(); } -void SNBA::SetSNBAk1 (RXA& rxa, float k1) +void SNBA::SetSNBAk1 (RXA& rxa, double k1) { rxa.csDSP.lock(); rxa.snba.p->sdet.k1 = k1; rxa.csDSP.unlock(); } -void SNBA::SetSNBAk2 (RXA& rxa, float k2) +void SNBA::SetSNBAk2 (RXA& rxa, double k2) { rxa.csDSP.lock(); rxa.snba.p->sdet.k2 = k2; @@ -709,21 +742,19 @@ void SNBA::SetSNBApostsamps (RXA& rxa, int postsamps) rxa.csDSP.unlock(); } -void SNBA::SetSNBApmultmin (RXA& rxa, float pmultmin) +void SNBA::SetSNBApmultmin (RXA& rxa, double pmultmin) { rxa.csDSP.lock(); rxa.snba.p->scan.pmultmin = pmultmin; rxa.csDSP.unlock(); } -void SNBA::SetSNBAOutputBandwidth (RXA& rxa, float flow, float fhigh) +void SNBA::SetSNBAOutputBandwidth (RXA& rxa, double flow, double fhigh) { - SNBA *a; - RESAMPLE *d; - float f_low, f_high; + SNBA *a = rxa.snba.p; + RESAMPLE *d = a->outresamp; + double f_low, f_high; rxa.csDSP.lock(); - a = rxa.snba.p; - d = a->outresamp; if (flow >= 0 && fhigh >= 0) { @@ -741,7 +772,7 @@ void SNBA::SetSNBAOutputBandwidth (RXA& rxa, float flow, float fhigh) } else if (flow < 0 && fhigh > 0) { - float absmax = std::max (-flow, fhigh); + double absmax = std::max (-flow, fhigh); if (absmax < a->out_low_cut) absmax = a->out_low_cut; f_low = a->out_low_cut; f_high = std::min (a->out_high_cut, absmax); @@ -751,183 +782,4 @@ void SNBA::SetSNBAOutputBandwidth (RXA& rxa, float flow, float fhigh) rxa.csDSP.unlock(); } - -/******************************************************************************************************** -* * -* BPSNBA Bandpass Filter * -* * -********************************************************************************************************/ - -// This is a thin wrapper for a notched-bandpass filter (nbp). The basic difference is that it provides -// for its input and output to happen at different points in the processing pipeline. This means it must -// include a buffer, 'buff'. Its input and output are done via functions xbpshbain() and xbpshbaout(). - -void BPSNBA::calc_bpsnba (BPSNBA *a) -{ - a->buff = new float[a->size * 2]; // (float *) malloc0 (a->size * sizeof (complex)); - a->bpsnba = NBP::create_nbp ( - 1, // run, always runs (use bpsnba 'run') - a->run_notches, // run the notches - 0, // position variable for nbp (not for bpsnba), always 0 - a->size, // buffer size - a->nc, // number of filter coefficients - a->mp, // minimum phase flag - a->buff, // pointer to input buffer - a->out, // pointer to output buffer - a->f_low, // lower filter frequency - a->f_high, // upper filter frequency - a->rate, // sample rate - a->wintype, // wintype - a->gain, // gain - a->autoincr, // auto-increase notch width if below min - a->maxpb, // max number of passbands - a->ptraddr); // addr of database pointer -} - -BPSNBA* BPSNBA::create_bpsnba ( - int run, - int run_notches, - int position, - int size, - int nc, - int mp, - float* in, - float* out, - int rate, - float abs_low_freq, - float abs_high_freq, - float f_low, - float f_high, - int wintype, - float gain, - int autoincr, - int maxpb, - NOTCHDB* ptraddr -) -{ - BPSNBA *a = new BPSNBA; - a->run = run; - a->run_notches = run_notches; - a->position = position; - a->size = size; - a->nc = nc; - a->mp = mp; - a->in = in; - a->out = out; - a->rate = rate; - a->abs_low_freq = abs_low_freq; - a->abs_high_freq = abs_high_freq; - a->f_low = f_low; - a->f_high = f_high; - a->wintype = wintype; - a->gain = gain; - a->autoincr = autoincr; - a->maxpb = maxpb; - a->ptraddr = ptraddr; - calc_bpsnba (a); - return a; -} - -void BPSNBA::decalc_bpsnba (BPSNBA *a) -{ - NBP::destroy_nbp (a->bpsnba); - delete[] (a->buff); -} - -void BPSNBA::destroy_bpsnba (BPSNBA *a) -{ - decalc_bpsnba (a); - delete[] (a); -} - -void BPSNBA::flush_bpsnba (BPSNBA *a) -{ - memset (a->buff, 0, a->size * sizeof (wcomplex)); - NBP::flush_nbp (a->bpsnba); -} - -void BPSNBA::setBuffers_bpsnba (BPSNBA *a, float* in, float* out) -{ - decalc_bpsnba (a); - a->in = in; - a->out = out; - calc_bpsnba (a); -} - -void BPSNBA::setSamplerate_bpsnba (BPSNBA *a, int rate) -{ - decalc_bpsnba (a); - a->rate = rate; - calc_bpsnba (a); -} - -void BPSNBA::setSize_bpsnba (BPSNBA *a, int size) -{ - decalc_bpsnba (a); - a->size = size; - calc_bpsnba (a); -} - -void BPSNBA::xbpsnbain (BPSNBA *a, int position) -{ - if (a->run && a->position == position) - memcpy (a->buff, a->in, a->size * sizeof (wcomplex)); -} - -void BPSNBA::xbpsnbaout (BPSNBA *a, int position) -{ - if (a->run && a->position == position) - NBP::xnbp (a->bpsnba, 0); -} - -void BPSNBA::recalc_bpsnba_filter (BPSNBA *a, int update) -{ - // Call anytime one of the parameters listed below has been changed in - // the BPSNBA struct. - NBP *b = a->bpsnba; - b->fnfrun = a->run_notches; - b->flow = a->f_low; - b->fhigh = a->f_high; - b->wintype = a->wintype; - b->gain = a->gain; - b->autoincr = a->autoincr; - NBP::calc_nbp_impulse (b); - FIRCORE::setImpulse_fircore (b->p, b->impulse, update); - delete[] (b->impulse); -} - -/******************************************************************************************************** -* * -* RXA Properties * -* * -********************************************************************************************************/ - - -void BPSNBA::BPSNBASetNC (RXA& rxa, int nc) -{ - BPSNBA *a; - rxa.csDSP.lock(); - a = rxa.bpsnba.p; - if (a->nc != nc) - { - a->nc = nc; - a->bpsnba->nc = a->nc; - NBP::setNc_nbp (a->bpsnba); - } - rxa.csDSP.unlock(); -} - - -void BPSNBA::BPSNBASetMP (RXA& rxa, int mp) -{ - BPSNBA *a; - a = rxa.bpsnba.p; - if (a->mp != mp) - { - a->mp = mp; - a->bpsnba->mp = a->mp; - NBP::setMp_nbp (a->bpsnba); - } -} - -} // namespace WDSP +} // namespace diff --git a/wdsp/snb.hpp b/wdsp/snba.hpp similarity index 58% rename from wdsp/snb.hpp rename to wdsp/snba.hpp index 8371a80a0..1caeeee71 100644 --- a/wdsp/snb.hpp +++ b/wdsp/snba.hpp @@ -28,14 +28,12 @@ warren@wpratt.com #ifndef wdsp_snba_h #define wdsp_snba_h -#include "export.h" - -namespace WDSP { +namespace WDSP{ class RESAMPLE; class RXA; -class WDSP_API SNBA +class SNBA { public: int run; @@ -79,8 +77,8 @@ public: } exec; struct _det { - float k1; - float k2; + double k1; + double k2; int b; int pre; int post; @@ -89,7 +87,7 @@ public: } sdet; struct _scan { - float pmultmin; + double pmultmin; } scan; struct _wrk { @@ -107,8 +105,8 @@ public: float* asolve_r; float* asolve_z; } wrk; - float out_low_cut; - float out_high_cut; + double out_low_cut; + double out_high_cut; static SNBA* create_snba ( int run, @@ -121,33 +119,37 @@ public: int xsize, int asize, int npasses, - float k1, - float k2, + double k1, + double k2, int b, int pre, int post, - float pmultmin, - float out_low_cut, - float out_high_cut + double pmultmin, + double out_low_cut, + double out_high_cut ); + static void destroy_snba (SNBA *d); static void flush_snba (SNBA *d); static void xsnba (SNBA *d); static void setBuffers_snba (SNBA *a, float* in, float* out); static void setSamplerate_snba (SNBA *a, int rate); static void setSize_snba (SNBA *a, int size); - // RXA - static void SetSNBAOutputBandwidth (RXA& rxa, float flow, float fhigh); + // RXA Properties static void SetSNBARun (RXA& rxa, int run); static void SetSNBAovrlp (RXA& rxa, int ovrlp); static void SetSNBAasize (RXA& rxa, int size); static void SetSNBAnpasses (RXA& rxa, int npasses); - static void SetSNBAk1 (RXA& rxa, float k1); - static void SetSNBAk2 (RXA& rxa, float k2); + static void SetSNBAk1 (RXA& rxa, double k1); + static void SetSNBAk2 (RXA& rxa, double k2); static void SetSNBAbridge (RXA& rxa, int bridge); static void SetSNBApresamps (RXA& rxa, int presamps); static void SetSNBApostsamps (RXA& rxa, int postsamps); - static void SetSNBApmultmin (RXA& rxa, float pmultmin); + static void SetSNBApmultmin (RXA& rxa, double pmultmin); + + + + static void SetSNBAOutputBandwidth (RXA& rxa, double flow, double fhigh); private: static void calc_snba (SNBA *d); @@ -177,7 +179,7 @@ private: static int scanFrame( int xsize, int pval, - float pmultmin, + double pmultmin, int* det, int* bimp, int* limp, @@ -189,73 +191,7 @@ private: static void execFrame(SNBA *d, float* x); }; - -class NBP; -class NOTCHDB; - -class WDSP_API BPSNBA -{ -public: - int run; // run the filter - int run_notches; // use the notches, vs straight bandpass - int position; // position in the processing pipeline - int size; // buffer size - int nc; // number of filter coefficients - int mp; // minimum phase flag - float* in; // input buffer - float* out; // output buffer - int rate; // sample rate - float* buff; // internal buffer - NBP *bpsnba; // pointer to the notched bandpass filter, nbp - float f_low; // low cutoff frequency - float f_high; // high cutoff frequency - float abs_low_freq; // lowest positive freq supported by SNB - float abs_high_freq; // highest positive freq supported by SNG - int wintype; // filter window type - float gain; // filter gain - int autoincr; // use auto increment for notch width - int maxpb; // maximum passband segments supported - NOTCHDB* ptraddr; // pointer to address of NOTCH DATABASE - - static BPSNBA* create_bpsnba ( - int run, - int run_notches, - int position, - int size, - int nc, - int mp, - float* in, - float* out, - int rate, - float abs_low_freq, - float abs_high_freq, - float f_low, - float f_high, - int wintype, - float gain, - int autoincr, - int maxpb, - NOTCHDB* ptraddr - ); - static void destroy_bpsnba (BPSNBA *a); - static void flush_bpsnba (BPSNBA *a); - static void setBuffers_bpsnba (BPSNBA *a, float* in, float* out); - static void setSamplerate_bpsnba (BPSNBA *a, int rate); - static void setSize_bpsnba (BPSNBA *a, int size); - static void xbpsnbain (BPSNBA *a, int position); - static void xbpsnbaout (BPSNBA *a, int position); - static void recalc_bpsnba_filter (BPSNBA *a, int update); - // RXA - static void BPSNBASetNC (RXA& rxa, int nc); - static void BPSNBASetMP (RXA& rxa, int mp); - static void bpsnbaCheck (RXA& rxa, int mode, int notch_run); - static void bpsnbaSet (RXA& rxa); - -private: - static void calc_bpsnba (BPSNBA *a); - static void decalc_bpsnba (BPSNBA *a); -}; - -} // namespace WDSP +} // namespace #endif +