1
0
mirror of https://github.com/f4exb/sdrangel.git synced 2024-12-23 01:55:48 -05:00

WDSP: AMSQ and AMD: replaced static methods

This commit is contained in:
f4exb 2024-07-26 17:52:34 +02:00
parent dac4bc08df
commit a239fe47e9
8 changed files with 348 additions and 381 deletions

View File

@ -466,9 +466,9 @@ void WDSPRxSink::applySettings(const WDSPRxSettings& settings, bool force)
WDSP::RXA::SetMode(*m_rxa, WDSP::RXA::RXA_SAM);
if (dsb) {
WDSP::AMD::SetAMDSBMode(*m_rxa, 0);
m_rxa->amd->setSBMode(0);
} else {
WDSP::AMD::SetAMDSBMode(*m_rxa, usb ? 2 : 1);
m_rxa->amd->setSBMode(usb ? 2 : 1);
}
}
else if (settings.m_demod == WDSPRxProfile::DemodFMN)
@ -643,7 +643,7 @@ void WDSPRxSink::applySettings(const WDSPRxSettings& settings, bool force)
// AM option
if ((m_settings.m_amFadeLevel != settings.m_amFadeLevel) || force) {
WDSP::AMD::SetAMDFadeLevel(*m_rxa, settings.m_amFadeLevel);
m_rxa->amd->setFadeLevel(settings.m_amFadeLevel);
}
// FM options
@ -681,7 +681,7 @@ void WDSPRxSink::applySettings(const WDSPRxSettings& settings, bool force)
|| (m_settings.m_squelchMode != settings.m_squelchMode) || force)
{
WDSP::SSQL::SetSSQLRun(*m_rxa, 0);
WDSP::AMSQ::SetAMSQRun(*m_rxa, 0);
m_rxa->amsq->setRun(0);
WDSP::FMSQ::SetFMSQRun(*m_rxa, 0);
if (settings.m_squelch)
@ -697,9 +697,9 @@ void WDSPRxSink::applySettings(const WDSPRxSettings& settings, bool force)
break;
case WDSPRxProfile::SquelchModeAM:
{
WDSP::AMSQ::SetAMSQRun(*m_rxa, 1);
m_rxa->amsq->setRun(1);
double threshold = ((settings.m_squelchThreshold / 100.0) * 160.0) - 160.0;
WDSP::AMSQ::SetAMSQThreshold(*m_rxa, threshold);
m_rxa->amsq->setThreshold(threshold);
}
break;
case WDSPRxProfile::SquelchModeFM:
@ -725,7 +725,7 @@ void WDSPRxSink::applySettings(const WDSPRxSettings& settings, bool force)
}
if ((m_settings.m_amsqMaxTail != settings.m_amsqMaxTail) || force) {
WDSP::AMSQ::SetAMSQMaxTail(*m_rxa, settings.m_amsqMaxTail);
m_rxa->amsq->setMaxTail(settings.m_amsqMaxTail);
}
// Equalizer

View File

