From 130d40c218bc8e59f990257724d37cbbe7f29bdf Mon Sep 17 00:00:00 2001 From: f4exb Date: Wed, 7 Aug 2024 21:14:09 +0200 Subject: [PATCH] WDSP: more rework --- wdsp/TXA.cpp | 193 +++++++++++++++++++-------- wdsp/TXA.hpp | 12 ++ wdsp/cfir.cpp | 253 ++++++++++++++++++----------------- wdsp/cfir.hpp | 27 ++-- wdsp/compress.cpp | 87 +++++------- wdsp/compress.hpp | 20 +-- wdsp/fmmod.cpp | 247 +++++++++++++++++----------------- wdsp/fmmod.hpp | 65 ++++----- wdsp/iqc.cpp | 328 ++++++++++++++++------------------------------ wdsp/iqc.hpp | 70 ++++++---- wdsp/nob.hpp | 18 ++- wdsp/osctrl.cpp | 149 +++++++++------------ wdsp/osctrl.hpp | 38 +++--- wdsp/slew.cpp | 211 ++++++++++++++--------------- wdsp/slew.hpp | 55 +++++--- 15 files changed, 866 insertions(+), 907 deletions(-) diff --git a/wdsp/TXA.cpp b/wdsp/TXA.cpp index f57c1426d..c1f160ef7 100644 --- a/wdsp/TXA.cpp +++ b/wdsp/TXA.cpp @@ -277,7 +277,7 @@ TXA::TXA( 1, // wintype 2.0); // gain - compressor = COMPRESSOR::create_compressor ( + compressor = new COMPRESSOR( 0, // run - OFF by default dsp_size, // size midbuff, // pointer to input buffer @@ -298,7 +298,7 @@ TXA::TXA( 1, // wintype 2.0); // gain - osctrl = OSCTRL::create_osctrl ( + osctrl = new OSCTRL( 0, // run dsp_size, // size midbuff, // input buffer @@ -368,7 +368,7 @@ TXA::TXA( 0.5); // carrier level - fmmod = FMMOD::create_fmmod ( + fmmod = new FMMOD( 0, // run - OFF by default dsp_size, // size midbuff, // pointer to input buffer @@ -392,15 +392,14 @@ TXA::TXA( dsp_rate, // sample rate 0); // mode - uslew = USLEW::create_uslew ( - this, + uslew = new USLEW( &upslew, // pointer to channel upslew flag dsp_size, // buffer size midbuff, // input buffer midbuff, // output buffer - (float) dsp_rate, // sample rate + (double) dsp_rate, // sample rate 0.000, // delay time - 0.005f); // upslew time + 0.005); // upslew time alcmeter = new METER( 1, // run @@ -446,17 +445,17 @@ TXA::TXA( // 256, // pin samples // 0.9); // alpha - iqc.p0 = iqc.p1 = IQC::create_iqc ( + iqc.p0 = iqc.p1 = new IQC( 0, // run dsp_size, // size midbuff, // input buffer midbuff, // output buffer - (float)dsp_rate, // sample rate + (double) dsp_rate, // sample rate 16, // ints - 0.005f, // changeover time + 0.005, // changeover time 256); // spi - cfir = CFIR::create_cfir( + cfir = new CFIR( 0, // run dsp_size, // size std::max(2048, dsp_size), // number of filter coefficients @@ -507,20 +506,20 @@ TXA::~TXA() // in reverse order, free each item we created delete outmeter; delete rsmpout; - CFIR::destroy_cfir(cfir); - IQC::destroy_iqc (iqc.p0); + delete cfir; + delete iqc.p0; delete sip1; delete alcmeter; - USLEW::destroy_uslew (uslew); + delete uslew; delete gen1; - FMMOD::destroy_fmmod (fmmod); + delete fmmod; delete ammod; delete alc; delete compmeter; delete bp2; - OSCTRL::destroy_osctrl (osctrl); + delete osctrl; delete bp1; - COMPRESSOR::destroy_compressor (compressor); + delete compressor; delete bp0; delete cfcmeter; delete cfcomp; @@ -554,20 +553,20 @@ void TXA::flush() cfcomp->flush(); cfcmeter->flush (); bp0->flush (); - COMPRESSOR::flush_compressor (compressor); + compressor->flush(); bp1->flush (); - OSCTRL::flush_osctrl (osctrl); + osctrl->flush(); bp2->flush (); compmeter->flush (); alc->flush (); ammod->flush(); - FMMOD::flush_fmmod (fmmod); + fmmod->flush(); gen1->flush(); - USLEW::flush_uslew (uslew); + uslew->flush(); alcmeter->flush (); sip1->flush(); - IQC::flush_iqc (iqc.p0); - CFIR::flush_cfir(cfir); + iqc.p0->flush(); + cfir->flush(); rsmpout->flush(); outmeter->flush (); } @@ -589,21 +588,21 @@ void TXA::execute() cfcomp->execute(0); // Continuous Frequency Compressor with post-EQ cfcmeter->execute (); // CFC+PostEQ Meter bp0->execute (0); // primary bandpass filter - COMPRESSOR::xcompressor (compressor); // COMP compressor + compressor->execute(); // COMP compressor bp1->execute (0); // aux bandpass (runs if COMP) - OSCTRL::xosctrl (osctrl); // CESSB Overshoot Control + osctrl->execute(); // CESSB Overshoot Control bp2->execute (0); // aux bandpass (runs if CESSB) compmeter->execute (); // COMP meter alc->execute (); // ALC ammod->execute(); // AM Modulator preemph->execute(1); // FM pre-emphasis (second option) - FMMOD::xfmmod (fmmod); // FM Modulator + fmmod->execute(); // FM Modulator gen1->execute(); // output signal generator (TUN and Two-tone) - USLEW::xuslew (uslew); // up-slew for AM, FM, and gens + uslew->execute(uslewCheck()); // up-slew for AM, FM, and gens alcmeter->execute (); // ALC Meter sip1->execute(0); // siphon data for display - IQC::xiqc (iqc.p0); // PureSignal correction - CFIR::xcfir(cfir); // compensating FIR filter (used Protocol_2 only) + iqc.p0->execute(); // PureSignal correction + cfir->execute(); // compensating FIR filter (used Protocol_2 only) rsmpout->execute(); // output resampler outmeter->execute (); // output meter } @@ -622,7 +621,7 @@ void TXA::setOutputSamplerate(int out_rate) { Unit::setBuffersOutputSamplerate(out_rate); // cfir - needs to know input rate of firmware CIC - CFIR::setOutRate_cfir (cfir, out_rate); + cfir->setOutRate(out_rate); // output resampler rsmpout->setBuffers(midbuff, outbuff); rsmpout->setOutRate(out_rate); @@ -654,20 +653,20 @@ void TXA::setDSPSamplerate(int dsp_rate) cfcomp->setSamplerate(dsp_rate); cfcmeter->setSamplerate (dsp_rate); bp0->setSamplerate (dsp_rate); - COMPRESSOR::setSamplerate_compressor (compressor, dsp_rate); + compressor->setSamplerate(dsp_rate); bp1->setSamplerate (dsp_rate); - OSCTRL::setSamplerate_osctrl (osctrl, dsp_rate); + osctrl->setSamplerate(dsp_rate); bp2->setSamplerate (dsp_rate); compmeter->setSamplerate (dsp_rate); alc->setSamplerate (dsp_rate); ammod->setSamplerate(dsp_rate); - FMMOD::setSamplerate_fmmod (fmmod, dsp_rate); + fmmod->setSamplerate(dsp_rate); gen1->setSamplerate(dsp_rate); - USLEW::setSamplerate_uslew (uslew, dsp_rate); + uslew->setSamplerate(dsp_rate); alcmeter->setSamplerate (dsp_rate); sip1->setSamplerate (dsp_rate); - IQC::setSamplerate_iqc (iqc.p0, dsp_rate); - CFIR::setSamplerate_cfir (cfir, dsp_rate); + iqc.p0->setSamplerate(dsp_rate); + cfir->setSamplerate(dsp_rate); // output resampler rsmpout->setBuffers(midbuff, outbuff); rsmpout->setInRate(dsp_rate); @@ -710,12 +709,12 @@ void TXA::setDSPBuffsize(int dsp_size) cfcmeter->setSize(dsp_size); bp0->setBuffers (midbuff, midbuff); bp0->setSize (dsp_size); - COMPRESSOR::setBuffers_compressor (compressor, midbuff, midbuff); - COMPRESSOR::setSize_compressor (compressor, dsp_size); + compressor->setBuffers(midbuff, midbuff); + compressor->setSize(dsp_size); bp1->setBuffers (midbuff, midbuff); bp1->setSize (dsp_size); - OSCTRL::setBuffers_osctrl (osctrl, midbuff, midbuff); - OSCTRL::setSize_osctrl (osctrl, dsp_size); + osctrl->setBuffers(midbuff, midbuff); + osctrl->setSize(dsp_size); bp2->setBuffers (midbuff, midbuff); bp2->setSize (dsp_size); compmeter->setBuffers(midbuff); @@ -724,20 +723,20 @@ void TXA::setDSPBuffsize(int dsp_size) alc->setSize( dsp_size); ammod->setBuffers(midbuff, midbuff); ammod->setSize(dsp_size); - FMMOD::setBuffers_fmmod (fmmod, midbuff, midbuff); - FMMOD::setSize_fmmod (fmmod, dsp_size); + fmmod->setBuffers(midbuff, midbuff); + fmmod->setSize(dsp_size); gen1->setBuffers(midbuff, midbuff); gen1->setSize(dsp_size); - USLEW::setBuffers_uslew (uslew, midbuff, midbuff); - USLEW::setSize_uslew (uslew, dsp_size); + uslew->setBuffers(midbuff, midbuff); + uslew->setSize(dsp_size); alcmeter->setBuffers (midbuff); alcmeter->setSize(dsp_size); sip1->setBuffers (midbuff); sip1->setSize (dsp_size); - IQC::setBuffers_iqc (iqc.p0, midbuff, midbuff); - IQC::setSize_iqc (iqc.p0, dsp_size); - CFIR::setBuffers_cfir (cfir, midbuff, midbuff); - CFIR::setSize_cfir (cfir, dsp_size); + iqc.p0->IQC::setBuffers(midbuff, midbuff); + iqc.p0->IQC::setSize(dsp_size); + cfir->setBuffers(midbuff, midbuff); + cfir->setSize(dsp_size); // output resampler rsmpout->setBuffers(midbuff, outbuff); rsmpout->setSize(dsp_size); @@ -1007,8 +1006,8 @@ void TXA::setNC(int _nc) setBandpassNC (_nc); preemph->setNC (_nc); eqp->setNC (_nc); - FMMOD::SetFMNC (*this, _nc); - CFIR::SetCFIRNC (*this, _nc); + fmmod->setNC (_nc); + cfir->setNC (_nc); state = oldstate; } @@ -1017,13 +1016,13 @@ void TXA::setMP(int _mp) setBandpassMP (_mp); preemph->setMP (_mp); eqp->setMP (_mp); - FMMOD::SetFMMP (*this, _mp); + fmmod->setMP (_mp); } void TXA::setFMAFFilter(float _low, float _high) { preemph->setFreqs (_low, _high); - FMMOD::SetFMAFFreqs(*this, _low, _high); + fmmod->setAFFreqs (_low, _high); } void TXA::SetBPSRun (TXA& txa, int _run) @@ -1095,7 +1094,7 @@ void TXA::SetBPSWindow (TXA& txa, int _wintype) delete[] (a->mults); impulse = FIR::fir_bandpass(a->size + 1, a->f_low, a->f_high, a->samplerate, a->wintype, 1, 1.0 / (float)(2 * a->size)); a->mults = FIR::fftcv_mults (2 * a->size, impulse); - delete[] (impulse); + delete[] impulse; } a = txa.bps2; @@ -1106,9 +1105,95 @@ void TXA::SetBPSWindow (TXA& txa, int _wintype) delete[] (a->mults); impulse = FIR::fir_bandpass (a->size + 1, a->f_low, a->f_high, a->samplerate, a->wintype, 1, 1.0 / (float)(2 * a->size)); a->mults = FIR::fftcv_mults (2 * a->size, impulse); - delete[] (impulse); + delete[] impulse; } } +void TXA::SetCompressorRun (TXA& txa, int _run) +{ + if (txa.compressor->run != _run) + { + txa.compressor->run = _run; + txa.setupBPFilters(); + } +} + +void TXA::SetosctrlRun (TXA& txa, int run) +{ + if (txa.osctrl->run != run) + { + txa.osctrl->run = run; + txa.setupBPFilters(); + } +} + +void TXA::GetiqcValues (TXA& txa, std::vector& cm, std::vector& cc, std::vector& cs) +{ + IQC *a; + a = txa.iqc.p0; + cm.resize(a->ints * 4); + cc.resize(a->ints * 4); + cs.resize(a->ints * 4); + std::copy(a->cm[a->cset].begin(), a->cm[a->cset].begin() + a->ints * 4, cm.begin()); + std::copy(a->cc[a->cset].begin(), a->cc[a->cset].begin() + a->ints * 4, cc.begin()); + std::copy(a->cs[a->cset].begin(), a->cs[a->cset].begin() + a->ints * 4, cs.begin()); +} + +void TXA::SetiqcValues (TXA& txa, const std::vector& cm, const std::vector& cc, const std::vector& cs) +{ + IQC *a; + a = txa.iqc.p0; + a->cset = 1 - a->cset; + std::copy(cm.begin(), cm.begin() + a->ints * 4, a->cm[a->cset].begin()); + std::copy(cc.begin(), cc.begin() + a->ints * 4, a->cc[a->cset].begin()); + std::copy(cs.begin(), cs.begin() + a->ints * 4, a->cs[a->cset].begin()); + a->state = IQC::IQCSTATE::RUN; +} + +void TXA::SetiqcSwap (TXA& txa, const std::vector& cm, const std::vector& cc, const std::vector& cs) +{ + IQC *a = txa.iqc.p1; + a->cset = 1 - a->cset; + std::copy(cm.begin(), cm.begin() + a->ints * 4, a->cm[a->cset].begin()); + std::copy(cc.begin(), cc.begin() + a->ints * 4, a->cc[a->cset].begin()); + std::copy(cs.begin(), cs.begin() + a->ints * 4, a->cs[a->cset].begin()); + a->busy = 1; + a->state = IQC::IQCSTATE::SWAP; + a->count = 0; +} + +void TXA::SetiqcStart (TXA& txa, const std::vector& cm, const std::vector& cc, const std::vector& cs) +{ + IQC *a = txa.iqc.p1; + a->cset = 0; + std::copy(cm.begin(), cm.begin() + a->ints * 4, a->cm[a->cset].begin()); + std::copy(cc.begin(), cc.begin() + a->ints * 4, a->cc[a->cset].begin()); + std::copy(cs.begin(), cs.begin() + a->ints * 4, a->cs[a->cset].begin()); + a->busy = 1; + a->state = IQC::IQCSTATE::BEGIN; + a->count = 0; + txa.iqc.p1->run = 1; +} + +void TXA::SetiqcEnd (TXA& txa) +{ + IQC *a = txa.iqc.p1; + a->busy = 1; + a->state = IQC::IQCSTATE::END; + a->count = 0; + txa.iqc.p1->run = 0; +} + +void TXA::GetiqcDogCount (TXA& txa, int* count) +{ + IQC *a = txa.iqc.p1; + *count = a->dog.count; +} + +void TXA::SetiqcDogCount (TXA& txa, int count) +{ + IQC *a = txa.iqc.p1; + a->dog.count = count; +} } // namespace WDSP diff --git a/wdsp/TXA.hpp b/wdsp/TXA.hpp index 55da102fb..6c3501411 100644 --- a/wdsp/TXA.hpp +++ b/wdsp/TXA.hpp @@ -194,6 +194,18 @@ public: static void SetBPSRun (TXA& txa, int run); static void SetBPSFreqs (TXA& txa, double low, double high); static void SetBPSWindow (TXA& txa, int wintype); + // COMPRESSOR + static void SetCompressorRun (TXA& txa, int run); + // OSCTRL + static void SetosctrlRun (TXA& txa, int run); + // IQC + static void GetiqcValues (TXA& txa, std::vector& cm, std::vector& cc, std::vector& cs); + static void SetiqcValues (TXA& txa, const std::vector& cm, const std::vector& cc, const std::vector& cs); + static void SetiqcSwap (TXA& txa, const std::vector& cm, const std::vector& cc, const std::vector& cs); + static void SetiqcStart (TXA& txa, const std::vector& cm, const std::vector& cc, const std::vector& cs); + static void SetiqcEnd (TXA& txa); + static void GetiqcDogCount (TXA& txa, int* count); + static void SetiqcDogCount (TXA& txa, int count); // Collectives void setNC(int nc); diff --git a/wdsp/cfir.cpp b/wdsp/cfir.cpp index 1e0b05bf7..456565df5 100644 --- a/wdsp/cfir.cpp +++ b/wdsp/cfir.cpp @@ -32,36 +32,36 @@ warren@wpratt.com namespace WDSP { -void CFIR::calc_cfir (CFIR *a) +void CFIR::calc() { float* impulse; - a->scale = 1.0 / (float)(2 * a->size); - impulse = cfir_impulse (a->nc, a->DD, a->R, a->Pairs, a->runrate, a->cicrate, a->cutoff, a->xtype, a->xbw, 1, a->scale, a->wintype); - a->p = new FIRCORE(a->size, a->in, a->out, a->nc, a->mp, impulse); - delete[] (impulse); + scale = 1.0 / (float)(2 * size); + impulse = cfir_impulse (nc, DD, R, Pairs, runrate, cicrate, cutoff, xtype, xbw, 1, scale, wintype); + p = new FIRCORE(size, in, out, nc, mp, impulse); + delete[] impulse; } -void CFIR::decalc_cfir (CFIR *a) +void CFIR::decalc() { - delete (a->p); + delete p; } -CFIR* CFIR::create_cfir ( - int run, - int size, - int nc, - int mp, - float* in, - float* out, - int runrate, - int cicrate, - int DD, - int R, - int Pairs, - double cutoff, - int xtype, - double xbw, - int wintype +CFIR::CFIR( + int _run, + int _size, + int _nc, + int _mp, + float* _in, + float* _out, + int _runrate, + int _cicrate, + int _DD, + int _R, + int _Pairs, + double _cutoff, + int _xtype, + double _xbw, + int _wintype ) // run: 0 - no action; 1 - operate // size: number of complex samples in an input buffer to the CFIR filter @@ -77,87 +77,84 @@ CFIR* CFIR::create_cfir ( // xtype: 0 - fourth power transition; 1 - raised cosine transition; 2 - brick wall // xbw: width of raised cosine transition { - CFIR *a = new CFIR; - a->run = run; - a->size = size; - a->nc = nc; - a->mp = mp; - a->in = in; - a->out = out; - a->runrate = runrate; - a->cicrate = cicrate; - a->DD = DD; - a->R = R; - a->Pairs = Pairs; - a->cutoff = cutoff; - a->xtype = xtype; - a->xbw = xbw; - a->wintype = wintype; - calc_cfir (a); - return a; + run = _run; + size = _size; + nc = _nc; + mp = _mp; + in = _in; + out = _out; + runrate = _runrate; + cicrate = _cicrate; + DD = _DD; + R = _R; + Pairs = _Pairs; + cutoff = _cutoff; + xtype = _xtype; + xbw = _xbw; + wintype = _wintype; + calc(); } -void CFIR::destroy_cfir (CFIR *a) +CFIR::~CFIR() { - decalc_cfir (a); - delete (a); + decalc(); } -void CFIR::flush_cfir (CFIR *a) +void CFIR::flush() { - a->p->flush(); + p->flush(); } -void CFIR::xcfir (CFIR *a) +void CFIR::execute() { - if (a->run) - a->p->execute(); - else if (a->in != a->out) - std::copy( a->in, a->in + a->size * 2, a->out); + if (run) + p->execute(); + else if (in != out) + std::copy( in, in + size * 2, out); } -void CFIR::setBuffers_cfir (CFIR *a, float* in, float* out) +void CFIR::setBuffers(float* _in, float* _out) { - decalc_cfir (a); - a->in = in; - a->out = out; - calc_cfir (a); + decalc(); + in = _in; + out = _out; + calc(); } -void CFIR::setSamplerate_cfir (CFIR *a, int rate) +void CFIR::setSamplerate(int rate) { - decalc_cfir (a); - a->runrate = rate; - calc_cfir (a); + decalc(); + runrate = rate; + calc(); } -void CFIR::setSize_cfir (CFIR *a, int size) +void CFIR::setSize(int _size) { - decalc_cfir (a); - a->size = size; - calc_cfir (a); + decalc(); + size = _size; + calc(); } -void CFIR::setOutRate_cfir (CFIR *a, int rate) +void CFIR::setOutRate(int rate) { - decalc_cfir (a); - a->cicrate = rate; - calc_cfir (a); + decalc(); + cicrate = rate; + calc(); } float* CFIR::cfir_impulse ( - int N, - int DD, - int R, - int Pairs, - double runrate, - double cicrate, - double cutoff, - int xtype, - double xbw, - int rtype, - double scale, - int wintype + int _N, + int _DD, + int _R, + int _Pairs, + double _runrate, + double _cicrate, + double _cutoff, + int _xtype, + double _xbw, + int _rtype, + double _scale, + int _wintype ) { // N: number of impulse response samples @@ -171,91 +168,93 @@ float* CFIR::cfir_impulse ( // xbw: transition bandwidth for raised cosine // rtype: 0 for real output, 1 for complex output // scale: scale factor to be applied to the output - int i, j; - double tmp, local_scale, ri, mag, fn; + int i; + int j; + double tmp; + double local_scale; + double ri; + double mag = 0; + double fn; float* impulse; - float* A = new float[N]; // (float *) malloc0 (N * sizeof (float)); - double ft = cutoff / cicrate; // normalized cutoff frequency - int u_samps = (N + 1) / 2; // number of unique samples, OK for odd or even N - int c_samps = (int)(cutoff / runrate * N) + (N + 1) / 2 - N / 2; // number of unique samples within bandpass, OK for odd or even N - int x_samps = (int)(xbw / runrate * N); // number of unique samples in transition region, OK for odd or even N - double offset = 0.5 - 0.5 * (float)((N + 1) / 2 - N / 2); // sample offset from center, OK for odd or even N - double* xistion = new double[x_samps + 1]; // (float *) malloc0 ((x_samps + 1) * sizeof (float)); - double delta = PI / (float)x_samps; - double L = cicrate / runrate; - double phs = 0.0; + std::vector A(_N); + double ft = _cutoff / _cicrate; // normalized cutoff frequency + int u_samps = (_N + 1) / 2; // number of unique samples, OK for odd or even N + int c_samps = (int)(_cutoff / _runrate * _N) + (_N + 1) / 2 - _N / 2; // number of unique samples within bandpass, OK for odd or even N + auto x_samps = (int)(_xbw / _runrate * _N); // number of unique samples in transition region, OK for odd or even N + double offset = 0.5 - 0.5 * (double)((_N + 1) / 2 - _N / 2); // sample offset from center, OK for odd or even N + std::vector xistion(x_samps + 1); + double delta = PI / (double)x_samps; + double L = _cicrate / _runrate; + double _phs = 0.0; for (i = 0; i <= x_samps; i++) { - xistion[i] = 0.5 * (cos (phs) + 1.0); - phs += delta; + xistion[i] = 0.5 * (cos (_phs) + 1.0); + _phs += delta; } - if ((tmp = DD * R * sin (PI * ft / R) / sin (PI * DD * ft)) < 0.0) //normalize by peak gain + if ((tmp = _DD * _R * sin (PI * ft / _R) / sin (PI * _DD * ft)) < 0.0) //normalize by peak gain tmp = -tmp; - local_scale = scale / pow (tmp, Pairs); - if (xtype == 0) + local_scale = _scale / pow (tmp, _Pairs); + if (_xtype == 0) { for (i = 0, ri = offset; i < u_samps; i++, ri += 1.0) { - fn = ri / (L * (float)N); + fn = ri / (L * (double) _N); if (fn <= ft) { if (fn == 0.0) tmp = 1.0; - else if ((tmp = DD * R * sin (PI * fn / R) / sin (PI * DD * fn)) < 0.0) + else if ((tmp = _DD * _R * sin (PI * fn / _R) / sin (PI * _DD * fn)) < 0.0) tmp = -tmp; - mag = pow (tmp, Pairs) * local_scale; + mag = pow (tmp, _Pairs) * local_scale; } else mag *= (ft * ft * ft * ft) / (fn * fn * fn * fn); - A[i] = mag; + A[i] = (float) mag; } } - else if (xtype == 1) + else if (_xtype == 1) { for (i = 0, ri = offset; i < u_samps; i++, ri += 1.0) { - fn = ri / (L *(float)N); + fn = ri / (L *(double) _N); if (i < c_samps) { if (fn == 0.0) tmp = 1.0; - else if ((tmp = DD * R * sin (PI * fn / R) / sin (PI * DD * fn)) < 0.0) + else if ((tmp = _DD * _R * sin (PI * fn / _R) / sin (PI * _DD * fn)) < 0.0) tmp = -tmp; - mag = pow (tmp, Pairs) * local_scale; - A[i] = mag; + mag = pow (tmp, _Pairs) * local_scale; + A[i] = (float) mag; } else if ( i >= c_samps && i <= c_samps + x_samps) - A[i] = mag * xistion[i - c_samps]; + A[i] = (float) (mag * xistion[i - c_samps]); else A[i] = 0.0; } } - else if (xtype == 2) + else if (_xtype == 2) { for (i = 0, ri = offset; i < u_samps; i++, ri += 1.0) { - fn = ri / (L * (float)N); + fn = ri / (L * (double) _N); if (fn <= ft) { if (fn == 0.0) tmp = 1.0; - else if ((tmp = DD * R * sin(PI * fn / R) / sin(PI * DD * fn)) < 0.0) + else if ((tmp = _DD * _R * sin(PI * fn / _R) / sin(PI * _DD * fn)) < 0.0) tmp = -tmp; - mag = pow (tmp, Pairs) * local_scale; + mag = pow (tmp, _Pairs) * local_scale; } else mag = 0.0; - A[i] = mag; + A[i] = (float) mag; } } - if (N & 1) - for (i = u_samps, j = 2; i < N; i++, j++) + if (_N & 1) + for (i = u_samps, j = 2; i < _N; i++, j++) A[i] = A[u_samps - j]; else - for (i = u_samps, j = 1; i < N; i++, j++) + for (i = u_samps, j = 1; i < _N; i++, j++) A[i] = A[u_samps - j]; - impulse = FIR::fir_fsamp (N, A, rtype, 1.0, wintype); - // print_impulse ("cfirImpulse.txt", N, impulse, 1, 0); - delete[] A; - delete[] xistion; + impulse = FIR::fir_fsamp (_N, A.data(), _rtype, 1.0, _wintype); return impulse; } @@ -265,22 +264,20 @@ float* CFIR::cfir_impulse ( * * ********************************************************************************************************/ -void CFIR::SetCFIRRun (TXA& txa, int run) +void CFIR::setRun(int _run) { - txa.cfir->run = run; + run = _run; } -void CFIR::SetCFIRNC(TXA& txa, int nc) +void CFIR::setNC(int _nc) { // NOTE: 'nc' must be >= 'size' - CFIR *a; - a = txa.cfir; - if (a->nc != nc) + if (nc != _nc) { - a->nc = nc; - decalc_cfir(a); - calc_cfir(a); + nc = _nc; + decalc(); + calc(); } } diff --git a/wdsp/cfir.hpp b/wdsp/cfir.hpp index ebd3c027e..155a24286 100644 --- a/wdsp/cfir.hpp +++ b/wdsp/cfir.hpp @@ -56,7 +56,7 @@ public: int wintype; FIRCORE *p; - static CFIR* create_cfir ( + CFIR( int run, int size, int nc, @@ -73,13 +73,16 @@ public: double xbw, int wintype ); - static void destroy_cfir (CFIR *a); - static void flush_cfir (CFIR *a); - static void xcfir (CFIR *a); - static void setBuffers_cfir (CFIR *a, float* in, float* out); - static void setSamplerate_cfir (CFIR *a, int rate); - static void setSize_cfir (CFIR *a, int size); - static void setOutRate_cfir (CFIR *a, int rate); + CFIR(const CFIR&) = delete; + CFIR& operator=(CFIR& other) = delete; + ~CFIR(); + + void flush(); + void execute(); + void setBuffers(float* in, float* out); + void setSamplerate(int rate); + void setSize(int size); + void setOutRate(int rate); static float* cfir_impulse ( int N, int DD, @@ -95,12 +98,12 @@ public: int wintype ); // TXA Properties - static void SetCFIRRun(TXA& txa, int run); - static void SetCFIRNC(TXA& txa, int nc); + void setRun(int run); + void setNC(int nc); private: - static void calc_cfir (CFIR *a); - static void decalc_cfir (CFIR *a); + void calc(); + void decalc(); }; } // namespace WDSP diff --git a/wdsp/compress.cpp b/wdsp/compress.cpp index a36e32927..a816760d8 100644 --- a/wdsp/compress.cpp +++ b/wdsp/compress.cpp @@ -34,62 +34,56 @@ in the January 2010 issue of RadCom magazine. namespace WDSP { -COMPRESSOR* COMPRESSOR::create_compressor ( - int run, - int buffsize, - float* inbuff, - float* outbuff, - double gain -) +COMPRESSOR::COMPRESSOR( + int _run, + int _buffsize, + float* _inbuff, + float* _outbuff, + double _gain +) : + run(_run), + buffsize(_buffsize), + inbuff(_inbuff), + outbuff(_outbuff), + gain(_gain) +{} + +void COMPRESSOR::flush() { - auto *a = new COMPRESSOR; - a->run = run; - a->inbuff = inbuff; - a->outbuff = outbuff; - a->buffsize = buffsize; - a->gain = gain; - return a; + // Nothing to do } -void COMPRESSOR::destroy_compressor (COMPRESSOR *a) +void COMPRESSOR::execute() { - delete (a); -} - -void COMPRESSOR::flush_compressor (COMPRESSOR *) -{ -} - -void COMPRESSOR::xcompressor (COMPRESSOR *a) -{ - float mag; - if (a->run) - for (int i = 0; i < a->buffsize; i++) + double mag; + if (run) + for (int i = 0; i < buffsize; i++) { - mag = sqrt(a->inbuff[2 * i + 0] * a->inbuff[2 * i + 0] + a->inbuff[2 * i + 1] * a->inbuff[2 * i + 1]); - if (a->gain * mag > 1.0) - a->outbuff[2 * i + 0] = a->inbuff[2 * i + 0] / mag; + mag = sqrt(inbuff[2 * i + 0] * inbuff[2 * i + 0] + inbuff[2 * i + 1] * inbuff[2 * i + 1]); + if (gain * mag > 1.0) + outbuff[2 * i + 0] = (float) (inbuff[2 * i + 0] / mag); else - a->outbuff[2 * i + 0] = a->inbuff[2 * i + 0] * a->gain; - a->outbuff[2 * i + 1] = 0.0; + outbuff[2 * i + 0] = (float) (inbuff[2 * i + 0] * gain); + outbuff[2 * i + 1] = 0.0; } - else if (a->inbuff != a->outbuff) - std::copy(a->inbuff, a->inbuff + a->buffsize * 2, a->outbuff); + else if (inbuff != outbuff) + std::copy(inbuff, inbuff + buffsize * 2, outbuff); } -void COMPRESSOR::setBuffers_compressor (COMPRESSOR *a, float* in, float* out) +void COMPRESSOR::setBuffers(float* _in, float* _out) { - a->inbuff = in; - a->outbuff = out; + inbuff = _in; + outbuff = _out; } -void COMPRESSOR::setSamplerate_compressor (COMPRESSOR *, int) +void COMPRESSOR::setSamplerate(int) { + // Nothing to do } -void COMPRESSOR::setSize_compressor (COMPRESSOR *a, int size) +void COMPRESSOR::setSize(int _size) { - a->buffsize = size; + buffsize = _size; } /******************************************************************************************************** @@ -98,18 +92,9 @@ void COMPRESSOR::setSize_compressor (COMPRESSOR *a, int size) * * ********************************************************************************************************/ -void COMPRESSOR::SetCompressorRun (TXA& txa, int run) +void COMPRESSOR::setGain(float _gain) { - if (txa.compressor->run != run) - { - txa.compressor->run = run; - txa.setupBPFilters(); - } -} - -void COMPRESSOR::SetCompressorGain (TXA& txa, float gain) -{ - txa.compressor->gain = pow (10.0, gain / 20.0); + gain = pow (10.0, _gain / 20.0); } } // namespace WDSP diff --git a/wdsp/compress.hpp b/wdsp/compress.hpp index dc134bb58..37d3cfdc6 100644 --- a/wdsp/compress.hpp +++ b/wdsp/compress.hpp @@ -43,22 +43,24 @@ public: float *outbuff; double gain; - static COMPRESSOR* create_compressor ( + COMPRESSOR( int run, int buffsize, float* inbuff, float* outbuff, double gain ); - static void destroy_compressor (COMPRESSOR *a); - static void flush_compressor (COMPRESSOR *a); - static void xcompressor (COMPRESSOR *a); - static void setBuffers_compressor (COMPRESSOR *a, float* in, float* out); - static void setSamplerate_compressor (COMPRESSOR *a, int rate); - static void setSize_compressor (COMPRESSOR *a, int size); + COMPRESSOR(const COMPRESSOR&) = delete; + COMPRESSOR& operator=(COMPRESSOR& other) = delete; + ~COMPRESSOR() = default; + + void flush(); + void execute(); + void setBuffers(float* in, float* out); + void setSamplerate(int rate); + void setSize(int size); // TXA Properties - static void SetCompressorRun (TXA& txa, int run); - static void SetCompressorGain (TXA& txa, float gain); + void setGain(float gain); }; } // namespace WDSP diff --git a/wdsp/fmmod.cpp b/wdsp/fmmod.cpp index 81eed4486..ee000b4db 100644 --- a/wdsp/fmmod.cpp +++ b/wdsp/fmmod.cpp @@ -33,130 +33,128 @@ warren@wpratt.com namespace WDSP { -void FMMOD::calc_fmmod (FMMOD *a) +void FMMOD::calc() { // ctcss gen - a->tscale = 1.0 / (1.0 + a->ctcss_level); - a->tphase = 0.0; - a->tdelta = TWOPI * a->ctcss_freq / a->samplerate; + tscale = 1.0 / (1.0 + ctcss_level); + tphase = 0.0; + tdelta = TWOPI * ctcss_freq / samplerate; // mod - a->sphase = 0.0; - a->sdelta = TWOPI * a->deviation / a->samplerate; + sphase = 0.0; + sdelta = TWOPI * deviation / samplerate; // bandpass - a->bp_fc = a->deviation + a->f_high; + bp_fc = deviation + f_high; } -FMMOD* FMMOD::create_fmmod ( - int run, - int size, - float* in, - float* out, - int rate, - float dev, - float f_low, - float f_high, - int ctcss_run, - float ctcss_level, - float ctcss_freq, - int bp_run, - int nc, - int mp +FMMOD::FMMOD( + int _run, + int _size, + float* _in, + float* _out, + int _rate, + double _dev, + double _f_low, + double _f_high, + int _ctcss_run, + double _ctcss_level, + double _ctcss_freq, + int _bp_run, + int _nc, + int _mp ) { - FMMOD *a = new FMMOD; float* impulse; - a->run = run; - a->size = size; - a->in = in; - a->out = out; - a->samplerate = (float)rate; - a->deviation = dev; - a->f_low = f_low; - a->f_high = f_high; - a->ctcss_run = ctcss_run; - a->ctcss_level = ctcss_level; - a->ctcss_freq = ctcss_freq; - a->bp_run = bp_run; - a->nc = nc; - a->mp = mp; - calc_fmmod (a); - impulse = FIR::fir_bandpass(a->nc, -a->bp_fc, +a->bp_fc, a->samplerate, 0, 1, 1.0 / (2 * a->size)); - a->p = new FIRCORE(a->size, a->out, a->out, a->nc, a->mp, impulse); - delete[] (impulse); - return a; + run = _run; + size = _size; + in = _in; + out = _out; + samplerate = (float) _rate; + deviation = _dev; + f_low = _f_low; + f_high = _f_high; + ctcss_run = _ctcss_run; + ctcss_level = _ctcss_level; + ctcss_freq = _ctcss_freq; + bp_run = _bp_run; + nc = _nc; + mp = _mp; + calc(); + impulse = FIR::fir_bandpass(nc, -bp_fc, +bp_fc, samplerate, 0, 1, 1.0 / (2 * size)); + p = new FIRCORE(size, out, out, nc, mp, impulse); + delete[] impulse; } -void FMMOD::destroy_fmmod (FMMOD *a) +FMMOD::~FMMOD() { - delete (a->p); - delete (a); + delete p; } -void FMMOD::flush_fmmod (FMMOD *a) +void FMMOD::flush() { - a->tphase = 0.0; - a->sphase = 0.0; + tphase = 0.0; + sphase = 0.0; } -void FMMOD::xfmmod (FMMOD *a) +void FMMOD::execute() { - int i; - float dp, magdp, peak; - if (a->run) + double dp; + double magdp; + double peak; + if (run) { peak = 0.0; - for (i = 0; i < a->size; i++) + for (int i = 0; i < size; i++) { - if (a->ctcss_run) + if (ctcss_run) { - a->tphase += a->tdelta; - if (a->tphase >= TWOPI) a->tphase -= TWOPI; - a->out[2 * i + 0] = a->tscale * (a->in[2 * i + 0] + a->ctcss_level * cos (a->tphase)); + tphase += tdelta; + if (tphase >= TWOPI) tphase -= TWOPI; + out[2 * i + 0] = (float) (tscale * (in[2 * i + 0] + ctcss_level * cos (tphase))); } - dp = a->out[2 * i + 0] * a->sdelta; - a->sphase += dp; - if (a->sphase >= TWOPI) a->sphase -= TWOPI; - if (a->sphase < 0.0 ) a->sphase += TWOPI; - a->out[2 * i + 0] = 0.7071 * cos (a->sphase); - a->out[2 * i + 1] = 0.7071 * sin (a->sphase); + dp = out[2 * i + 0] * sdelta; + sphase += dp; + if (sphase >= TWOPI) sphase -= TWOPI; + if (sphase < 0.0 ) sphase += TWOPI; + out[2 * i + 0] = (float) (0.7071 * cos (sphase)); + out[2 * i + 1] = (float) (0.7071 * sin (sphase)); if ((magdp = dp) < 0.0) magdp = - magdp; if (magdp > peak) peak = magdp; } - //print_deviation ("peakdev.txt", peak, a->samplerate); - if (a->bp_run) - a->p->execute(); + + if (bp_run) + p->execute(); } - else if (a->in != a->out) - std::copy( a->in, a->in + a->size * 2, a->out); + else if (in != out) + std::copy( in, in + size * 2, out); } -void FMMOD::setBuffers_fmmod (FMMOD *a, float* in, float* out) +void FMMOD::setBuffers(float* _in, float* _out) { - a->in = in; - a->out = out; - calc_fmmod (a); - a->p->setBuffers(a->out, a->out); + in = _in; + out = _out; + calc(); + p->setBuffers(out, out); } -void FMMOD::setSamplerate_fmmod (FMMOD *a, int rate) +void FMMOD::setSamplerate(int _rate) { float* impulse; - a->samplerate = rate; - calc_fmmod (a); - impulse = FIR::fir_bandpass(a->nc, -a->bp_fc, +a->bp_fc, a->samplerate, 0, 1, 1.0 / (2 * a->size)); - a->p->setImpulse(impulse, 1); - delete[] (impulse); + samplerate = _rate; + calc(); + impulse = FIR::fir_bandpass(nc, -bp_fc, +bp_fc, samplerate, 0, 1, 1.0 / (2 * size)); + p->setImpulse(impulse, 1); + delete[] impulse; } -void FMMOD::setSize_fmmod (FMMOD *a, int size) +void FMMOD::setSize(int _size) { float* impulse; - a->size = size; - calc_fmmod (a); - a->p->setSize(a->size); - impulse = FIR::fir_bandpass(a->nc, -a->bp_fc, +a->bp_fc, a->samplerate, 0, 1, 1.0 / (2 * a->size)); - a->p->setImpulse(impulse, 1); - delete[] (impulse); + size = _size; + calc(); + p->setSize(size); + impulse = FIR::fir_bandpass(nc, -bp_fc, +bp_fc, samplerate, 0, 1, 1.0 / (2 * size)); + p->setImpulse(impulse, 1); + delete[] impulse; } /******************************************************************************************************** @@ -165,76 +163,67 @@ void FMMOD::setSize_fmmod (FMMOD *a, int size) * * ********************************************************************************************************/ -void FMMOD::SetFMDeviation (TXA& txa, float deviation) +void FMMOD::setDeviation(float _deviation) { - FMMOD *a = txa.fmmod; - float bp_fc = a->f_high + deviation; - float* impulse = FIR::fir_bandpass (a->nc, -bp_fc, +bp_fc, a->samplerate, 0, 1, 1.0 / (2 * a->size)); - a->p->setImpulse(impulse, 0); - delete[] (impulse); - a->deviation = deviation; + double _bp_fc = f_high + _deviation; + float* impulse = FIR::fir_bandpass (nc, -_bp_fc, +_bp_fc, samplerate, 0, 1, 1.0 / (2 * size)); + p->setImpulse(impulse, 0); + delete[] impulse; + deviation = _deviation; // mod - a->sphase = 0.0; - a->sdelta = TWOPI * a->deviation / a->samplerate; + sphase = 0.0; + sdelta = TWOPI * deviation / samplerate; // bandpass - a->bp_fc = bp_fc; - a->p->setUpdate(); + bp_fc = _bp_fc; + p->setUpdate(); } -void FMMOD::SetCTCSSFreq (TXA& txa, float freq) +void FMMOD::setCTCSSFreq (float _freq) { - FMMOD *a; - a = txa.fmmod; - a->ctcss_freq = freq; - a->tphase = 0.0; - a->tdelta = TWOPI * a->ctcss_freq / a->samplerate; + ctcss_freq = _freq; + tphase = 0.0; + tdelta = TWOPI * ctcss_freq / samplerate; } -void FMMOD::SetCTCSSRun (TXA& txa, int run) +void FMMOD::setCTCSSRun (int _run) { - txa.fmmod->ctcss_run = run; + ctcss_run = _run; } -void FMMOD::SetFMNC (TXA& txa, int nc) +void FMMOD::setNC(int _nc) { - FMMOD *a; float* impulse; - a = txa.fmmod; - if (a->nc != nc) + if (nc != _nc) { - a->nc = nc; - impulse = FIR::fir_bandpass (a->nc, -a->bp_fc, +a->bp_fc, a->samplerate, 0, 1, 1.0 / (2 * a->size)); - a->p->setNc(a->nc, impulse); - delete[] (impulse); + nc = _nc; + impulse = FIR::fir_bandpass (nc, -bp_fc, +bp_fc, samplerate, 0, 1, 1.0 / (2 * size)); + p->setNc(nc, impulse); + delete[] impulse; } } -void FMMOD::SetFMMP (TXA& txa, int mp) +void FMMOD::setMP(int _mp) { - FMMOD *a; - a = txa.fmmod; - if (a->mp != mp) + if (mp != _mp) { - a->mp = mp; - a->p->setMp(a->mp); + mp = _mp; + p->setMp(mp); } } -void FMMOD::SetFMAFFreqs (TXA& txa, float low, float high) +void FMMOD::setAFFreqs(float _low, float _high) { - FMMOD *a; float* impulse; - a = txa.fmmod; - if (a->f_low != low || a->f_high != high) + if (f_low != _low || f_high != _high) { - a->f_low = low; - a->f_high = high; - a->bp_fc = a->deviation + a->f_high; - impulse = FIR::fir_bandpass (a->nc, -a->bp_fc, +a->bp_fc, a->samplerate, 0, 1, 1.0 / (2 * a->size)); - a->p->setImpulse(impulse, 1); - delete[] (impulse); + f_low = _low; + f_high = _high; + bp_fc = deviation + f_high; + impulse = FIR::fir_bandpass (nc, -bp_fc, +bp_fc, samplerate, 0, 1, 1.0 / (2 * size)); + p->setImpulse(impulse, 1); + delete[] impulse; } } diff --git a/wdsp/fmmod.hpp b/wdsp/fmmod.hpp index 30dfc87ac..411d3f447 100644 --- a/wdsp/fmmod.hpp +++ b/wdsp/fmmod.hpp @@ -42,59 +42,62 @@ public: int size; float* in; float* out; - float samplerate; - float deviation; - float f_low; - float f_high; + double samplerate; + double deviation; + double f_low; + double f_high; int ctcss_run; - float ctcss_level; - float ctcss_freq; + double ctcss_level; + double ctcss_freq; // for ctcss gen - float tscale; - float tphase; - float tdelta; + double tscale; + double tphase; + double tdelta; // mod - float sphase; - float sdelta; + double sphase; + double sdelta; // bandpass int bp_run; - float bp_fc; + double bp_fc; int nc; int mp; FIRCORE *p; - static FMMOD* create_fmmod ( + FMMOD( int run, int size, float* in, float* out, int rate, - float dev, - float f_low, - float f_high, + double dev, + double f_low, + double f_high, int ctcss_run, - float ctcss_level, - float ctcss_freq, + double ctcss_level, + double ctcss_freq, int bp_run, int nc, int mp ); - static void destroy_fmmod (FMMOD *a); - static void flush_fmmod (FMMOD *a); - static void xfmmod (FMMOD *a); - static void setBuffers_fmmod (FMMOD *a, float* in, float* out); - static void setSamplerate_fmmod (FMMOD *a, int rate); - static void setSize_fmmod (FMMOD *a, int size); + FMMOD(const FMMOD&) = delete; + FMMOD& operator=(const FMMOD& other) = delete; + ~FMMOD(); + + void flush(); + void execute(); + void setBuffers(float* in, float* out); + void setSamplerate(int rate); + void setSize(int size); // TXA Properties - static void SetFMDeviation (TXA& txa, float deviation); - static void SetCTCSSFreq (TXA& txa, float freq); - static void SetCTCSSRun (TXA& txa, int run); - static void SetFMMP (TXA& txa, int mp); - static void SetFMNC (TXA& txa, int nc); - static void SetFMAFFreqs (TXA& txa, float low, float high); + void setDeviation(float deviation); + void setCTCSSFreq(float freq); + void setCTCSSRun(int run); + void setMP(int mp); + void setNC(int nc); + void setAFFreqs(float low, float high); private: - static void calc_fmmod (FMMOD *a); + void calc(); }; } // namespace WDSP diff --git a/wdsp/iqc.cpp b/wdsp/iqc.cpp index 4f273ad24..3ad055a80 100644 --- a/wdsp/iqc.cpp +++ b/wdsp/iqc.cpp @@ -34,278 +34,174 @@ warren@wpratt.com namespace WDSP { -void IQC::size_iqc (IQC *a) +void IQC::size_iqc() { int i; - a->t = new float[a->ints + 1]; // (float *) malloc0 ((a->ints + 1) * sizeof(float)); - for (i = 0; i <= a->ints; i++) - a->t[i] = (float)i / (float)a->ints; + t.resize(ints + 1); + for (i = 0; i <= ints; i++) + t[i] = (double)i / (double)ints; for (i = 0; i < 2; i++) { - a->cm[i] = new float[a->ints * 4]; // (float *) malloc0 (a->ints * 4 * sizeof(float)); - a->cc[i] = new float[a->ints * 4]; // (float *) malloc0 (a->ints * 4 * sizeof(float)); - a->cs[i] = new float[a->ints * 4]; // (float *) malloc0 (a->ints * 4 * sizeof(float)); + cm[i].resize(ints * 4); + cc[i].resize(ints * 4); + cs[i].resize(ints * 4); } - a->dog.cpi = new int[a->ints]; // (int *) malloc0 (a->ints * sizeof (int)); - a->dog.count = 0; - a->dog.full_ints = 0; + dog.cpi.resize(ints); + dog.count = 0; + dog.full_ints = 0; } -void IQC::desize_iqc (IQC *a) +void IQC::calc() { - int i; - delete[] (a->dog.cpi); - for (i = 0; i < 2; i++) - { - delete[] (a->cm[i]); - delete[] (a->cc[i]); - delete[] (a->cs[i]); - } - delete[] (a->t); -} - -void IQC::calc_iqc (IQC *a) -{ - int i; - float delta, theta; - a->cset = 0; - a->count = 0; - a->state = 0; - a->busy = 0; - a->ntup = (int)(a->tup * a->rate); - a->cup = new float[a->ntup + 1]; // (float *) malloc0 ((a->ntup + 1) * sizeof (float)); - delta = PI / (float)a->ntup; + double delta; + double theta; + cset = 0; + count = 0; + state = IQCSTATE::RUN; + busy = 0; + ntup = (int)(tup * rate); + cup.resize(ntup + 1); + delta = PI / (double)ntup; theta = 0.0; - for (i = 0; i <= a->ntup; i++) + for (int i = 0; i <= ntup; i++) { - a->cup[i] = 0.5 * (1.0 - cos (theta)); + cup[i] = 0.5 * (1.0 - cos (theta)); theta += delta; } - size_iqc (a); + size_iqc(); } -void IQC::decalc_iqc (IQC *a) +IQC::IQC( + int _run, + int _size, + float* _in, + float* _out, + double _rate, + int _ints, + double _tup, + int _spi +) : + run(_run), + size(_size), + in(_in), + out(_out), + rate(_rate), + ints(_ints), + tup(_tup) { - desize_iqc (a); - delete[] (a->cup); + dog.spi = _spi; + calc(); } -IQC* IQC::create_iqc (int run, int size, float* in, float* out, float rate, int ints, float tup, int spi) +void IQC::flush() { - IQC *a = new IQC; - a->run = run; - a->size = size; - a->in = in; - a->out = out; - a->rate = rate; - a->ints = ints; - a->tup = tup; - a->dog.spi = spi; - calc_iqc (a); - return a; + // Nothing to do } -void IQC::destroy_iqc (IQC *a) +void IQC::execute() { - decalc_iqc (a); - delete (a); -} - -void IQC::flush_iqc (IQC *) -{ - -} - -enum _iqcstate -{ - RUN = 0, - BEGIN, - SWAP, - END, - DONE -}; - -void IQC::xiqc (IQC *a) -{ - if (a->run == 1) + if (run == 1) { - int i, k, cset, mset; - float I, Q, env, dx, ym, yc, ys, PRE0, PRE1; - for (i = 0; i < a->size; i++) + int k; + int icset; + int mset; + double I; + double Q; + double env; + double dx; + double ym; + double yc; + double ys; + double PRE0; + double PRE1; + for (int i = 0; i < size; i++) { - I = a->in[2 * i + 0]; - Q = a->in[2 * i + 1]; + I = in[2 * i + 0]; + Q = in[2 * i + 1]; env = sqrt (I * I + Q * Q); - if ((k = (int)(env * a->ints)) > a->ints - 1) k = a->ints - 1; - dx = env - a->t[k]; - cset = a->cset; - ym = a->cm[cset][4 * k + 0] + dx * (a->cm[cset][4 * k + 1] + dx * (a->cm[cset][4 * k + 2] + dx * a->cm[cset][4 * k + 3])); - yc = a->cc[cset][4 * k + 0] + dx * (a->cc[cset][4 * k + 1] + dx * (a->cc[cset][4 * k + 2] + dx * a->cc[cset][4 * k + 3])); - ys = a->cs[cset][4 * k + 0] + dx * (a->cs[cset][4 * k + 1] + dx * (a->cs[cset][4 * k + 2] + dx * a->cs[cset][4 * k + 3])); + if ((k = (int)(env * ints)) > ints - 1) k = ints - 1; + dx = env - t[k]; + icset = cset; + ym = cm[icset][4 * k + 0] + dx * (cm[icset][4 * k + 1] + dx * (cm[icset][4 * k + 2] + dx * cm[icset][4 * k + 3])); + yc = cc[icset][4 * k + 0] + dx * (cc[icset][4 * k + 1] + dx * (cc[icset][4 * k + 2] + dx * cc[icset][4 * k + 3])); + ys = cs[icset][4 * k + 0] + dx * (cs[icset][4 * k + 1] + dx * (cs[icset][4 * k + 2] + dx * cs[icset][4 * k + 3])); PRE0 = ym * (I * yc - Q * ys); PRE1 = ym * (I * ys + Q * yc); - switch (a->state) + switch (state) { - case RUN: - if (a->dog.cpi[k] != a->dog.spi) - if (++a->dog.cpi[k] == a->dog.spi) - a->dog.full_ints++; - if (a->dog.full_ints == a->ints) + case IQCSTATE::RUN: + if ((dog.cpi[k] != dog.spi) && (++dog.cpi[k] == dog.spi)) + dog.full_ints++; + if (dog.full_ints == ints) { - ++a->dog.count; - a->dog.full_ints = 0; - memset (a->dog.cpi, 0, a->ints * sizeof (int)); + ++dog.count; + dog.full_ints = 0; + std::fill(dog.cpi.begin(), dog.cpi.end(), 0); } break; - case BEGIN: - PRE0 = (1.0 - a->cup[a->count]) * I + a->cup[a->count] * PRE0; - PRE1 = (1.0 - a->cup[a->count]) * Q + a->cup[a->count] * PRE1; - if (a->count++ == a->ntup) + case IQCSTATE::BEGIN: + PRE0 = (1.0 - cup[count]) * I + cup[count] * PRE0; + PRE1 = (1.0 - cup[count]) * Q + cup[count] * PRE1; + if (count++ == ntup) { - a->state = RUN; - a->count = 0; - a->busy = 0; // InterlockedBitTestAndReset (&a->busy, 0); + state = IQCSTATE::RUN; + count = 0; + busy = 0; } break; - case SWAP: + case IQCSTATE::SWAP: mset = 1 - cset; - ym = a->cm[mset][4 * k + 0] + dx * (a->cm[mset][4 * k + 1] + dx * (a->cm[mset][4 * k + 2] + dx * a->cm[mset][4 * k + 3])); - yc = a->cc[mset][4 * k + 0] + dx * (a->cc[mset][4 * k + 1] + dx * (a->cc[mset][4 * k + 2] + dx * a->cc[mset][4 * k + 3])); - ys = a->cs[mset][4 * k + 0] + dx * (a->cs[mset][4 * k + 1] + dx * (a->cs[mset][4 * k + 2] + dx * a->cs[mset][4 * k + 3])); - PRE0 = (1.0 - a->cup[a->count]) * ym * (I * yc - Q * ys) + a->cup[a->count] * PRE0; - PRE1 = (1.0 - a->cup[a->count]) * ym * (I * ys + Q * yc) + a->cup[a->count] * PRE1; - if (a->count++ == a->ntup) + ym = cm[mset][4 * k + 0] + dx * (cm[mset][4 * k + 1] + dx * (cm[mset][4 * k + 2] + dx * cm[mset][4 * k + 3])); + yc = cc[mset][4 * k + 0] + dx * (cc[mset][4 * k + 1] + dx * (cc[mset][4 * k + 2] + dx * cc[mset][4 * k + 3])); + ys = cs[mset][4 * k + 0] + dx * (cs[mset][4 * k + 1] + dx * (cs[mset][4 * k + 2] + dx * cs[mset][4 * k + 3])); + PRE0 = (1.0 - cup[count]) * ym * (I * yc - Q * ys) + cup[count] * PRE0; + PRE1 = (1.0 - cup[count]) * ym * (I * ys + Q * yc) + cup[count] * PRE1; + if (count++ == ntup) { - a->state = RUN; - a->count = 0; - a->busy = 0; // InterlockedBitTestAndReset (&a->busy, 0); + state = IQCSTATE::RUN; + count = 0; + busy = 0; } break; - case END: - PRE0 = (1.0 - a->cup[a->count]) * PRE0 + a->cup[a->count] * I; - PRE1 = (1.0 - a->cup[a->count]) * PRE1 + a->cup[a->count] * Q; - if (a->count++ == a->ntup) + case IQCSTATE::END: + PRE0 = (1.0 - cup[count]) * PRE0 + cup[count] * I; + PRE1 = (1.0 - cup[count]) * PRE1 + cup[count] * Q; + if (count++ == ntup) { - a->state = DONE; - a->count = 0; - a->busy = 0; // InterlockedBitTestAndReset (&a->busy, 0); + state = IQCSTATE::DONE; + count = 0; + busy = 0; } break; - case DONE: + case IQCSTATE::DONE: PRE0 = I; PRE1 = Q; break; } - a->out[2 * i + 0] = PRE0; - a->out[2 * i + 1] = PRE1; - // print_iqc_values("iqc.txt", a->state, env, PRE0, PRE1, ym, yc, ys, 1.1); + out[2 * i + 0] = (float) PRE0; + out[2 * i + 1] = (float) PRE1; } } - else if (a->out != a->in) - std::copy( a->in, a->in + a->size * 2, a->out); + else if (out != in) + std::copy( in, in + size * 2, out); } -void IQC::setBuffers_iqc (IQC *a, float* in, float* out) +void IQC::setBuffers(float* _in, float* _out) { - a->in = in; - a->out = out; + in = _in; + out = _out; } -void IQC::setSamplerate_iqc (IQC *a, int rate) +void IQC::setSamplerate(int _rate) { - decalc_iqc (a); - a->rate = rate; - calc_iqc (a); + rate = _rate; + calc(); } -void IQC::setSize_iqc (IQC *a, int size) +void IQC::setSize(int _size) { - a->size = size; -} - -/******************************************************************************************************** -* * -* TXA Properties * -* * -********************************************************************************************************/ - -void IQC::GetiqcValues (TXA& txa, float* cm, float* cc, float* cs) -{ - IQC *a; - a = txa.iqc.p0; - memcpy (cm, a->cm[a->cset], a->ints * 4 * sizeof (float)); - memcpy (cc, a->cc[a->cset], a->ints * 4 * sizeof (float)); - memcpy (cs, a->cs[a->cset], a->ints * 4 * sizeof (float)); -} - -void IQC::SetiqcValues (TXA& txa, float* cm, float* cc, float* cs) -{ - IQC *a; - a = txa.iqc.p0; - a->cset = 1 - a->cset; - memcpy (a->cm[a->cset], cm, a->ints * 4 * sizeof (float)); - memcpy (a->cc[a->cset], cc, a->ints * 4 * sizeof (float)); - memcpy (a->cs[a->cset], cs, a->ints * 4 * sizeof (float)); - a->state = RUN; -} - -void IQC::SetiqcSwap (TXA& txa, float* cm, float* cc, float* cs) -{ - IQC *a = txa.iqc.p1; - a->cset = 1 - a->cset; - memcpy (a->cm[a->cset], cm, a->ints * 4 * sizeof (float)); - memcpy (a->cc[a->cset], cc, a->ints * 4 * sizeof (float)); - memcpy (a->cs[a->cset], cs, a->ints * 4 * sizeof (float)); - a->busy = 1; // InterlockedBitTestAndSet (&a->busy, 0); - a->state = SWAP; - a->count = 0; - // while (_InterlockedAnd (&a->busy, 1)) Sleep(1); - while (a->busy == 1) { - std::this_thread::sleep_for(std::chrono::seconds(1)); - } -} - -void IQC::SetiqcStart (TXA& txa, float* cm, float* cc, float* cs) -{ - IQC *a = txa.iqc.p1; - a->cset = 0; - memcpy (a->cm[a->cset], cm, a->ints * 4 * sizeof (float)); - memcpy (a->cc[a->cset], cc, a->ints * 4 * sizeof (float)); - memcpy (a->cs[a->cset], cs, a->ints * 4 * sizeof (float)); - a->busy = 1; // InterlockedBitTestAndSet (&a->busy, 0); - a->state = BEGIN; - a->count = 0; - txa.iqc.p1->run = 1; //InterlockedBitTestAndSet (&txa.iqc.p1->run, 0); - // while (_InterlockedAnd (&a->busy, 1)) Sleep(1); - while (a->busy == 1) { - std::this_thread::sleep_for(std::chrono::seconds(1)); - } -} - -void IQC::SetiqcEnd (TXA& txa) -{ - IQC *a = txa.iqc.p1; - a->busy = 1; // InterlockedBitTestAndSet (&a->busy, 0); - a->state = END; - a->count = 0; - // while (_InterlockedAnd (&a->busy, 1)) Sleep(1); - while (a->busy == 1) { - std::this_thread::sleep_for(std::chrono::seconds(1)); - } - txa.iqc.p1->run = 0; //InterlockedBitTestAndReset (&txa.iqc.p1->run, 0); -} - -void IQC::GetiqcDogCount (TXA& txa, int* count) -{ - IQC *a = txa.iqc.p1; - *count = a->dog.count; -} - -void IQC::SetiqcDogCount (TXA& txa, int count) -{ - IQC *a = txa.iqc.p1; - a->dog.count = count; + size = _size; } } // namespace WDSP diff --git a/wdsp/iqc.hpp b/wdsp/iqc.hpp index bf8bac161..4f58283c4 100644 --- a/wdsp/iqc.hpp +++ b/wdsp/iqc.hpp @@ -28,6 +28,9 @@ warren@wpratt.com #ifndef wdsp_iqc_h #define wdsp_iqc_h +#include +#include + #include "export.h" namespace WDSP { @@ -37,52 +40,63 @@ class TXA; class WDSP_API IQC { public: + enum class IQCSTATE + { + RUN = 0, + BEGIN, + SWAP, + END, + DONE + }; + long run; long busy; int size; float* in; float* out; - float rate; + double rate; int ints; - float* t; + std::vector t; int cset; - float* cm[2]; - float* cc[2]; - float* cs[2]; - float tup; - float* cup; + std::array, 2> cm; + std::array, 2> cc; + std::array, 2> cs; + double tup; + std::vector cup; int count; int ntup; - int state; + IQCSTATE state; struct { int spi; - int* cpi; + std::vector cpi; int full_ints; int count; } dog; - static IQC* create_iqc (int run, int size, float* in, float* out, float rate, int ints, float tup, int spi); - static void destroy_iqc (IQC *a); - static void flush_iqc (IQC *a); - static void xiqc (IQC *a); - static void setBuffers_iqc (IQC *a, float* in, float* out); - static void setSamplerate_iqc (IQC *a, int rate); - static void setSize_iqc (IQC *a, int size); - // TXA Properties - static void GetiqcValues (TXA& txa, float* cm, float* cc, float* cs); - static void SetiqcValues (TXA& txa, float* cm, float* cc, float* cs); - static void SetiqcSwap (TXA& txa, float* cm, float* cc, float* cs); - static void SetiqcStart (TXA& txa, float* cm, float* cc, float* cs); - static void SetiqcEnd (TXA& txa); - static void GetiqcDogCount (TXA& txa, int* count); - static void SetiqcDogCount (TXA& txa, int count); + IQC( + int run, + int size, + float* in, + float* out, + double rate, + int ints, + double tup, + int spi + ); + IQC(const IQC&) = delete; + IQC& operator=(const IQC& other) = delete; + ~IQC() = default; + + void flush(); + void execute(); + void setBuffers(float* in, float* out); + void setSamplerate(int rate); + void setSize(int size); private: - static void size_iqc (IQC *a); - static void desize_iqc (IQC *a); - static void calc_iqc (IQC *a); - static void decalc_iqc (IQC *a); + void size_iqc(); + void calc(); }; } // namespace WDSP diff --git a/wdsp/nob.hpp b/wdsp/nob.hpp index 6264d00be..d8850536b 100644 --- a/wdsp/nob.hpp +++ b/wdsp/nob.hpp @@ -75,12 +75,18 @@ public: int out_idx; // ring buffer position from which delayed samples are pulled double backmult; // multiplier for waveform averaging double ombackmult; // multiplier for waveform averaging - double I1, Q1; - double I2, Q2; - double I, Q; - double Ilast, Qlast; - double deltaI, deltaQ; - double Inext, Qnext; + double I1; + double Q1; + double I2; + double Q2; + double I; + double Q; + double Ilast; + double Qlast; + double deltaI; + double deltaQ; + double Inext; + double Qnext; int overflow; NOB( diff --git a/wdsp/osctrl.cpp b/wdsp/osctrl.cpp index 084f495f7..de2cfee84 100644 --- a/wdsp/osctrl.cpp +++ b/wdsp/osctrl.cpp @@ -35,122 +35,91 @@ warren@wpratt.com namespace WDSP { -void OSCTRL::calc_osctrl (OSCTRL *a) +void OSCTRL::calc() { - a->pn = (int)((0.3 / a->bw) * a->rate + 0.5); - if ((a->pn & 1) == 0) a->pn += 1; - if (a->pn < 3) a->pn = 3; - a->dl_len = a->pn >> 1; - a->dl = new float[a->pn * 2]; // (float *) malloc0 (a->pn * sizeof (complex)); - a->dlenv = new float[a->pn]; // (float *) malloc0 (a->pn * sizeof (float)); - a->in_idx = 0; - a->out_idx = a->in_idx + a->dl_len; - a->max_env = 0.0; + pn = (int)((0.3 / bw) * rate + 0.5); + if ((pn & 1) == 0) pn += 1; + if (pn < 3) pn = 3; + dl_len = pn >> 1; + dl.resize(pn * 2); + dlenv.resize(pn); + in_idx = 0; + out_idx = in_idx + dl_len; + max_env = 0.0; } -void OSCTRL::decalc_osctrl (OSCTRL *a) +OSCTRL::OSCTRL( + int _run, + int _size, + float* _inbuff, + float* _outbuff, + int _rate, + double _osgain +) : + run(_run), + size(_size), + inbuff(_inbuff), + outbuff(_outbuff), + rate(_rate), + osgain(_osgain) { - delete[] (a->dlenv); - delete[] (a->dl); + bw = 3000.0; + calc(); } -OSCTRL* OSCTRL::create_osctrl ( - int run, - int size, - float* inbuff, - float* outbuff, - int rate, - float osgain -) +void OSCTRL::flush() { - OSCTRL *a = new OSCTRL; - a->run = run; - a->size = size; - a->inbuff = inbuff; - a->outbuff = outbuff; - a->rate = rate; - a->osgain = osgain; - a->bw = 3000.0; - calc_osctrl (a); - return a; + std::fill(dl.begin(), dl.end(), 0); + std::fill(dlenv.begin(), dlenv.end(), 0); } -void OSCTRL::destroy_osctrl (OSCTRL *a) +void OSCTRL::execute() { - decalc_osctrl (a); - delete (a); -} - -void OSCTRL::flush_osctrl (OSCTRL *a) -{ - std::fill(a->dl, a->dl + a->dl_len * 2, 0); - std::fill(a->dlenv, a->dlenv + a->pn, 0); -} - -void OSCTRL::xosctrl (OSCTRL *a) -{ - if (a->run) + if (run) { - int i, j; - float divisor; - for (i = 0; i < a->size; i++) + double divisor; + for (int i = 0; i < size; i++) { - a->dl[2 * a->in_idx + 0] = a->inbuff[2 * i + 0]; // put sample in delay line - a->dl[2 * a->in_idx + 1] = a->inbuff[2 * i + 1]; - a->env_out = a->dlenv[a->in_idx]; // take env out of delay line - a->dlenv[a->in_idx] = sqrt (a->inbuff[2 * i + 0] * a->inbuff[2 * i + 0] // put env in delay line - + a->inbuff[2 * i + 1] * a->inbuff[2 * i + 1]); - if (a->dlenv[a->in_idx] > a->max_env) a->max_env = a->dlenv[a->in_idx]; - if (a->env_out >= a->max_env && a->env_out > 0.0) // run the buffer + dl[2 * in_idx + 0] = inbuff[2 * i + 0]; // put sample in delay line + dl[2 * in_idx + 1] = inbuff[2 * i + 1]; + env_out = dlenv[in_idx]; // take env out of delay line + dlenv[in_idx] = sqrt (inbuff[2 * i + 0] * inbuff[2 * i + 0] // put env in delay line + + inbuff[2 * i + 1] * inbuff[2 * i + 1]); + if (dlenv[in_idx] > max_env) max_env = dlenv[in_idx]; + if (env_out >= max_env && env_out > 0.0) // run the buffer { - a->max_env = 0.0; - for (j = 0; j < a->pn; j++) - if (a->dlenv[j] > a->max_env) a->max_env = a->dlenv[j]; + max_env = 0.0; + for (int j = 0; j < pn; j++) + if (dlenv[j] > max_env) max_env = dlenv[j]; } - if (a->max_env > 1.0) divisor = 1.0 + a->osgain * (a->max_env - 1.0); + if (max_env > 1.0) divisor = 1.0 + osgain * (max_env - 1.0); else divisor = 1.0; - a->outbuff[2 * i + 0] = a->dl[2 * a->out_idx + 0] / divisor; // output sample - a->outbuff[2 * i + 1] = a->dl[2 * a->out_idx + 1] / divisor; - if (--a->in_idx < 0) a->in_idx += a->pn; - if (--a->out_idx < 0) a->out_idx += a->pn; + outbuff[2 * i + 0] = (float) (dl[2 * out_idx + 0] / divisor); // output sample + outbuff[2 * i + 1] = (float) (dl[2 * out_idx + 1] / divisor); + if (--in_idx < 0) in_idx += pn; + if (--out_idx < 0) out_idx += pn; } } - else if (a->inbuff != a->outbuff) - std::copy(a->inbuff, a->inbuff + a->size * 2, a->outbuff); + else if (inbuff != outbuff) + std::copy(inbuff, inbuff + size * 2, outbuff); } -void OSCTRL::setBuffers_osctrl (OSCTRL *a, float* in, float* out) +void OSCTRL::setBuffers(float* _in, float* _out) { - a->inbuff = in; - a->outbuff = out; + inbuff = _in; + outbuff = _out; } -void OSCTRL::setSamplerate_osctrl (OSCTRL *a, int rate) +void OSCTRL::setSamplerate(int _rate) { - decalc_osctrl (a); - a->rate = rate; - calc_osctrl (a); + rate = _rate; + calc(); } -void OSCTRL::setSize_osctrl (OSCTRL *a, int size) +void OSCTRL::setSize(int _size) { - a->size = size; - flush_osctrl (a); -} - -/******************************************************************************************************** -* * -* TXA Properties * -* * -********************************************************************************************************/ - -void OSCTRL::SetosctrlRun (TXA& txa, int run) -{ - if (txa.osctrl->run != run) - { - txa.osctrl->run = run; - txa.setupBPFilters(); - } + size = _size; + flush(); } } // namespace WDSP diff --git a/wdsp/osctrl.hpp b/wdsp/osctrl.hpp index 14a31d51c..a5b49ffb7 100644 --- a/wdsp/osctrl.hpp +++ b/wdsp/osctrl.hpp @@ -32,6 +32,8 @@ warren@wpratt.com #ifndef wdsp_osctrl_h #define wdsp_osctrl_h +#include + #include "export.h" namespace WDSP { @@ -46,37 +48,37 @@ public: float *inbuff; // input buffer float *outbuff; // output buffer int rate; // sample rate - float osgain; // gain applied to overshoot "clippings" - float bw; // bandwidth + double osgain; // gain applied to overshoot "clippings" + double bw; // bandwidth int pn; // "peak stretcher" window, samples int dl_len; // delay line length, samples - float* dl; // delay line for complex samples - float* dlenv; // delay line for envelope values + std::vector dl; // delay line for complex samples + std::vector dlenv; // delay line for envelope values int in_idx; // input index for dl int out_idx; // output index for dl - float max_env; // maximum env value in env delay line - float env_out; + double max_env; // maximum env value in env delay line + double env_out; - static void xosctrl (OSCTRL *a); - static OSCTRL* create_osctrl ( + OSCTRL( int run, int size, float* inbuff, float* outbuff, int rate, - float osgain + double osgain ); - static void destroy_osctrl (OSCTRL *a); - static void flush_osctrl (OSCTRL *a); - static void setBuffers_osctrl (OSCTRL *a, float* in, float* out); - static void setSamplerate_osctrl (OSCTRL *a, int rate); - static void setSize_osctrl (OSCTRL *a, int size); - // TXA Properties - static void SetosctrlRun (TXA& txa, int run); + OSCTRL(const OSCTRL&) = delete; + OSCTRL& operator=(const OSCTRL& other) = delete; + ~OSCTRL() = default; + + void flush(); + void execute(); + void setBuffers(float* in, float* out); + void setSamplerate(int rate); + void setSize(int size); private: - static void calc_osctrl (OSCTRL *a); - static void decalc_osctrl (OSCTRL *a); + void calc(); }; } // namespace WDSP diff --git a/wdsp/slew.cpp b/wdsp/slew.cpp index 50651bfd1..b66a2d8e9 100644 --- a/wdsp/slew.cpp +++ b/wdsp/slew.cpp @@ -31,162 +31,141 @@ warren@wpratt.com namespace WDSP { -enum _USLEW +void USLEW::calc() { - BEGIN, - WAIT, - UP, - ON -}; - -void USLEW::calc_uslew (USLEW *a) -{ - int i; - float delta, theta; - a->runmode = 0; - a->state = BEGIN; - a->count = 0; - a->ndelup = (int)(a->tdelay * a->rate); - a->ntup = (int)(a->tupslew * a->rate); - a->cup = new float[a->ntup + 1]; // (float *) malloc0 ((a->ntup + 1) * sizeof (float)); - delta = PI / (float)a->ntup; + double delta; + double theta; + runmode = 0; + state = _USLEW::BEGIN; + count = 0; + ndelup = (int)(tdelay * rate); + ntup = (int)(tupslew * rate); + cup.resize(ntup + 1); + delta = PI / (float)ntup; theta = 0.0; - for (i = 0; i <= a->ntup; i++) + for (int i = 0; i <= ntup; i++) { - a->cup[i] = 0.5 * (1.0 - cos (theta)); + cup[i] = 0.5 * (1.0 - cos (theta)); theta += delta; } - *a->ch_upslew &= ~((long)1); // InterlockedBitTestAndReset (a->ch_upslew, 0); + *ch_upslew &= ~((long)1); } -void USLEW::decalc_uslew (USLEW *a) +USLEW::USLEW( + long *_ch_upslew, + int _size, + float* _in, + float* _out, + double _rate, + double _tdelay, + double _tupslew +) : + ch_upslew(_ch_upslew), + size(_size), + in(_in), + out(_out), + rate(_rate), + tdelay(_tdelay), + tupslew(_tupslew) { - delete[] (a->cup); + calc(); } -USLEW* USLEW::create_uslew ( - TXA *txa, - long *ch_upslew, - int size, - float* in, - float* out, - float rate, - float tdelay, - float tupslew -) +void USLEW::flush() { - USLEW *a = new USLEW; - a->txa = txa; - a->ch_upslew = ch_upslew; - a->size = size; - a->in = in; - a->out = out; - a->rate = rate; - a->tdelay = tdelay; - a->tupslew = tupslew; - calc_uslew (a); - return a; + state = _USLEW::BEGIN; + runmode = 0; + *ch_upslew &= ~1L; } -void USLEW::destroy_uslew (USLEW *a) +void USLEW::execute (int check) { - decalc_uslew (a); - delete (a); -} + if (!runmode && check) + runmode = 1; -void USLEW::flush_uslew (USLEW *a) -{ - a->state = BEGIN; - a->runmode = 0; - *a->ch_upslew &= ~1L; //InterlockedBitTestAndReset (a->ch_upslew, 0); -} - -void USLEW::xuslew (USLEW *a) -{ - if (!a->runmode && a->txa->uslewCheck()) - a->runmode = 1; - - long upslew = *a->ch_upslew; - *a->ch_upslew = 1L; - if (a->runmode && upslew) //_InterlockedAnd (a->ch_upslew, 1)) + long upslew = *ch_upslew; + *ch_upslew = 1L; + if (runmode && upslew) //_InterlockedAnd (ch_upslew, 1)) { - int i; - float I, Q; - for (i = 0; i < a->size; i++) + double I; + double Q; + for (int i = 0; i < size; i++) { - I = a->in[2 * i + 0]; - Q = a->in[2 * i + 1]; - switch (a->state) + I = in[2 * i + 0]; + Q = in[2 * i + 1]; + switch (state) { - case BEGIN: - a->out[2 * i + 0] = 0.0; - a->out[2 * i + 1] = 0.0; + case _USLEW::BEGIN: + out[2 * i + 0] = 0.0; + out[2 * i + 1] = 0.0; if ((I != 0.0) || (Q != 0.0)) { - if (a->ndelup > 0) + if (ndelup > 0) { - a->state = WAIT; - a->count = a->ndelup; + state = _USLEW::WAIT; + count = ndelup; } - else if (a->ntup > 0) + else if (ntup > 0) { - a->state = UP; - a->count = a->ntup; + state = _USLEW::UP; + count = ntup; } else - a->state = ON; + state = _USLEW::ON; } break; - case WAIT: - a->out[2 * i + 0] = 0.0; - a->out[2 * i + 1] = 0.0; - if (a->count-- == 0) + case _USLEW::WAIT: + out[2 * i + 0] = 0.0; + out[2 * i + 1] = 0.0; + if (count-- == 0) { - if (a->ntup > 0) + if (ntup > 0) { - a->state = UP; - a->count = a->ntup; + state = _USLEW::UP; + count = ntup; } else - a->state = ON; + state = _USLEW::ON; } break; - case UP: - a->out[2 * i + 0] = I * a->cup[a->ntup - a->count]; - a->out[2 * i + 1] = Q * a->cup[a->ntup - a->count]; - if (a->count-- == 0) - a->state = ON; + case _USLEW::UP: + out[2 * i + 0] = (float) (I * cup[ntup - count]); + out[2 * i + 1] = (float) (Q * cup[ntup - count]); + if (count-- == 0) + state = _USLEW::ON; break; - case ON: - a->out[2 * i + 0] = I; - a->out[2 * i + 1] = Q; - *a->ch_upslew &= ~((long)1); // InterlockedBitTestAndReset (a->ch_upslew, 0); - a->runmode = 0; + case _USLEW::ON: + out[2 * i + 0] = (float) I; + out[2 * i + 1] = (float) Q; + *ch_upslew &= ~((long)1); + runmode = 0; + break; + default: break; } } } - else if (a->out != a->in) - std::copy( a->in, a->in + a->size * 2, a->out); + else if (out != in) + std::copy( in, in + size * 2, out); } -void USLEW::setBuffers_uslew (USLEW *a, float* in, float* out) +void USLEW::setBuffers(float* _in, float* _out) { - a->in = in; - a->out = out; + in = _in; + out = _out; } -void USLEW::setSamplerate_uslew (USLEW *a, int rate) +void USLEW::setSamplerate(int _rate) { - decalc_uslew (a); - a->rate = rate; - calc_uslew (a); + decalc(); + rate = _rate; + calc(); } -void USLEW::setSize_uslew (USLEW *a, int size) +void USLEW::setSize(int _size) { - a->size = size; - flush_uslew (a); + size = _size; + flush(); } /******************************************************************************************************** @@ -195,13 +174,17 @@ void USLEW::setSize_uslew (USLEW *a, int size) * * ********************************************************************************************************/ -void USLEW::SetuSlewTime (TXA& txa, float time) +void USLEW::setuSlewTime(double _time) { // NOTE: 'time' is in seconds - USLEW *a = txa.uslew; - decalc_uslew (a); - a->tupslew = time; - calc_uslew (a); + decalc(); + tupslew = _time; + calc(); +} + +void USLEW::setRun(int run) +{ + runmode = run; } } // namespace WDSP diff --git a/wdsp/slew.hpp b/wdsp/slew.hpp index 3569701b1..61f71b856 100644 --- a/wdsp/slew.hpp +++ b/wdsp/slew.hpp @@ -28,6 +28,8 @@ warren@wpratt.com #ifndef wdsp_slew_h #define wdsp_slew_h +#include + #include "export.h" namespace WDSP { @@ -37,42 +39,53 @@ class TXA; class WDSP_API USLEW { public: - TXA *txa; + enum class _USLEW + { + BEGIN, + WAIT, + UP, + ON + }; + long *ch_upslew; int size; float* in; float* out; - float rate; - float tdelay; - float tupslew; + double rate; + double tdelay; + double tupslew; int runmode; - int state; + _USLEW state; int count; int ndelup; int ntup; - float* cup; + std::vector cup; - static USLEW* create_uslew ( - TXA *txa, + USLEW( long *ch_upslew, - int size, float* in, + int size, + float* in, float* out, - float rate, - float tdelay, - float tupslew + double rate, + double tdelay, + double tupslew ); - static void destroy_uslew (USLEW *a); - static void flush_uslew (USLEW *a); - static void xuslew (USLEW *a); - static void setBuffers_uslew (USLEW *a, float* in, float* out); - static void setSamplerate_uslew (USLEW *a, int rate); - static void setSize_uslew (USLEW *a, int size); + USLEW(const USLEW&) = delete; + USLEW& operator=(const USLEW& other) = delete; + ~USLEW() = default; + + void flush(); + void execute (int check); + void setBuffers(float* in, float* out); + void setSamplerate(int rate); + void setSize(int size); // TXA Properties - static void SetuSlewTime (TXA& txa, float time); + void setuSlewTime(double time); + void setRun(int run); private: - static void calc_uslew (USLEW *a); - static void decalc_uslew (USLEW *a); + void calc(); + void decalc(); }; } // namespace WDSP