1
0
mirror of https://github.com/f4exb/sdrangel.git synced 2024-11-22 08:04:49 -05:00

WDSP: notched bandpass filter: replaced static methods

This commit is contained in:
f4exb 2024-07-24 20:29:55 +02:00
parent 42fa9f5eb2
commit cc8c6d8004
6 changed files with 485 additions and 460 deletions

View File

@ -447,7 +447,7 @@ void WDSPRxSink::applySettings(const WDSPRxSettings& settings, bool force)
m_interpolatorDistance = (Real) m_channelSampleRate / (Real) m_audioSampleRate; m_interpolatorDistance = (Real) m_channelSampleRate / (Real) m_audioSampleRate;
WDSP::RXA::SetPassband(*m_rxa, fLow, fHigh); WDSP::RXA::SetPassband(*m_rxa, fLow, fHigh);
WDSP::NBP::NBPSetWindow(*m_rxa, m_settings.m_profiles[m_settings.m_profileIndex].m_fftWindow); WDSP::RXA::NBPSetWindow(*m_rxa, m_settings.m_profiles[m_settings.m_profileIndex].m_fftWindow);
if (settings.m_demod == WDSPRxProfile::DemodSSB) if (settings.m_demod == WDSPRxProfile::DemodSSB)
{ {

View File

@ -156,12 +156,12 @@ RXA* RXA::create_rxa (
// Notched bandpass section // Notched bandpass section
// notch database // notch database
rxa->ndb = NOTCHDB::create_notchdb ( rxa->ndb = new NOTCHDB (
0, // master run for all nbp's 0, // master run for all nbp's
1024); // max number of notches 1024); // max number of notches
// notched bandpass // notched bandpass
rxa->nbp0 = NBP::create_nbp ( rxa->nbp0 = new NBP (
1, // run, always runs 1, // run, always runs
0, // run the notches 0, // run the notches
0, // position 0, // position
@ -585,8 +585,8 @@ void RXA::destroy_rxa (RXA *rxa)
delete (rxa->smeter); delete (rxa->smeter);
SENDER::destroy_sender (rxa->sender); SENDER::destroy_sender (rxa->sender);
BPSNBA::destroy_bpsnba (rxa->bpsnba); BPSNBA::destroy_bpsnba (rxa->bpsnba);
NBP::destroy_nbp (rxa->nbp0); delete (rxa->nbp0);
NOTCHDB::destroy_notchdb (rxa->ndb); delete (rxa->ndb);
delete (rxa->adcmeter); delete (rxa->adcmeter);
delete (rxa->rsmpin); delete (rxa->rsmpin);
delete (rxa->shift); delete (rxa->shift);
@ -608,7 +608,7 @@ void RXA::flush_rxa (RXA *rxa)
rxa->shift->flush(); rxa->shift->flush();
rxa->rsmpin->flush(); rxa->rsmpin->flush();
rxa->adcmeter->flush(); rxa->adcmeter->flush();
NBP::flush_nbp (rxa->nbp0); rxa->nbp0->flush();
BPSNBA::flush_bpsnba (rxa->bpsnba); BPSNBA::flush_bpsnba (rxa->bpsnba);
SENDER::flush_sender (rxa->sender); SENDER::flush_sender (rxa->sender);
rxa->smeter->flush(); rxa->smeter->flush();
@ -641,7 +641,7 @@ void RXA::xrxa (RXA *rxa)
rxa->rsmpin->execute(); rxa->rsmpin->execute();
rxa->adcmeter->execute(); rxa->adcmeter->execute();
BPSNBA::xbpsnbain (rxa->bpsnba, 0); BPSNBA::xbpsnbain (rxa->bpsnba, 0);
NBP::xnbp (rxa->nbp0, 0); rxa->nbp0->execute(0);
rxa->smeter->execute(); rxa->smeter->execute();
SENDER::xsender (rxa->sender); SENDER::xsender (rxa->sender);
AMSQ::xamsqcap (rxa->amsq); AMSQ::xamsqcap (rxa->amsq);
@ -753,7 +753,7 @@ void RXA::setDSPSamplerate (RXA *rxa, int dsp_rate)
rxa->rsmpin->setOutRate(rxa->dsp_rate); rxa->rsmpin->setOutRate(rxa->dsp_rate);
// dsp_rate blocks // dsp_rate blocks
rxa->adcmeter->setSamplerate(rxa->dsp_rate); rxa->adcmeter->setSamplerate(rxa->dsp_rate);
NBP::setSamplerate_nbp (rxa->nbp0, rxa->dsp_rate); rxa->nbp0->setSamplerate(rxa->dsp_rate);
BPSNBA::setSamplerate_bpsnba (rxa->bpsnba, rxa->dsp_rate); BPSNBA::setSamplerate_bpsnba (rxa->bpsnba, rxa->dsp_rate);
rxa->smeter->setSamplerate(rxa->dsp_rate); rxa->smeter->setSamplerate(rxa->dsp_rate);
SENDER::setSamplerate_sender (rxa->sender, rxa->dsp_rate); SENDER::setSamplerate_sender (rxa->sender, rxa->dsp_rate);
@ -817,8 +817,8 @@ void RXA::setDSPBuffsize (RXA *rxa, int dsp_size)
// dsp_size blocks // dsp_size blocks
rxa->adcmeter->setBuffers(rxa->midbuff); rxa->adcmeter->setBuffers(rxa->midbuff);
rxa->adcmeter->setSize(rxa->dsp_size); rxa->adcmeter->setSize(rxa->dsp_size);
NBP::setBuffers_nbp (rxa->nbp0, rxa->midbuff, rxa->midbuff); rxa->nbp0->setBuffers(rxa->midbuff, rxa->midbuff);
NBP::setSize_nbp (rxa->nbp0, rxa->dsp_size); rxa->nbp0->setSize(rxa->dsp_size);
BPSNBA::setBuffers_bpsnba (rxa->bpsnba, rxa->midbuff, rxa->midbuff); BPSNBA::setBuffers_bpsnba (rxa->bpsnba, rxa->midbuff, rxa->midbuff);
BPSNBA::setSize_bpsnba (rxa->bpsnba, rxa->dsp_size); BPSNBA::setSize_bpsnba (rxa->bpsnba, rxa->dsp_size);
rxa->smeter->setBuffers(rxa->midbuff); rxa->smeter->setBuffers(rxa->midbuff);
@ -1066,7 +1066,163 @@ void RXA::bpsnbaSet (RXA& rxa)
a->run = 0; a->run = 0;
break; break;
} }
FIRCORE::setUpdate_fircore (a->bpsnba->p); FIRCORE::setUpdate_fircore (a->bpsnba->fircore);
}
void RXA::UpdateNBPFiltersLightWeight (RXA& rxa)
{ // called when setting tune freq or shift freq
rxa.nbp0->calc_lightweight();
rxa.bpsnba->bpsnba->calc_lightweight();
}
void RXA::UpdateNBPFilters(RXA& rxa)
{
NBP *a = rxa.nbp0;
BPSNBA *b = rxa.bpsnba;
if (a->fnfrun)
{
a->calc_impulse();
FIRCORE::setImpulse_fircore (a->fircore, a->impulse, 1);
delete[] (a->impulse);
}
if (b->bpsnba->fnfrun)
{
BPSNBA::recalc_bpsnba_filter (b, 1);
}
}
int RXA::NBPAddNotch (RXA& rxa, int notch, double fcenter, double fwidth, int active)
{
NOTCHDB *b = rxa.ndb;
int rval = b->addNotch(notch, fcenter, fwidth, active);
if (rval == 0) {
RXA::UpdateNBPFilters (rxa);
}
return rval;
}
int RXA::NBPGetNotch (RXA& rxa, int notch, double* fcenter, double* fwidth, int* active)
{
NOTCHDB *a = rxa.ndb;
int rval = a->getNotch(notch, fcenter, fwidth, active);
return rval;
}
int RXA::NBPDeleteNotch (RXA& rxa, int notch)
{
NOTCHDB *a = rxa.ndb;
int rval = a->deleteNotch(notch);
if (rval == 0) {
RXA::UpdateNBPFilters (rxa);
}
return rval;
}
int RXA::NBPEditNotch (RXA& rxa, int notch, double fcenter, double fwidth, int active)
{
NOTCHDB *a = rxa.ndb;
int rval = a->editNotch(notch, fcenter, fwidth, active);
if (rval == 0) {
RXA::UpdateNBPFilters (rxa);
}
return rval;
}
void RXA::NBPGetNumNotches (RXA& rxa, int* nnotches)
{
NOTCHDB *a = rxa.ndb;
a->getNumNotches(nnotches);
}
void RXA::NBPSetTuneFrequency (RXA& rxa, double tunefreq)
{
NOTCHDB *a;
a = rxa.ndb;
if (tunefreq != a->tunefreq)
{
a->tunefreq = tunefreq;
RXA::UpdateNBPFiltersLightWeight (rxa);
}
}
void RXA::NBPSetShiftFrequency (RXA& rxa, double shift)
{
NOTCHDB *a;
a = rxa.ndb;
if (shift != a->shift)
{
a->shift = shift;
RXA::UpdateNBPFiltersLightWeight (rxa);
}
}
void RXA::NBPSetNotchesRun (RXA& rxa, int run)
{
NOTCHDB *a = rxa.ndb;
NBP *b = rxa.nbp0;
if ( run != a->master_run)
{
a->master_run = run; // update variables
b->fnfrun = a->master_run;
RXA::bpsnbaCheck (rxa, rxa.mode, run);
b->calc_impulse(); // recalc nbp impulse response
FIRCORE::setImpulse_fircore (b->fircore, b->impulse, 0); // calculate new filter masks
delete[] (b->impulse);
RXA::bpsnbaSet (rxa);
FIRCORE::setUpdate_fircore (b->fircore); // apply new filter masks
}
}
void RXA::NBPSetWindow (RXA& rxa, int wintype)
{
NBP *a;
BPSNBA *b;
a = rxa.nbp0;
b = rxa.bpsnba;
if ((a->wintype != wintype))
{
a->wintype = wintype;
a->calc_impulse();
FIRCORE::setImpulse_fircore (a->fircore, a->impulse, 1);
delete[] (a->impulse);
}
if ((b->wintype != wintype))
{
b->wintype = wintype;
BPSNBA::recalc_bpsnba_filter (b, 1);
}
}
void RXA::NBPSetAutoIncrease (RXA& rxa, int autoincr)
{
NBP *a;
BPSNBA *b;
a = rxa.nbp0;
b = rxa.bpsnba;
if ((a->autoincr != autoincr))
{
a->autoincr = autoincr;
a->calc_impulse();
FIRCORE::setImpulse_fircore (a->fircore, a->impulse, 1);
delete[] (a->impulse);
}
if ((b->autoincr != autoincr))
{
b->autoincr = autoincr;
BPSNBA::recalc_bpsnba_filter (b, 1);
}
} }
/******************************************************************************************************** /********************************************************************************************************
@ -1079,13 +1235,13 @@ void RXA::SetPassband (RXA& rxa, float f_low, float f_high)
{ {
BANDPASS::SetBandpassFreqs (rxa, f_low, f_high); // After spectral noise reduction ( AM || ANF || ANR || EMNR) BANDPASS::SetBandpassFreqs (rxa, f_low, f_high); // After spectral noise reduction ( AM || ANF || ANR || EMNR)
SNBA::SetSNBAOutputBandwidth (rxa, f_low, f_high); // Spectral noise blanker (SNB) SNBA::SetSNBAOutputBandwidth (rxa, f_low, f_high); // Spectral noise blanker (SNB)
NBP::NBPSetFreqs (rxa, f_low, f_high); // Notched bandpass rxa.nbp0->SetFreqs (f_low, f_high); // Notched bandpass
} }
void RXA::SetNC (RXA& rxa, int nc) void RXA::SetNC (RXA& rxa, int nc)
{ {
int oldstate = rxa.state; int oldstate = rxa.state;
NBP::NBPSetNC (rxa, nc); rxa.nbp0->SetNC (nc);
BPSNBA::BPSNBASetNC (rxa, nc); BPSNBA::BPSNBASetNC (rxa, nc);
BANDPASS::SetBandpassNC (rxa, nc); BANDPASS::SetBandpassNC (rxa, nc);
EQP::SetEQNC (rxa, nc); EQP::SetEQNC (rxa, nc);
@ -1097,7 +1253,7 @@ void RXA::SetNC (RXA& rxa, int nc)
void RXA::SetMP (RXA& rxa, int mp) void RXA::SetMP (RXA& rxa, int mp)
{ {
NBP::NBPSetMP (rxa, mp); rxa.nbp0->SetMP (mp);
BPSNBA::BPSNBASetMP (rxa, mp); BPSNBA::BPSNBASetMP (rxa, mp);
BANDPASS::SetBandpassMP (rxa, mp); BANDPASS::SetBandpassMP (rxa, mp);
EQP::SetEQMP (rxa, mp); EQP::SetEQMP (rxa, mp);

View File

@ -154,6 +154,19 @@ public:
static void bp1Set (RXA& rxa); static void bp1Set (RXA& rxa);
static void bpsnbaCheck (RXA& rxa, int mode, int notch_run); static void bpsnbaCheck (RXA& rxa, int mode, int notch_run);
static void bpsnbaSet (RXA& rxa); static void bpsnbaSet (RXA& rxa);
// NOTCHDB, NBP, SNBA
static void UpdateNBPFiltersLightWeight (RXA& rxa);
static void UpdateNBPFilters(RXA& rxa);
static int NBPAddNotch (RXA& rxa, int notch, double fcenter, double fwidth, int active);
static int NBPGetNotch (RXA& rxa, int notch, double* fcenter, double* fwidth, int* active);
static int NBPDeleteNotch (RXA& rxa, int notch);
static int NBPEditNotch (RXA& rxa, int notch, double fcenter, double fwidth, int active);
static void NBPGetNumNotches (RXA& rxa, int* nnotches);
static void NBPSetTuneFrequency (RXA& rxa, double tunefreq);
static void NBPSetShiftFrequency (RXA& rxa, double shift);
static void NBPSetNotchesRun (RXA& rxa, int run);
static void NBPSetWindow (RXA& rxa, int wintype);
static void NBPSetAutoIncrease (RXA& rxa, int autoincr);
// Collectives // Collectives
static void SetPassband (RXA& rxa, float f_low, float f_high); static void SetPassband (RXA& rxa, float f_low, float f_high);

View File

@ -54,7 +54,7 @@ namespace WDSP {
void BPSNBA::calc_bpsnba (BPSNBA *a) void BPSNBA::calc_bpsnba (BPSNBA *a)
{ {
a->buff = new float[a->size * 2]; // (double *) malloc0 (a->size * sizeof (complex)); a->buff = new float[a->size * 2]; // (double *) malloc0 (a->size * sizeof (complex));
a->bpsnba = NBP::create_nbp ( a->bpsnba = new NBP (
1, // run, always runs (use bpsnba 'run') 1, // run, always runs (use bpsnba 'run')
a->run_notches, // run the notches a->run_notches, // run the notches
0, // position variable for nbp (not for bpsnba), always 0 0, // position variable for nbp (not for bpsnba), always 0
@ -119,7 +119,7 @@ BPSNBA* BPSNBA::create_bpsnba (
void BPSNBA::decalc_bpsnba (BPSNBA *a) void BPSNBA::decalc_bpsnba (BPSNBA *a)
{ {
NBP::destroy_nbp (a->bpsnba); delete (a->bpsnba);
delete[] (a->buff); delete[] (a->buff);
} }
@ -132,7 +132,7 @@ void BPSNBA::destroy_bpsnba (BPSNBA *a)
void BPSNBA::flush_bpsnba (BPSNBA *a) void BPSNBA::flush_bpsnba (BPSNBA *a)
{ {
std::fill(a->buff, a->buff + a->size * 2, 0); std::fill(a->buff, a->buff + a->size * 2, 0);
NBP::flush_nbp (a->bpsnba); a->bpsnba->flush();
} }
void BPSNBA::setBuffers_bpsnba (BPSNBA *a, float* in, float* out) void BPSNBA::setBuffers_bpsnba (BPSNBA *a, float* in, float* out)
@ -166,7 +166,7 @@ void BPSNBA::xbpsnbain (BPSNBA *a, int position)
void BPSNBA::xbpsnbaout (BPSNBA *a, int position) void BPSNBA::xbpsnbaout (BPSNBA *a, int position)
{ {
if (a->run && a->position == position) if (a->run && a->position == position)
NBP::xnbp (a->bpsnba, 0); a->bpsnba->execute(0);
} }
void BPSNBA::recalc_bpsnba_filter (BPSNBA *a, int update) void BPSNBA::recalc_bpsnba_filter (BPSNBA *a, int update)
@ -180,8 +180,8 @@ void BPSNBA::recalc_bpsnba_filter (BPSNBA *a, int update)
b->wintype = a->wintype; b->wintype = a->wintype;
b->gain = a->gain; b->gain = a->gain;
b->autoincr = a->autoincr; b->autoincr = a->autoincr;
NBP::calc_nbp_impulse (b); b->calc_impulse();
FIRCORE::setImpulse_fircore (b->p, b->impulse, update); FIRCORE::setImpulse_fircore (b->fircore, b->impulse, update);
delete[] (b->impulse); delete[] (b->impulse);
} }
@ -199,7 +199,7 @@ void BPSNBA::BPSNBASetNC (RXA& rxa, int nc)
{ {
a->nc = nc; a->nc = nc;
a->bpsnba->nc = a->nc; a->bpsnba->nc = a->nc;
NBP::setNc_nbp (a->bpsnba); a->bpsnba->setNc();
} }
} }
@ -211,7 +211,7 @@ void BPSNBA::BPSNBASetMP (RXA& rxa, int mp)
{ {
a->mp = mp; a->mp = mp;
a->bpsnba->mp = a->mp; a->bpsnba->mp = a->mp;
NBP::setMp_nbp (a->bpsnba); a->bpsnba->setMp();
} }
} }

View File

@ -30,7 +30,6 @@ warren@wpratt.com
#include "fircore.hpp" #include "fircore.hpp"
#include "bpsnba.hpp" #include "bpsnba.hpp"
#include "nbp.hpp" #include "nbp.hpp"
#include "RXA.hpp"
namespace WDSP { namespace WDSP {
@ -40,27 +39,122 @@ namespace WDSP {
* * * *
********************************************************************************************************/ ********************************************************************************************************/
NOTCHDB* NOTCHDB::create_notchdb (int master_run, int maxnotches) NOTCHDB::NOTCHDB(int _master_run, int _maxnotches)
{ {
NOTCHDB *a = new NOTCHDB; master_run = _master_run;
a->master_run = master_run; maxnotches = _maxnotches;
a->maxnotches = maxnotches; nn = 0;
a->nn = 0; fcenter = new double[maxnotches]; // (float *) malloc0 (maxnotches * sizeof (float));
a->fcenter = new double[a->maxnotches]; // (float *) malloc0 (a->maxnotches * sizeof (float)); fwidth = new double[maxnotches]; // (float *) malloc0 (maxnotches * sizeof (float));
a->fwidth = new double[a->maxnotches]; // (float *) malloc0 (a->maxnotches * sizeof (float)); nlow = new double[maxnotches]; // (float *) malloc0 (maxnotches * sizeof (float));
a->nlow = new double[a->maxnotches]; // (float *) malloc0 (a->maxnotches * sizeof (float)); nhigh = new double[maxnotches]; // (float *) malloc0 (maxnotches * sizeof (float));
a->nhigh = new double[a->maxnotches]; // (float *) malloc0 (a->maxnotches * sizeof (float)); active = new int[maxnotches]; // (int *) malloc0 (maxnotches * sizeof (int ));
a->active = new int[a->maxnotches]; // (int *) malloc0 (a->maxnotches * sizeof (int ));
return a;
} }
void NOTCHDB::destroy_notchdb (NOTCHDB *b) NOTCHDB::~NOTCHDB()
{ {
delete[] (b->active); delete[] (active);
delete[] (b->nhigh); delete[] (nhigh);
delete[] (b->nlow); delete[] (nlow);
delete[] (b->fwidth); delete[] (fwidth);
delete[] (b->fcenter); delete[] (fcenter);
}
int NOTCHDB::addNotch(int notch, double _fcenter, double _fwidth, int _active)
{
int i, j;
int rval;
if (notch <= nn && nn < maxnotches)
{
nn++;
for (i = nn - 2, j = nn - 1; i >= notch; i--, j--)
{
fcenter[j] = fcenter[i];
fwidth[j] = fwidth[i];
nlow[j] = nlow[i];
nhigh[j] = nhigh[i];
active[j] = active[i];
}
fcenter[notch] = _fcenter;
fwidth[notch] = _fwidth;
nlow[notch] = _fcenter - 0.5 * _fwidth;
nhigh[notch] = _fcenter + 0.5 * _fwidth;
active[notch] = _active;
rval = 0;
}
else
rval = -1;
return rval;
}
int NOTCHDB::getNotch(int _notch, double* _fcenter, double* _fwidth, int* _active)
{
int rval;
if (_notch < nn)
{
*_fcenter = fcenter[_notch];
*_fwidth = fwidth[_notch];
*_active = active[_notch];
rval = 0;
}
else
{
*_fcenter = -1.0;
*_fwidth = 0.0;
*_active = -1;
rval = -1;
}
return rval;
}
int NOTCHDB::deleteNotch(int _notch)
{
int i, j;
int rval;
if (_notch < nn)
{
nn--;
for (i = _notch, j = _notch + 1; i < nn; i++, j++)
{
fcenter[i] = fcenter[j];
fwidth[i] = fwidth[j];
nlow[i] = nlow[j];
nhigh[i] = nhigh[j];
active[i] = active[j];
}
rval = 0;
}
else
rval = -1;
return rval;
}
int NOTCHDB::editNotch(int _notch, double _fcenter, double _fwidth, int _active)
{
int rval;
if (_notch < nn)
{
fcenter[_notch] = _fcenter;
fwidth[_notch] = _fwidth;
nlow[_notch] = _fcenter - 0.5 * _fwidth;
nhigh[_notch] = _fcenter + 0.5 * _fwidth;
active[_notch] = _active;
rval = 0;
}
else
rval = -1;
return rval;
}
void NOTCHDB::getNumNotches(int* _nnotches)
{
*_nnotches = nn;
} }
/******************************************************************************************************** /********************************************************************************************************
@ -87,16 +181,16 @@ float* NBP::fir_mbandpass (int N, int nbp, double* flow, double* fhigh, double r
return impulse; return impulse;
} }
double NBP::min_notch_width (NBP *a) double NBP::min_notch_width()
{ {
double min_width; double min_width;
switch (a->wintype) switch (wintype)
{ {
case 0: case 0:
min_width = 1600.0 / (a->nc / 256) * (a->rate / 48000); min_width = 1600.0 / (nc / 256) * (rate / 48000);
break; break;
case 1: case 1:
min_width = 2200.0 / (a->nc / 256) * (a->rate / 48000); min_width = 2200.0 / (nc / 256) * (rate / 48000);
break; break;
} }
return min_width; return min_width;
@ -200,485 +294,255 @@ int NBP::make_nbp (
return nbp; return nbp;
} }
void NBP::calc_nbp_lightweight (NBP *a) void NBP::calc_lightweight()
{ // calculate and set new impulse response; used when changing tune freq or shift freq { // calculate and set new impulse response; used when changing tune freq or shift freq
int i; int i;
double fl, fh; double fl, fh;
double offset; double offset;
NOTCHDB *b = a->ptraddr; NOTCHDB *b = notchdb;
if (a->fnfrun) if (fnfrun)
{ {
offset = b->tunefreq + b->shift; offset = b->tunefreq + b->shift;
fl = a->flow + offset; fl = flow + offset;
fh = a->fhigh + offset; fh = fhigh + offset;
a->numpb = make_nbp ( numpb = make_nbp (
b->nn, b->nn,
b->active, b->active,
b->fcenter, b->fcenter,
b->fwidth, b->fwidth,
b->nlow, b->nlow,
b->nhigh, b->nhigh,
min_notch_width (a), min_notch_width(),
a->autoincr, autoincr,
fl, fl,
fh, fh,
a->bplow, bplow,
a->bphigh, bphigh,
&a->havnotch &havnotch
); );
// when tuning, no need to recalc filter if there were not and are not any notches in passband // when tuning, no need to recalc filter if there were not and are not any notches in passband
if (a->hadnotch || a->havnotch) if (hadnotch || havnotch)
{ {
for (i = 0; i < a->numpb; i++) for (i = 0; i < numpb; i++)
{ {
a->bplow[i] -= offset; bplow[i] -= offset;
a->bphigh[i] -= offset; bphigh[i] -= offset;
} }
a->impulse = fir_mbandpass (a->nc, a->numpb, a->bplow, a->bphigh, impulse = fir_mbandpass (nc, numpb, bplow, bphigh,
a->rate, a->gain / (float)(2 * a->size), a->wintype); rate, gain / (float)(2 * size), wintype);
FIRCORE::setImpulse_fircore (a->p, a->impulse, 1); FIRCORE::setImpulse_fircore (fircore, impulse, 1);
// print_impulse ("nbp.txt", a->size + 1, impulse, 1, 0); // print_impulse ("nbp.txt", size + 1, impulse, 1, 0);
delete[](a->impulse); delete[](impulse);
} }
a->hadnotch = a->havnotch; hadnotch = havnotch;
} }
else else
a->hadnotch = 1; hadnotch = 1;
} }
void NBP::calc_nbp_impulse (NBP *a) void NBP::calc_impulse ()
{ // calculates impulse response; for create_fircore() and parameter changes { // calculates impulse response; for create_fircore() and parameter changes
int i; int i;
float fl, fh; float fl, fh;
double offset; double offset;
NOTCHDB *b = a->ptraddr; NOTCHDB *b = notchdb;
if (a->fnfrun)
if (fnfrun)
{ {
offset = b->tunefreq + b->shift; offset = b->tunefreq + b->shift;
fl = a->flow + offset; fl = flow + offset;
fh = a->fhigh + offset; fh = fhigh + offset;
a->numpb = make_nbp ( numpb = make_nbp (
b->nn, b->nn,
b->active, b->active,
b->fcenter, b->fcenter,
b->fwidth, b->fwidth,
b->nlow, b->nlow,
b->nhigh, b->nhigh,
min_notch_width (a), min_notch_width(),
a->autoincr, autoincr,
fl, fl,
fh, fh,
a->bplow, bplow,
a->bphigh, bphigh,
&a->havnotch &havnotch
); );
for (i = 0; i < a->numpb; i++) for (i = 0; i < numpb; i++)
{ {
a->bplow[i] -= offset; bplow[i] -= offset;
a->bphigh[i] -= offset; bphigh[i] -= offset;
} }
a->impulse = fir_mbandpass ( impulse = fir_mbandpass (
a->nc, nc,
a->numpb, numpb,
a->bplow, bplow,
a->bphigh, bphigh,
a->rate, rate,
a->gain / (float)(2 * a->size), gain / (float)(2 * size),
a->wintype wintype
); );
} }
else else
{ {
a->impulse = FIR::fir_bandpass( impulse = FIR::fir_bandpass(
a->nc, nc,
a->flow, flow,
a->fhigh, fhigh,
a->rate, rate,
a->wintype, wintype,
1, 1,
a->gain / (float)(2 * a->size) gain / (float)(2 * size)
); );
} }
} }
NBP* NBP::create_nbp( NBP::NBP(
int run, int _run,
int fnfrun, int _fnfrun,
int position, int _position,
int size, int _size,
int nc, int _nc,
int mp, int _mp,
float* in, float* _in,
float* out, float* _out,
double flow, double _flow,
double fhigh, double _fhigh,
int rate, int _rate,
int wintype, int _wintype,
double gain, double _gain,
int autoincr, int _autoincr,
int maxpb, int _maxpb,
NOTCHDB* ptraddr NOTCHDB* _notchdb
) ) :
run(_run),
fnfrun(_fnfrun),
position(_position),
size(_size),
nc(_nc),
mp(_mp),
rate((double) _rate),
wintype(_wintype),
gain(_gain),
in(_in),
out(_out),
autoincr(_autoincr),
flow(_flow),
fhigh(_fhigh),
maxpb(_maxpb),
notchdb(_notchdb)
{ {
NBP *a = new NBP; bplow = new double[maxpb]; // (float *) malloc0 (maxpb * sizeof (float));
a->run = run; bphigh = new double[maxpb]; // (float *) malloc0 (maxpb * sizeof (float));
a->fnfrun = fnfrun; calc_impulse ();
a->position = position; fircore = FIRCORE::create_fircore (size, in, out, nc, mp, impulse);
a->size = size; // print_impulse ("nbp.txt", size + 1, impulse, 1, 0);
a->nc = nc; delete[](impulse);
a->mp = mp;
a->rate = (double) rate;
a->wintype = wintype;
a->gain = gain;
a->in = in;
a->out = out;
a->autoincr = autoincr;
a->flow = flow;
a->fhigh = fhigh;
a->maxpb = maxpb;
a->ptraddr = ptraddr;
a->bplow = new double[a->maxpb]; // (float *) malloc0 (a->maxpb * sizeof (float));
a->bphigh = new double[a->maxpb]; // (float *) malloc0 (a->maxpb * sizeof (float));
calc_nbp_impulse (a);
a->p = FIRCORE::create_fircore (a->size, a->in, a->out, a->nc, a->mp, a->impulse);
// print_impulse ("nbp.txt", a->size + 1, impulse, 1, 0);
delete[](a->impulse);
return a;
} }
void NBP::destroy_nbp (NBP *a) NBP::~NBP()
{ {
FIRCORE::destroy_fircore (a->p); FIRCORE::destroy_fircore (fircore);
delete[] (a->bphigh); delete[] (bphigh);
delete[] (a->bplow); delete[] (bplow);
delete (a);
} }
void NBP::flush_nbp (NBP *a) void NBP::flush()
{ {
FIRCORE::flush_fircore (a->p); FIRCORE::flush_fircore (fircore);
} }
void NBP::xnbp (NBP *a, int pos) void NBP::execute (int pos)
{ {
if (a->run && pos == a->position) if (run && pos == position)
FIRCORE::xfircore (a->p); FIRCORE::xfircore (fircore);
else if (a->in != a->out) else if (in != out)
std::copy( a->in, a->in + a->size * 2, a->out); std::copy( in, in + size * 2, out);
} }
void NBP::setBuffers_nbp (NBP *a, float* in, float* out) void NBP::setBuffers(float* _in, float* _out)
{ {
a->in = in; in = _in;
a->out = out; out = _out;
FIRCORE::setBuffers_fircore (a->p, a->in, a->out); FIRCORE::setBuffers_fircore (fircore, in, out);
} }
void NBP::setSamplerate_nbp (NBP *a, int rate) void NBP::setSamplerate(int _rate)
{ {
a->rate = rate; rate = _rate;
calc_nbp_impulse (a); calc_impulse ();
FIRCORE::setImpulse_fircore (a->p, a->impulse, 1); FIRCORE::setImpulse_fircore (fircore, impulse, 1);
delete[] (a->impulse); delete[] (impulse);
} }
void NBP::setSize_nbp (NBP *a, int size) void NBP::setSize(int _size)
{ {
// NOTE: 'size' must be <= 'nc' // NOTE: 'size' must be <= 'nc'
a->size = size; size = _size;
FIRCORE::setSize_fircore (a->p, a->size); FIRCORE::setSize_fircore (fircore, size);
calc_nbp_impulse (a); calc_impulse ();
FIRCORE::setImpulse_fircore (a->p, a->impulse, 1); FIRCORE::setImpulse_fircore (fircore, impulse, 1);
delete[] (a->impulse); delete[] (impulse);
} }
void NBP::setNc_nbp (NBP *a) void NBP::setNc()
{ {
calc_nbp_impulse (a); calc_impulse();
FIRCORE::setNc_fircore (a->p, a->nc, a->impulse); FIRCORE::setNc_fircore (fircore, nc, impulse);
delete[] (a->impulse); delete[] (impulse);
} }
void NBP::setMp_nbp (NBP *a) void NBP::setMp()
{ {
FIRCORE::setMp_fircore (a->p, a->mp); FIRCORE::setMp_fircore (fircore, mp);
} }
/******************************************************************************************************** /********************************************************************************************************
* * * *
* RXA Properties * * Public Properties *
* * * *
********************************************************************************************************/ ********************************************************************************************************/
// DATABASE PROPERTIES
void NBP::UpdateNBPFiltersLightWeight (RXA& rxa)
{ // called when setting tune freq or shift freq
calc_nbp_lightweight (rxa.nbp0);
calc_nbp_lightweight (rxa.bpsnba->bpsnba);
}
void NBP::UpdateNBPFilters(RXA& rxa)
{
NBP *a = rxa.nbp0;
BPSNBA *b = rxa.bpsnba;
if (a->fnfrun)
{
calc_nbp_impulse (a);
FIRCORE::setImpulse_fircore (a->p, a->impulse, 1);
delete[] (a->impulse);
}
if (b->bpsnba->fnfrun)
{
BPSNBA::recalc_bpsnba_filter (b, 1);
}
}
int NBP::NBPAddNotch (RXA& rxa, int notch, double fcenter, double fwidth, int active)
{
NOTCHDB *b;
int i, j;
int rval;
b = rxa.ndb;
if (notch <= b->nn && b->nn < b->maxnotches)
{
b->nn++;
for (i = b->nn - 2, j = b->nn - 1; i >= notch; i--, j--)
{
b->fcenter[j] = b->fcenter[i];
b->fwidth[j] = b->fwidth[i];
b->nlow[j] = b->nlow[i];
b->nhigh[j] = b->nhigh[i];
b->active[j] = b->active[i];
}
b->fcenter[notch] = fcenter;
b->fwidth[notch] = fwidth;
b->nlow[notch] = fcenter - 0.5 * fwidth;
b->nhigh[notch] = fcenter + 0.5 * fwidth;
b->active[notch] = active;
UpdateNBPFilters (rxa);
rval = 0;
}
else
rval = -1;
return rval;
}
int NBP::NBPGetNotch (RXA& rxa, int notch, double* fcenter, double* fwidth, int* active)
{
NOTCHDB *a;
int rval;
a = rxa.ndb;
if (notch < a->nn)
{
*fcenter = a->fcenter[notch];
*fwidth = a->fwidth[notch];
*active = a->active[notch];
rval = 0;
}
else
{
*fcenter = -1.0;
*fwidth = 0.0;
*active = -1;
rval = -1;
}
return rval;
}
int NBP::NBPDeleteNotch (RXA& rxa, int notch)
{
int i, j;
int rval;
NOTCHDB *a;
a = rxa.ndb;
if (notch < a->nn)
{
a->nn--;
for (i = notch, j = notch + 1; i < a->nn; i++, j++)
{
a->fcenter[i] = a->fcenter[j];
a->fwidth[i] = a->fwidth[j];
a->nlow[i] = a->nlow[j];
a->nhigh[i] = a->nhigh[j];
a->active[i] = a->active[j];
}
UpdateNBPFilters (rxa);
rval = 0;
}
else
rval = -1;
return rval;
}
int NBP::NBPEditNotch (RXA& rxa, int notch, double fcenter, double fwidth, int active)
{
NOTCHDB *a;
int rval;
a = rxa.ndb;
if (notch < a->nn)
{
a->fcenter[notch] = fcenter;
a->fwidth[notch] = fwidth;
a->nlow[notch] = fcenter - 0.5 * fwidth;
a->nhigh[notch] = fcenter + 0.5 * fwidth;
a->active[notch] = active;
UpdateNBPFilters (rxa);
rval = 0;
}
else
rval = -1;
return rval;
}
void NBP::NBPGetNumNotches (RXA& rxa, int* nnotches)
{
NOTCHDB *a;
a = rxa.ndb;
*nnotches = a->nn;
}
void NBP::NBPSetTuneFrequency (RXA& rxa, double tunefreq)
{
NOTCHDB *a;
a = rxa.ndb;
if (tunefreq != a->tunefreq)
{
a->tunefreq = tunefreq;
UpdateNBPFiltersLightWeight (rxa);
}
}
void NBP::NBPSetShiftFrequency (RXA& rxa, double shift)
{
NOTCHDB *a;
a = rxa.ndb;
if (shift != a->shift)
{
a->shift = shift;
UpdateNBPFiltersLightWeight (rxa);
}
}
void NBP::NBPSetNotchesRun (RXA& rxa, int run)
{
NOTCHDB *a = rxa.ndb;
NBP *b = rxa.nbp0;
if ( run != a->master_run)
{
a->master_run = run; // update variables
b->fnfrun = a->master_run;
RXA::bpsnbaCheck (rxa, rxa.mode, run);
calc_nbp_impulse (b); // recalc nbp impulse response
FIRCORE::setImpulse_fircore (b->p, b->impulse, 0); // calculate new filter masks
delete[] (b->impulse);
RXA::bpsnbaSet (rxa);
FIRCORE::setUpdate_fircore (b->p); // apply new filter masks
}
}
// FILTER PROPERTIES // FILTER PROPERTIES
void NBP::NBPSetRun (RXA& rxa, int run) void NBP::SetRun(int _run)
{ {
NBP *a; run = _run;
a = rxa.nbp0;
a->run = run;
} }
void NBP::NBPSetFreqs (RXA& rxa, double flow, double fhigh) void NBP::SetFreqs(double _flow, double _fhigh)
{ {
NBP *a; if ((flow != _flow) || (fhigh != _fhigh))
a = rxa.nbp0;
if ((flow != a->flow) || (fhigh != a->fhigh))
{ {
a->flow = flow; flow = _flow;
a->fhigh = fhigh; fhigh = _fhigh;
calc_nbp_impulse (a); calc_impulse();
FIRCORE::setImpulse_fircore (a->p, a->impulse, 1); FIRCORE::setImpulse_fircore (fircore, impulse, 1);
delete[] (a->impulse); delete[] (impulse);
} }
} }
void NBP::NBPSetWindow (RXA& rxa, int wintype) void NBP::SetNC(int _nc)
{
NBP *a;
BPSNBA *b;
a = rxa.nbp0;
b = rxa.bpsnba;
if ((a->wintype != wintype))
{
a->wintype = wintype;
calc_nbp_impulse (a);
FIRCORE::setImpulse_fircore (a->p, a->impulse, 1);
delete[] (a->impulse);
}
if ((b->wintype != wintype))
{
b->wintype = wintype;
BPSNBA::recalc_bpsnba_filter (b, 1);
}
}
void NBP::NBPSetNC (RXA& rxa, int nc)
{ {
// NOTE: 'nc' must be >= 'size' // NOTE: 'nc' must be >= 'size'
NBP *a; if (nc != _nc)
a = rxa.nbp0;
if (a->nc != nc)
{ {
a->nc = nc; nc = _nc;
setNc_nbp (a); setNc();
} }
} }
void NBP::NBPSetMP (RXA& rxa, int mp) void NBP::SetMP(int _mp)
{ {
NBP *a; if (mp != _mp)
a = rxa.nbp0;
if (a->mp != mp)
{ {
a->mp = mp; mp = _mp;
setMp_nbp (a); setMp();
} }
} }
void NBP::NBPGetMinNotchWidth (RXA& rxa, double* minwidth) void NBP::GetMinNotchWidth(double* minwidth)
{ {
NBP *a; *minwidth = min_notch_width();
a = rxa.nbp0;
*minwidth = min_notch_width (a);
}
void NBP::NBPSetAutoIncrease (RXA& rxa, int autoincr)
{
NBP *a;
BPSNBA *b;
a = rxa.nbp0;
b = rxa.bpsnba;
if ((a->autoincr != autoincr))
{
a->autoincr = autoincr;
calc_nbp_impulse (a);
FIRCORE::setImpulse_fircore (a->p, a->impulse, 1);
delete[] (a->impulse);
}
if ((b->autoincr != autoincr))
{
b->autoincr = autoincr;
BPSNBA::recalc_bpsnba_filter (b, 1);
}
} }
} // namespace WDSP } // namespace WDSP

View File

@ -33,7 +33,6 @@ warren@wpratt.com
namespace WDSP { namespace WDSP {
class FIRCORE; class FIRCORE;
class RXA;
class WDSP_API NOTCHDB class WDSP_API NOTCHDB
{ {
@ -49,8 +48,14 @@ public:
double* nhigh; double* nhigh;
int maxnotches; int maxnotches;
static NOTCHDB* create_notchdb (int master_run, int maxnotches); NOTCHDB(int master_run, int maxnotches);
static void destroy_notchdb (NOTCHDB *b); ~NOTCHDB();
int addNotch (int notch, double fcenter, double fwidth, int active);
int getNotch (int notch, double* fcenter, double* fwidth, int* active);
int deleteNotch (int notch);
int editNotch (int notch, double fcenter, double fwidth, int active);
void getNumNotches (int* nnotches);
}; };
@ -63,25 +68,25 @@ public:
int size; // buffer size int size; // buffer size
int nc; // number of filter coefficients int nc; // number of filter coefficients
int mp; // minimum phase flag int mp; // minimum phase flag
float* in; // input buffer
float* out; // output buffer
double flow; // low bandpass cutoff freq
double fhigh; // high bandpass cutoff freq
float* impulse; // filter impulse response
double rate; // sample rate double rate; // sample rate
int wintype; // filter window type int wintype; // filter window type
double gain; // filter gain double gain; // filter gain
float* in; // input buffer
float* out; // output buffer
int autoincr; // auto-increment notch width int autoincr; // auto-increment notch width
double flow; // low bandpass cutoff freq
double fhigh; // high bandpass cutoff freq
float* impulse; // filter impulse response
int maxpb; // maximum number of passbands int maxpb; // maximum number of passbands
NOTCHDB* ptraddr; // ptr to addr of notch-database data structure NOTCHDB* notchdb; // ptr to addr of notch-database data structure
double* bplow; // array of passband lows double* bplow; // array of passband lows
double* bphigh; // array of passband highs double* bphigh; // array of passband highs
int numpb; // number of passbands int numpb; // number of passbands
FIRCORE *p; FIRCORE *fircore;
int havnotch; int havnotch;
int hadnotch; int hadnotch;
static NBP* create_nbp( NBP(
int run, int run,
int fnfrun, int fnfrun,
int position, int position,
@ -97,41 +102,29 @@ public:
double gain, double gain,
int autoincr, int autoincr,
int maxpb, int maxpb,
NOTCHDB* ptraddr NOTCHDB* notchdb
); );
static void destroy_nbp (NBP *a); ~NBP();
static void flush_nbp (NBP *a);
static void xnbp (NBP *a, int pos);
static void setBuffers_nbp (NBP *a, float* in, float* out);
static void setSamplerate_nbp (NBP *a, int rate);
static void setSize_nbp (NBP *a, int size);
static void calc_nbp_impulse (NBP *a);
static void setNc_nbp (NBP *a);
static void setMp_nbp (NBP *a);
// RXA Properties
static void UpdateNBPFiltersLightWeight (RXA& rxa);
static void UpdateNBPFilters(RXA& rxa);
static int NBPAddNotch (RXA& rxa, int notch, double fcenter, double fwidth, int active);
static int NBPGetNotch (RXA& rxa, int notch, double* fcenter, double* fwidth, int* active);
static int NBPDeleteNotch (RXA& rxa, int notch);
static int NBPEditNotch (RXA& rxa, int notch, double fcenter, double fwidth, int active);
static void NBPGetNumNotches (RXA& rxa, int* nnotches);
static void NBPSetTuneFrequency (RXA& rxa, double tunefreq);
static void NBPSetShiftFrequency (RXA& rxa, double shift);
static void NBPSetNotchesRun (RXA& rxa, int run);
static void NBPSetRun (RXA& rxa, int run);
static void NBPSetFreqs (RXA& rxa, double flow, double fhigh);
static void NBPSetWindow (RXA& rxa, int wintype);
static void NBPSetNC (RXA& rxa, int nc); void flush();
static void NBPSetMP (RXA& rxa, int mp); void execute(int pos);
void setBuffers(float* in, float* out);
static void NBPGetMinNotchWidth (RXA& rxa, double* minwidth); void setSamplerate(int rate);
static void NBPSetAutoIncrease (RXA& rxa, int autoincr); void setSize(int size);
void calc_impulse();
void setNc();
void setMp();
// public Properties
void SetRun(int run);
void SetFreqs(double flow, double fhigh);
void SetNC(int nc);
void SetMP(int mp);
void GetMinNotchWidth(double* minwidth);
void calc_lightweight();
private: private:
static float* fir_mbandpass (int N, int nbp, double* flow, double* fhigh, double rate, double scale, int wintype); static float* fir_mbandpass (int N, int nbp, double* flow, double* fhigh, double rate, double scale, int wintype);
static double min_notch_width (NBP *a); double min_notch_width ();
static int make_nbp ( static int make_nbp (
int nn, int nn,
int* active, int* active,
@ -147,7 +140,6 @@ private:
double* bphigh, double* bphigh,
int* havnotch int* havnotch
); );
static void calc_nbp_lightweight (NBP *a);
}; };
} // namespace WDSP } // namespace WDSP