@ -227,7 +227,7 @@ RXA* RXA::create_rxa (
0); // pointer for gain computation
// AM squelch capture (for other modes than FM)
rxa->amsq = AMSQ::create_amsq (
rxa->amsq = new AMSQ(
0, // run
rxa->dsp_size, // buffer size
rxa->midbuff, // pointer to signal input buffer used by xamsq
@ -244,7 +244,7 @@ RXA* RXA::create_rxa (
0.0); // muted gain
// AM/SAM demodulator
rxa->amd = AMD::create_amd (
rxa->amd = new AMD(
0, // run - OFF by default
rxa->dsp_size, // buffer size
rxa->midbuff, // pointer to input buffer
@ -580,8 +580,8 @@ void RXA::destroy_rxa (RXA *rxa)
SNBA::destroy_snba (rxa->snba);
FMSQ::destroy_fmsq (rxa->fmsq);
FMD::destroy_fmd (rxa->fmd);
AMD::destroy_amd (rxa->amd);
AMSQ::destroy_amsq (rxa->amsq);
delete (rxa->amd);
delete (rxa->amsq);
delete (rxa->smeter);
delete (rxa->sender);
delete (rxa->bpsnba);
@ -612,8 +612,8 @@ void RXA::flush_rxa (RXA *rxa)
rxa->bpsnba->flush();
rxa->sender->flush();
rxa->smeter->flush();
AMSQ::flush_amsq (rxa->amsq);
AMD::flush_amd (rxa->amd);
rxa->amsq->flush();
rxa->amd->flush();
FMD::flush_fmd (rxa->fmd);
FMSQ::flush_fmsq (rxa->fmsq);
SNBA::flush_snba (rxa->snba);
@ -644,9 +644,9 @@ void RXA::xrxa (RXA *rxa)
rxa->nbp0->execute(0);
rxa->smeter->execute();
rxa->sender->execute();
AMSQ::xamsqcap (rxa->amsq);
rxa->amsq->xcap();
rxa->bpsnba->exec_out(0);
AMD::xamd (rxa->amd);
rxa->amd->execute();
FMD::xfmd (rxa->fmd);
FMSQ::xfmsq (rxa->fmsq);
rxa->bpsnba->exec_in(1);
@ -669,7 +669,7 @@ void RXA::xrxa (RXA *rxa)
MPEAK::xmpeak (rxa->mpeak);
SSQL::xssql (rxa->ssql);
PANEL::xpanel (rxa->panel);
AMSQ::xamsq (rxa->amsq);
rxa->amsq->execute();
rxa->rsmpout->execute();
}
@ -757,8 +757,8 @@ void RXA::setDSPSamplerate (RXA *rxa, int dsp_rate)
rxa->bpsnba->setSamplerate(rxa->dsp_rate);
rxa->smeter->setSamplerate(rxa->dsp_rate);
rxa->sender->setSamplerate(rxa->dsp_rate);
AMSQ::setSamplerate_amsq (rxa->amsq, rxa->dsp_rate);
AMD::setSamplerate_amd (rxa->amd, rxa->dsp_rate);
rxa->amsq->setSamplerate(rxa->dsp_rate);
rxa->amd->setSamplerate(rxa->dsp_rate);
FMD::setSamplerate_fmd (rxa->fmd, rxa->dsp_rate);
FMSQ::setBuffers_fmsq (rxa->fmsq, rxa->midbuff, rxa->midbuff, rxa->fmd->audio);
FMSQ::setSamplerate_fmsq (rxa->fmsq, rxa->dsp_rate);
@ -825,10 +825,10 @@ void RXA::setDSPBuffsize (RXA *rxa, int dsp_size)
rxa->smeter->setSize(rxa->dsp_size);
rxa->sender->setBuffers(rxa->midbuff);
rxa->sender->setSize(rxa->dsp_size);
AMSQ::setBuffers_amsq (rxa->amsq, rxa->midbuff, rxa->midbuff, rxa->midbuff);
AMSQ::setSize_amsq (rxa->amsq, rxa->dsp_size);
AMD::setBuffers_amd (rxa->amd, rxa->midbuff, rxa->midbuff);
AMD::setSize_amd (rxa->amd, rxa->dsp_size);
rxa->amsq->setBuffers(rxa->midbuff, rxa->midbuff, rxa->midbuff);
rxa->amsq->setSize(rxa->dsp_size);
rxa->amd->setBuffers(rxa->midbuff, rxa->midbuff);
rxa->amd->setSize(rxa->dsp_size);
FMD::setBuffers_fmd (rxa->fmd, rxa->midbuff, rxa->midbuff);
FMD::setSize_fmd (rxa->fmd, rxa->dsp_size);
FMSQ::setBuffers_fmsq (rxa->fmsq, rxa->midbuff, rxa->midbuff, rxa->fmd->audio);
@ -1225,6 +1225,26 @@ void RXA::NBPSetAutoIncrease (RXA& rxa, int autoincr)
}
}
void RXA::SetAMDRun(RXA& rxa, int run)
{
AMD *a = rxa.amd;
if (run != run)
{
RXA::bp1Check (
rxa,
run,
rxa.snba->run,
rxa.emnr->run,
rxa.anf->run,
rxa.anr->run
);
run = run;
RXA::bp1Set (rxa);
}
}
/********************************************************************************************************
* *
* Collectives *

View File

@ -167,6 +167,8 @@ public:
static void NBPSetNotchesRun (RXA& rxa, int run);
static void NBPSetWindow (RXA& rxa, int wintype);
static void NBPSetAutoIncrease (RXA& rxa, int autoincr);
// AMD
static void SetAMDRun(RXA& rxa, int run);
// Collectives
static void SetPassband (RXA& rxa, float f_low, float f_high);

View File

@ -135,7 +135,7 @@ TXA* TXA::create_txa (
-1, // index for gain value
0); // pointer for gain computation
txa->amsq.p = AMSQ::create_amsq (
txa->amsq.p = new AMSQ(
0, // run
txa->dsp_size, // size
txa->midbuff, // input buffer
@ -544,7 +544,7 @@ void TXA::destroy_txa (TXA *txa)
EMPHP::destroy_emphp (txa->preemph.p);
delete (txa->eqmeter.p);
EQP::destroy_eqp (txa->eqp.p);
AMSQ::destroy_amsq (txa->amsq.p);
delete (txa->amsq.p);
delete (txa->micmeter.p);
PHROT::destroy_phrot (txa->phrot.p);
PANEL::destroy_panel (txa->panel.p);
@ -566,7 +566,7 @@ void TXA::flush_txa (TXA* txa)
PANEL::flush_panel (txa->panel.p);
PHROT::flush_phrot (txa->phrot.p);
txa->micmeter.p->flush ();
AMSQ::flush_amsq (txa->amsq.p);
txa->amsq.p->flush ();
EQP::flush_eqp (txa->eqp.p);
txa->eqmeter.p->flush ();
EMPHP::flush_emphp (txa->preemph.p);
@ -600,8 +600,8 @@ void xtxa (TXA* txa)
PANEL::xpanel (txa->panel.p); // includes MIC gain
PHROT::xphrot (txa->phrot.p); // phase rotator
txa->micmeter.p->execute (); // MIC meter
AMSQ::xamsqcap (txa->amsq.p); // downward expander capture
AMSQ::xamsq (txa->amsq.p); // downward expander action
txa->amsq.p->xcap (); // downward expander capture
txa->amsq.p->execute (); // downward expander action
EQP::xeqp (txa->eqp.p); // pre-EQ
txa->eqmeter.p->execute (); // EQ meter
EMPHP::xemphp (txa->preemph.p, 0); // FM pre-emphasis (first option)
@ -698,7 +698,7 @@ void TXA::setDSPSamplerate (TXA *txa, int dsp_rate)
PANEL::setSamplerate_panel (txa->panel.p, txa->dsp_rate);
PHROT::setSamplerate_phrot (txa->phrot.p, txa->dsp_rate);
txa->micmeter.p->setSamplerate (txa->dsp_rate);
AMSQ::setSamplerate_amsq (txa->amsq.p, txa->dsp_rate);
txa->amsq.p->setSamplerate (txa->dsp_rate);
EQP::setSamplerate_eqp (txa->eqp.p, txa->dsp_rate);
txa->eqmeter.p->setSamplerate (txa->dsp_rate);
EMPHP::setSamplerate_emphp (txa->preemph.p, txa->dsp_rate);
@ -762,8 +762,8 @@ void TXA::setDSPBuffsize (TXA *txa, int dsp_size)
PHROT::setSize_phrot (txa->phrot.p, txa->dsp_size);
txa->micmeter.p->setBuffers (txa->midbuff);
txa->micmeter.p->setSize (txa->dsp_size);
AMSQ::setBuffers_amsq (txa->amsq.p, txa->midbuff, txa->midbuff, txa->midbuff);
AMSQ::setSize_amsq (txa->amsq.p, txa->dsp_size);
txa->amsq.p->setBuffers (txa->midbuff, txa->midbuff, txa->midbuff);
txa->amsq.p->setSize (txa->dsp_size);
EQP::setBuffers_eqp (txa->eqp.p, txa->midbuff, txa->midbuff);
EQP::setSize_eqp (txa->eqp.p, txa->dsp_size);
txa->eqmeter.p->setBuffers (txa->midbuff);

View File

@ -37,93 +37,85 @@ warren@wpratt.com
namespace WDSP {
AMD* AMD::create_amd
AMD::AMD
(
int run,
int buff_size,
float *in_buff,
float *out_buff,
int mode,
int levelfade,
int sbmode,
int sample_rate,
double fmin,
double fmax,
double zeta,
double omegaN,
double tauR,
double tauI
int _run,
int _buff_size,
float *_in_buff,
float *_out_buff,
int _mode,
int _levelfade,
int _sbmode,
int _sample_rate,
double _fmin,
double _fmax,
double _zeta,
double _omegaN,
double _tauR,
double _tauI
)
{
AMD *a = new AMD();
a->run = run;
a->buff_size = buff_size;
a->in_buff = in_buff;
a->out_buff = out_buff;
a->mode = mode;
a->levelfade = levelfade;
a->sbmode = sbmode;
a->sample_rate = (float)sample_rate;
a->fmin = fmin;
a->fmax = fmax;
a->zeta = zeta;
a->omegaN = omegaN;
a->tauR = tauR;
a->tauI = tauI;
init_amd(a);
return a;
run = _run;
buff_size = _buff_size;
in_buff = _in_buff;
out_buff = _out_buff;
mode = _mode;
levelfade = _levelfade;
sbmode = _sbmode;
sample_rate = (double) _sample_rate;
fmin = _fmin;
fmax = _fmax;
zeta = _zeta;
omegaN = _omegaN;
tauR = _tauR;
tauI = _tauI;
init();
}
void AMD::destroy_amd(AMD *a)
{
delete a;
}
void AMD::init_amd(AMD *a)
void AMD::init()
{
//pll
a->omega_min = 2 * M_PI * a->fmin / a->sample_rate;
a->omega_max = 2 * M_PI * a->fmax / a->sample_rate;
a->g1 = 1.0 - std::exp(-2.0 * a->omegaN * a->zeta / a->sample_rate);
a->g2 = -a->g1 + 2.0 * (1 - exp(-a->omegaN * a->zeta / a->sample_rate) * cos(a->omegaN / a->sample_rate * sqrt(1.0 - a->zeta * a->zeta)));
a->phs = 0.0;
a->fil_out = 0.0;
a->omega = 0.0;
omega_min = 2 * M_PI * fmin / sample_rate;
omega_max = 2 * M_PI * fmax / sample_rate;
g1 = 1.0 - std::exp(-2.0 * omegaN * zeta / sample_rate);
g2 = -g1 + 2.0 * (1 - exp(-omegaN * zeta / sample_rate) * cos(omegaN / sample_rate * sqrt(1.0 - zeta * zeta)));
phs = 0.0;
fil_out = 0.0;
omega = 0.0;
//fade leveler
a->dc = 0.0;
a->dc_insert = 0.0;
a->mtauR = exp(-1.0 / (a->sample_rate * a->tauR));
a->onem_mtauR = 1.0 - a->mtauR;
a->mtauI = exp(-1.0 / (a->sample_rate * a->tauI));
a->onem_mtauI = 1.0 - a->mtauI;
dc = 0.0;
dc_insert = 0.0;
mtauR = exp(-1.0 / (sample_rate * tauR));
onem_mtauR = 1.0 - mtauR;
mtauI = exp(-1.0 / (sample_rate * tauI));
onem_mtauI = 1.0 - mtauI;
//sideband separation
a->c0[0] = -0.328201924180698;
a->c0[1] = -0.744171491539427;
a->c0[2] = -0.923022915444215;
a->c0[3] = -0.978490468768238;
a->c0[4] = -0.994128272402075;
a->c0[5] = -0.998458978159551;
a->c0[6] = -0.999790306259206;
c0[0] = -0.328201924180698;
c0[1] = -0.744171491539427;
c0[2] = -0.923022915444215;
c0[3] = -0.978490468768238;
c0[4] = -0.994128272402075;
c0[5] = -0.998458978159551;
c0[6] = -0.999790306259206;
a->c1[0] = -0.0991227952747244;
a->c1[1] = -0.565619728761389;
a->c1[2] = -0.857467122550052;
a->c1[3] = -0.959123933111275;
a->c1[4] = -0.988739372718090;
a->c1[5] = -0.996959189310611;
a->c1[6] = -0.999282492800792;
c1[0] = -0.0991227952747244;
c1[1] = -0.565619728761389;
c1[2] = -0.857467122550052;
c1[3] = -0.959123933111275;
c1[4] = -0.988739372718090;
c1[5] = -0.996959189310611;
c1[6] = -0.999282492800792;
}
void AMD::flush_amd (AMD *a)
void AMD::flush()
{
a->dc = 0.0;
a->dc_insert = 0.0;
dc = 0.0;
dc_insert = 0.0;
}
void AMD::xamd (AMD *a)
void AMD::execute()
{
int i;
double audio;
@ -135,28 +127,28 @@ void AMD::xamd (AMD *a)
double ai_ps, bi_ps, aq_ps, bq_ps;
int j, k;
if (a->run)
if (run)
{
switch (a->mode)
switch (mode)
{
case 0: //AM Demodulator
{
for (i = 0; i < a->buff_size; i++)
for (i = 0; i < buff_size; i++)
{
double xr = a->in_buff[2 * i + 0];
double xi = a->in_buff[2 * i + 1];
double xr = in_buff[2 * i + 0];
double xi = in_buff[2 * i + 1];
audio = sqrt(xr*xr + xi*xi);
if (a->levelfade)
if (levelfade)
{
a->dc = a->mtauR * a->dc + a->onem_mtauR * audio;
a->dc_insert = a->mtauI * a->dc_insert + a->onem_mtauI * audio;
audio += a->dc_insert - a->dc;
dc = mtauR * dc + onem_mtauR * audio;
dc_insert = mtauI * dc_insert + onem_mtauI * audio;
audio += dc_insert - dc;
}
a->out_buff[2 * i + 0] = audio;
a->out_buff[2 * i + 1] = audio;
out_buff[2 * i + 0] = audio;
out_buff[2 * i + 1] = audio;
}
break;
@ -164,52 +156,52 @@ void AMD::xamd (AMD *a)
case 1: //Synchronous AM Demodulator with Sideband Separation
{
for (i = 0; i < a->buff_size; i++)
for (i = 0; i < buff_size; i++)
{
vco[0] = cos(a->phs);
vco[1] = sin(a->phs);
vco[0] = cos(phs);
vco[1] = sin(phs);
ai = a->in_buff[2 * i + 0] * vco[0];
bi = a->in_buff[2 * i + 0] * vco[1];
aq = a->in_buff[2 * i + 1] * vco[0];
bq = a->in_buff[2 * i + 1] * vco[1];
ai = in_buff[2 * i + 0] * vco[0];
bi = in_buff[2 * i + 0] * vco[1];
aq = in_buff[2 * i + 1] * vco[0];
bq = in_buff[2 * i + 1] * vco[1];
if (a->sbmode != 0)
if (sbmode != 0)
{
a->a[0] = a->dsI;
a->b[0] = bi;
a->c[0] = a->dsQ;
a->d[0] = aq;
a->dsI = ai;
a->dsQ = bq;
a[0] = dsI;
b[0] = bi;
c[0] = dsQ;
d[0] = aq;
dsI = ai;
dsQ = bq;
for (j = 0; j < STAGES; j++)
{
k = 3 * j;
a->a[k + 3] = a->c0[j] * (a->a[k] - a->a[k + 5]) + a->a[k + 2];
a->b[k + 3] = a->c1[j] * (a->b[k] - a->b[k + 5]) + a->b[k + 2];
a->c[k + 3] = a->c0[j] * (a->c[k] - a->c[k + 5]) + a->c[k + 2];
a->d[k + 3] = a->c1[j] * (a->d[k] - a->d[k + 5]) + a->d[k + 2];
a[k + 3] = c0[j] * (a[k] - a[k + 5]) + a[k + 2];
b[k + 3] = c1[j] * (b[k] - b[k + 5]) + b[k + 2];
c[k + 3] = c0[j] * (c[k] - c[k + 5]) + c[k + 2];
d[k + 3] = c1[j] * (d[k] - d[k + 5]) + d[k + 2];
}
ai_ps = a->a[OUT_IDX];
bi_ps = a->b[OUT_IDX];
bq_ps = a->c[OUT_IDX];
aq_ps = a->d[OUT_IDX];
ai_ps = a[OUT_IDX];
bi_ps = b[OUT_IDX];
bq_ps = c[OUT_IDX];
aq_ps = d[OUT_IDX];
for (j = OUT_IDX + 2; j > 0; j--)
{
a->a[j] = a->a[j - 1];
a->b[j] = a->b[j - 1];
a->c[j] = a->c[j - 1];
a->d[j] = a->d[j - 1];
a[j] = a[j - 1];
b[j] = b[j - 1];
c[j] = c[j - 1];
d[j] = d[j - 1];
}
}
corr[0] = +ai + bq;
corr[1] = -bi + aq;
switch(a->sbmode)
switch(sbmode)
{
case 0: //both sidebands
{
@ -228,100 +220,80 @@ void AMD::xamd (AMD *a)
}
}
if (a->levelfade)
if (levelfade)
{
a->dc = a->mtauR * a->dc + a->onem_mtauR * audio;
a->dc_insert = a->mtauI * a->dc_insert + a->onem_mtauI * corr[0];
audio += a->dc_insert - a->dc;
dc = mtauR * dc + onem_mtauR * audio;
dc_insert = mtauI * dc_insert + onem_mtauI * corr[0];
audio += dc_insert - dc;
}
a->out_buff[2 * i + 0] = audio;
a->out_buff[2 * i + 1] = audio;
out_buff[2 * i + 0] = audio;
out_buff[2 * i + 1] = audio;
if ((corr[0] == 0.0) && (corr[1] == 0.0))
corr[0] = 1.0;
det = atan2(corr[1], corr[0]);
del_out = a->fil_out;
a->omega += a->g2 * det;
del_out = fil_out;
omega += g2 * det;
if (a->omega < a->omega_min)
a->omega = a->omega_min;
if (omega < omega_min)
omega = omega_min;
if (a->omega > a->omega_max)
a->omega = a->omega_max;
if (omega > omega_max)
omega = omega_max;
a->fil_out = a->g1 * det + a->omega;
a->phs += del_out;
fil_out = g1 * det + omega;
phs += del_out;
while (a->phs >= 2 * M_PI)
a->phs -= 2 * M_PI;
while (phs >= 2 * M_PI)
phs -= 2 * M_PI;
while (a->phs < 0.0)
a->phs += 2 * M_PI;
while (phs < 0.0)
phs += 2 * M_PI;
}
break;
}
}
}
else if (a->in_buff != a->out_buff)
else if (in_buff != out_buff)
{
std::copy (a->in_buff, a->in_buff + a->buff_size * 2, a->out_buff);
std::copy (in_buff, in_buff + buff_size * 2, out_buff);
}
}
void AMD::setBuffers_amd (AMD *a, float* in, float* out)
void AMD::setBuffers(float* in, float* out)
{
a->in_buff = in;
a->out_buff = out;
in_buff = in;
out_buff = out;
}
void AMD::setSamplerate_amd (AMD *a, int rate)
void AMD::setSamplerate(int rate)
{
a->sample_rate = rate;
init_amd(a);
sample_rate = rate;
init();
}
void AMD::setSize_amd (AMD *a, int size)
void AMD::setSize(int size)
{
a->buff_size = size;
buff_size = size;
}
/********************************************************************************************************
* *
* RXA Properties *
* Public Properties *
* *
********************************************************************************************************/
void AMD::SetAMDRun(RXA& rxa, int run)
void AMD::setSBMode(int _sbmode)
{
AMD *a = rxa.amd;
if (a->run != run)
{
RXA::bp1Check (
rxa,
run,
rxa.snba->run,
rxa.emnr->run,
rxa.anf->run,
rxa.anr->run
);
a->run = run;
RXA::bp1Set (rxa);
}
sbmode = _sbmode;
}
void AMD::SetAMDSBMode(RXA& rxa, int sbmode)
void AMD::setFadeLevel(int _levelfade)
{
rxa.amd->sbmode = sbmode;
}
void AMD::SetAMDFadeLevel(RXA& rxa, int levelfade)
{
rxa.amd->levelfade = levelfade;
levelfade = _levelfade;
}
} // namesoace WDSP

