diff --git a/plugins/channelrx/wdsprx/wdsprxsink.cpp b/plugins/channelrx/wdsprx/wdsprxsink.cpp index f72df0145..c6e7593e9 100644 --- a/plugins/channelrx/wdsprx/wdsprxsink.cpp +++ b/plugins/channelrx/wdsprx/wdsprxsink.cpp @@ -770,46 +770,46 @@ void WDSPRxSink::applySettings(const WDSPRxSettings& settings, bool force) || (m_settings.m_agcHangThreshold != settings.m_agcHangThreshold) || (m_settings.m_agcGain != settings.m_agcGain) || force) { - WDSP::WCPAGC::SetAGCSlope(*m_rxa, settings.m_agcSlope); // SetRXAAGCSlope(id, rx->agc_slope); - WDSP::WCPAGC::SetAGCTop(*m_rxa, (float) settings.m_agcGain); // SetRXAAGCTop(id, rx->agc_gain); + m_rxa->agc->setSlope(settings.m_agcSlope); // SetRXAAGCSlope(id, rx->agc_slope); + m_rxa->agc->setTop((float) settings.m_agcGain); // SetRXAAGCTop(id, rx->agc_gain); if (settings.m_agc) { switch (settings.m_agcMode) { case WDSPRxProfile::WDSPRxAGCMode::AGCLong: - WDSP::WCPAGC::SetAGCMode(*m_rxa, 1); - WDSP::WCPAGC::SetAGCAttack(*m_rxa, 2); // SetRXAAGCAttack(id, 2); - WDSP::WCPAGC::SetAGCHang(*m_rxa, 2000); // SetRXAAGCHang(id, 2000); - WDSP::WCPAGC::SetAGCDecay(*m_rxa, 2000); // SetRXAAGCDecay(id, 2000); - WDSP::WCPAGC::SetAGCHangThreshold(*m_rxa, settings.m_agcHangThreshold); // SetRXAAGCHangThreshold(id, (int)rx->agc_hang_threshold); + m_rxa->agc->setMode(1); + m_rxa->agc->setAttack(2); // SetRXAAGCAttack(id, 2); + m_rxa->agc->setHang(2000); // SetRXAAGCHang(id, 2000); + m_rxa->agc->setDecay(2000); // SetRXAAGCDecay(id, 2000); + m_rxa->agc->setHangThreshold(settings.m_agcHangThreshold); // SetRXAAGCHangThreshold(id, (int)rx->agc_hang_threshold); break; case WDSPRxProfile::WDSPRxAGCMode::AGCSlow: - WDSP::WCPAGC::SetAGCMode(*m_rxa, 2); - WDSP::WCPAGC::SetAGCAttack(*m_rxa, 2); // SetRXAAGCAttack(id, 2); - WDSP::WCPAGC::SetAGCHang(*m_rxa, 1000); // SetRXAAGCHang(id, 1000); - WDSP::WCPAGC::SetAGCDecay(*m_rxa, 500); // SetRXAAGCDecay(id, 500); - WDSP::WCPAGC::SetAGCHangThreshold(*m_rxa, settings.m_agcHangThreshold); // SetRXAAGCHangThreshold(id, (int)rx->agc_hang_threshold); + m_rxa->agc->setMode(2); + m_rxa->agc->setAttack(2); // SetRXAAGCAttack(id, 2); + m_rxa->agc->setHang(1000); // SetRXAAGCHang(id, 1000); + m_rxa->agc->setDecay(500); // SetRXAAGCDecay(id, 500); + m_rxa->agc->setHangThreshold(settings.m_agcHangThreshold); // SetRXAAGCHangThreshold(id, (int)rx->agc_hang_threshold); break; case WDSPRxProfile::WDSPRxAGCMode::AGCMedium: - WDSP::WCPAGC::SetAGCMode(*m_rxa, 3); - WDSP::WCPAGC::SetAGCAttack(*m_rxa, 2); // SetRXAAGCAttack(id, 2); - WDSP::WCPAGC::SetAGCHang(*m_rxa, 0); // SetRXAAGCHang(id, 0); - WDSP::WCPAGC::SetAGCDecay(*m_rxa, 250); // SetRXAAGCDecay(id, 250); - WDSP::WCPAGC::SetAGCHangThreshold(*m_rxa, settings.m_agcHangThreshold); // SetRXAAGCHangThreshold(id, 100); + m_rxa->agc->setMode(3); + m_rxa->agc->setAttack(2); // SetRXAAGCAttack(id, 2); + m_rxa->agc->setHang(0); // SetRXAAGCHang(id, 0); + m_rxa->agc->setDecay(250); // SetRXAAGCDecay(id, 250); + m_rxa->agc->setHangThreshold(settings.m_agcHangThreshold); // SetRXAAGCHangThreshold(id, 100); break; case WDSPRxProfile::WDSPRxAGCMode::AGCFast: - WDSP::WCPAGC::SetAGCMode(*m_rxa, 4); - WDSP::WCPAGC::SetAGCAttack(*m_rxa, 2); // SetRXAAGCAttack(id, 2); - WDSP::WCPAGC::SetAGCHang(*m_rxa, 0); // SetRXAAGCHang(id, 0); - WDSP::WCPAGC::SetAGCDecay(*m_rxa, 50); // SetRXAAGCDecay(id, 50); - WDSP::WCPAGC::SetAGCHangThreshold(*m_rxa, settings.m_agcHangThreshold); // SetRXAAGCHangThreshold(id, 100); + m_rxa->agc->setMode(4); + m_rxa->agc->setAttack(2); // SetRXAAGCAttack(id, 2); + m_rxa->agc->setHang(0); // SetRXAAGCHang(id, 0); + m_rxa->agc->setDecay(50); // SetRXAAGCDecay(id, 50); + m_rxa->agc->setHangThreshold(settings.m_agcHangThreshold); // SetRXAAGCHangThreshold(id, 100); break; } } else { - WDSP::WCPAGC::SetAGCMode(*m_rxa, 0); + m_rxa->agc->setMode(0); } } diff --git a/wdsp/RXA.cpp b/wdsp/RXA.cpp index bae905898..bc681c05e 100644 --- a/wdsp/RXA.cpp +++ b/wdsp/RXA.cpp @@ -403,7 +403,7 @@ RXA* RXA::create_rxa ( 1); // ae_run // AGC - rxa->agc = WCPAGC::create_wcpagc ( + rxa->agc = new WCPAGC( 1, // run 3, // mode 1, // peakmode = envelope @@ -572,7 +572,7 @@ void RXA::destroy_rxa (RXA *rxa) SIPHON::destroy_siphon (rxa->sip1); BANDPASS::destroy_bandpass (rxa->bp1); delete (rxa->agcmeter); - WCPAGC::destroy_wcpagc (rxa->agc); + delete (rxa->agc); delete (rxa->emnr); delete (rxa->anr); delete (rxa->anf); @@ -621,7 +621,7 @@ void RXA::flush_rxa (RXA *rxa) rxa->anf->flush(); rxa->anr->flush(); rxa->emnr->flush(); - WCPAGC::flush_wcpagc (rxa->agc); + rxa->agc->flush(); rxa->agcmeter->flush(); BANDPASS::flush_bandpass (rxa->bp1); SIPHON::flush_siphon (rxa->sip1); @@ -657,7 +657,7 @@ void RXA::xrxa (RXA *rxa) rxa->anr->ANR::execute(0); rxa->emnr->execute(0); BANDPASS::xbandpass (rxa->bp1, 0); - WCPAGC::xwcpagc (rxa->agc); + rxa->agc->execute(); rxa->anf->execute(1); rxa->anr->execute(1); rxa->emnr->execute(1); @@ -768,7 +768,7 @@ void RXA::setDSPSamplerate (RXA *rxa, int dsp_rate) rxa->anr->setSamplerate(rxa->dsp_rate); rxa->emnr->setSamplerate(rxa->dsp_rate); BANDPASS::setSamplerate_bandpass (rxa->bp1, rxa->dsp_rate); - WCPAGC::setSamplerate_wcpagc (rxa->agc, rxa->dsp_rate); + rxa->agc->setSamplerate(rxa->dsp_rate); rxa->agcmeter->setSamplerate(rxa->dsp_rate); SIPHON::setSamplerate_siphon (rxa->sip1, rxa->dsp_rate); CBL::setSamplerate_cbl (rxa->cbl, rxa->dsp_rate); @@ -845,8 +845,8 @@ void RXA::setDSPBuffsize (RXA *rxa, int dsp_size) rxa->emnr->setSize(rxa->dsp_size); BANDPASS::setBuffers_bandpass (rxa->bp1, rxa->midbuff, rxa->midbuff); BANDPASS::setSize_bandpass (rxa->bp1, rxa->dsp_size); - WCPAGC::setBuffers_wcpagc (rxa->agc, rxa->midbuff, rxa->midbuff); - WCPAGC::setSize_wcpagc (rxa->agc, rxa->dsp_size); + rxa->agc->setBuffers(rxa->midbuff, rxa->midbuff); + rxa->agc->setSize(rxa->dsp_size); rxa->agcmeter->setBuffers(rxa->midbuff); rxa->agcmeter->setSize(rxa->dsp_size); SIPHON::setBuffers_siphon (rxa->sip1, rxa->midbuff); @@ -1343,6 +1343,23 @@ void RXA::SetEMNRPosition (RXA& rxa, int position) rxa.bp1->position = position; } +void RXA::GetAGCThresh(RXA& rxa, double *thresh, double size, double rate) +//for line on bandscope. +{ + double noise_offset; + noise_offset = 10.0 * log10((rxa.nbp0->fhigh - rxa.nbp0->flow) * size / rate); + *thresh = 20.0 * log10( rxa.agc->min_volts ) - noise_offset; +} + +void RXA::SetAGCThresh(RXA& rxa, double thresh, double size, double rate) +//for line on bandscope +{ + double noise_offset; + noise_offset = 10.0 * log10((rxa.nbp0->fhigh - rxa.nbp0->flow) * size / rate); + rxa.agc->max_gain = rxa.agc->out_target / (rxa.agc->var_gain * pow (10.0, (thresh + noise_offset) / 20.0)); + rxa.agc->loadWcpAGC(); +} + /******************************************************************************************************** * * * Collectives * diff --git a/wdsp/RXA.hpp b/wdsp/RXA.hpp index ac8e1b861..629a9374e 100644 --- a/wdsp/RXA.hpp +++ b/wdsp/RXA.hpp @@ -180,6 +180,9 @@ public: // EMNR static void SetEMNRRun (RXA& rxa, int run); static void SetEMNRPosition (RXA& rxa, int position); + // WCPAGC + static void SetAGCThresh(RXA& rxa, double thresh, double size, double rate); + static void GetAGCThresh(RXA& rxa, double *thresh, double size, double rate); // Collectives static void SetPassband (RXA& rxa, float f_low, float f_high); static void SetNC (RXA& rxa, int nc); diff --git a/wdsp/TXA.cpp b/wdsp/TXA.cpp index 61243c5e3..b9062f590 100644 --- a/wdsp/TXA.cpp +++ b/wdsp/TXA.cpp @@ -197,7 +197,7 @@ TXA* TXA::create_txa ( 300.0, // f_low 3000.0); // f_high - txa->leveler = WCPAGC::create_wcpagc ( + txa->leveler = new WCPAGC( 0, // run - OFF by default 5, // mode 0, // 0 for max(I,Q), 1 for envelope @@ -347,7 +347,7 @@ TXA* TXA::create_txa ( -1, // index for gain value 0); // pointer for gain computation - txa->alc = WCPAGC::create_wcpagc ( + txa->alc = new WCPAGC( 1, // run - always ON 5, // mode 1, // 0 for max(I,Q), 1 for envelope @@ -530,7 +530,7 @@ void TXA::destroy_txa (TXA *txa) delete (txa->gen1); FMMOD::destroy_fmmod (txa->fmmod); AMMOD::destroy_ammod (txa->ammod); - WCPAGC::destroy_wcpagc (txa->alc); + delete (txa->alc); delete (txa->compmeter); BANDPASS::destroy_bandpass (txa->bp2); OSCTRL::destroy_osctrl (txa->osctrl); @@ -540,7 +540,7 @@ void TXA::destroy_txa (TXA *txa) delete (txa->cfcmeter); CFCOMP::destroy_cfcomp (txa->cfcomp); delete (txa->lvlrmeter); - WCPAGC::destroy_wcpagc (txa->leveler); + delete (txa->leveler); EMPHP::destroy_emphp (txa->preemph); delete (txa->eqmeter); delete (txa->eqp); @@ -570,7 +570,7 @@ void TXA::flush_txa (TXA* txa) txa->eqp->flush(); txa->eqmeter->flush (); EMPHP::flush_emphp (txa->preemph); - WCPAGC::flush_wcpagc (txa->leveler); + txa->leveler->flush(); txa->lvlrmeter->flush (); CFCOMP::flush_cfcomp (txa->cfcomp); txa->cfcmeter->flush (); @@ -580,7 +580,7 @@ void TXA::flush_txa (TXA* txa) OSCTRL::flush_osctrl (txa->osctrl); BANDPASS::flush_bandpass (txa->bp2); txa->compmeter->flush (); - WCPAGC::flush_wcpagc (txa->alc); + txa->alc->flush (); AMMOD::flush_ammod (txa->ammod); FMMOD::flush_fmmod (txa->fmmod); txa->gen1->flush(); @@ -605,7 +605,7 @@ void xtxa (TXA* txa) txa->eqp->execute (); // pre-EQ txa->eqmeter->execute (); // EQ meter EMPHP::xemphp (txa->preemph, 0); // FM pre-emphasis (first option) - WCPAGC::xwcpagc (txa->leveler); // Leveler + txa->leveler->execute (); // Leveler txa->lvlrmeter->execute (); // Leveler Meter CFCOMP::xcfcomp (txa->cfcomp, 0); // Continuous Frequency Compressor with post-EQ txa->cfcmeter->execute (); // CFC+PostEQ Meter @@ -615,7 +615,7 @@ void xtxa (TXA* txa) OSCTRL::xosctrl (txa->osctrl); // CESSB Overshoot Control BANDPASS::xbandpass (txa->bp2, 0); // aux bandpass (runs if CESSB) txa->compmeter->execute (); // COMP meter - WCPAGC::xwcpagc (txa->alc); // ALC + txa->alc->execute (); // ALC AMMOD::xammod (txa->ammod); // AM Modulator EMPHP::xemphp (txa->preemph, 1); // FM pre-emphasis (second option) FMMOD::xfmmod (txa->fmmod); // FM Modulator @@ -702,7 +702,7 @@ void TXA::setDSPSamplerate (TXA *txa, int dsp_rate) txa->eqp->setSamplerate (txa->dsp_rate); txa->eqmeter->setSamplerate (txa->dsp_rate); EMPHP::setSamplerate_emphp (txa->preemph, txa->dsp_rate); - WCPAGC::setSamplerate_wcpagc (txa->leveler, txa->dsp_rate); + txa->leveler->setSamplerate (txa->dsp_rate); txa->lvlrmeter->setSamplerate (txa->dsp_rate); CFCOMP::setSamplerate_cfcomp (txa->cfcomp, txa->dsp_rate); txa->cfcmeter->setSamplerate (txa->dsp_rate); @@ -712,7 +712,7 @@ void TXA::setDSPSamplerate (TXA *txa, int dsp_rate) OSCTRL::setSamplerate_osctrl (txa->osctrl, txa->dsp_rate); BANDPASS::setSamplerate_bandpass (txa->bp2, txa->dsp_rate); txa->compmeter->setSamplerate (txa->dsp_rate); - WCPAGC::setSamplerate_wcpagc (txa->alc, txa->dsp_rate); + txa->alc->setSamplerate (txa->dsp_rate); AMMOD::setSamplerate_ammod (txa->ammod, txa->dsp_rate); FMMOD::setSamplerate_fmmod (txa->fmmod, txa->dsp_rate); txa->gen1->setSamplerate(txa->dsp_rate); @@ -770,8 +770,8 @@ void TXA::setDSPBuffsize (TXA *txa, int dsp_size) txa->eqmeter->setSize (txa->dsp_size); EMPHP::setBuffers_emphp (txa->preemph, txa->midbuff, txa->midbuff); EMPHP::setSize_emphp (txa->preemph, txa->dsp_size); - WCPAGC::setBuffers_wcpagc (txa->leveler, txa->midbuff, txa->midbuff); - WCPAGC::setSize_wcpagc (txa->leveler, txa->dsp_size); + txa->leveler->setBuffers(txa->midbuff, txa->midbuff); + txa->leveler->setSize(txa->dsp_size); txa->lvlrmeter->setBuffers(txa->midbuff); txa->lvlrmeter->setSize(txa->dsp_size); CFCOMP::setBuffers_cfcomp (txa->cfcomp, txa->midbuff, txa->midbuff); @@ -790,8 +790,8 @@ void TXA::setDSPBuffsize (TXA *txa, int dsp_size) BANDPASS::setSize_bandpass (txa->bp2, txa->dsp_size); txa->compmeter->setBuffers(txa->midbuff); txa->compmeter->setSize(txa->dsp_size); - WCPAGC::setBuffers_wcpagc (txa->alc, txa->midbuff, txa->midbuff); - WCPAGC::setSize_wcpagc (txa->alc, txa->dsp_size); + txa->alc->setBuffers(txa->midbuff, txa->midbuff); + txa->alc->setSize( txa->dsp_size); AMMOD::setBuffers_ammod (txa->ammod, txa->midbuff, txa->midbuff); AMMOD::setSize_ammod (txa->ammod, txa->dsp_size); FMMOD::setBuffers_fmmod (txa->fmmod, txa->midbuff, txa->midbuff); diff --git a/wdsp/fmd.cpp b/wdsp/fmd.cpp index 27de2f753..bac132be5 100644 --- a/wdsp/fmd.cpp +++ b/wdsp/fmd.cpp @@ -55,7 +55,7 @@ void FMD::calc() // CTCSS Removal sntch = SNOTCH::create_snotch(1, size, out, out, (int)rate, ctcss_freq, 0.0002); // detector limiter - plim = WCPAGC::create_wcpagc ( + plim = new WCPAGC( 1, // run - always ON 5, // mode 1, // 0 for max(I,Q), 1 for envelope @@ -83,7 +83,7 @@ void FMD::calc() void FMD::decalc() { - WCPAGC::destroy_wcpagc(plim); + delete (plim); SNOTCH::destroy_snotch(sntch); } @@ -163,7 +163,7 @@ void FMD::flush() omega = 0.0; fmdc = 0.0; SNOTCH::flush_snotch (sntch); - WCPAGC::flush_wcpagc (plim); + plim->flush(); } void FMD::execute() @@ -205,7 +205,7 @@ void FMD::execute() { for (i = 0; i < 2 * size; i++) out[i] *= lim_pre_gain; - WCPAGC::xwcpagc (plim); + plim->execute(); } } else if (in != out) @@ -220,7 +220,7 @@ void FMD::setBuffers(float* _in, float* _out) calc(); FIRCORE::setBuffers_fircore (pde, audio.data(), out); FIRCORE::setBuffers_fircore (paud, out, out); - WCPAGC::setBuffers_wcpagc (plim, out, out); + plim->setBuffers(out, out); } void FMD::setSamplerate(int _rate) @@ -237,7 +237,7 @@ void FMD::setSamplerate(int _rate) impulse = FIR::fir_bandpass(nc_aud, 0.8 * f_low, 1.1 * f_high, rate, 0, 1, afgain / (2.0 * size)); FIRCORE::setImpulse_fircore (paud, impulse, 1); delete[] (impulse); - WCPAGC::setSamplerate_wcpagc (plim, (int)rate); + plim->setSamplerate((int) rate); } void FMD::setSize(int _size) @@ -257,7 +257,7 @@ void FMD::setSize(int _size) impulse = FIR::fir_bandpass(nc_aud, 0.8 * f_low, 1.1 * f_high, rate, 0, 1, afgain / (2.0 * size)); paud = FIRCORE::create_fircore (size, out, out, nc_aud, mp_aud, impulse); delete[] (impulse); - WCPAGC::setSize_wcpagc (plim, size); + plim->setSize(size); } /******************************************************************************************************** diff --git a/wdsp/wcpAGC.cpp b/wdsp/wcpAGC.cpp index 34a36b4e5..e1f9a8a42 100644 --- a/wdsp/wcpAGC.cpp +++ b/wdsp/wcpAGC.cpp @@ -39,218 +39,201 @@ Santa Cruz, CA 95060 namespace WDSP { -void WCPAGC::calc_wcpagc (WCPAGC *a) +void WCPAGC::calc() { //assign constants - a->ring_buffsize = RB_SIZE; //do one-time initialization - a->out_index = -1; - a->ring_max = 0.0; - a->volts = 0.0; - a->save_volts = 0.0; - a->fast_backaverage = 0.0; - a->hang_backaverage = 0.0; - a->hang_counter = 0; - a->decay_type = 0; - a->state = 0; - a->ring = new double[RB_SIZE * 2]; // (float *)malloc0(RB_SIZE * sizeof(complex)); - a->abs_ring = new double[RB_SIZE]; //(float *)malloc0(RB_SIZE * sizeof(float)); - loadWcpAGC(a); + out_index = -1; + ring_max = 0.0; + volts = 0.0; + save_volts = 0.0; + fast_backaverage = 0.0; + hang_backaverage = 0.0; + hang_counter = 0; + decay_type = 0; + state = 0; + loadWcpAGC(); } -void WCPAGC::decalc_wcpagc (WCPAGC *a) -{ - delete[] (a->abs_ring); - delete[] (a->ring); -} - -WCPAGC* WCPAGC::create_wcpagc ( - int run, - int mode, - int pmode, - float* in, - float* out, - int io_buffsize, - int sample_rate, - double tau_attack, - double tau_decay, - int n_tau, - double max_gain, - double var_gain, - double fixed_gain, - double max_input, - double out_targ, - double tau_fast_backaverage, - double tau_fast_decay, - double pop_ratio, - int hang_enable, - double tau_hang_backmult, - double hangtime, - double hang_thresh, - double tau_hang_decay -) -{ - WCPAGC *a = new WCPAGC; +WCPAGC::WCPAGC( + int _run, + int _mode, + int _pmode, + float* _in, + float* _out, + int _io_buffsize, + int _sample_rate, + double _tau_attack, + double _tau_decay, + int _n_tau, + double _max_gain, + double _var_gain, + double _fixed_gain, + double _max_input, + double _out_targ, + double _tau_fast_backaverage, + double _tau_fast_decay, + double _pop_ratio, + int _hang_enable, + double _tau_hang_backmult, + double _hangtime, + double _hang_thresh, + double _tau_hang_decay +) : //initialize per call parameters - a->run = run; - a->mode = mode; - a->pmode = pmode; - a->in = in; - a->out = out; - a->io_buffsize = io_buffsize; - a->sample_rate = (double) sample_rate; - a->tau_attack = tau_attack; - a->tau_decay = tau_decay; - a->n_tau = n_tau; - a->max_gain = max_gain; - a->var_gain = var_gain; - a->fixed_gain = fixed_gain; - a->max_input = max_input; - a->out_targ = out_targ; - a->tau_fast_backaverage = tau_fast_backaverage; - a->tau_fast_decay = tau_fast_decay; - a->pop_ratio = pop_ratio; - a->hang_enable = hang_enable; - a->tau_hang_backmult = tau_hang_backmult; - a->hangtime = hangtime; - a->hang_thresh = hang_thresh; - a->tau_hang_decay = tau_hang_decay; - calc_wcpagc (a); - return a; + run(_run), + mode(_mode), + pmode(_pmode), + in(_in), + out(_out), + io_buffsize(_io_buffsize), + sample_rate((double) _sample_rate), + tau_attack(_tau_attack), + tau_decay(_tau_decay), + n_tau(_n_tau), + max_gain(_max_gain), + var_gain(_var_gain), + fixed_gain(_fixed_gain), + max_input(_max_input), + out_targ(_out_targ), + tau_fast_backaverage(_tau_fast_backaverage), + tau_fast_decay(_tau_fast_decay), + pop_ratio(_pop_ratio), + hang_enable(_hang_enable), + tau_hang_backmult(_tau_hang_backmult), + hangtime(_hangtime), + hang_thresh(_hang_thresh), + tau_hang_decay(_tau_hang_decay) +{ + calc(); } -void WCPAGC::loadWcpAGC (WCPAGC *a) +void WCPAGC::loadWcpAGC() { double tmp; //calculate internal parameters - a->attack_buffsize = (int)ceil(a->sample_rate * a->n_tau * a->tau_attack); - a->in_index = a->attack_buffsize + a->out_index; - a->attack_mult = 1.0 - exp(-1.0 / (a->sample_rate * a->tau_attack)); - a->decay_mult = 1.0 - exp(-1.0 / (a->sample_rate * a->tau_decay)); - a->fast_decay_mult = 1.0 - exp(-1.0 / (a->sample_rate * a->tau_fast_decay)); - a->fast_backmult = 1.0 - exp(-1.0 / (a->sample_rate * a->tau_fast_backaverage)); - a->onemfast_backmult = 1.0 - a->fast_backmult; + attack_buffsize = (int)ceil(sample_rate * n_tau * tau_attack); + in_index = attack_buffsize + out_index; + attack_mult = 1.0 - exp(-1.0 / (sample_rate * tau_attack)); + decay_mult = 1.0 - exp(-1.0 / (sample_rate * tau_decay)); + fast_decay_mult = 1.0 - exp(-1.0 / (sample_rate * tau_fast_decay)); + fast_backmult = 1.0 - exp(-1.0 / (sample_rate * tau_fast_backaverage)); + onemfast_backmult = 1.0 - fast_backmult; - a->out_target = a->out_targ * (1.0 - exp(-(double)a->n_tau)) * 0.9999; - a->min_volts = a->out_target / (a->var_gain * a->max_gain); - a->inv_out_target = 1.0 / a->out_target; + out_target = out_targ * (1.0 - exp(-(double)n_tau)) * 0.9999; + min_volts = out_target / (var_gain * max_gain); + inv_out_target = 1.0 / out_target; - tmp = log10(a->out_target / (a->max_input * a->var_gain * a->max_gain)); + tmp = log10(out_target / (max_input * var_gain * max_gain)); if (tmp == 0.0) tmp = 1e-16; - a->slope_constant = (a->out_target * (1.0 - 1.0 / a->var_gain)) / tmp; - a->inv_max_input = 1.0 / a->max_input; - tmp = pow (10.0, (a->hang_thresh - 1.0) / 0.125); - a->hang_level = (a->max_input * tmp + (a->out_target / - (a->var_gain * a->max_gain)) * (1.0 - tmp)) * 0.637; - a->hang_backmult = 1.0 - exp(-1.0 / (a->sample_rate * a->tau_hang_backmult)); - a->onemhang_backmult = 1.0 - a->hang_backmult; - a->hang_decay_mult = 1.0 - exp(-1.0 / (a->sample_rate * a->tau_hang_decay)); + slope_constant = (out_target * (1.0 - 1.0 / var_gain)) / tmp; + inv_max_input = 1.0 / max_input; + tmp = pow (10.0, (hang_thresh - 1.0) / 0.125); + hang_level = (max_input * tmp + (out_target / + (var_gain * max_gain)) * (1.0 - tmp)) * 0.637; + hang_backmult = 1.0 - exp(-1.0 / (sample_rate * tau_hang_backmult)); + onemhang_backmult = 1.0 - hang_backmult; + hang_decay_mult = 1.0 - exp(-1.0 / (sample_rate * tau_hang_decay)); } -void WCPAGC::destroy_wcpagc (WCPAGC *a) +void WCPAGC::flush() { - decalc_wcpagc (a); - delete (a); + std::fill(ring.begin(), ring.end(), 0); + std::fill(abs_ring.begin(), abs_ring.end(), 0); + ring_max = 0.0; } -void WCPAGC::flush_wcpagc (WCPAGC *a) -{ - memset ((void *)a->ring, 0, sizeof(double) * RB_SIZE * 2); - a->ring_max = 0.0; - memset ((void *)a->abs_ring, 0, sizeof(double)* RB_SIZE); -} - -void WCPAGC::xwcpagc (WCPAGC *a) +void WCPAGC::execute() { int i, j, k; double mult; - if (a->run) + if (run) { - if (a->mode == 0) + if (mode == 0) { - for (i = 0; i < a->io_buffsize; i++) + for (i = 0; i < io_buffsize; i++) { - a->out[2 * i + 0] = a->fixed_gain * a->in[2 * i + 0]; - a->out[2 * i + 1] = a->fixed_gain * a->in[2 * i + 1]; + out[2 * i + 0] = fixed_gain * in[2 * i + 0]; + out[2 * i + 1] = fixed_gain * in[2 * i + 1]; } return; } - for (i = 0; i < a->io_buffsize; i++) + for (i = 0; i < io_buffsize; i++) { - if (++a->out_index >= a->ring_buffsize) - a->out_index -= a->ring_buffsize; + if (++out_index >= ring_buffsize) + out_index -= ring_buffsize; - if (++a->in_index >= a->ring_buffsize) - a->in_index -= a->ring_buffsize; + if (++in_index >= ring_buffsize) + in_index -= ring_buffsize; - a->out_sample[0] = a->ring[2 * a->out_index + 0]; - a->out_sample[1] = a->ring[2 * a->out_index + 1]; - a->abs_out_sample = a->abs_ring[a->out_index]; - double xr = a->ring[2 * a->in_index + 0] = a->in[2 * i + 0]; - double xi = a->ring[2 * a->in_index + 1] = a->in[2 * i + 1]; + out_sample[0] = ring[2 * out_index + 0]; + out_sample[1] = ring[2 * out_index + 1]; + abs_out_sample = abs_ring[out_index]; + double xr = ring[2 * in_index + 0] = in[2 * i + 0]; + double xi = ring[2 * in_index + 1] = in[2 * i + 1]; - if (a->pmode == 0) - a->abs_ring[a->in_index] = std::max(fabs(xr), fabs(xi)); + if (pmode == 0) + abs_ring[in_index] = std::max(fabs(xr), fabs(xi)); else - a->abs_ring[a->in_index] = sqrt(xr*xr + xi*xi); + abs_ring[in_index] = sqrt(xr*xr + xi*xi); - a->fast_backaverage = a->fast_backmult * a->abs_out_sample + a->onemfast_backmult * a->fast_backaverage; - a->hang_backaverage = a->hang_backmult * a->abs_out_sample + a->onemhang_backmult * a->hang_backaverage; + fast_backaverage = fast_backmult * abs_out_sample + onemfast_backmult * fast_backaverage; + hang_backaverage = hang_backmult * abs_out_sample + onemhang_backmult * hang_backaverage; - if ((a->abs_out_sample >= a->ring_max) && (a->abs_out_sample > 0.0)) + if ((abs_out_sample >= ring_max) && (abs_out_sample > 0.0)) { - a->ring_max = 0.0; - k = a->out_index; + ring_max = 0.0; + k = out_index; - for (j = 0; j < a->attack_buffsize; j++) + for (j = 0; j < attack_buffsize; j++) { - if (++k == a->ring_buffsize) + if (++k == ring_buffsize) k = 0; - if (a->abs_ring[k] > a->ring_max) - a->ring_max = a->abs_ring[k]; + if (abs_ring[k] > ring_max) + ring_max = abs_ring[k]; } } - if (a->abs_ring[a->in_index] > a->ring_max) - a->ring_max = a->abs_ring[a->in_index]; + if (abs_ring[in_index] > ring_max) + ring_max = abs_ring[in_index]; - if (a->hang_counter > 0) - --a->hang_counter; + if (hang_counter > 0) + --hang_counter; - switch (a->state) + switch (state) { case 0: { - if (a->ring_max >= a->volts) + if (ring_max >= volts) { - a->volts += (a->ring_max - a->volts) * a->attack_mult; + volts += (ring_max - volts) * attack_mult; } else { - if (a->volts > a->pop_ratio * a->fast_backaverage) + if (volts > pop_ratio * fast_backaverage) { - a->state = 1; - a->volts += (a->ring_max - a->volts) * a->fast_decay_mult; + state = 1; + volts += (ring_max - volts) * fast_decay_mult; } else { - if (a->hang_enable && (a->hang_backaverage > a->hang_level)) + if (hang_enable && (hang_backaverage > hang_level)) { - a->state = 2; - a->hang_counter = (int)(a->hangtime * a->sample_rate); - a->decay_type = 1; + state = 2; + hang_counter = (int)(hangtime * sample_rate); + decay_type = 1; } else { - a->state = 3; - a->volts += (a->ring_max - a->volts) * a->decay_mult; - a->decay_type = 0; + state = 3; + volts += (ring_max - volts) * decay_mult; + decay_type = 0; } } } @@ -259,34 +242,34 @@ void WCPAGC::xwcpagc (WCPAGC *a) case 1: { - if (a->ring_max >= a->volts) + if (ring_max >= volts) { - a->state = 0; - a->volts += (a->ring_max - a->volts) * a->attack_mult; + state = 0; + volts += (ring_max - volts) * attack_mult; } else { - if (a->volts > a->save_volts) + if (volts > save_volts) { - a->volts += (a->ring_max - a->volts) * a->fast_decay_mult; + volts += (ring_max - volts) * fast_decay_mult; } else { - if (a->hang_counter > 0) + if (hang_counter > 0) { - a->state = 2; + state = 2; } else { - if (a->decay_type == 0) + if (decay_type == 0) { - a->state = 3; - a->volts += (a->ring_max - a->volts) * a->decay_mult; + state = 3; + volts += (ring_max - volts) * decay_mult; } else { - a->state = 4; - a->volts += (a->ring_max - a->volts) * a->hang_decay_mult; + state = 4; + volts += (ring_max - volts) * hang_decay_mult; } } } @@ -296,18 +279,18 @@ void WCPAGC::xwcpagc (WCPAGC *a) case 2: { - if (a->ring_max >= a->volts) + if (ring_max >= volts) { - a->state = 0; - a->save_volts = a->volts; - a->volts += (a->ring_max - a->volts) * a->attack_mult; + state = 0; + save_volts = volts; + volts += (ring_max - volts) * attack_mult; } else { - if (a->hang_counter == 0) + if (hang_counter == 0) { - a->state = 4; - a->volts += (a->ring_max - a->volts) * a->hang_decay_mult; + state = 4; + volts += (ring_max - volts) * hang_decay_mult; } } break; @@ -315,280 +298,202 @@ void WCPAGC::xwcpagc (WCPAGC *a) case 3: { - if (a->ring_max >= a->volts) + if (ring_max >= volts) { - a->state = 0; - a->save_volts = a->volts; - a->volts += (a->ring_max - a->volts) * a->attack_mult; + state = 0; + save_volts = volts; + volts += (ring_max - volts) * attack_mult; } else { - a->volts += (a->ring_max - a->volts) * a->decay_mult; + volts += (ring_max - volts) * decay_mult; } break; } case 4: { - if (a->ring_max >= a->volts) + if (ring_max >= volts) { - a->state = 0; - a->save_volts = a->volts; - a->volts += (a->ring_max - a->volts) * a->attack_mult; + state = 0; + save_volts = volts; + volts += (ring_max - volts) * attack_mult; } else { - a->volts += (a->ring_max - a->volts) * a->hang_decay_mult; + volts += (ring_max - volts) * hang_decay_mult; } break; } } - if (a->volts < a->min_volts) - a->volts = a->min_volts; + if (volts < min_volts) + volts = min_volts; - a->gain = a->volts * a->inv_out_target; - mult = (a->out_target - a->slope_constant * std::min (0.0, log10(a->inv_max_input * a->volts))) / a->volts; - a->out[2 * i + 0] = a->out_sample[0] * mult; - a->out[2 * i + 1] = a->out_sample[1] * mult; + gain = volts * inv_out_target; + mult = (out_target - slope_constant * std::min (0.0, log10(inv_max_input * volts))) / volts; + out[2 * i + 0] = out_sample[0] * mult; + out[2 * i + 1] = out_sample[1] * mult; } } - else if (a->out != a->in) + else if (out != in) { - std::copy(a->in, a->in + a->io_buffsize * 2, a->out); + std::copy(in, in + io_buffsize * 2, out); } } -void WCPAGC::setBuffers_wcpagc (WCPAGC *a, float* in, float* out) +void WCPAGC::setBuffers(float* _in, float* _out) { - a->in = in; - a->out = out; + in = _in; + out = _out; } -void WCPAGC::setSamplerate_wcpagc (WCPAGC *a, int rate) +void WCPAGC::setSamplerate(int _rate) { - decalc_wcpagc (a); - a->sample_rate = rate; - calc_wcpagc (a); + sample_rate = _rate; + calc(); } -void WCPAGC::setSize_wcpagc (WCPAGC *a, int size) +void WCPAGC::setSize(int _size) { - decalc_wcpagc (a); - a->io_buffsize = size; - calc_wcpagc (a); + io_buffsize = _size; + calc(); } /******************************************************************************************************** * * -* RXA Properties * +* Public Properties * * * ********************************************************************************************************/ -void WCPAGC::SetAGCMode (RXA& rxa, int mode) +void WCPAGC::setMode(int _mode) { - switch (mode) + switch (_mode) { case 0: //agcOFF - rxa.agc->mode = 0; - loadWcpAGC ( rxa.agc ); + mode = 0; + loadWcpAGC(); break; case 1: //agcLONG - rxa.agc->mode = 1; - rxa.agc->hangtime = 2.000; - rxa.agc->tau_decay = 2.000; - loadWcpAGC ( rxa.agc ); + mode = 1; + hangtime = 2.000; + tau_decay = 2.000; + loadWcpAGC(); break; case 2: //agcSLOW - rxa.agc->mode = 2; - rxa.agc->hangtime = 1.000; - rxa.agc->tau_decay = 0.500; - loadWcpAGC ( rxa.agc ); + mode = 2; + hangtime = 1.000; + tau_decay = 0.500; + loadWcpAGC(); break; case 3: //agcMED - rxa.agc->mode = 3; - rxa.agc->hang_thresh = 1.0; - rxa.agc->hangtime = 0.000; - rxa.agc->tau_decay = 0.250; - loadWcpAGC ( rxa.agc ); + mode = 3; + hang_thresh = 1.0; + hangtime = 0.000; + tau_decay = 0.250; + loadWcpAGC(); break; case 4: //agcFAST - rxa.agc->mode = 4; - rxa.agc->hang_thresh = 1.0; - rxa.agc->hangtime = 0.000; - rxa.agc->tau_decay = 0.050; - loadWcpAGC ( rxa.agc ); + mode = 4; + hang_thresh = 1.0; + hangtime = 0.000; + tau_decay = 0.050; + loadWcpAGC(); break; default: - rxa.agc->mode = 5; + mode = 5; break; } } -void WCPAGC::SetAGCAttack (RXA& rxa, int attack) +void WCPAGC::setFixed(double _fixed_agc) { - rxa.agc->tau_attack = (float)attack / 1000.0; - loadWcpAGC ( rxa.agc ); + fixed_gain = pow (10.0, (double) _fixed_agc / 20.0); + loadWcpAGC(); } -void WCPAGC::SetAGCDecay (RXA& rxa, int decay) +void WCPAGC::setAttack(int _attack) { - rxa.agc->tau_decay = (float)decay / 1000.0; - loadWcpAGC ( rxa.agc ); + tau_attack = (double) _attack / 1000.0; + loadWcpAGC(); } -void WCPAGC::SetAGCHang (RXA& rxa, int hang) +void WCPAGC::setDecay(int _decay) { - rxa.agc->hangtime = (float)hang / 1000.0; - loadWcpAGC ( rxa.agc ); + tau_decay = (double) _decay / 1000.0; + loadWcpAGC(); } -void WCPAGC::GetAGCHangLevel(RXA& rxa, double *hangLevel) +void WCPAGC::setHang(int _hang) +{ + hangtime = (double) _hang / 1000.0; + loadWcpAGC(); +} + +void WCPAGC::getHangLevel(double *hangLevel) //for line on bandscope { - *hangLevel = 20.0 * log10( rxa.agc->hang_level / 0.637 ); + *hangLevel = 20.0 * log10(hang_level / 0.637); } -void WCPAGC::SetAGCHangLevel(RXA& rxa, double hangLevel) +void WCPAGC::setHangLevel(double _hangLevel) //for line on bandscope { double convert, tmp; - if (rxa.agc->max_input > rxa.agc->min_volts) + if (max_input > min_volts) { - convert = pow (10.0, hangLevel / 20.0); - tmp = std::max(1e-8, (convert - rxa.agc->min_volts) / (rxa.agc->max_input - rxa.agc->min_volts)); - rxa.agc->hang_thresh = 1.0 + 0.125 * log10 (tmp); + convert = pow (10.0, _hangLevel / 20.0); + tmp = std::max(1e-8, (convert - min_volts) / (max_input - min_volts)); + hang_thresh = 1.0 + 0.125 * log10 (tmp); } else - rxa.agc->hang_thresh = 1.0; + hang_thresh = 1.0; - loadWcpAGC ( rxa.agc ); + loadWcpAGC(); } -void WCPAGC::GetAGCHangThreshold(RXA& rxa, int *hangthreshold) +void WCPAGC::getHangThreshold(int *hangthreshold) //for slider in setup { - *hangthreshold = (int) (100.0 * rxa.agc->hang_thresh); + *hangthreshold = (int) (100.0 * hang_thresh); } -void WCPAGC::SetAGCHangThreshold (RXA& rxa, int hangthreshold) +void WCPAGC::setHangThreshold(int _hangthreshold) //For slider in setup { - rxa.agc->hang_thresh = (double) hangthreshold / 100.0; - loadWcpAGC ( rxa.agc ); + hang_thresh = (double) _hangthreshold / 100.0; + loadWcpAGC(); } -void WCPAGC::GetAGCThresh(RXA& rxa, double *thresh, double size, double rate) -//for line on bandscope. -{ - double noise_offset; - noise_offset = 10.0 * log10((rxa.nbp0->fhigh - rxa.nbp0->flow) * size / rate); - *thresh = 20.0 * log10( rxa.agc->min_volts ) - noise_offset; -} - -void WCPAGC::SetAGCThresh(RXA& rxa, double thresh, double size, double rate) -//for line on bandscope -{ - double noise_offset; - noise_offset = 10.0 * log10((rxa.nbp0->fhigh - rxa.nbp0->flow) * size / rate); - rxa.agc->max_gain = rxa.agc->out_target / (rxa.agc->var_gain * pow (10.0, (thresh + noise_offset) / 20.0)); - loadWcpAGC ( rxa.agc ); -} - -void WCPAGC::GetAGCTop(RXA& rxa, double *max_agc) +void WCPAGC::getTop(double *max_agc) //for AGC Max Gain in setup { - *max_agc = 20 * log10 (rxa.agc->max_gain); + *max_agc = 20 * log10 (max_gain); } -void WCPAGC::SetAGCTop (RXA& rxa, double max_agc) +void WCPAGC::setTop(double _max_agc) //for AGC Max Gain in setup { - rxa.agc->max_gain = pow (10.0, (double) max_agc / 20.0); - loadWcpAGC ( rxa.agc ); + max_gain = pow (10.0, (double) _max_agc / 20.0); + loadWcpAGC(); } -void WCPAGC::SetAGCSlope (RXA& rxa, int slope) +void WCPAGC::setSlope(int _slope) { - rxa.agc->var_gain = pow (10.0, (double) slope / 20.0 / 10.0); - loadWcpAGC ( rxa.agc ); + var_gain = pow (10.0, (double) _slope / 20.0 / 10.0); + loadWcpAGC(); } -void WCPAGC::SetAGCFixed (RXA& rxa, double fixed_agc) +void WCPAGC::setMaxInputLevel(double _level) { - rxa.agc->fixed_gain = pow (10.0, (double) fixed_agc / 20.0); - loadWcpAGC ( rxa.agc ); + max_input = _level; + loadWcpAGC(); } -void WCPAGC::SetAGCMaxInputLevel (RXA& rxa, double level) +void WCPAGC::setRun(int state) { - rxa.agc->max_input = level; - loadWcpAGC ( rxa.agc ); -} - -/******************************************************************************************************** -* * -* TXA Properties * -* * -********************************************************************************************************/ - -void WCPAGC::SetALCSt (TXA& txa, int state) -{ - txa.alc->run = state; -} - -void WCPAGC::SetALCAttack (TXA& txa, int attack) -{ - txa.alc->tau_attack = (double) attack / 1000.0; - loadWcpAGC(txa.alc); -} - -void WCPAGC::SetALCDecay (TXA& txa, int decay) -{ - txa.alc->tau_decay = (double) decay / 1000.0; - loadWcpAGC(txa.alc); -} - -void WCPAGC::SetALCHang (TXA& txa, int hang) -{ - txa.alc->hangtime = (double) hang / 1000.0; - loadWcpAGC(txa.alc); -} - -void WCPAGC::SetALCMaxGain (TXA& txa, double maxgain) -{ - txa.alc->max_gain = pow (10.0,(double) maxgain / 20.0); - loadWcpAGC(txa.alc); -} - -void WCPAGC::SetLevelerSt (TXA& txa, int state) -{ - txa.leveler->run = state; -} - -void WCPAGC::SetLevelerAttack (TXA& txa, int attack) -{ - txa.leveler->tau_attack = (double) attack / 1000.0; - loadWcpAGC(txa.leveler); -} - -void WCPAGC::SetLevelerDecay (TXA& txa, int decay) -{ - txa.leveler->tau_decay = (double) decay / 1000.0; - loadWcpAGC(txa.leveler); -} - -void WCPAGC::SetLevelerHang (TXA& txa, int hang) -{ - txa.leveler->hangtime = (double) hang / 1000.0; - loadWcpAGC(txa.leveler); -} - -void WCPAGC::SetLevelerTop (TXA& txa, double maxgain) -{ - txa.leveler->max_gain = pow (10.0,(double) maxgain / 20.0); - loadWcpAGC(txa.leveler); + run = state; } } // namespace WDSP diff --git a/wdsp/wcpAGC.hpp b/wdsp/wcpAGC.hpp index 267595d24..a52e9620d 100644 --- a/wdsp/wcpAGC.hpp +++ b/wdsp/wcpAGC.hpp @@ -28,6 +28,8 @@ warren@wpratt.com #ifndef wdsp_wcpagc_h #define wdsp_wcpagc_h +#include + #include "export.h" #define MAX_SAMPLE_RATE (384000.0) @@ -37,9 +39,6 @@ warren@wpratt.com namespace WDSP { -class RXA; -class TXA; - class WDSP_API WCPAGC { public: @@ -71,16 +70,16 @@ public: int in_index; int attack_buffsize; - double* ring; - double* abs_ring; - int ring_buffsize; + std::array ring; + std::array abs_ring; + static const int ring_buffsize = RB_SIZE; double ring_max; double attack_mult; double decay_mult; double volts; double save_volts; - double out_sample[2]; + std::array out_sample; double abs_out_sample; int state; @@ -106,8 +105,7 @@ public: double hang_decay_mult; int decay_type; - static void xwcpagc (WCPAGC *a); - static WCPAGC* create_wcpagc ( + WCPAGC( int run, int mode, int pmode, @@ -132,43 +130,34 @@ public: double hang_thresh, double tau_hang_decay ); - static void destroy_wcpagc (WCPAGC *a); - static void flush_wcpagc (WCPAGC *a); - static void setBuffers_wcpagc (WCPAGC *a, float* in, float* out); - static void setSamplerate_wcpagc (WCPAGC *a, int rate); - static void setSize_wcpagc (WCPAGC *a, int size); - // RXA Properties - static void SetAGCMode (RXA& rxa, int mode); - static void SetAGCFixed (RXA& rxa, double fixed_agc); - static void SetAGCAttack (RXA& rxa, int attack); - static void SetAGCDecay (RXA& rxa, int decay); - static void SetAGCHang (RXA& rxa, int hang); - static void GetAGCHangLevel(RXA& rxa, double *hangLevel); - static void SetAGCHangLevel(RXA& rxa, double hangLevel); - static void GetAGCHangThreshold(RXA& rxa, int *hangthreshold); - static void SetAGCHangThreshold (RXA& rxa, int hangthreshold); - static void GetAGCTop(RXA& rxa, double *max_agc); - static void SetAGCTop (RXA& rxa, double max_agc); - static void SetAGCSlope (RXA& rxa, int slope); - static void SetAGCThresh(RXA& rxa, double thresh, double size, double rate); - static void GetAGCThresh(RXA& rxa, double *thresh, double size, double rate); - static void SetAGCMaxInputLevel (RXA& rxa, double level); - // TXA Properties - static void SetALCSt (TXA& txa, int state); - static void SetALCAttack (TXA& txa, int attack); - static void SetALCDecay (TXA& txa, int decay); - static void SetALCHang (TXA& txa, int hang); - static void SetLevelerSt (TXA& txa, int state); - static void SetLevelerAttack (TXA& txa, int attack); - static void SetLevelerDecay (TXA& txa, int decay); - static void SetLevelerHang (TXA& txa, int hang); - static void SetLevelerTop (TXA& txa, double maxgain); - static void SetALCMaxGain (TXA& txa, double maxgain); + WCPAGC(const WCPAGC&) = delete; + WCPAGC& operator=(const WCPAGC& other) = delete; + ~WCPAGC() = default; + + void flush(); + void execute(); + void setBuffers(float* in, float* out); + void setSamplerate(int rate); + void setSize(int size); + // Public Properties + void setMode(int mode); + void setFixed(double fixed_agc); + void setAttack(int attack); + void setDecay(int decay); + void setHang(int hang); + void getHangLevel(double *hangLevel); + void setHangLevel(double hangLevel); + void getHangThreshold(int *hangthreshold); + void setHangThreshold(int hangthreshold); + void getTop(double *max_agc); + void setTop(double max_agc); + void setSlope(int slope); + void setMaxInputLevel(double level); + void setRun(int state); + void loadWcpAGC(); private: - static void loadWcpAGC (WCPAGC *a); - static void calc_wcpagc (WCPAGC *a); - static void decalc_wcpagc (WCPAGC *a); + void calc(); }; } // namespace WDSP