View File

@ -80,7 +80,7 @@ public:
int sbmode; // sideband mode
int levelfade; // Fade Leveler switch
static AMD* create_amd
AMD
(
int run,
int buff_size,
@ -97,18 +97,17 @@ public:
double tauR,
double tauI
);
~AMD() = default;
static void init_amd (AMD *a);
static void destroy_amd (AMD *a);
static void flush_amd (AMD *a);
static void xamd (AMD *a);
static void setBuffers_amd (AMD *a, float* in, float* out);
static void setSamplerate_amd (AMD *a, int rate);
static void setSize_amd (AMD *a, int size);
// RXA Properties
static void SetAMDRun(RXA& rxa, int run);
static void SetAMDSBMode(RXA& rxa, int sbmode);
static void SetAMDFadeLevel(RXA& rxa, int levelfade);
void init();
void flush();
void execute();
void setBuffers(float* in, float* out);
void setSamplerate(int rate);
void setSize(int size);
// Public Properties
void setSBMode(int sbmode);
void setFadeLevel(int levelfade);
};
} // namespace WDSP

View File

@ -32,100 +32,97 @@ warren@wpratt.com
namespace WDSP {
void AMSQ::compute_slews(AMSQ *a)
void AMSQ::compute_slews()
{
int i;
double delta, theta;
delta = PI / (double)a->ntup;
delta = PI / (double)ntup;
theta = 0.0;
for (i = 0; i <= a->ntup; i++)
for (i = 0; i <= ntup; i++)
{
a->cup[i] = a->muted_gain + (1.0 - a->muted_gain) * 0.5 * (1.0 - cos (theta));
cup[i] = muted_gain + (1.0 - muted_gain) * 0.5 * (1.0 - cos (theta));
theta += delta;
}
delta = PI / (double)a->ntdown;
delta = PI / (double)ntdown;
theta = 0.0;
for (i = 0; i <= a->ntdown; i++)
for (i = 0; i <= ntdown; i++)
{
a->cdown[i] = a->muted_gain + (1.0 - a->muted_gain) * 0.5 * (1.0 + cos (theta));
cdown[i] = muted_gain + (1.0 - muted_gain) * 0.5 * (1.0 + cos (theta));
theta += delta;
}
}
void AMSQ::calc_amsq(AMSQ *a)
void AMSQ::calc()
{
// signal averaging
a->trigsig = new float[a->size * 2];
a->avm = exp(-1.0 / (a->rate * a->avtau));
a->onem_avm = 1.0 - a->avm;
a->avsig = 0.0;
trigsig = new float[size * 2];
avm = exp(-1.0 / (rate * avtau));
onem_avm = 1.0 - avm;
avsig = 0.0;
// level change
a->ntup = (int)(a->tup * a->rate);
a->ntdown = (int)(a->tdown * a->rate);
a->cup = new double[(a->ntup + 1) * 2]; // (float *)malloc0((a->ntup + 1) * sizeof(float));
a->cdown = new double[(a->ntdown + 1) * 2]; // (float *)malloc0((a->ntdown + 1) * sizeof(float));
compute_slews(a);
ntup = (int)(tup * rate);
ntdown = (int)(tdown * rate);
cup = new double[(ntup + 1) * 2]; // (float *)malloc0((ntup + 1) * sizeof(float));
cdown = new double[(ntdown + 1) * 2]; // (float *)malloc0((ntdown + 1) * sizeof(float));
compute_slews();
// control
a->state = 0;
state = 0;
}
void AMSQ::decalc_amsq (AMSQ *a)
void AMSQ::decalc()
{
delete[] a->cdown;
delete[] a->cup;
delete[] a->trigsig;
delete[] cdown;
delete[] cup;
delete[] trigsig;
}
AMSQ* AMSQ::create_amsq (
int run,
int size,
float* in,
float* out,
float* trigger,
int rate,
double avtau,
double tup,
double tdown,
double tail_thresh,
double unmute_thresh,
double min_tail,
double max_tail,
double muted_gain
)
AMSQ::AMSQ (
int _run,
int _size,
float* _in,
float* _out,
float* _trigger,
int _rate,
double _avtau,
double _tup,
double _tdown,
double _tail_thresh,
double _unmute_thresh,
double _min_tail,
double _max_tail,
double _muted_gain
) :
run(_run),
size(_size),
in(_in),
out(_out),
trigger(_trigger),
rate((double) _rate),
avtau(_avtau),
tup(_tup),
tdown(_tdown),
tail_thresh(_tail_thresh),
unmute_thresh(_unmute_thresh),
min_tail(_min_tail),
max_tail(_max_tail),
muted_gain(_muted_gain)
{
AMSQ *a = new AMSQ;
a->run = run;
a->size = size;
a->in = in;
a->out = out;
a->rate = (float)rate;
a->muted_gain = muted_gain;
a->trigger = trigger;
a->avtau = avtau;
a->tup = tup;
a->tdown = tdown;
a->tail_thresh = tail_thresh;
a->unmute_thresh = unmute_thresh;
a->min_tail = min_tail;
a->max_tail = max_tail;
calc_amsq (a);
return a;
calc();
}
void AMSQ::destroy_amsq (AMSQ *a)
AMSQ::~AMSQ()
{
decalc_amsq (a);
delete a;
decalc();
}
void AMSQ::flush_amsq (AMSQ*a)
void AMSQ::flush()
{
std::fill(a->trigsig, a->trigsig + a->size * 2, 0);
a->avsig = 0.0;
a->state = 0;
std::fill(trigsig, trigsig + size * 2, 0);
avsig = 0.0;
state = 0;
}
enum _amsqstate
@ -137,114 +134,116 @@ enum _amsqstate
DECREASE
};
void AMSQ::xamsq (AMSQ *a)
void AMSQ::execute()
{
if (a->run)
if (run)
{
int i;
double sig, siglimit;
for (i = 0; i < a->size; i++)
for (i = 0; i < size; i++)
{
sig = sqrt (a->trigsig[2 * i + 0] * a->trigsig[2 * i + 0] + a->trigsig[2 * i + 1] * a->trigsig[2 * i + 1]);
a->avsig = a->avm * a->avsig + a->onem_avm * sig;
double trigr = trigsig[2 * i + 0];
double trigi = trigsig[2 * i + 1];
sig = sqrt (trigr*trigr + trigi*trigi);
avsig = avm * avsig + onem_avm * sig;
switch (a->state)
switch (state)
{
case MUTED:
if (a->avsig > a->unmute_thresh)
if (avsig > unmute_thresh)
{
a->state = INCREASE;
a->count = a->ntup;
state = INCREASE;
count = ntup;
}
a->out[2 * i + 0] = a->muted_gain * a->in[2 * i + 0];
a->out[2 * i + 1] = a->muted_gain * a->in[2 * i + 1];
out[2 * i + 0] = muted_gain * in[2 * i + 0];
out[2 * i + 1] = muted_gain * in[2 * i + 1];
break;
case INCREASE:
a->out[2 * i + 0] = a->in[2 * i + 0] * a->cup[a->ntup - a->count];
a->out[2 * i + 1] = a->in[2 * i + 1] * a->cup[a->ntup - a->count];
out[2 * i + 0] = in[2 * i + 0] * cup[ntup - count];
out[2 * i + 1] = in[2 * i + 1] * cup[ntup - count];
if (a->count-- == 0)
a->state = UNMUTED;
if (count-- == 0)
state = UNMUTED;
break;
case UNMUTED:
if (a->avsig < a->tail_thresh)
if (avsig < tail_thresh)
{
a->state = TAIL;
state = TAIL;
if ((siglimit = a->avsig) > 1.0)
if ((siglimit = avsig) > 1.0)
siglimit = 1.0;
a->count = (int)((a->min_tail + (a->max_tail - a->min_tail) * (1.0 - siglimit)) * a->rate);
count = (int)((min_tail + (max_tail - min_tail) * (1.0 - siglimit)) * rate);
}
a->out[2 * i + 0] = a->in[2 * i + 0];
a->out[2 * i + 1] = a->in[2 * i + 1];
out[2 * i + 0] = in[2 * i + 0];
out[2 * i + 1] = in[2 * i + 1];
break;
case TAIL:
a->out[2 * i + 0] = a->in[2 * i + 0];
a->out[2 * i + 1] = a->in[2 * i + 1];
out[2 * i + 0] = in[2 * i + 0];
out[2 * i + 1] = in[2 * i + 1];
if (a->avsig > a->unmute_thresh)
if (avsig > unmute_thresh)
{
a->state = UNMUTED;
state = UNMUTED;
}
else if (a->count-- == 0)
else if (count-- == 0)
{
a->state = DECREASE;
a->count = a->ntdown;
state = DECREASE;
count = ntdown;
}
break;
case DECREASE:
a->out[2 * i + 0] = a->in[2 * i + 0] * a->cdown[a->ntdown - a->count];
a->out[2 * i + 1] = a->in[2 * i + 1] * a->cdown[a->ntdown - a->count];
out[2 * i + 0] = in[2 * i + 0] * cdown[ntdown - count];
out[2 * i + 1] = in[2 * i + 1] * cdown[ntdown - count];
if (a->count-- == 0)
a->state = MUTED;
if (count-- == 0)
state = MUTED;
break;
}
}
}
else if (a->in != a->out)
else if (in != out)
{
std::copy( a->in, a->in + a->size * 2, a->out);
std::copy( in, in + size * 2, out);
}
}
void AMSQ::xamsqcap (AMSQ *a)
void AMSQ::xcap()
{
std::copy(a->trigger, a->trigger + a->size * 2, a->trigsig);
std::copy(trigger, trigger + size * 2, trigsig);
}
void AMSQ::setBuffers_amsq (AMSQ *a, float* in, float* out, float* trigger)
void AMSQ::setBuffers(float* _in, float* _out, float* _trigger)
{
a->in = in;
a->out = out;
a->trigger = trigger;
in = _in;
out = _out;
trigger = _trigger;
}
void AMSQ::setSamplerate_amsq (AMSQ *a, int rate)
void AMSQ::setSamplerate(int _rate)
{
decalc_amsq (a);
a->rate = rate;
calc_amsq (a);
decalc();
rate = _rate;
calc();
}
void AMSQ::setSize_amsq (AMSQ *a, int size)
void AMSQ::setSize(int _size)
{
decalc_amsq (a);
a->size = size;
calc_amsq (a);
decalc();
size = _size;
calc();
}
/********************************************************************************************************
@ -253,53 +252,30 @@ void AMSQ::setSize_amsq (AMSQ *a, int size)
* *
********************************************************************************************************/
void AMSQ::SetAMSQRun (RXA& rxa, int run)
void AMSQ::setRun(int _run)
{
rxa.amsq->run = run;
run = _run;
}
void AMSQ::SetAMSQThreshold (RXA& rxa, double threshold)
void AMSQ::setThreshold(double _threshold)
{
double thresh = pow (10.0, threshold / 20.0);
rxa.amsq->tail_thresh = 0.9 * thresh;
rxa.amsq->unmute_thresh = thresh;
double thresh = pow (10.0, _threshold / 20.0);
tail_thresh = 0.9 * thresh;
unmute_thresh = thresh;
}
void AMSQ::SetAMSQMaxTail (RXA& rxa, double tail)
void AMSQ::setMaxTail(double _tail)
{
AMSQ *a;
a = rxa.amsq;
if (_tail < min_tail)
_tail = min_tail;
if (tail < a->min_tail)
tail = a->min_tail;
a->max_tail = tail;
max_tail = _tail;
}
/********************************************************************************************************
* *
* TXA Properties *
* *
********************************************************************************************************/
void AMSQ::SetAMSQRun (TXA& txa, int run)
{
txa.amsq.p->run = run;
}
void AMSQ::SetAMSQMutedGain (TXA& txa, double dBlevel)
void AMSQ::setMutedGain(double dBlevel)
{ // dBlevel is negative
AMSQ *a;
a = txa.amsq.p;
a->muted_gain = pow (10.0, dBlevel / 20.0);
compute_slews(a);
}
void AMSQ::SetAMSQThreshold (TXA& txa, double threshold)
{
double thresh = pow (10.0, threshold / 20.0);
txa.amsq.p->tail_thresh = 0.9 * thresh;
txa.amsq.p->unmute_thresh = thresh;
muted_gain = pow (10.0, dBlevel / 20.0);
compute_slews();
}
} // namespace WDSP

View File

@ -62,42 +62,40 @@ public:
double max_tail;
double muted_gain;
static AMSQ* create_amsq (
int run,
int size,
float* in,
float* out,
float* trigger,
int rate,
double avtau,
double tup,
double tdown,
double tail_thresh,
double unmute_thresh,
double min_tail,
double max_tail,
double muted_gain
AMSQ (
int _run,
int _size,
float* _in,
float* _out,
float* _trigger,
int _rate,
double _avtau,
double _tup,
double _tdown,
double _tail_thresh,
double _unmute_thresh,
double _min_tail,
double _max_tail,
double _muted_gain
);
static void destroy_amsq (AMSQ *a);
static void flush_amsq (AMSQ *a);
static void xamsq (AMSQ *a);
static void xamsqcap (AMSQ *a);
static void setBuffers_amsq (AMSQ *a, float* in, float* out, float* trigger);
static void setSamplerate_amsq (AMSQ *a, int rate);
static void setSize_amsq (AMSQ *a, int size);
~AMSQ();
void flush();
void execute();
void xcap();
void setBuffers(float* in, float* out, float* trigger);
void setSamplerate(int rate);
void setSize(int size);
// RXA Properties
static void SetAMSQRun (RXA& rxa, int run);
static void SetAMSQThreshold (RXA& rxa, double threshold);
static void SetAMSQMaxTail (RXA& rxa, double tail);
// TXA Properties
static void SetAMSQRun (TXA& txa, int run);
static void SetAMSQMutedGain (TXA& txa, double dBlevel);
static void SetAMSQThreshold (TXA& txa, double threshold);
void setRun(int run);
void setThreshold(double threshold);
void setMaxTail(double tail);
void setMutedGain(double dBlevel);
private:
static void compute_slews(AMSQ *a);
static void calc_amsq(AMSQ *a);
static void decalc_amsq (AMSQ *a);
void compute_slews();
void calc();
void decalc();
};
} // namespace WDSP